Пример #1
0
/**
 * Verify port library management.
 *
 * The port library allocates resources as part of it's normal running.  Thus
 * prior to terminating the application the port library must free all it's
 * resource via the port library table function
 * @ref omrport.c::omrport_shutdown_library "omrport_shutdown_library()"
 *
 * @note self allocated port libraries de-allocate their memory as part of this
 * function.
 */
TEST(PortTest, port_test6)
{
	OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
	const char *testName = "omrport_test6";

	OMRPortLibrary *fakePtr;
	int32_t rc;
	omrthread_t attachedThread = NULL;

	reportTestEntry(OMRPORTLIB, testName);

	if (0 != omrthread_attach_ex(&attachedThread, J9THREAD_ATTR_DEFAULT)) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "Failed to attach to omrthread\n");
		goto exit;
	}

	memset(&portLibraryToTest, '0', sizeof(OMRPortLibrary));
	fakePtr = &portLibraryToTest;
	rc = omrport_init_library(fakePtr, sizeof(OMRPortLibrary));
	if (0 != rc) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_init_library() returned %d expected 0\n", rc);
	}
	/* Shut it down */
	portLibraryToTest.port_shutdown_library(fakePtr);
	omrthread_detach(attachedThread);

	/* Global pointer should be NULL */
	if (NULL != fakePtr->portGlobals) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "port_shutdown_library() portGlobal pointer is not NULL\n");
	}

	/* Shutdown again, should be ok, nothing to check ...
	 * TODO support this?
	portLibraryToTest.port_shutdown_library(fakePtr);
	 */

	/* Let's do it all over again, this time self allocated
	 * Note a self allocated library does not startup, so there are no
	 * port globals etc.  Verifies the shutdown routines are safe
	 */
	fakePtr = NULL;
	rc = omrport_allocate_library(&fakePtr);
	if (0 != rc) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_allocate_library() returned %d expected 0\n", rc);
		goto exit;
	}
	/*	TODO library not started, fair to shut it down ?
	fakePtr->port_shutdown_library(fakePtr);
	*/
	fakePtr = NULL;

exit:
	reportTestExit(OMRPORTLIB, testName);
}
Пример #2
0
omr_error_t
OMR_MethodDictionary::insert(OMR_MethodDictionaryEntry *entry)
{
	omr_error_t rc = OMR_ERROR_NONE;
	omrthread_t self = NULL;
	if (0 == omrthread_attach_ex(&self, J9THREAD_ATTR_DEFAULT)) {
		if (0 == omrthread_monitor_enter_using_threadId(_lock, self)) {
			OMR_MethodDictionaryEntry *newEntry =
				(OMR_MethodDictionaryEntry *)hashTableAdd(_hashTable, entry);
			if (NULL == newEntry) {
				rc = OMR_ERROR_OUT_OF_NATIVE_MEMORY;
			} else {
				bool reusedEntry = false;

				if (!entryValueEquals(newEntry, entry)) {
					/* There was an existing hash table entry with the same key.
					 * Overwrite its contents.
					 */
					traceInsertEntryReplace(newEntry);
					cleanupEntryStrings(newEntry, this);
					reusedEntry = true;
				}

				/* copy the entry strings */
				rc = dupEntryStrings(newEntry, entry);
				if (OMR_ERROR_NONE == rc) {
					traceInsertEntrySuccess(newEntry);
					if (!reusedEntry) {
						_currentBytes += _sizeofEntry;
					}
					_currentBytes += countEntryNameBytesNeeded(newEntry);
					if (_currentBytes > _maxBytes) {
						_maxBytes = _currentBytes;
						_maxEntries = hashTableGetCount(_hashTable);
					}
				}
			}
			omrthread_monitor_exit_using_threadId(_lock, self);
		} else {
			rc = OMR_ERROR_INTERNAL;
		}
		omrthread_detach(self);
	} else {
		rc = OMR_ERROR_FAILED_TO_ATTACH_NATIVE_THREAD;
	}
	if (OMR_ERROR_NONE != rc) {
		traceInsertEntryFailed(rc, entry);
	}
	return rc;
}
Пример #3
0
int main(void)
{
	int32_t totalFiles = 0;
	intptr_t rc = 0;
	char resultBuffer[128];
	uintptr_t rcFile;
	uintptr_t handle;
	OMRPortLibrary portLibrary;

	rc = omrthread_attach_ex(NULL, J9THREAD_ATTR_DEFAULT);
	if (0 != rc) {
		fprintf(stderr, "omrthread_attach_ex(NULL, J9THREAD_ATTR_DEFAULT) failed, rc=%d\n", (int)rc);
		return -1;
	}

	rc = omrport_init_library(&portLibrary, sizeof(OMRPortLibrary));
	if (0 != rc) {
		fprintf(stderr, "omrport_init_library(&portLibrary, sizeof(OMRPortLibrary)), rc=%d\n", (int)rc);
		return -1;
	}

	OMRPORT_ACCESS_FROM_OMRPORT(&portLibrary);

	rcFile = handle = omrfile_findfirst(SRC_DIR, resultBuffer);

	if(rcFile == (uintptr_t)-1) {
		fprintf(stderr, "omrfile_findfirst(SRC_DIR, resultBuffer), return code=%d\n", (int)rcFile);
		return -1;
	}

	while ((uintptr_t)-1 != rcFile) {
		if (strncmp(resultBuffer, VERBOSE_GC_FILE_PREFIX, strlen(VERBOSE_GC_FILE_PREFIX)) == 0) {
			analyze(resultBuffer, portLibrary);
			totalFiles++;
			/* Clean up verbose log file */
			omrfile_unlink(resultBuffer);
		}
		rcFile = omrfile_findnext(handle, resultBuffer);
	}
	if (handle != (uintptr_t)-1) {
		omrfile_findclose(handle);
	}

	if(totalFiles < 1) {
		omrtty_printf("Failed to find any verbose GC file to process!\n\n");
	}

	portLibrary.port_shutdown_library(&portLibrary);
	omrthread_detach(NULL);
}
Пример #4
0
/**
 * PortLibrary shutdown.
 *
 * Shutdown the port library, de-allocate resources required by the components of the portlibrary.
 * Any resources that were created by @ref omrport_startup_library should be destroyed here.
 *
 * @param[in] portLibrary The portlibrary.
 *
 * @return 0 on success, negative return code on failure
 */
int32_t
omrport_shutdown_library(struct OMRPortLibrary *portLibrary)
{
	/* Ensure that the current thread is attached.
	 * If it is not, there will be a crash trying to using
	 * thread functions in the following shutdown functions.
	 */
	omrthread_t attached_thread = NULL;
	intptr_t rc = omrthread_attach_ex(&attached_thread, J9THREAD_ATTR_DEFAULT);
	if (0 != rc) {
		return (int32_t)rc;
	}

#if defined(OMR_OPT_CUDA)
	portLibrary->cuda_shutdown(portLibrary);
#endif /* OMR_OPT_CUDA */
	portLibrary->introspect_shutdown(portLibrary);
	portLibrary->sig_shutdown(portLibrary);
	portLibrary->str_shutdown(portLibrary);
	/* vmem shutdown now requires sl support.*/
	portLibrary->vmem_shutdown(portLibrary);
	portLibrary->sl_shutdown(portLibrary);
	portLibrary->sysinfo_shutdown(portLibrary);
	portLibrary->exit_shutdown(portLibrary);
	portLibrary->dump_shutdown(portLibrary);
	portLibrary->time_shutdown(portLibrary);

	/* Shutdown the socket library before the tty, so it can write to the tty if required */
	portLibrary->nls_shutdown(portLibrary);
	portLibrary->mmap_shutdown(portLibrary);
	portLibrary->tty_shutdown(portLibrary);
	portLibrary->file_shutdown(portLibrary);
	portLibrary->file_blockingasync_shutdown(portLibrary);

	portLibrary->cpu_shutdown(portLibrary);
	portLibrary->error_shutdown(portLibrary);
	omrport_tls_shutdown(portLibrary);

	portLibrary->mem_shutdown(portLibrary);

	omrthread_detach(attached_thread);

	/* Last thing to do.  If this port library was self allocated free this memory */
	if (NULL != portLibrary->self_handle) {
		omrmem_deallocate_portLibrary(portLibrary);
	}

	return (int32_t)0;
}
Пример #5
0
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);
		}
	}
}
Пример #6
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;
}
Пример #7
0
int
testMain(int argc, char ** argv, char **envp)
{
	/* Start up */
	OMR_VM_Example exampleVM;
	OMR_VMThread *omrVMThread = NULL;
	omrthread_t self = NULL;
	exampleVM._omrVM = NULL;
	exampleVM.rootTable = NULL;

	/* Initialize the VM */
	omr_error_t rc = OMR_Initialize(&exampleVM, &exampleVM._omrVM);
	Assert_MM_true(OMR_ERROR_NONE == rc);

	/* Recursive omrthread_attach() (i.e. re-attaching a thread that is already attached) is cheaper and less fragile
	 * than non-recursive. If performing a sequence of function calls that are likely to attach & detach internally,
	 * it is more efficient to call omrthread_attach() before the entire block.
	 */
	int j9rc = (int) omrthread_attach_ex(&self, J9THREAD_ATTR_DEFAULT);
	Assert_MM_true(0 == j9rc);

	/* Initialize root table */
	exampleVM.rootTable = hashTableNew(
			exampleVM._omrVM->_runtime->_portLibrary, OMR_GET_CALLSITE(), 0, sizeof(RootEntry), 0, 0, OMRMEM_CATEGORY_MM,
			rootTableHashFn, rootTableHashEqualFn, NULL, NULL);

	/* Initialize heap and collector */
	{
		/* This has to be done in local scope because MM_StartupManager has a destructor that references the OMR VM */
		MM_StartupManagerImpl startupManager(exampleVM._omrVM);
		rc = OMR_GC_IntializeHeapAndCollector(exampleVM._omrVM, &startupManager);
	}
	Assert_MM_true(OMR_ERROR_NONE == rc);

	/* Attach current thread to the VM */
	rc = OMR_Thread_Init(exampleVM._omrVM, NULL, &omrVMThread, "GCTestMailThread");
	Assert_MM_true(OMR_ERROR_NONE == rc);

	/* Kick off the dispatcher therads */
	rc = OMR_GC_InitializeDispatcherThreads(omrVMThread);
	Assert_MM_true(OMR_ERROR_NONE == rc);
	
	OMRPORT_ACCESS_FROM_OMRVM(exampleVM._omrVM);
	omrtty_printf("VM/GC INITIALIZED\n");

	/* Do stuff */

	MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(omrVMThread);
	MM_ObjectAllocationInterface *allocationInterface = env->_objectAllocationInterface;
	MM_GCExtensionsBase *extensions = env->getExtensions();

	omrtty_printf("configuration is %s\n", extensions->configuration->getBaseVirtualTypeId());
	omrtty_printf("collector interface is %s\n", env->getExtensions()->collectorLanguageInterface->getBaseVirtualTypeId());
	omrtty_printf("garbage collector is %s\n", env->getExtensions()->getGlobalCollector()->getBaseVirtualTypeId());
	omrtty_printf("allocation interface is %s\n", allocationInterface->getBaseVirtualTypeId());

	/* Allocate objects without collection until heap exhausted */
	uintptr_t allocatedFlags = 0;
	uintptr_t size = extensions->objectModel.adjustSizeInBytes(24);
	MM_AllocateDescription mm_allocdescription(size, allocatedFlags, true, true);
	uintptr_t allocatedCount = 0;
	while (true) {
		omrobjectptr_t obj = (omrobjectptr_t)allocationInterface->allocateObject(env, &mm_allocdescription, env->getMemorySpace(), false);
		if (NULL != obj) {
			extensions->objectModel.setObjectSize(obj, mm_allocdescription.getBytesRequested());
			RootEntry rEntry = {"root1", obj};
			RootEntry *entryInTable = (RootEntry *)hashTableAdd(exampleVM.rootTable, &rEntry);
			if (NULL == entryInTable) {
				omrtty_printf("failed to add new root to root table!\n");
			}
			/* update entry if it already exists in table */
			entryInTable->rootPtr = obj;
			allocatedCount++;
		} else {
			break;
		}
	}

	/* Print/verify thread allocation stats before GC */
	MM_AllocationStats *allocationStats = allocationInterface->getAllocationStats();
	omrtty_printf("thread allocated %d tlh bytes, %d non-tlh bytes, from %d allocations before NULL\n",
		allocationStats->tlhBytesAllocated(), allocationStats->nontlhBytesAllocated(), allocatedCount);
	uintptr_t allocationTotalBytes = allocationStats->tlhBytesAllocated() + allocationStats->nontlhBytesAllocated();
	uintptr_t allocatedTotalBytes = size * allocatedCount;
	Assert_MM_true(allocatedTotalBytes == allocationTotalBytes);

	/* Force GC to print verbose system allocation stats -- should match thread allocation stats from before GC */
	omrobjectptr_t obj = (omrobjectptr_t)allocationInterface->allocateObject(env, &mm_allocdescription, env->getMemorySpace(), true);
	env->unwindExclusiveVMAccessForGC();
	Assert_MM_false(NULL == obj);
	extensions->objectModel.setObjectSize(obj, mm_allocdescription.getBytesRequested());

	omrtty_printf("ALL TESTS PASSED\n");

	/* Shut down */

	/* Shut down the dispatcher therads */
	rc = OMR_GC_ShutdownDispatcherThreads(omrVMThread);
	Assert_MM_true(OMR_ERROR_NONE == rc);

	/* Shut down collector */
	rc = OMR_GC_ShutdownCollector(omrVMThread);
	Assert_MM_true(OMR_ERROR_NONE == rc);

	/* Detach from VM */
	rc = OMR_Thread_Free(omrVMThread);
	Assert_MM_true(OMR_ERROR_NONE == rc);

	/* Shut down heap */
	rc = OMR_GC_ShutdownHeap(exampleVM._omrVM);
	Assert_MM_true(OMR_ERROR_NONE == rc);

	/* Free root hash table */
	hashTableFree(exampleVM.rootTable);

	/* Balance the omrthread_attach_ex() issued above */
	omrthread_detach(self);

	/* Shut down VM
	 * This destroys the port library and the omrthread library.
	 * Don't use any port library or omrthread functions after this.
	 *
	 * (This also shuts down trace functionality, so the trace assertion
	 * macros might not work after this.)
	 */
	rc = OMR_Shutdown(exampleVM._omrVM);
	Assert_MM_true(OMR_ERROR_NONE == rc);

	return rc;
}
Пример #8
0
int
main(int argc, char *argv[])
{
	omrthread_attach(NULL);

	OMRPortLibrary portLibrary;
	omrport_init_library(&portLibrary, sizeof(portLibrary));
	DDR_RC rc = DDR_RC_OK;

	/* Get options. */
	const char *macroFile = "src/macros/test/macroList";
	const char *supersetFile = "superset.out";
	const char *blobFile = "blob.dat";
	const char *overrideFile = NULL;
	vector<string> debugFiles;
	rc = getOptions(&portLibrary, argc, argv, &macroFile, &supersetFile, &blobFile, &overrideFile, &debugFiles);

	/* Create IR from input. */
#if defined(_MSC_VER)
	PdbScanner scanner;
#else /* defined(_MSC_VER) */
	DwarfScanner scanner;
#endif /* defined(_MSC_VER) */
	Symbol_IR ir;
	if ((DDR_RC_OK == rc) && !debugFiles.empty()) {
		rc = scanner.startScan(&portLibrary, &ir, &debugFiles);
	}

	/* Compute field offsets for UDTs. */
	if (DDR_RC_OK == rc) {
		rc = ir.computeOffsets();
	}
	/* Remove duplicate types. */
	if (DDR_RC_OK == rc) {
		rc = ir.removeDuplicates();
	}
	MacroTool macroTool;
	/* Read macros. */
	if ((DDR_RC_OK == rc) && (NULL != macroFile)) {
		rc = macroTool.getMacros(macroFile);
	}
	/* Add Macros to IR. */
	if (DDR_RC_OK == rc) {
		rc = macroTool.addMacrosToIR(&ir);
	}

	/* Apply Type Overrides; must be after scanning and loading macros. */
	if ((DDR_RC_OK == rc) && (NULL != overrideFile)) {
		rc = ir.applyOverrideList(&portLibrary, overrideFile);
	}

	/* Generate output. */
	if ((DDR_RC_OK == rc) && !ir._types.empty()) {
		rc = genBlob(&portLibrary, &ir, supersetFile, blobFile);
	}

	portLibrary.port_shutdown_library(&portLibrary);
	omrthread_detach(NULL);
	omrthread_shutdown_library();
	return 0;
}
Пример #9
0
/**
 * Verify port library management.
 *
 * The port library requires a region of memory for it's function table pointer.
 * This table must not be declared on a stack that is torn down prior to the application
 * running to completion and tearing down the port library.  It can either be
 * created as a global variable to the program, or if a running port library is
 * present it can be allocated on behalf of the application.  Self allocating
 * port libraries use the exported function
 * @ref omrport.c::omrport_allocate_library "omrport_allocate_library()".
 * This function allocates, initializes and starts the port library.
 * The port library is responsible for deallocation of this memory
 * as part of it's shutdown.
 */
TEST(PortTest, port_test5)
{
	OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
	const char *testName = "omrport_test5";

	OMRPortLibrary *fakePortLibrary = NULL;
	int32_t rc;
	omrthread_t attachedThread = NULL;

	reportTestEntry(OMRPORTLIB, testName);

	if (0 != omrthread_attach_ex(&attachedThread, J9THREAD_ATTR_DEFAULT)) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "Failed to attach to omrthread\n");
		goto exit;
	}

	/* Pass */
	fakePortLibrary = NULL;
	rc = omrport_allocate_library(&fakePortLibrary);
	if (0 != rc) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_allocate_library() returned %d expected 0\n", rc);
		goto exit;
	}

	/* Verify we have a pointer */
	if (NULL == fakePortLibrary) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_allocate_library() returned NULL pointer\n");
		goto exit;
	}

	/* Verify not started */
	if (NULL != fakePortLibrary->portGlobals) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_allocate_library() portGlobals pointer is not NULL\n");
	}

	/* Verify self allocated */
	if (NULL == fakePortLibrary->self_handle) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_allocate_library() self_handle pointer is NULL\n");
	}

	/* Verify it will start */
	rc = omrport_startup_library(fakePortLibrary);
	if (0 != rc) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_startup_library() returned %d expected 0\n", rc);
	}

	/* Take this port library down */
	fakePortLibrary->port_shutdown_library(fakePortLibrary);

	/* Try again, but force failure during startup by over riding one of the startup functions */
	fakePortLibrary = NULL;
	rc = omrport_allocate_library(&fakePortLibrary);
	if (0 != rc) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_allocate_library() returned %d expected 0\n", rc);
		goto exit;
	}

	/* Override omrmem_startup */
	fakePortLibrary->mem_startup = fake_mem_startup;
	rc = omrport_startup_library(fakePortLibrary);
	if (failMemStartup != rc) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_startup_library() returned %d expected %d\n", rc, failMemStartup);
	}

	/* No way to tell if it freed the memory properly.  The pointer we have to the port library is
	 * not updated as part of omrport_startup_library(), so we are now pointing at dead memory.
	 *
	 * NULL our pointer to exit can clean-up if required
	 */
	fakePortLibrary = NULL;

exit:
	if (NULL != fakePortLibrary) {
		fakePortLibrary->port_shutdown_library(fakePortLibrary);
	}
	if (NULL != attachedThread) {
		omrthread_detach(attachedThread);
	}
	reportTestExit(OMRPORTLIB, testName);
}
Пример #10
0
/**
 * Verify port library management.
 *
 * The second stage in starting a port library.  Once a port library table has
 * been created via
 * @ref omrport.c::omrport_create_library "omrport_create_library()"
 * it is started via the exported function
 * @ref omrport.c::omrport_startup_library "omrport_startup_library()".
 *
 * @see omrport.c::omrport_create_library "omrport_create_library()"
 * @see omrport.c::omrport_init_library "omrport_init_library()"
 */
TEST(PortTest, port_test3)
{
	OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
	const char *testName = "omrport_test3";

	OMRPortLibrary *fakePtr = &portLibraryToTest;
	int32_t rc;
	omrthread_t attachedThread = NULL;

	reportTestEntry(OMRPORTLIB, testName);

	if (0 != omrthread_attach_ex(&attachedThread, J9THREAD_ATTR_DEFAULT)) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "Failed to attach to omrthread\n");
		goto exit;
	}

	/* create a library and ensure the port globals is non NULL, what else can we do? */
	memset(&portLibraryToTest, '0', sizeof(OMRPortLibrary));
	rc = omrport_create_library(fakePtr, sizeof(OMRPortLibrary));
	if (0 != rc) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() returned %d expected 0\n", rc);
		goto exit;
	}

	/* check the rc */
	rc = omrport_startup_library(fakePtr);
	if (0 != rc) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_startup_library() returned %d expected 0\n", rc);
	}

	/* check portGlobals were allocated */
	if (NULL == fakePtr->portGlobals) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_startup_library() portGlobals not allocated\n");
	}

	if (NULL != fakePtr->self_handle) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_startup_library() self_handle pointer not NULL\n");
	}

	/* Clean this port library up */
	portLibraryToTest.port_shutdown_library(fakePtr);

	/* Do it again, but before starting override memory (first startup function) and
	 * ensure everything is ok
	 */
	memset(&portLibraryToTest, '0', sizeof(OMRPortLibrary));
	rc = omrport_create_library(fakePtr, sizeof(OMRPortLibrary));
	if (0 != rc) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() returned %d expected 0\n", rc);
		goto exit;
	}

	/* override time_startup */
	fakePtr->time_startup = fake_time_startup;
	rc = omrport_startup_library(fakePtr);
	if (failMemStartup != rc) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_startup_library() returned %d expected %d\n", rc, failMemStartup);
	}

exit:
	portLibraryToTest.port_shutdown_library(fakePtr);
	if (NULL != attachedThread) {
		omrthread_detach(attachedThread);
	}
	reportTestExit(OMRPORTLIB, testName);
}