/* * 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; }
/* * 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; }
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; }
/** * 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; }
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; }
/** * 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; }
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; }
/** * 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; }
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; }
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; }
/* * 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); }
CMonitor::CMonitor(const char *pName) { if (omrthread_monitor_init_with_name(&m_monitor, 0, (char *) pName)) { } }
CMonitor::CMonitor(uintptr_t flags, const char *pName) { if (omrthread_monitor_init_with_name(&m_monitor, flags, (char *) pName)) { } }
/* * 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); }