mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-07-24 15:27:41 +08:00
fix(lockstep_scheduler): wait for threads before advancing time in test (#27798)
test_multiple_semaphores_waiting() spawns a worker thread per TestCase, then advances virtual time in a loop and completes each case in check(). Since check() early-returns while !_thread_ready, a slow-to-start worker thread can miss the whole loop: the loop advances past the case's timeout before the thread registers, so the case is never completed. ~TestCase() then fails EXPECT_TRUE(_is_done) and destroys a still-joinable std::thread, which calls std::terminate() and aborts the test. This was flaky (~50% locally, worse under CI load). Wait for every worker thread to be ready before advancing virtual time. Also re-comment the per-iteration std::cout that was left enabled. Signed-off-by: Julian Oes <julian@oes.ch>
This commit is contained in:
@@ -159,6 +159,18 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
void wait_until_ready()
|
||||
{
|
||||
// Block until the worker thread has locked its mutex and is about to wait
|
||||
// on the condition. Otherwise advancing virtual time could pass this case's
|
||||
// timeout before the thread even starts, so check() (which early-returns on
|
||||
// !_thread_ready) would never complete it and its thread would be left
|
||||
// joinable at destruction.
|
||||
while (!_thread_ready) {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
void check()
|
||||
{
|
||||
if (_is_done || !_thread_ready) {
|
||||
@@ -258,6 +270,12 @@ void test_multiple_semaphores_waiting()
|
||||
test_case->run();
|
||||
}
|
||||
|
||||
// Make sure every thread has started and is waiting before we advance virtual
|
||||
// time, so the loop below can't skip past a case's timeout before it registers.
|
||||
for (auto &test_case : test_cases) {
|
||||
test_case->wait_until_ready();
|
||||
}
|
||||
|
||||
const int min_step_size = 1;
|
||||
const int max_step_size = 100;
|
||||
|
||||
@@ -321,7 +339,7 @@ void test_usleep()
|
||||
TEST(LockstepScheduler, All)
|
||||
{
|
||||
for (unsigned iteration = 1; iteration <= 100; ++iteration) {
|
||||
std::cout << "Test iteration: " << iteration << "\n";
|
||||
//std::cout << "Test iteration: " << iteration << "\n";
|
||||
test_absolute_time();
|
||||
test_condition_timing_out();
|
||||
test_locked_semaphore_getting_unlocked();
|
||||
|
||||
Reference in New Issue
Block a user