Пример #1
0
/*
 * Prepares the specified hook interface for first use.
 *
 * This function may be called directly.
 *
 * Returns 0 on success, non-zero on failure
 */
intptr_t
J9HookInitializeInterface(struct J9HookInterface **hookInterface, OMRPortLibrary *portLib, size_t interfaceSize)
{
	J9CommonHookInterface *commonInterface = (J9CommonHookInterface *)hookInterface;

	memset(commonInterface, 0, interfaceSize);

	commonInterface->hookInterface = (J9HookInterface *)GLOBAL_TABLE(hookFunctionTable);

	commonInterface->size = interfaceSize;

	if (omrthread_monitor_init_with_name(&commonInterface->lock, 0, "Hook Interface")) {
		J9HookShutdownInterface(hookInterface);
		return J9HOOK_ERR_NOMEM;
	}

	commonInterface->pool = pool_new(sizeof(J9HookRecord), 0, 0, 0, OMR_GET_CALLSITE(), OMRMEM_CATEGORY_VM, POOL_FOR_PORT((OMRPortLibrary *)portLib));
	if (commonInterface->pool == NULL) {
		J9HookShutdownInterface(hookInterface);
		return J9HOOK_ERR_NOMEM;
	}

	commonInterface->nextAgentID = J9HOOK_AGENTID_DEFAULT + 1;
	commonInterface->portLib = portLib;
	commonInterface->threshold4Trace = OMRHOOK_DEFAULT_THRESHOLD_IN_MILLISECONDS_WARNING_CALLBACK_ELAPSED_TIME;

	commonInterface->eventSize = (interfaceSize - sizeof(J9CommonHookInterface)) / (sizeof(U_8) + sizeof(OMREventInfo4Dump) + sizeof(J9HookRecord*));
	return 0;
}
Пример #2
0
/*
 * Prepares the specified hook interface for first use.
 *
 * This function may be called directly.
 *
 * Returns 0 on success, non-zero on failure
 */
intptr_t
J9HookInitializeInterface(struct J9HookInterface **hookInterface, OMRPortLibrary *portLib, size_t interfaceSize)
{
	J9CommonHookInterface *commonInterface = (J9CommonHookInterface *)hookInterface;

	memset(commonInterface, 0, interfaceSize);

	commonInterface->hookInterface = (J9HookInterface *)GLOBAL_TABLE(hookFunctionTable);

	commonInterface->size = interfaceSize;

	if (omrthread_monitor_init_with_name(&commonInterface->lock, 0, "Hook Interface")) {
		J9HookShutdownInterface(hookInterface);
		return J9HOOK_ERR_NOMEM;
	}

	commonInterface->pool = pool_new(sizeof(J9HookRecord), 0, 0, 0, OMR_GET_CALLSITE(), OMRMEM_CATEGORY_VM, POOL_FOR_PORT((OMRPortLibrary *)portLib));
	if (commonInterface->pool == NULL) {
		J9HookShutdownInterface(hookInterface);
		return J9HOOK_ERR_NOMEM;
	}

	commonInterface->nextAgentID = J9HOOK_AGENTID_DEFAULT + 1;

	return 0;
}
Пример #3
0
intptr_t
sem_init_zos(j9sem_t s, int pShared, int initValue)
{
	intptr_t rval;
	zos_sem_t *zs = (zos_sem_t *) s;

	zs->count = initValue;
	rval = omrthread_monitor_init_with_name(&zs->monitor, 0, "&zs->monitor");
	return rval;
}
Пример #4
0
/**
 * This method is called to create a SupportThreadInfo for a test.  It will populate the monitor and
 * rwmutex being used and zero out the counter
 *
 * @param functionsToRun an array of functions pointers. Each function will be run one in sequence synchronized
 *        using the monitor within the SupporThreadInfo
 * @param numberFunctions the number of functions in the functionsToRun array
 * @returns a pointer to the newly created SupporThreadInfo
 */
SupportThreadInfo *
createSupportThreadInfo(omrthread_entrypoint_t *functionsToRun, uintptr_t numberFunctions)
{
	OMRPORT_ACCESS_FROM_OMRPORT(omrTestEnv->getPortLibrary());
	SupportThreadInfo *info = (SupportThreadInfo *)omrmem_allocate_memory(sizeof(SupportThreadInfo), OMRMEM_CATEGORY_THREADS);
	info->readCounter = 0;
	info->writeCounter = 0;
	info->functionsToRun = functionsToRun;
	info->numberFunctions = numberFunctions;
	info->done = FALSE;
	omrthread_rwmutex_init((omrthread_rwmutex_t *)&info->handle, 0, "supportThreadInfo rwmutex");
	omrthread_monitor_init_with_name(&info->synchronization, 0, "supportThreadAInfo monitor");
	return info;
}
Пример #5
0
bool
MM_MasterGCThread::initialize(MM_Collector *collector, bool runAsImplicit, bool acquireVMAccessDuringConcurrent)
{
	bool success = true;
	if(omrthread_monitor_init_with_name(&_collectorControlMutex, 0, "MM_MasterGCThread::_collectorControlMutex")) {
		success = false;
	}

	_collector = collector;
	_runAsImplicit = runAsImplicit;
	_acquireVMAccessDuringConcurrent = acquireVMAccessDuringConcurrent;

	return success;
}
Пример #6
0
/**
 * Initialize a MM_ConcurrentOverflow object.
 * 
 * @return true on success, false otherwise
 */
bool
MM_ConcurrentOverflow::initialize(MM_EnvironmentBase *env)
{
	bool result = MM_WorkPacketOverflow::initialize(env);

	if (result) {
		/* Initialize monitor for safe initial Cards cleaning in Work Packets Overflow handler */
		if(omrthread_monitor_init_with_name(&_cardsClearingMonitor, 0, "MM_ConcurrentOverflow::cardsClearingMonitor")) {
			result = false;
		}
	}

	return result;
}
Пример #7
0
bool
MM_AllocationContextSegregated::initialize(MM_EnvironmentBase *env)
{
	memset(&_perContextSmallFullRegions[0], 0, sizeof(_perContextSmallFullRegions));

	if (!MM_AllocationContext::initialize(env)) {
		return false;
	}

	if (0 != omrthread_monitor_init_with_name(&_mutexSmallAllocations, 0, "MM_AllocationContextSegregated small allocation monitor")) {
		return false;
	}

	if (0 != omrthread_monitor_init_with_name(&_mutexArrayletAllocations, 0, "MM_AllocationContextSegregated arraylet allocation monitor")) {
		return false;
	}

	for (int32_t i = 0; i < OMR_SIZECLASSES_NUM_SMALL + 1; i++) {
		_smallRegions[i] = NULL;
		/* the small allocation lock needs to be acquired before small full region queue can be accessed, no concurrent access should be possible */
		_perContextSmallFullRegions[i] = MM_RegionPoolSegregated::allocateHeapRegionQueue(env, MM_HeapRegionList::HRL_KIND_FULL, true, false, false);
		if (NULL == _perContextSmallFullRegions[i]) {
			return false;
		}
	}

	/* the arraylet allocation lock needs to be acquired before arraylet full region queue can be accessed, no concurrent access should be possible */
	_perContextArrayletFullRegions = MM_RegionPoolSegregated::allocateHeapRegionQueue(env, MM_HeapRegionList::HRL_KIND_FULL, true, false, false);
	/* no locking done in the AC level for large allocation, large full page queue _is_ accessed concurrently */
	_perContextLargeFullRegions = MM_RegionPoolSegregated::allocateHeapRegionQueue(env, MM_HeapRegionList::HRL_KIND_FULL, false, true, false);
	if ((NULL == _perContextArrayletFullRegions ) || (NULL == _perContextLargeFullRegions)) {
		return false;
	}

	return true;
}
Пример #8
0
/**
 * Initialize any internal structures.
 * @return true if initialization is successful, false otherwise.
 */
bool
MM_ParallelSweepScheme::initialize(MM_EnvironmentBase *env)
{
	MM_GCExtensionsBase *extensions = env->getExtensions();
	extensions->sweepHeapSectioning = MM_SweepHeapSectioningSegmented::newInstance(env);
	if(NULL == extensions->sweepHeapSectioning) {
		return false;
	}
	_sweepHeapSectioning = extensions->sweepHeapSectioning;

	if (0 != omrthread_monitor_init_with_name(&_mutexSweepPoolState, 0, "SweepPoolState Monitor")) {
		return false;
	}
	
	return true;
}
Пример #9
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;
}
Пример #10
0
omr_error_t
OMR_MethodDictionary::init(OMR_VM *vm, size_t numProperties, const char * const *propertyNames)
{
	_lock = NULL;
	_hashTable = NULL;
	_currentBytes = 0;
	_maxBytes = 0;
	_maxEntries = 0;
	_vm = vm;
	_numProperties = numProperties;
	_propertyNames = propertyNames;
	_sizeofEntry = (uint32_t)(sizeof(OMR_MethodDictionaryEntry) + (_numProperties * sizeof(char *)));

	omr_error_t rc = OMR_ERROR_NONE;
	omrthread_t self = NULL;
	if (0 == omrthread_attach_ex(&self, J9THREAD_ATTR_DEFAULT)) {
		OMRPORT_ACCESS_FROM_OMRVM(vm);
		_hashTable = hashTableNew(
			OMRPORTLIB, OMR_GET_CALLSITE(), 0, _sizeofEntry, 0, 0, OMRMEM_CATEGORY_OMRTI,
			entryHash, entryEquals, NULL, NULL);
		if (NULL != _hashTable) {
			if (0 != omrthread_monitor_init_with_name(&_lock, 0, "omrVM->_methodDictionary")) {
				rc = OMR_ERROR_FAILED_TO_ALLOCATE_MONITOR;
			}
		} else {
			rc = OMR_ERROR_OUT_OF_NATIVE_MEMORY;
		}

		if (OMR_ERROR_NONE != rc) {
			cleanup();
		}
		omrthread_detach(self);
	} else {
		rc = OMR_ERROR_FAILED_TO_ATTACH_NATIVE_THREAD;
	}
	return rc;
}
Пример #11
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);
}
Пример #12
0
CMonitor::CMonitor(const char *pName)
{
	if (omrthread_monitor_init_with_name(&m_monitor, 0, (char *) pName)) {
	}
}
Пример #13
0
CMonitor::CMonitor(uintptr_t flags, const char *pName)
{
	if (omrthread_monitor_init_with_name(&m_monitor, flags, (char *) pName)) {
	}
}
Пример #14
0
/*
 * 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);
}