diff --git a/Aurora/Runtime b/Aurora/Runtime index c6ce29a..5947e6a 160000 --- a/Aurora/Runtime +++ b/Aurora/Runtime @@ -1 +1 @@ -Subproject commit c6ce29a188350e8977cc6bfb2c020c836ad3895b +Subproject commit 5947e6a2c3a782f1363d1ae308b52441eb52879b diff --git a/Tests/Public/5. Hello Loop/Main.cpp b/Tests/Public/5. Hello Loop/Main.cpp index 426c8d8..f8b8226 100644 --- a/Tests/Public/5. Hello Loop/Main.cpp +++ b/Tests/Public/5. Hello Loop/Main.cpp @@ -85,6 +85,177 @@ TEST(Loop, Semaphore) ASSERT_TRUE(loop->WaitAll(100)); } +TEST(Loop, Semaphore2) +{ + auto semaA = AuLoop::NewLSSemaphore(1); + auto semaB = AuLoop::NewLSSemaphore(0); + auto loop = AuLoop::NewLoopQueue(); + + // Add initial loop sources + ASSERT_TRUE(loop->SourceAdd(semaA)); + ASSERT_TRUE(loop->SourceAdd(semaB)); + + auto semACallback = AuMakeShared([](const AuSPtr &source) -> bool + { + AuLogInfo("Hello from semaphore a's work queue [ FAIL ]"); + return false; + }); + + auto semBCallback = AuMakeShared([](const AuSPtr &source) -> bool + { + AuLogInfo("Hello from semaphore b's work queue [ FAIL ]"); + return false; + }); + + // Add optional subscriptions + ASSERT_TRUE(loop->AddCallback(semaA, semACallback)); + ASSERT_TRUE(loop->AddCallback(semaB, semBCallback)); + + // Commit source changes + ASSERT_TRUE(loop->Commit()); + + ASSERT_TRUE(!loop->WaitAll(1000)); + + ASSERT_TRUE(semaA->IsSignaled()); + ASSERT_TRUE(!semaB->IsSignaled()); +} + +TEST(WFMO_WithUserlandFastPath, SemaphoreWaitForMultipleObjects) +{ + auto semaA = AuLoop::NewLSSemaphore(0); + auto semaB = AuLoop::NewLSSemaphore(1); + auto semaC = AuLoop::NewLSSemaphore(1); + + AuList> signaled; + AuLoop::WaitMultipleLoopSourcesEx({ semaA, semaB, semaC }, + signaled, + AuLoop::kWaitMultipleFlagAny | AuLoop::kWaitMultipleFlagBreakAfterOne /*nt-like yield*/, + {}); + + + ASSERT_TRUE(signaled.size() == 1); + + ASSERT_TRUE(!semaA->IsSignaled()); + ASSERT_TRUE(!semaB->IsSignaled()); + ASSERT_TRUE(semaC->IsSignaled()); +} + +TEST(WFMO_WithUserlandFastPath, SemaphoreWaitForMultipleObjects2) +{ + auto semaA = AuLoop::NewLSSemaphore(0); + auto semaB = AuLoop::NewLSSemaphore(1); + auto semaC = AuLoop::NewLSSemaphore(1); + + AuList> signaled; + AuLoop::WaitMultipleLoopSourcesEx({ semaA, semaB, semaC }, + signaled, + AuLoop::kWaitMultipleFlagAny, + {}); + + + ASSERT_TRUE(signaled.size() == 2); + + ASSERT_TRUE(!semaA->IsSignaled()); + ASSERT_TRUE(!semaB->IsSignaled()); + ASSERT_TRUE(!semaC->IsSignaled()); +} + +TEST(WFMO_WithUserlandFastPath, SemaphoreWaitForMultipleObjects3) +{ + auto semaA = AuLoop::NewLSSemaphore(0); + auto semaB = AuLoop::NewLSSemaphore(1); + auto semaC = AuLoop::NewLSSemaphore(1); + + AuList> signaled; + AuLoop::WaitMultipleLoopSourcesEx({ semaA, semaB, semaC }, + signaled, + 0, + { 4 }); + + + ASSERT_TRUE(signaled.empty()); + + ASSERT_TRUE(!semaA->IsSignaled()); + ASSERT_TRUE(semaB->IsSignaled()); + ASSERT_TRUE(semaC->IsSignaled()); +} + +TEST(WFMO_NoUserlandFastPath, SemaphoreWaitForMultipleObjects) +{ + auto semaA = AuLoop::NewLSSemaphoreSlow(0); + auto semaB = AuLoop::NewLSSemaphoreSlow(1); + auto semaC = AuLoop::NewLSSemaphoreSlow(1); + + AuList> signaled; + AuLoop::WaitMultipleLoopSourcesEx({ semaA, semaB, semaC }, + signaled, + AuLoop::kWaitMultipleFlagAny | AuLoop::kWaitMultipleFlagBreakAfterOne /*nt-like yield*/, + {}); + + + ASSERT_TRUE(signaled.size() == 1); + + ASSERT_TRUE(!semaA->IsSignaled()); + ASSERT_TRUE(!semaB->IsSignaled()); + ASSERT_TRUE(semaC->IsSignaled()); +} + +TEST(WFMO_NoUserlandFastPath, SemaphoreWaitForMultipleObjects2) +{ + auto semaA = AuLoop::NewLSSemaphoreSlow(0); + auto semaB = AuLoop::NewLSSemaphoreSlow(1); + auto semaC = AuLoop::NewLSSemaphoreSlow(1); + + AuList> signaled; + AuLoop::WaitMultipleLoopSourcesEx({ semaA, semaB, semaC }, + signaled, + AuLoop::kWaitMultipleFlagAny, + {}); + + + ASSERT_TRUE(signaled.size() == 2); + + ASSERT_TRUE(!semaA->IsSignaled()); + ASSERT_TRUE(!semaB->IsSignaled()); + ASSERT_TRUE(!semaC->IsSignaled()); +} + +TEST(WFMO_NoUserlandFastPath, SemaphoreWaitForMultipleObjects3) +{ + auto semaA = AuLoop::NewLSSemaphoreSlow(0); + auto semaB = AuLoop::NewLSSemaphoreSlow(1); + auto semaC = AuLoop::NewLSSemaphoreSlow(1); + + AuList> signaled; + AuLoop::WaitMultipleLoopSourcesEx({ semaA, semaB, semaC }, + signaled, + 0, + { 4 }); + + + ASSERT_TRUE(signaled.empty()); + + ASSERT_TRUE(!semaA->IsSignaled()); + ASSERT_TRUE(semaB->IsSignaled()); + ASSERT_TRUE(semaC->IsSignaled()); +} + +#if defined(AURORA_PLATFORM_MODERNNT_DERIVED) +TEST(WinNT, SemaphoreTest) +{ + auto semaA = AuLoop::NewLSSemaphoreSlow(0); + ReleaseSemaphore((HANDLE)AuLoop::DbgLoopSourceToWriteFd(semA), 1, nullptr); + ASSERT_TRUE(semaA->IsSignaled()); +} + +TEST(WinNT, SemaphoreTest2) +{ + auto event = AuLoop::NewLSEventSlow(false, false, false); + SetEvent((HANDLE)AuLoop::DbgLoopSourceToWriteFd(event)); + ASSERT_TRUE(event->IsSignaled()); +} +#endif + TEST(Loop, Timer0) { SysBenchmark("Hello?"); @@ -178,6 +349,8 @@ TEST(Loop, Timer4) ASSERT_FALSE(loop->WaitAll(100)); } +// OLD COMMENTS + REMARKS FROM LATE 2021 + // // Note: kernel loop queues also support async file and pipe transactions. // See the specialized tests for loop queue related interfaces