#if ENABLE_UNIT_TESTS #include "UnitTest++.h" #include "../Semaphore-c-api.h" #include "../../Semaphore.h" #include "../../Event.h" #include "../../Thread.h" SUITE(Semaphore) { struct SemaphoreFixture { SemaphoreFixture() { il2cpp::os::Thread::Init(); semaphore = UnityPalSemaphoreNew(0, 1); unblockedThreadEvent = new il2cpp::os::Event(); unblockedThreadCount = 0; } ~SemaphoreFixture() { UnityPalSemaphoreDelete(semaphore); } UnityPalSemaphore* semaphore; il2cpp::os::Event* unblockedThreadEvent; int unblockedThreadCount; static void WaitForSemaphoreAndIncrementCounter(void* arg) { SemaphoreFixture* data = static_cast(arg); UnityPalSemaphoreWait(data->semaphore, false); data->unblockedThreadCount++; data->unblockedThreadEvent->Set(); } }; TEST_FIXTURE(SemaphoreFixture, CanCreateASemaphore) { CHECK_NOT_NULL(semaphore); } TEST_FIXTURE(SemaphoreFixture, VerifyThatPostingASemaphoreAGivenNumberOfTimesReturnsThePreviousCount) { int32_t actualPreviousCount = 0; UnityPalSemaphorePost(semaphore, 2, &actualPreviousCount); CHECK_EQUAL(0, actualPreviousCount); } TEST_FIXTURE(SemaphoreFixture, VerifyThatPostWithMultipleThreadsWaitingUnblocksOnlyOneThread) { // Create two threads which each increment the counter once. il2cpp::os::Thread thread1; thread1.Run(WaitForSemaphoreAndIncrementCounter, this); il2cpp::os::Thread thread2; thread2.Run(WaitForSemaphoreAndIncrementCounter, this); UnityPalSemaphorePost(semaphore, 1, NULL); // Let one thread increment and wait for it. unblockedThreadEvent->Wait(); CHECK_EQUAL(1, unblockedThreadCount); // Let the other thread increment and wait for it so we can exit the test cleanly. UnityPalSemaphorePost(semaphore, 1, NULL); unblockedThreadEvent->Wait(); thread1.Join(); thread2.Join(); } struct SemaphoreHandleFixture { SemaphoreHandleFixture() { il2cpp::os::Thread::Init(); semaphore = UnityPalSemaphoreNew(0, 1); semaphoreHandle = UnityPalSemaphoreHandleNew(semaphore); unblockedThreadEvent = new il2cpp::os::Event(); unblockedThreadCount = 0; } ~SemaphoreHandleFixture() { UnityPalSemaphoreHandleDelete(semaphoreHandle); } UnityPalSemaphore* semaphore; UnityPalSemaphoreHandle* semaphoreHandle; il2cpp::os::Event* unblockedThreadEvent; int unblockedThreadCount; static void WaitForSemaphoreAndIncrementCounter(void* arg) { SemaphoreHandleFixture* data = static_cast(arg); UnityPalSemaphoreHandleWait(data->semaphoreHandle); data->unblockedThreadCount++; data->unblockedThreadEvent->Set(); } }; TEST_FIXTURE(SemaphoreHandleFixture, CanCreateASemaphoreHandle) { CHECK_NOT_NULL(semaphoreHandle); } TEST_FIXTURE(SemaphoreHandleFixture, VerifyThatPostingASemaphoreHandleAGivenNumberOfTimesReturnsThePreviousCount) { int32_t actualPreviousCount = 0; UnityPalSemaphoreHandleSignal(semaphoreHandle); CHECK_EQUAL(0, actualPreviousCount); } TEST_FIXTURE(SemaphoreHandleFixture, VerifyThatPostHandleWithMultipleThreadsWaitingUnblocksOnlyOneThread) { // Create two threads which each increment the counter once. il2cpp::os::Thread thread1; thread1.Run(WaitForSemaphoreAndIncrementCounter, this); il2cpp::os::Thread thread2; thread2.Run(WaitForSemaphoreAndIncrementCounter, this); UnityPalSemaphoreHandleSignal(semaphoreHandle); // Let one thread increment and wait for it. unblockedThreadEvent->Wait(); CHECK_EQUAL(1, unblockedThreadCount); // Let the other thread increment and wait for it so we can exit the test cleanly. UnityPalSemaphoreHandleSignal(semaphoreHandle); unblockedThreadEvent->Wait(); thread1.Join(); thread2.Join(); } } #endif // ENABLE_UNIT_TESTS