Ejemplo n.º 1
0
TEST(TraceLifecycleTest, moduleUnloadAfterThreadDetach)
{
	/* OMR VM data structures */
	OMRTestVM testVM;
	OMR_VMThread *vmthread = NULL;

	omrthread_t childThread = NULL;
	ChildThreadData *childData = NULL;

	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, "moduleLoadBeforeThreadAttach"));

	ASSERT_NO_FATAL_FAILURE(startChildThread(&testVM, &childThread, moduleUnloadAfterThreadDetachHelper, &childData));
	ASSERT_EQ(1, omrthread_resume(childThread));
	OMRTEST_ASSERT_ERROR_NONE(waitForChildThread(&testVM, childThread, childData));

	/* Unload the module that was left loaded by the child thread */
	UT_OMR_TEST_MODULE_UNLOADED(testVM.omrVM._trcEngine->utIntf);

	/* Now clear up the VM we started for this test case. */
	OMRTEST_ASSERT_ERROR_NONE(omr_ras_cleanupTraceEngine(vmthread));
	OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread));
	OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM));

	ASSERT_TRUE(NULL == (void *)omr_test_UtModuleInfo.intf);
}
Ejemplo n.º 2
0
TEST(TraceLifecycleTest, threadAttachDetachStress)
{
	/* OMR VM data structures */
	OMRTestVM testVM;
	OMR_VMThread *vmthread = NULL;
	const int attachDetachHelpersCount = 10;
	omrthread_t attachDetachHelpers[attachDetachHelpersCount];
	ChildThreadData *attachDetachData[attachDetachHelpersCount];
	omrthread_t shutdownHelper = NULL;
	ChildThreadData *shutdownData = NULL;

	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", datDir));

	/* Attach the thread to the trace engine */
	OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Init(&testVM.omrVM, NULL, &vmthread, "registerSubscriberAfterShutdown"));
	UT_OMR_TEST_MODULE_LOADED(testVM.omrVM._trcEngine->utIntf);
	/* module is not unloaded before trace engine shutdown */

	for (int i = 0; i < attachDetachHelpersCount; i++) {
		ASSERT_NO_FATAL_FAILURE(startChildThread(&testVM, &attachDetachHelpers[i], attachDetachHelper, &attachDetachData[i]));
	}
	ASSERT_NO_FATAL_FAILURE(startChildThread(&testVM, &shutdownHelper, shutdownTraceHelper, &shutdownData));

	for (int i = 0; i < attachDetachHelpersCount; i++) {
		ASSERT_EQ(1, omrthread_resume(attachDetachHelpers[i]));
	}
	ASSERT_EQ(1, omrthread_resume(shutdownHelper));

	for (int i = 0; i < attachDetachHelpersCount; i++) {
		OMRTEST_ASSERT_ERROR_NONE(waitForChildThread(&testVM, attachDetachHelpers[i], attachDetachData[i]));
	}
	OMRTEST_ASSERT_ERROR_NONE(waitForChildThread(&testVM, shutdownHelper, shutdownData));

	/* Now clear up the VM we started for this test case. */
	UT_OMR_TEST_MODULE_UNLOADED(testVM.omrVM._trcEngine->utIntf);
	OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread));
	OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM));

	ASSERT_TRUE(NULL == (void *)omr_test_UtModuleInfo.intf);
}
Ejemplo n.º 3
0
static uintptr_t
canCreateThread(const create_attr_t *expected, const omrthread_attr_t attr)
{
	uintptr_t status = 0;
	uintptr_t rc;
	omrthread_t handle;
	threaddata_t data;

	data.expected = expected;
	data.status = 0;
	getCurrentOsSched(&data.curPriority, &data.curPolicy);

	rc = J9THREAD_VERBOSE(omrthread_create_ex(&handle, (attr? &attr : J9THREAD_ATTR_DEFAULT), 1, threadmain, &data));
	if (J9THREAD_SUCCESS == rc) {
		OSTHREAD tid = handle->handle;

		omrthread_resume(handle);

#if defined(SPEC_PTHREAD_API)
#if defined(LINUX)
		/* bug? Linux can return a success code, but still fail to create the thread.
		 * NOTE: It is not guaranteed that tid 0 is invalid in all pthread implementations.
		 */
		if (0 == tid) {
			omrTestEnv->log(LEVEL_ERROR, "  LINUX: tid 0 returned\n");
			status |= CREATE_FAILED;
			return status;
		}
#endif /* defined(LINUX) */
		/* this may fail because omrthreads detach themselves upon exiting */

#if defined(OSX)
		/* OSX TODO: Why do the tests segfault in child thread when accessing &data on OSX without a 1ms sleep? */
		omrthread_sleep(10);
#endif /* defined(OSX) */
		PTHREAD_VERBOSE(pthread_join(tid, NULL));
		status |= data.status;

#elif defined(SPEC_WIN_API)
		WaitForSingleObject(tid, INFINITE);
		status |= data.status;
#else
		/* In this case,
		 * threadmain() doesn't access the expected data, so it's ok to continue without
		 * waiting for the child thread to complete.
		 */
#endif /* defined(SPEC_PTHREAD_API) */
	} else {
		status |= CREATE_FAILED;
	}
	return status;
}
Ejemplo n.º 4
0
TEST(JoinTest, joinLiveThread)
{
	omrthread_t suspendedThr = NULL;
	omrthread_t joinHelperThr = NULL;
	JoinThreadHelperData helperData;

	/* suspend the child thread when it starts */
	ASSERT_NO_FATAL_FAILURE(createThread(&suspendedThr, TRUE, J9THREAD_CREATE_JOINABLE, doNothingHelper, NULL));

	/* create a thread to join on the suspended thread */
	helperData.threadToJoin = suspendedThr;
	helperData.expectedRc = J9THREAD_SUCCESS;
	ASSERT_NO_FATAL_FAILURE(createThread(&joinHelperThr, FALSE, J9THREAD_CREATE_JOINABLE, joinThreadHelper, &helperData));

	/* hopefully wait long enough for the join helper thread to start joining */
	ASSERT_EQ(J9THREAD_SUCCESS, omrthread_sleep(3000));

	/* resume the child thread */
	printf("resuming suspendedThr\n");
	fflush(stdout);
	ASSERT_EQ(1, omrthread_resume(suspendedThr));

	VERBOSE_JOIN(joinHelperThr, J9THREAD_SUCCESS);
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
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;
}