bool mutex_wait(mutex_t* mutex) { #if FOUNDATION_PLATFORM_WINDOWS return mutex_try_wait(mutex, INFINITE); #else return mutex_try_wait(mutex, 0xFFFFFFFF); #endif }
DECLARE_TEST(mutex, basic) { mutex_t* mutex; mutex = mutex_allocate(STRING_CONST("test")); EXPECT_CONSTSTRINGEQ(mutex_name(mutex), string_const(STRING_CONST("test"))); EXPECT_TRUE(mutex_try_lock(mutex)); EXPECT_TRUE(mutex_lock(mutex)); EXPECT_TRUE(mutex_try_lock(mutex)); EXPECT_TRUE(mutex_lock(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_WARNING); EXPECT_FALSE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_INFO); mutex_signal(mutex); thread_yield(); EXPECT_TRUE(mutex_try_wait(mutex, 1)); EXPECT_TRUE(mutex_unlock(mutex)); mutex_signal(mutex); thread_yield(); EXPECT_TRUE(mutex_wait(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_WARNING); EXPECT_FALSE(mutex_try_wait(mutex, 100)); EXPECT_FALSE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_INFO); mutex_signal(mutex); thread_yield(); EXPECT_TRUE(mutex_try_wait(mutex, 1)); log_set_suppress(0, ERRORLEVEL_WARNING); EXPECT_FALSE(mutex_try_wait(mutex, 100)); EXPECT_TRUE(mutex_unlock(mutex)); EXPECT_FALSE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_INFO); mutex_deallocate(mutex); return 0; }
static void* thread_waiter(void* arg) { mutex_t* mutex = arg; atomic_incr32(&thread_waiting); if (mutex_try_wait(mutex, 30000)) { atomic_incr32(&thread_waited); mutex_unlock(mutex); } else { log_warn(HASH_TEST, WARNING_SUSPICIOUS, STRING_CONST("Thread timeout")); } return 0; }
DECLARE_TEST(mutex, signal) { mutex_t* mutex; thread_t thread[32]; size_t ith; mutex = mutex_allocate(STRING_CONST("test")); mutex_lock(mutex); for (ith = 0; ith < 32; ++ith) thread_initialize(&thread[ith], thread_waiter, mutex, STRING_CONST("thread_wait"), THREAD_PRIORITY_NORMAL, 0); for (ith = 0; ith < 32; ++ith) thread_start(&thread[ith]); mutex_unlock(mutex); test_wait_for_threads_startup(thread, 32); while (atomic_load32(&thread_waiting) < 32) thread_yield(); thread_sleep(1000); //Hack wait to give threads time to progress from atomic_incr to mutex_wait mutex_signal(mutex); test_wait_for_threads_finish(thread, 32); for (ith = 0; ith < 32; ++ith) thread_finalize(&thread[ith]); EXPECT_EQ(atomic_load32(&thread_waited), 32); EXPECT_FALSE(mutex_try_wait(mutex, 500)); mutex_deallocate(mutex); return 0; }