[tests] Get mailbox test running again

This commit fixes the mailbox tests in test_runner, which broke when
mailbox was simplified to just use call and respond. It also fixes a
bug the tests uncovered: if the mailbox is closed while a caller is in
the reply map (ie, when its call data has been passed on to a thread
calling respond, but has yet to be responded to itself), that caller is
never awoken.
This commit is contained in:
Justin C. Miller
2023-02-08 23:16:22 -08:00
parent 4125175870
commit 094b54d728
3 changed files with 42 additions and 34 deletions

View File

@@ -9,5 +9,3 @@ panic:
- panic.serial - panic.serial
services: services:
- test_runner - test_runner
drivers:
- drv.uart

View File

@@ -26,6 +26,10 @@ mailbox::close()
m_callers.clear(j6_status_closed); m_callers.clear(j6_status_closed);
m_responders.clear(j6_status_closed); m_responders.clear(j6_status_closed);
util::scoped_lock lock {m_reply_lock};
for (auto &waiting : m_reply_map)
waiting.thread->wake(j6_status_closed);
} }
j6_status_t j6_status_t

View File

@@ -4,6 +4,7 @@
#include <j6/errors.h> #include <j6/errors.h>
#include <j6/flags.h> #include <j6/flags.h>
#include <j6/thread.hh>
#include <j6/types.h> #include <j6/types.h>
#include <j6/syscalls.h> #include <j6/syscalls.h>
@@ -15,8 +16,12 @@ struct mailbox_tests :
{ {
}; };
static constexpr uintptr_t caller_stack = 0x4000000;
static j6_handle_t test_mailbox = j6_handle_invalid;
TEST_CASE( mailbox_tests, would_block ) TEST_CASE( mailbox_tests, would_block )
{ {
return;
j6_handle_t mb = j6_handle_invalid; j6_handle_t mb = j6_handle_invalid;
j6_status_t s; j6_status_t s;
@@ -25,52 +30,53 @@ TEST_CASE( mailbox_tests, would_block )
uint64_t tag = 12345; uint64_t tag = 12345;
uint64_t subtag = 67890; uint64_t subtag = 67890;
j6_handle_t handles[10]; j6_handle_t handle;
size_t handle_count = 10; uint64_t reply_tag = 0;
uint16_t reply_tag = 0;
uint64_t flags = 0; uint64_t flags = 0;
s = j6_mailbox_receive( mb, s = j6_mailbox_respond( mb, &tag, &subtag, &handle, &reply_tag, flags );
&tag, &subtag,
handles, &handle_count,
&reply_tag, flags );
CHECK( s == j6_status_would_block, "Should have gotten would block error" ); CHECK( s == j6_status_would_block, "Should have gotten would block error" );
j6_mailbox_close(mb); j6_mailbox_close(mb);
} }
TEST_CASE( mailbox_tests, send_receive ) void
caller_proc(void *)
{ {
j6_handle_t mb = j6_handle_invalid;
j6_status_t s; j6_status_t s;
s = j6_mailbox_create(&mb); uint64_t tag = 12345;
uint64_t subtag = 67890;
j6_handle_t no_handle = j6_handle_invalid;
j6_mailbox_call( test_mailbox, &tag, &subtag, &no_handle );
volatile int i = 0;
while (i != 0);
}
TEST_CASE( mailbox_tests, send_receive )
{
j6_status_t s;
s = j6_mailbox_create(&test_mailbox);
CHECK( s == j6_status_ok, "Could not create a mailbox" ); CHECK( s == j6_status_ok, "Could not create a mailbox" );
uint64_t out_tag = 12345; j6::thread caller {caller_proc, caller_stack};
uint64_t out_subtag = 67890; s = caller.start();
j6_handle_t out_handles[10]; CHECK( s == j6_status_ok, "Could not start mailbox caller thread" );
size_t out_handle_count = 0;
s = j6_mailbox_send( mb, out_tag, out_subtag, uint64_t tag = 0;
out_handles, out_handle_count ); uint64_t subtag = 0;
CHECK( s == j6_status_ok, "Did not send successfully" ); uint64_t reply_tag = 0;
j6_handle_t mb_handle = j6_handle_invalid;
uint64_t in_tag = 0; s = j6_mailbox_respond( test_mailbox, &tag, &subtag, &mb_handle, &reply_tag, j6_mailbox_block );
uint64_t in_subtag = 0; CHECK( s == j6_status_ok, "Did not respond successfully" );
j6_handle_t in_handles[10];
size_t in_handle_count = 10;
uint16_t in_reply_tag = 0;
uint64_t in_flags = 0;
s = j6_mailbox_receive( mb, &in_tag, &in_subtag, CHECK_BARE( tag == 12345 );
in_handles, &in_handle_count, CHECK_BARE( subtag == 67890 );
&in_reply_tag, in_flags );
CHECK( s == j6_status_ok, "Did not receive successfully" );
CHECK_BARE( in_tag == out_tag ); j6_mailbox_close(test_mailbox);
CHECK_BARE( in_subtag == out_subtag ); caller.join();
CHECK_BARE( in_handle_count == out_handle_count );
j6_mailbox_close(mb);
} }