Esempio n. 1
0
/**
 * This test validates that
 *
 * a thread can enter a rwmutex for read recursively
 * as a thread exits a rwmutex for read any threads trying to enter remain blocked
 *   the same number of exits as enters have been done
 * a thread waiting to enter a rwmutex wakes up and enter when the last exit for
 *   a series of recusive enters is called
 */
TEST(RWMutex, RecursiveReadTest)
{
	int i;
	omrthread_rwmutex_t saveHandle;
	SupportThreadInfo *infoReader1;
	SupportThreadInfo *infoWriter1;
	omrthread_entrypoint_t functionsToRunReader1[7];
	omrthread_entrypoint_t functionsToRunWriter1[2];

	/* set up the steps for the 2 concurrent threads */
	functionsToRunReader1[0] = (omrthread_entrypoint_t) &enter_rwmutex_read;
	functionsToRunReader1[1] = (omrthread_entrypoint_t) &enter_rwmutex_read;
	functionsToRunReader1[2] = (omrthread_entrypoint_t) &enter_rwmutex_read;
	functionsToRunReader1[3] = (omrthread_entrypoint_t) &exit_rwmutex_read;
	functionsToRunReader1[4] = (omrthread_entrypoint_t) &exit_rwmutex_read;
	functionsToRunReader1[5] = (omrthread_entrypoint_t) &exit_rwmutex_read;
	functionsToRunReader1[6] = (omrthread_entrypoint_t) &nop;
	functionsToRunWriter1[0] = (omrthread_entrypoint_t) &enter_rwmutex_write;
	functionsToRunWriter1[1] = (omrthread_entrypoint_t) &exit_rwmutex_write;

	infoReader1 = createSupportThreadInfo(functionsToRunReader1, 7);
	infoWriter1 = createSupportThreadInfo(functionsToRunWriter1, 2);

	/* set the two SupporThreadInfo structures so that they use the same rwmutex */
	saveHandle = infoWriter1->handle;
	infoWriter1->handle = infoReader1->handle;
	ASSERT_TRUE(0 == infoReader1->readCounter);
	ASSERT_TRUE(0 == infoWriter1->writeCounter);

	/* start the concurrent thread that will try to enter for read */
	startConcurrentThread(infoReader1);
	ASSERT_TRUE(1 == infoReader1->readCounter);

	/* start the concurrent thread that will try to enter for read and
	 * check that it is blocked
	 */
	startConcurrentThread(infoWriter1);
	ASSERT_TRUE(0 == infoWriter1->writeCounter);

	/* now re-enter 2 more times for read on the same thread */
	triggerNextStep(infoReader1);
	triggerNextStep(infoReader1);
	ASSERT_TRUE(3 == infoReader1->readCounter);

	/* now read exit the rwmutex making sure the writer is blocked until
	 * we have called the required number of exits
	 */
	for (i = 3; i > 0; i--) {
		omrthread_monitor_enter(infoWriter1->synchronization);
		triggerNextStep(infoReader1);
		/* cannot validate this on RT as although the reader has exited the mutex it
		 * will not proceed until the writer has exited */
		ASSERT_TRUE((uintptr_t)(i - 1) == infoReader1->readCounter);

		/* make sure waiter is still waiting*/
		if (i > 1) {
			omrthread_monitor_wait_interruptable(infoWriter1->synchronization, MILLI_TIMEOUT, NANO_TIMEOUT);
			omrthread_monitor_exit(infoWriter1->synchronization);
			/* cannot validate this on RT as although the reader has exited the mutex it
			 * will not proceed until the writer has exited
			 */
			ASSERT_TRUE((uintptr_t)(i - 1) == infoReader1->readCounter);
			ASSERT_TRUE(0 == infoWriter1->writeCounter);
		} else {
			/* all readers have exited so writer should be in */
			omrthread_monitor_wait_interruptable(infoWriter1->synchronization, MILLI_TIMEOUT, NANO_TIMEOUT);
			omrthread_monitor_exit(infoWriter1->synchronization);
			/* cannot validate this on RT as although the reader has exited the mutex it
			 * will not proceed until the writer has exited
			 */
			ASSERT_TRUE(0 == infoReader1->readCounter);
			ASSERT_TRUE(1 == infoWriter1->writeCounter);
		}
	}

	/* ok now let the writer exit */
	triggerNextStepDone(infoWriter1);
	ASSERT_TRUE(0 == infoWriter1->writeCounter);

	/* now let the threads clean up. First fix up handle in infoReader so that we
	 * can clean up properly
	 */
	triggerNextStepDone(infoReader1);
	infoWriter1->handle = saveHandle;
	freeSupportThreadInfo(infoReader1);
	freeSupportThreadInfo(infoWriter1);
}
Esempio n. 2
0
intptr_t
CMonitor::WaitInterruptable(void)
{
	return omrthread_monitor_wait_interruptable(m_monitor, 0, 0);
}
Esempio n. 3
0
/**
 * 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);
}
Esempio n. 4
0
intptr_t
CMonitor::WaitInterruptable(int64_t millis, intptr_t nanos)
{
	return omrthread_monitor_wait_interruptable(m_monitor, millis, nanos);
}