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); }
void MM_MasterGCThread::tearDown(MM_EnvironmentBase *env) { if (NULL != _collectorControlMutex) { omrthread_monitor_destroy(_collectorControlMutex); _collectorControlMutex = NULL; } _collector = NULL; }
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; }
/** * 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); }
/** * 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); }
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; }
/* * 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); } }
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; }
/** * 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); } }
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); } } }
/* * 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); }
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; }
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(¤tMask); 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, ¤tMask)) { 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(¤tMask, &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 *)¤tMask), 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); }