/** * Validate that we can enter/exit a RWMutex for write */ TEST(RWMutex, RWWriteEnterExitTest) { intptr_t result; omrthread_rwmutex_t handle; uintptr_t flags = 0; const char *mutexName = "test_mutex"; result = omrthread_rwmutex_init(&handle, flags, mutexName); ASSERT_TRUE(0 == result); result = omrthread_rwmutex_enter_write(handle); ASSERT_TRUE(0 == result); result = omrthread_rwmutex_exit_write(handle); ASSERT_TRUE(0 == result); result = omrthread_rwmutex_try_enter_write(handle); ASSERT_TRUE(0 == result); result = omrthread_rwmutex_exit_write(handle); ASSERT_TRUE(0 == result); /* clean up */ result = omrthread_rwmutex_destroy(handle); ASSERT_TRUE(0 == result); }
/** * validates the following * * writer is excluded while another thread holds the rwmutex for write * once writer exits second writer can enter */ TEST(RWMutex, WriterExcludesWriterTesttryenter) { SupportThreadInfo *info; omrthread_entrypoint_t functionsToRun[2]; functionsToRun[0] = (omrthread_entrypoint_t) &enter_rwmutex_write; functionsToRun[1] = (omrthread_entrypoint_t) &exit_rwmutex_write; info = createSupportThreadInfo(functionsToRun, 2); /* first enter the mutex for write */ ASSERT_TRUE(0 == info->writeCounter); omrthread_rwmutex_try_enter_write(info->handle); /* start the concurrent thread that will try to enter for write and * check that it is blocked */ startConcurrentThread(info); ASSERT_TRUE(0 == info->writeCounter); /* now release the rwmutex and validate that the thread enters it */ omrthread_monitor_enter(info->synchronization); omrthread_rwmutex_exit_write(info->handle); omrthread_monitor_wait_interruptable(info->synchronization, MILLI_TIMEOUT, NANO_TIMEOUT); omrthread_monitor_exit(info->synchronization); ASSERT_TRUE(1 == info->writeCounter); /* done now so ask thread to release and clean up */ triggerNextStepDone(info); freeSupportThreadInfo(info); }
/** * This step exits the rwmutex in the SupporThreadInfo for write * @param info the SupporThreadInfo which can be used by the step */ static intptr_t J9THREAD_PROC exit_rwmutex_write(SupportThreadInfo *info) { omrthread_rwmutex_exit_write(info->handle); info->writeCounter--; return 0; }
/** * Validate that is_writelocked return true in writing state */ TEST(RWMutex, IsWriteLockedTest) { intptr_t result; omrthread_rwmutex_t handle; uintptr_t flags = 0; BOOLEAN ret; const char *mutexName = "test_mutex"; result = omrthread_rwmutex_init(&handle, flags, mutexName); ASSERT_TRUE(0 == result); ret = omrthread_rwmutex_is_writelocked(handle); ASSERT_TRUE(FALSE == ret); result = omrthread_rwmutex_enter_read(handle); ASSERT_TRUE(0 == result); ret = omrthread_rwmutex_is_writelocked(handle); ASSERT_TRUE(FALSE == ret); result = omrthread_rwmutex_exit_read(handle); ASSERT_TRUE(0 == result); result = omrthread_rwmutex_enter_write(handle); ASSERT_TRUE(0 == result); ret = omrthread_rwmutex_is_writelocked(handle); ASSERT_TRUE(TRUE == ret); result = omrthread_rwmutex_exit_write(handle); ASSERT_TRUE(0 == result); /* clean up */ result = omrthread_rwmutex_destroy(handle); ASSERT_TRUE(0 == result); }
/** * validates the following * * readers are excludes while another thread holds the rwmutex for write * once writer exits, all readers wake up and can enter */ TEST(RWMutex, AllReadersProceedTest) { omrthread_rwmutex_t saveHandle; SupportThreadInfo *infoReader1; SupportThreadInfo *infoReader2; omrthread_entrypoint_t functionsToRunReader1[2]; omrthread_entrypoint_t functionsToRunReader2[2]; /* set up the steps for the 2 concurrent threads */ functionsToRunReader1[0] = (omrthread_entrypoint_t) &enter_rwmutex_read; functionsToRunReader1[1] = (omrthread_entrypoint_t) &exit_rwmutex_read; functionsToRunReader2[0] = (omrthread_entrypoint_t) &enter_rwmutex_read; functionsToRunReader2[1] = (omrthread_entrypoint_t) &exit_rwmutex_read; infoReader1 = createSupportThreadInfo(functionsToRunReader1, 2); infoReader2 = createSupportThreadInfo(functionsToRunReader2, 2); /* set the two SupporThreadInfo structures so that they use the same rwmutex */ saveHandle = infoReader2->handle; infoReader2->handle = infoReader1->handle; /* first enter the mutex for write */ ASSERT_TRUE(0 == infoReader1->readCounter); ASSERT_TRUE(0 == infoReader2->readCounter); omrthread_rwmutex_enter_write(infoReader1->handle); /* start the concurrent thread that will try to enter for read and * check that it is blocked */ startConcurrentThread(infoReader1); ASSERT_TRUE(0 == infoReader1->readCounter); /* start the concurrent thread that will try to enter for read and * check that it is blocked */ startConcurrentThread(infoReader2); ASSERT_TRUE(0 == infoReader2->readCounter); /* now release the rwmutex and validate that the second readers still excludes the writer */ omrthread_monitor_enter(infoReader2->synchronization); omrthread_monitor_enter(infoReader1->synchronization); omrthread_rwmutex_exit_write(infoReader1->handle); ASSERT_TRUE(0 == infoReader1->writeCounter); /* now validate that the readers have entered the mutex*/ omrthread_monitor_wait_interruptable(infoReader1->synchronization, MILLI_TIMEOUT, NANO_TIMEOUT); omrthread_monitor_exit(infoReader1->synchronization); omrthread_monitor_wait_interruptable(infoReader2->synchronization, MILLI_TIMEOUT, NANO_TIMEOUT); omrthread_monitor_exit(infoReader2->synchronization); ASSERT_TRUE(1 == infoReader1->readCounter); ASSERT_TRUE(1 == infoReader2->readCounter); /* ok now let the readers exit */ triggerNextStepDone(infoReader1); ASSERT_TRUE(0 == infoReader1->readCounter); triggerNextStepDone(infoReader2); ASSERT_TRUE(0 == infoReader2->readCounter); /* now let the threads clean up. First fix up handle in infoReader so that we * can clean up properly */ infoReader2->handle = saveHandle; freeSupportThreadInfo(infoReader1); freeSupportThreadInfo(infoReader2); }
void CRWMutex::ExitWrite(void) { omrthread_rwmutex_exit_write(m_monitor); }