void
MM_AllocationContextSegregated::tearDown(MM_EnvironmentBase *env)
{
	if (_mutexSmallAllocations) {
		omrthread_monitor_destroy(_mutexSmallAllocations);
	}

	if (_mutexArrayletAllocations) {
		omrthread_monitor_destroy(_mutexArrayletAllocations);
	}

	for (int32_t i = 0; i < OMR_SIZECLASSES_NUM_SMALL + 1; i++) {
		if (NULL != _perContextSmallFullRegions[i]) {
			_perContextSmallFullRegions[i]->kill(env);
			_perContextSmallFullRegions[i] = NULL;
		}
	}

	if (NULL != _perContextArrayletFullRegions) {
		_perContextArrayletFullRegions->kill(env);
		_perContextArrayletFullRegions = NULL;
	}

	if (NULL != _perContextLargeFullRegions) {
		_perContextLargeFullRegions->kill(env);
		_perContextLargeFullRegions = NULL;
	}

	MM_AllocationContext::tearDown(env);
}
Exemple #2
0
void
MM_MasterGCThread::tearDown(MM_EnvironmentBase *env)
{
	if (NULL != _collectorControlMutex) {
		omrthread_monitor_destroy(_collectorControlMutex);
		_collectorControlMutex = NULL;
	}
	_collector = NULL;
}
Exemple #3
0
intptr_t
sem_destroy_zos(j9sem_t s)
{
	intptr_t rval = 0;
	zos_sem_t *zs = (zos_sem_t *) s;
	if (zs->monitor) {
		rval = omrthread_monitor_destroy(zs->monitor);
	}
	return rval;
}
Exemple #4
0
/**
 * Cleanup the resources for a MM_ConcurrentOverflow object
 */
void
MM_ConcurrentOverflow::tearDown(MM_EnvironmentBase *env)
{
	if(NULL != _cardsClearingMonitor) {
		omrthread_monitor_destroy(_cardsClearingMonitor);
		_cardsClearingMonitor = NULL;
	}

	MM_WorkPacketOverflow::tearDown(env);
}
Exemple #5
0
/**
 * This method free the internal structures and memory for a SupportThreadInfo
 * @param info the SupportThreadInfo instance to be freed
 */
void
freeSupportThreadInfo(SupportThreadInfo *info)
{
	OMRPORT_ACCESS_FROM_OMRPORT(omrTestEnv->getPortLibrary());
	if (info->synchronization != NULL) {
		omrthread_monitor_destroy(info->synchronization);
	}
	if (info->handle != NULL) {
		omrthread_rwmutex_destroy(info->handle);
	}
	omrmem_free_memory(info);
}
Exemple #6
0
TEST_F(ThreadCreateTest, NumaSetAffinity)
{
	uintptr_t status = 0;
	omrthread_t thread;
	omrthread_monitor_t monitor;
	numadata_t data;
	uintptr_t nodeCount = 0;
	intptr_t affinityResultCode = 0;

	if (0 != J9THREAD_VERBOSE(omrthread_monitor_init(&monitor, 0))) {
		omrTestEnv->log(LEVEL_ERROR, "Failed to initialize monitor\n");
		status |= NULL_ATTR;
		goto endtest;
	}

	data.monitor = monitor;
	data.status = 0;
	data.expectedAffinity = 0;

	omrthread_monitor_enter(monitor);

	nodeCount = 1;
	affinityResultCode = omrthread_numa_get_node_affinity(omrthread_self(), &data.expectedAffinity, &nodeCount);
	if (J9THREAD_NUMA_ERR_AFFINITY_NOT_SUPPORTED == affinityResultCode) {
		/* this platform can't meaningfully run this test so just end */
		omrTestEnv->log(LEVEL_ERROR, "NUMA-level thread affinity not supported on this platform\n");
		goto endtest;
	}
	if (J9THREAD_NUMA_OK != affinityResultCode) {
		omrTestEnv->log(LEVEL_ERROR, "Failed to get parent thread's affinity\n");
		status |= CREATE_FAILED;
		goto endtest;
	}

	if (J9THREAD_SUCCESS != J9THREAD_VERBOSE(omrthread_create_ex(&thread, J9THREAD_ATTR_DEFAULT, 0, numaSetAffinityThreadMain, &data))) {
		omrTestEnv->log(LEVEL_ERROR, "Failed to create the thread\n");
		status |= CREATE_FAILED;
		goto endtest;
	}

	if (0 != omrthread_monitor_wait(monitor)) {
		omrTestEnv->log(LEVEL_ERROR, "Failed to wait on monitor\n");
		status |= NULL_ATTR;
		goto endtest;
	}

	status |= data.status;
endtest:
	omrthread_monitor_exit(monitor);
	omrthread_monitor_destroy(monitor);
	ASSERT_EQ((uintptr_t)0, status) << "Failed with Code: " << std::hex << status;
}
Exemple #7
0
/*
 * Shuts down the specified hook interface.
 *
 * This function should not be called directly. It should be called through the hook interface
 */
static void
J9HookShutdownInterface(struct J9HookInterface **hookInterface)
{
	J9CommonHookInterface *commonInterface = (J9CommonHookInterface *)hookInterface;

	if (commonInterface->lock) {
		omrthread_monitor_destroy(commonInterface->lock);
	}

	if (commonInterface->pool) {
		pool_kill(commonInterface->pool);
	}
}
Exemple #8
0
static omr_error_t
waitForTestChildThread(OMRTestVM *testVM, omrthread_t childThead, TestChildThreadData *childData)
{
	omr_error_t childRc = OMR_ERROR_NONE;
	OMRPORT_ACCESS_FROM_OMRPORT(testVM->portLibrary);

	omrthread_monitor_enter(childData->shutdownCond);
	while (!childData->isDead) {
		omrthread_monitor_wait(childData->shutdownCond);
	}
	omrthread_monitor_exit(childData->shutdownCond);

	childRc = childData->childRc;

	omrthread_monitor_destroy(childData->shutdownCond);
	omrmem_free_memory(childData);
	return childRc;
}
Exemple #9
0
/**
 * Tear down internal structures.
 */
void
MM_ParallelSweepScheme::tearDown(MM_EnvironmentBase *env)
{
	MM_GCExtensionsBase *extensions = env->getExtensions();

	if(NULL != extensions->sweepHeapSectioning) {
		extensions->sweepHeapSectioning->kill(env);
		extensions->sweepHeapSectioning = NULL;
		_sweepHeapSectioning = NULL;
	}

	if (NULL != _poolSweepPoolState) {
		pool_kill(_poolSweepPoolState);
		_poolSweepPoolState = NULL;
	}

	if (0 != _mutexSweepPoolState) {
		omrthread_monitor_destroy(_mutexSweepPoolState);
	}
}
Exemple #10
0
static omr_error_t
startTestChildThread(OMRTestVM *testVM, OMR_VMThread *curVMThread, omrthread_t *childThread, TestChildThreadData **childData)
{
	omr_error_t rc = OMR_ERROR_NONE;
	OMRPORT_ACCESS_FROM_OMRPORT(testVM->portLibrary);
	TestChildThreadData *newChildData = (TestChildThreadData *)omrmem_allocate_memory(sizeof(*newChildData), OMRMEM_CATEGORY_VM);
	if (NULL == newChildData) {
		rc = OMR_ERROR_OUT_OF_NATIVE_MEMORY;
		omrtty_printf("%s:%d ERROR: Failed to alloc newChildData\n", __FILE__, __LINE__);
	}

	if (OMR_ERROR_NONE == rc) {
		if (0 != omrthread_monitor_init_with_name(&newChildData->shutdownCond, 0, "traceTestChildShutdown")) {
			rc = OMR_ERROR_FAILED_TO_ALLOCATE_MONITOR;
			omrtty_printf("%s:%d ERROR: Failed to init shutdownCond monitor\n", __FILE__, __LINE__);
			omrmem_free_memory(newChildData);
		} else {
			newChildData->testVM = testVM;
			newChildData->isDead = FALSE;
			newChildData->childRc = OMR_ERROR_NONE;
		}
	}

	if (OMR_ERROR_NONE == rc) {
		if (0 != omrthread_create_ex(
			NULL, /* handle */
			J9THREAD_ATTR_DEFAULT, /* attr */
			FALSE, /* suspend */
			childThreadMain, /* entrypoint */
			newChildData)  /* entryarg */
		) {
			rc = OMR_ERROR_OUT_OF_NATIVE_MEMORY;
			omrtty_printf("%s:%d ERROR: Failed to init shutdownCond monitor\n", __FILE__, __LINE__);
			omrthread_monitor_destroy(newChildData->shutdownCond);
			omrmem_free_memory(newChildData);
		} else {
			*childData = newChildData;
		}
	}
	return rc;
}
void
OMR_MethodDictionary::cleanup()
{
	if (NULL != _vm) {
		omrthread_t self = NULL;
		if (0 == omrthread_attach_ex(&self, J9THREAD_ATTR_DEFAULT)) {
			Trc_OMRPROF_methodDictionaryHighWaterMark(_maxBytes, _maxEntries, _sizeofEntry,
				_maxBytes - (_maxEntries * _sizeofEntry));
			if (NULL != _hashTable) {
				hashTableForEachDo(_hashTable, OMR_MethodDictionary::cleanupEntryStrings, this);
				hashTableFree(_hashTable);
				_hashTable = NULL;
			}
			if (NULL != _lock) {
				omrthread_monitor_destroy(_lock);
				_lock = NULL;
			}
			_vm = NULL;
			omrthread_detach(self);
		}
	}
}
Exemple #12
0
/*
 * Tests:
 * - Attempt to log a tracepoint after trace engine shutdown started.
 * - Attempt to unload a module after trace engine shutdown started.
 *
 * If module unloading fails, this test case tends to cause later tests
 * to crash because the static omr_test_UtModuleInfo and omr_test_UtActive
 * structures are left in a polluted state.
 */
TEST(TraceLifecycleTest, traceAndModuleUnloadAfterTraceShutdown)
{
	const OMR_TI *ti = omr_agent_getTI();
	UtSubscription *subscriptionID = NULL;

	/* OMR VM data structures */
	OMRTestVM testVM;
	OMR_VMThread *vmthread = NULL;

	/* child thread data */
	omrthread_t shutdownTrcThr = NULL;
	ChildThreadData *shutdownTrcData = NULL;

	TracePointCountsMT tpCountsMT;
	TracePointCounts tpCounts[2];
	tpCountsMT.numThreads = 2;
	tpCountsMT.tpCounts = tpCounts;
	memset(tpCounts, 0, sizeof(TracePointCounts) * 2);
	initWrapBuffer(&tpCounts[0].wrapBuffer);
	initWrapBuffer(&tpCounts[1].wrapBuffer);
	tpCounts[0].osThread = omrthread_self();
	ASSERT_EQ(0, omrthread_monitor_init_with_name(&tpCountsMT.lock, 0, "&tpCountsMT.lock"));

	OMRPORT_ACCESS_FROM_OMRPORT(rasTestEnv->getPortLibrary());
	char *datDir = getTraceDatDir(rasTestEnv->_argc, (const char **)rasTestEnv->_argv);

	OMRTEST_ASSERT_ERROR_NONE(omrTestVMInit(&testVM, OMRPORTLIB));
	/* use small buffers to exercise buffer wrapping */
	OMRTEST_ASSERT_ERROR_NONE(omr_ras_initTraceEngine(&testVM.omrVM, "buffers=1k:maximal=all:print=omr_test", datDir));
	OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Init(&testVM.omrVM, NULL, &vmthread, "traceTest"));

	/* start counting tracepoints */
	OMRTEST_ASSERT_ERROR_NONE(
		ti->RegisterRecordSubscriber(vmthread, "traceAndModuleUnloadAfterTraceShutdown", countTracepointsMT, NULL, (void *)&tpCountsMT, &subscriptionID));

	/* Initialise the omr_test module for tracing */
	UT_OMR_TEST_MODULE_LOADED(testVM.omrVM._trcEngine->utIntf);

	/* Shut down the trace engine */
	ASSERT_NO_FATAL_FAILURE(startChildThread(&testVM, &shutdownTrcThr, shutdownTraceHelper, &shutdownTrcData));
	ASSERT_EQ(1, omrthread_resume(shutdownTrcThr));
	OMRTEST_ASSERT_ERROR_NONE(waitForChildThread(&testVM, shutdownTrcThr, shutdownTrcData));

	/* Attempt to log a tracepoint. It will not be logged. */
	Trc_OMR_Test_UnloggedTracepoint(vmthread, "Tracepoint initiated after trace engine shutdown is started.");

	UT_OMR_TEST_MODULE_UNLOADED(testVM.omrVM._trcEngine->utIntf);

	/* Now clear up the VM we started for this test case. */

	/* Stop counting tracepoints */
	omr_trc_stopThreadTrace(vmthread);  /* flush the thread's trace buffer and delete all subscribers */
	OMRTEST_ASSERT_ERROR_NONE(ti->DeregisterRecordSubscriber(vmthread, subscriptionID)); /* do nothing */

	OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread));
	OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM));

	ASSERT_EQ(0, tpCounts[0].unloggedCount);
	ASSERT_EQ(0, tpCounts[0].loggedCount);
	freeWrapBuffer(&tpCounts[0].wrapBuffer);

	ASSERT_EQ(0, tpCounts[1].unloggedCount);
	ASSERT_EQ(0, tpCounts[1].loggedCount);
	freeWrapBuffer(&tpCounts[1].wrapBuffer);

	ASSERT_EQ(0, omrthread_monitor_destroy(tpCountsMT.lock));

	ASSERT_TRUE(NULL == (void *)omr_test_UtModuleInfo.intf);
}
Exemple #13
0
TEST_F(ThreadCreateTest, NumaSetAffinitySuspended)
{
	omrthread_t thread;
	omrthread_monitor_t monitor;
	numadata_t data;

	intptr_t result = 0;
	uintptr_t status = 0;
	uintptr_t numaMaxNode = omrthread_numa_get_max_node();
	uintptr_t numaNode = 0;
	uintptr_t expectedAffinityBeforeStart = 0;
	omrthread_monitor_init(&monitor, 0);

	if (numaMaxNode > 0) {
		uintptr_t nodeCount = 1;
		/* first, see if we can even run this test */
		intptr_t affinityResultCode = omrthread_numa_get_node_affinity(omrthread_self(), &data.expectedAffinity, &nodeCount);
		data.monitor = monitor;
		data.status = 0;

		if (J9THREAD_NUMA_ERR_AFFINITY_NOT_SUPPORTED == affinityResultCode) {
			/* this platform can't meaningfully run this test so just end */
			omrTestEnv->log(LEVEL_ERROR, "NUMA-level thread affinity not supported on this platform\n");
			goto endtest;
		}
		/* Create the thread suspended */
		if (J9THREAD_SUCCESS != J9THREAD_VERBOSE(omrthread_create_ex(&thread, J9THREAD_ATTR_DEFAULT, 1, numaSetAffinitySuspendedThreadMain, &data))) {
			status |= CREATE_FAILED;
			goto endtest;
		}

		/* Set the affinity to the highest node which has CPUs associated to it */
		numaNode = numaMaxNode;
		while (numaNode > 0) {
			omrTestEnv->log(LEVEL_ERROR, "Setting thread numa affinity to %zu\n", numaNode);
			result = omrthread_numa_set_node_affinity(thread, &numaNode, 1, 0);
			if (result == J9THREAD_NUMA_ERR_NO_CPUS_FOR_NODE) {
				omrTestEnv->log(LEVEL_ERROR, "Tried to set thread numa affinity to node %zu, but no CPUs associated with node\n", numaNode);
				numaNode--;
				continue;
			} else if (result != 0) {
				omrTestEnv->log(LEVEL_ERROR, "Failed to set affinity to %zu\n", numaNode);
				status |= EXPECTED_VALID;
				goto endtest;
			} else {
				data.expectedAffinity = numaNode;
				break;
			}
		}

		/* Check that the affinity on the suspended thread is indeed what we set it to */
		if (0 != J9THREAD_VERBOSE(omrthread_numa_get_node_affinity(thread, &expectedAffinityBeforeStart, &nodeCount))) {
			omrTestEnv->log(LEVEL_ERROR, "Failed to get affinity on the thread while it's still suspended\n");
			status |= EXPECTED_VALID;
			goto endtest;
		}

		if (expectedAffinityBeforeStart != data.expectedAffinity) {
			omrTestEnv->log(LEVEL_ERROR, "Suspended thread's deferred affinity is not what it should be. Expected:%zu Actual:%zu\n", data.expectedAffinity, expectedAffinityBeforeStart);
			status |= EXPECTED_VALID;
			goto endtest;
		}

		J9THREAD_VERBOSE(omrthread_monitor_enter(monitor));
		if (1 != omrthread_resume(thread)) {
			omrTestEnv->log(LEVEL_ERROR, "Failed to resume the thread\n");
			goto endtest;
		}

		if (0 != J9THREAD_VERBOSE(omrthread_monitor_wait(monitor))) {
			status |= NULL_ATTR;
			goto endtest;
		}

		status |= data.status;
	} else {
		omrTestEnv->log("Doesn't look like NUMA is available on this system\n");
	}

endtest:
	omrthread_monitor_exit(monitor);
	omrthread_monitor_destroy(monitor);
	ASSERT_EQ((uintptr_t)0, status) << "Failed with Code: " << std::hex << status;
}
Exemple #14
0
CMonitor::~CMonitor(void)
{
	omrthread_monitor_destroy(m_monitor);
}
/*
 * Test pthread_sigmask() with cross fire signaling.
 *  - create 2 threads
 *  - one thread calls pthread_sigmask() and verifies that the specified mask is set
 *  - other thread verifies that the specified mask is not set
 *  - send some signals to each thread, e.g. by pthread_kill and verify that it is blocked or not.
 *
 *  Note: under heavy load test environment, the signal may not be delivered in timely fashion
 *
 * mask   thread:----s(READY)-w(SIGMASK)-----------m---s(READY)-w(PTHREADKILL)----------j----s(READY)------w(EXIT)-------s(FINISHED)---------->>
 * main   thread:-w(READY)---------s(SIGMASK)-w(READY)------------c----s(PTHREADKILL)-w(READY)----------k----s(EXIT)--w(FINISHED)--------->>
 *
 * main   thread:-w(READY)---------s(SIGMASK)-w(READY)------------c----s(PTHREADKILL)----w(FINISHED)---------->>
 * unmask thread:---s(READY)-w(SIGMASK)-------m--s(READY)-w(PTHREADKILL)----------j----i----s(FINISHED)-------------->>
 *
 * where:
 * 	m: run pthread_sigmask
 * 	c: check result of pthread_sigmask
 * 	j: run sigprotected function
 * 	k: run pthread_kill
 * 	i: signal handler (OMRPORT_SIG_EXCEPTION_RETURN)
 *
 */
TEST(PortSignalExtendedTests, sig_ext_test1)
{
	OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
	const char *testName = "omrsig_ext_test1";
	omrthread_monitor_t maskMonitor = NULL;
	omrthread_monitor_t unmaskMonitor = NULL;
	omrthread_t mainThread = NULL;
	omrthread_t maskThread = NULL;
	omrthread_t unmaskThread = NULL;
	pthread_t osMaskThread = 0;
	pthread_t osUnmaskThread = 0;
	uint32_t flags = 0;
	SigMaskTestInfo maskThreadInfo;
	SigMaskTestInfo unmaskThreadInfo;
	intptr_t monitorRC = 0;
	int memcmp_ret = 0;
	sigset_t mask;
	sigset_t oldMask;
	sigset_t currentMask;
	sigset_t maskThread_mask;
	sigset_t unmaskThread_mask;
	portTestEnv->changeIndent(1);

	reportTestEntry(OMRPORTLIB, testName);

	/* initialize local variables */
	memset(&maskThreadInfo, 0, sizeof(maskThreadInfo));
	memset(&unmaskThreadInfo, 0, sizeof(unmaskThreadInfo));
	sigemptyset(&mask);
	sigemptyset(&oldMask);
	sigemptyset(&currentMask);
	sigemptyset(&maskThread_mask);
	sigemptyset(&unmaskThread_mask);

	/*
	 * OSX will redirect the SIGILL from the masked thread to other threads unless they are also masked.
	 * This thread's mask will be inherited. Mask SIGILL for all threads for mask testing.
	 */
	sigaddset(&mask, SIGILL);
	if (0 != pthread_sigmask(SIG_SETMASK, &mask, &oldMask)) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "pthread_sigmask failed: %s(%d).\n", strerror(errno), errno);
		FAIL();
	}

	monitorRC = omrthread_monitor_init_with_name(&maskMonitor, 0, "omrsig_ext_sigmask_monitor");
	if (0 != monitorRC) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrthread_monitor_init_with_name failed with %i\n", monitorRC);
		FAIL();
	}
	setSigMaskTestInfo(&maskThreadInfo, OMRPORTLIB, "Masked Thread", maskMonitor, maskProtectedFunction, INVALID);

	monitorRC = omrthread_monitor_init_with_name(&unmaskMonitor, 0, "omrsig_ext_sigunmask_monitor");
	if (0 != monitorRC) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrthread_monitor_init_with_name failed with %i\n", monitorRC);
		FAIL();
	}
	setSigMaskTestInfo(&unmaskThreadInfo, OMRPORTLIB, "Unmasked Thread", unmaskMonitor, unmaskProtectedFunction, INVALID);

	mainThread = omrthread_self();
	maskThread = create_thread(OMRPORTLIB, (omrthread_entrypoint_t)sigMaskThread, &maskThreadInfo);
	unmaskThread = create_thread(OMRPORTLIB, (omrthread_entrypoint_t)sigMaskThread, &unmaskThreadInfo);

	if ((NULL != mainThread) && (NULL != maskThread) && (NULL != unmaskThread)) {
		portTestEnv->log("%s\t:created test threads.\n", testName);
		/* wait for maskThread and unmaskThread ready */
		if (!waitForEvent(testName, &maskThreadInfo, READY, &osMaskThread, sizeof(pthread_t))) {
			goto exit;
		}
		if (!waitForEvent(testName, &unmaskThreadInfo, READY, &osUnmaskThread, sizeof(pthread_t))) {
			goto exit;
		}
		portTestEnv->log("%s\t:test threads are READY.\n", testName);

		/* test pthread_sigmask */
		/* ask maskThread to mask SIGBUS signal */
		flags = SIGBUS;
		portTestEnv->log("%s\t:configure mask thread to mask SIGBUS signal.\n", testName);
		sendEvent(&maskThreadInfo, SIGMASK, &flags, sizeof(flags));
		/* ask unMaskThread to not mask any signal */
		flags = 0;
		portTestEnv->log("%s\t:configure unmask thread to not mask any tested signal.\n", testName);
		sendEvent(&unmaskThreadInfo, SIGMASK, &flags, sizeof(flags));

		portTestEnv->log("%s\t:testing pthread_sigmask...\n", testName);

		/* check pthread_sigmask result */
		if (!waitForEvent(testName, &maskThreadInfo, READY, &maskThread_mask, sizeof(maskThread_mask))) {
			goto exit;
		}
		if (!waitForEvent(testName, &unmaskThreadInfo, READY, &unmaskThread_mask, sizeof(unmaskThread_mask))) {
			goto exit;
		}
		portTestEnv->log("%s\t:operation pthread_sigmask has been done. checking pthread_sigmask result...\n", testName);

		/*
		 * Expected behavior:
		 * 1. main thread's signal mask shall be untouched
		 * 2. child threads shall inherit main thread's signal mask
		 * 3. child threads' pthread_sigmask operation shall not interfere each other
		 */
		if (0 != pthread_sigmask(SIG_SETMASK, NULL, &currentMask)) {
			outputErrorMessage(PORTTEST_ERROR_ARGS, "pthread_sigmask failed: %s(%d).\n", strerror(errno), errno);
			goto exit;
		}
		/* check whether main thread signal mask was affected by child thread pthread_sigmask operation */
		if (0 != (memcmp_ret = memcmp(&currentMask, &mask, sizeof(currentMask)))) {
			outputErrorMessage(PORTTEST_ERROR_ARGS, "main thread mask was modified (old=0x%X, new=0x%X), %X\n", *((uint32_t *)&mask), *((uint32_t *)&currentMask), memcmp_ret);
			goto exit;
		} else {
			portTestEnv->log("%s\t:main thread signal mask was not affected.\n", testName);
		}

		/* UNIX opengroup example says that newly created thread shall inherit the mask */
		if (!sigismember(&maskThread_mask, SIGILL) || !sigismember(&unmaskThread_mask, SIGILL)) {
			outputErrorMessage(PORTTEST_ERROR_ARGS, "created threads did not inherit mask.(maskThreadInfo=0x%X, unmaskThreadInfo=0x%X)\n", *((uint32_t *)&maskThread_mask), *((uint32_t *)&unmaskThread_mask));
			goto exit;
		} else {
			portTestEnv->log("%s\t:child thread inherited main thread's signal mask.\n", testName);
		}

		/* Check whether two child threads' pthread_sigmask operation can interfere each other. */
		if (!sigismember(&maskThread_mask, SIGBUS) || sigismember(&unmaskThread_mask, SIGBUS)) {
			outputErrorMessage(PORTTEST_ERROR_ARGS, "pthread_sigmask did not work.(maskThreadInfo=0x%X, unmaskThreadInfo=0x%X)\n", *((uint32_t *)&maskThread_mask), *((uint32_t *)&unmaskThread_mask));
			goto exit;
		} else {
			portTestEnv->log("%s\t:pthread_sigmask operation in each child thread did not interfere each other.\n", testName);
		}

		/*
		 * test unmask thread signal handling behavior
		 * unmask thread will install SIGSEGV handler and launch a protected function unmaskProtectedFunction().
		 * unmaskProtectedFunction() shall be terminated by SIGSEGV generated in its body, and the unmask thread
		 * will send report to this main thread.
		 */
		flags = OMRPORT_SIG_FLAG_MAY_RETURN | OMRPORT_SIG_FLAG_SIGSEGV; /* SIGSEGV shall be received */
		portTestEnv->log("%s\t:configure unmask thread to prepare for unmasked signal SIGSEGV test.\n", testName);
		sendEvent(&unmaskThreadInfo, PTHREADKILL, &flags, sizeof(flags));

		if (!waitForEvent(testName, &unmaskThreadInfo, FINISHED, NULL, 0)) {
			goto exit;
		} else {
			portTestEnv->log("%s\t:unmasked thread finished. checking unmask thread's signal status...\n", testName);

			if (unmaskThreadInfo.bulletinBoard.status ==  SIGNALED) {
				portTestEnv->log("%s\t:unmasked thread received signal as expected.\n", testName);
			} else {
				outputErrorMessage(PORTTEST_ERROR_ARGS, "unmasked thread did not received signal as expected.(SignalStatus=%d)\n", unmaskThreadInfo.bulletinBoard.status);
				goto exit;
			}
		}


		/*
		 * test mask thread signal handling behavior
		 * mask thread will install SIGILL handler and launch a protected function maskProtectedFunction().
		 */
		portTestEnv->log("%s\t:testing pthread_kill...\n", testName);
		flags = OMRPORT_SIG_FLAG_MAY_RETURN | OMRPORT_SIG_FLAG_SIGILL; /* SIGILL shall not be received */
		sendEvent(&maskThreadInfo, PTHREADKILL, &flags, sizeof(flags));
		portTestEnv->log("%s\t:configure mask thread to prepare for pthread_kill test.\n", testName);

		if (!waitForEvent(testName, &maskThreadInfo, READY, NULL, 0)) {
			goto exit;
		}
		portTestEnv->log("%s\t:mask thread is ready to receive signal. sending pthread_kill...\n", testName);
		/* send SIGILL to maskThread which will never receive this signal */
		pthread_kill(osMaskThread, SIGILL);

		/* check pthread_kill result */
		/*
		 * Expected behavior:
		 * 1. child thread with signal mask on SIGILL shall not receive this signal and therefore NOTSIGNALED.
		 */

		portTestEnv->log("%s\t:notify mask thread to exit.\n", testName);
		sendEvent(&maskThreadInfo, EXIT, NULL, 0);
		if (!waitForEvent(testName, &maskThreadInfo, FINISHED, NULL, 0)) {
			goto exit;
		} else {
			portTestEnv->log("%s\t:masked thread finished. checking mask thread's signal status...\n", testName);
			if (maskThreadInfo.bulletinBoard.status ==  NOTSIGNALED) {
				portTestEnv->log("%s\t:masked thread did not receive signal as expected.\n", testName);
			} else {
				outputErrorMessage(PORTTEST_ERROR_ARGS, "masked thread received signal as not expected.(SignalStatus=%d)\n", maskThreadInfo.bulletinBoard.status);
				goto exit;
			}
		}

		portTestEnv->log("%s\t:pthread_sigmask works on each individual thread.\n", testName);

	}

	portTestEnv->log("%s\t:destroying unmaskMonitor...\n", testName);
	omrthread_monitor_destroy(unmaskMonitor);

	portTestEnv->log("%s\t:destroying maskMonitor...\n", testName);
	omrthread_monitor_destroy(maskMonitor);

	goto cleanup;

exit:
	portTestEnv->log(LEVEL_ERROR, "%s\t:test stopped with errors\n", testName);
	FAIL();

cleanup:
	/* restore signal mask */
	pthread_sigmask(SIG_SETMASK, &oldMask, NULL);
	portTestEnv->changeIndent(-1);
	reportTestExit(OMRPORTLIB, testName);
}