-
Notifications
You must be signed in to change notification settings - Fork 747
/
Copy pathFlushProcessWriteBuffers.cpp
123 lines (114 loc) · 4.03 KB
/
FlushProcessWriteBuffers.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*******************************************************************************
* Copyright IBM Corp. and others 2018
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
* or the Apache License, Version 2.0 which accompanies this distribution and
* is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* This Source Code may also be made available under the following
* Secondary Licenses when the conditions for such availability set
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
* General Public License, version 2 with the GNU Classpath
* Exception [1] and GNU General Public License, version 2 with the
* OpenJDK Assembly Exception [2].
*
* [1] https://www.gnu.org/software/classpath/license.html
* [2] https://openjdk.org/legal/assembly-exception.html
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
*******************************************************************************/
#if defined(WIN32)
#include <windows.h>
#endif /* WIN32 */
#include "vm_internal.h"
#if defined(J9UNIX) || defined(AIXPPC)
#include <sys/mman.h>
#endif /* J9UNIX || AIXPPC */
#include "ut_j9vm.h"
#include "AtomicSupport.hpp"
extern "C" {
#if defined(J9VM_INTERP_ATOMIC_FREE_JNI_USES_FLUSH)
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)
if (NULL != vm->flushFunction) {
((VOID (WINAPI*)(void))vm->flushFunction)();
}
#elif defined(J9UNIX) || 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 /* J9UNIX || AIXPPC */
#error flushProcessWriteBuffers unimplemented
#endif /* J9UNIX || AIXPPC */
}
UDATA
initializeExclusiveAccess(J9JavaVM *vm)
{
UDATA rc = 0;
#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_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 || AIXPPC */
HMODULE h_kernel32 = GetModuleHandle("kernel32");
Assert_VM_notNull(h_kernel32);
void *flushFunction = (void*)GetProcAddress(h_kernel32, "FlushProcessWriteBuffers");
Assert_VM_notNull(flushFunction);
vm->flushFunction = flushFunction;
#endif /* WIN32 */
return rc;
}
void
shutDownExclusiveAccess(J9JavaVM *vm)
{
#if defined(LINUX) || defined(AIXPPC)
J9PortVmemIdentifier *guardPage = &vm->exclusiveGuardPage;
void *addr = guardPage->address;
if (NULL != addr) {
PORT_ACCESS_FROM_JAVAVM(vm);
j9vmem_free_memory(addr, guardPage->pageSize, guardPage);
}
if (NULL != vm->flushMutex) {
omrthread_monitor_destroy(vm->flushMutex);
vm->flushMutex = NULL;
}
#endif /* LINUX || AIXPPC */
}
#endif /* J9VM_INTERP_ATOMIC_FREE_JNI_USES_FLUSH */
} /* extern "C" */