Skip to content

Commit

Permalink
Merge pull request #2353 from gacholio/aixflush
Browse files Browse the repository at this point in the history
Atomic-free JNI work
  • Loading branch information
DanHeidinga authored Jul 10, 2018
2 parents be905b0 + 05ea976 commit 476aa5c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 37 deletions.
4 changes: 2 additions & 2 deletions runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -5473,10 +5473,10 @@ typedef struct J9JavaVM {
UDATA safePointResponseCount;
struct J9VMRuntimeStateListener vmRuntimeStateListener;
#if defined(J9VM_INTERP_ATOMIC_FREE_JNI_USES_FLUSH)
#if defined(LINUX)
#if defined(LINUX) || defined(AIXPPC)
J9PortVmemIdentifier exclusiveGuardPage;
omrthread_monitor_t flushMutex;
#elif defined(WIN32) /* LINUX */
#elif defined(WIN32) /* LINUX || AIXPPC */
void *flushFunction;
#endif /* WIN32 */
#endif /* J9VM_INTERP_ATOMIC_FREE_JNI_USES_FLUSH */
Expand Down
1 change: 1 addition & 0 deletions runtime/oti/j9port.h
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ typedef struct J9CacheInfoQuery {
#define J9PORT_VMEM_ZOS_USE_EXTENDED_PRIVATE_AREA OMRPORT_VMEM_ZOS_USE2TO32G_AREA
#define J9PORT_VMEM_ALLOCATE_TOP_DOWN OMRPORT_VMEM_ALLOCATE_TOP_DOWN
#define J9PORT_VMEM_ADDRESS_HINT OMRPORT_VMEM_ADDRESS_HINT
#define J9PORT_VMEM_NO_AFFINITY OMRPORT_VMEM_NO_AFFINITY

#define J9PORT_SLOPEN_DECORATE OMRPORT_SLOPEN_DECORATE
#define J9PORT_SLOPEN_LAZY OMRPORT_SLOPEN_LAZY
Expand Down
50 changes: 30 additions & 20 deletions runtime/vm/FlushProcessWriteBuffers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@

#if defined(WIN32)
#include <windows.h>
#elif defined(LINUX) /* WIN32 */
#elif defined(LINUX) || defined(AIXPPC) /* WIN32 */
#include <sys/mman.h>
#endif /* LINUX */
#endif /* LINUX || AIXPPC */

#include "vm_internal.h"
#include "ut_j9vm.h"
Expand All @@ -37,50 +37,60 @@ extern "C" {
void
flushProcessWriteBuffers(J9JavaVM *vm)
{
/* If this is called before the underlying data structures have been initialized,
* assume that the VM is single-threaded and proceed without error.
*/
#if defined(WIN32)
((VOID (WINAPI*)(void))vm->flushFunction)();
#elif defined(LINUX) /* WIN32 */
omrthread_monitor_enter(vm->flushMutex);
void *addr = vm->exclusiveGuardPage.address;
UDATA pageSize = vm->exclusiveGuardPage.pageSize;
int mprotectrc = mprotect(addr, pageSize, PROT_READ | PROT_WRITE);
Assert_VM_true(0 == mprotectrc);
VM_AtomicSupport::add((UDATA*)addr, 1);
mprotectrc = mprotect(addr, pageSize, PROT_NONE);
Assert_VM_true(0 == mprotectrc);
omrthread_monitor_exit(vm->flushMutex);
#else /* LINUX */
if (NULL != vm->flushFunction) {
((VOID (WINAPI*)(void))vm->flushFunction)();
}
#elif defined(LINUX) || defined(AIXPPC) /* WIN32 */
if (NULL != vm->flushMutex) {
omrthread_monitor_enter(vm->flushMutex);
void *addr = vm->exclusiveGuardPage.address;
UDATA pageSize = vm->exclusiveGuardPage.pageSize;
int mprotectrc = mprotect(addr, pageSize, PROT_READ | PROT_WRITE);
Assert_VM_true(0 == mprotectrc);
VM_AtomicSupport::add((UDATA*)addr, 1);
mprotectrc = mprotect(addr, pageSize, PROT_NONE);
Assert_VM_true(0 == mprotectrc);
omrthread_monitor_exit(vm->flushMutex);
}
#else /* LINUX || AIXPPC */
#error flushProcessWriteBuffers unimplemented
#endif /* LINUX */
#endif /* LINUX || AIXPPC */
}

UDATA
initializeExclusiveAccess(J9JavaVM *vm)
{
UDATA rc = 0;
#if defined(LINUX)
#if defined(LINUX) || defined(AIXPPC)
PORT_ACCESS_FROM_JAVAVM(vm);
UDATA pageSize = j9vmem_supported_page_sizes()[0];
void *addr = j9vmem_reserve_memory(
NULL,
pageSize,
&vm->exclusiveGuardPage,
J9PORT_VMEM_MEMORY_MODE_READ | J9PORT_VMEM_MEMORY_MODE_WRITE | J9PORT_VMEM_MEMORY_MODE_COMMIT,
J9PORT_VMEM_MEMORY_MODE_READ | J9PORT_VMEM_MEMORY_MODE_WRITE | J9PORT_VMEM_MEMORY_MODE_COMMIT | J9PORT_VMEM_NO_AFFINITY,
pageSize, OMRMEM_CATEGORY_VM);
if (NULL == addr) {
Trc_VM_failedtoAllocateGuardPage(pageSize);
rc = 1;
} else {
/* AIX mlock is only allowed as root */
#if defined(LINUX)
int mlockrc = mlock(addr, pageSize);
Assert_VM_true(0 == mlockrc);
#endif /* LINUX */
int mprotectrc = mprotect(addr, pageSize, PROT_NONE);
Assert_VM_true(0 == mprotectrc);
}
if (0 != omrthread_monitor_init_with_name(&vm->flushMutex, 0, "flushProcessWriteBuffers")) {
shutDownExclusiveAccess(vm);
rc = 1;
}
#elif defined(WIN32) /* LINUX */
#elif defined(WIN32) /* LINUX || AIXPPC */
HMODULE h_kernel32 = GetModuleHandle("kernel32");
Assert_VM_notNull(h_kernel32);
void *flushFunction = (void*)GetProcAddress(h_kernel32, "FlushProcessWriteBuffers");
Expand All @@ -93,7 +103,7 @@ initializeExclusiveAccess(J9JavaVM *vm)
void
shutDownExclusiveAccess(J9JavaVM *vm)
{
#if defined(LINUX)
#if defined(LINUX) || defined(AIXPPC)
J9PortVmemIdentifier *guardPage = &vm->exclusiveGuardPage;
void *addr = guardPage->address;
if (NULL != addr) {
Expand All @@ -104,7 +114,7 @@ shutDownExclusiveAccess(J9JavaVM *vm)
omrthread_monitor_destroy(vm->flushMutex);
vm->flushMutex = NULL;
}
#endif /* LINUX */
#endif /* LINUX || AIXPPC */
}

#endif /* J9VM_INTERP_ATOMIC_FREE_JNI_USES_FLUSH */
Expand Down
28 changes: 13 additions & 15 deletions runtime/vm/jvminit.c
Original file line number Diff line number Diff line change
Expand Up @@ -2245,6 +2245,11 @@ IDATA VMInitStages(J9JavaVM *vm, IDATA stage, void* reserved) {
break;

case ABOUT_TO_BOOTSTRAP :
#if defined(J9VM_INTERP_ATOMIC_FREE_JNI_USES_FLUSH)
if (0 != initializeExclusiveAccess(vm)) {
goto _error;
}
#endif /* J9VM_INTERP_ATOMIC_FREE_JNI_USES_FLUSH */
TRIGGER_J9HOOK_VM_ABOUT_TO_BOOTSTRAP(vm->hookInterface, vm->mainThread);
/* At this point, the decision about which interpreter to use has been made */
vm->bytecodeLoop = J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags, J9_EXTENDED_RUNTIME_DEBUG_MODE)
Expand Down Expand Up @@ -3328,15 +3333,6 @@ threadInitStages(J9JavaVM* vm, IDATA stage, void* reserved)
loadInfo->fatalErrorStr = "cannot parse -Xjni:";
return returnVal;
}

#if defined(J9VM_THR_ASYNC_NAME_UPDATE)
vm->threadNameHandlerKey = J9RegisterAsyncEvent(vm, setThreadNameAsyncHandler, vm);
if (vm->threadNameHandlerKey < 0) {
loadInfo->fatalErrorStr = "cannot initialize threadNameHandlerKey";
goto _error;
}
#endif /* J9VM_THR_ASYNC_NAME_UPDATE */

break;
case HEAP_STRUCTURES_INITIALIZED :
break;
Expand All @@ -3351,6 +3347,14 @@ threadInitStages(J9JavaVM* vm, IDATA stage, void* reserved)
case JIT_INITIALIZED :
break;
case ABOUT_TO_BOOTSTRAP :
#if defined(J9VM_THR_ASYNC_NAME_UPDATE)
vm->threadNameHandlerKey = J9RegisterAsyncEvent(vm, setThreadNameAsyncHandler, vm);
if (vm->threadNameHandlerKey < 0) {
loadInfo = FIND_DLL_TABLE_ENTRY( FUNCTION_THREAD_INIT );
loadInfo->fatalErrorStr = "cannot initialize threadNameHandlerKey";
goto _error;
}
#endif /* J9VM_THR_ASYNC_NAME_UPDATE */
break;
case JCL_INITIALIZED :
break;
Expand Down Expand Up @@ -5333,12 +5337,6 @@ protectedInitializeJavaVM(J9PortLibrary* portLibrary, void * userData)
OMRSIG_SIGACTION(SIGPIPE,&newSignalAction,(struct sigaction *)vm->originalSIGPIPESignalAction);
#endif

#if defined(J9VM_INTERP_ATOMIC_FREE_JNI_USES_FLUSH)
if (0 != initializeExclusiveAccess(vm)) {
goto error;
}
#endif /* J9VM_INTERP_ATOMIC_FREE_JNI_USES_FLUSH */

#ifdef J9VM_OPT_SIDECAR
vm->j2seVersion = initArgs->j2seVersion;
vm->j2seRootDirectory = initArgs->j2seRootDirectory;
Expand Down

0 comments on commit 476aa5c

Please sign in to comment.