Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_glue_java/JNICriticalRegion.cpp
5985 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2021 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
#include "j9.h"
24
25
#include "JNICriticalRegion.hpp"
26
27
/**
28
* Re-acquire VM and/or JNI critical access as specified by the accessMask.
29
* This will block if another thread holds exclusive VM access.
30
*
31
* This function is intended for use with releaseAccess.
32
*
33
* @param vmThread the J9VMThread requesting access
34
* @param accessMask the types of access that were held
35
*/
36
void
37
MM_JNICriticalRegion::reacquireAccess(J9VMThread* vmThread, UDATA accessMask)
38
{
39
#if defined(J9VM_INTERP_ATOMIC_FREE_JNI)
40
// Current thread must have entered the VM before acquiring exclusive
41
Assert_MM_false(vmThread->inNative);
42
#endif /* J9VM_INTERP_ATOMIC_FREE_JNI */
43
if (J9_ARE_ANY_BITS_SET(vmThread->publicFlags, J9_PUBLIC_FLAGS_DEBUG_VM_ACCESS)) {
44
Assert_MM_true(J9_VM_FUNCTION(vmThread, currentVMThread)(vmThread->javaVM) == vmThread);
45
}
46
47
Assert_MM_true(0 != (accessMask & (J9_PUBLIC_FLAGS_VM_ACCESS | J9_PUBLIC_FLAGS_JNI_CRITICAL_ACCESS)));
48
Assert_MM_true(0 == (accessMask & ~(J9_PUBLIC_FLAGS_VM_ACCESS | J9_PUBLIC_FLAGS_JNI_CRITICAL_ACCESS)));
49
omrthread_monitor_enter(vmThread->publicFlagsMutex);
50
Assert_MM_true(0 == (vmThread->publicFlags & (J9_PUBLIC_FLAGS_VM_ACCESS | J9_PUBLIC_FLAGS_JNI_CRITICAL_ACCESS)));
51
while (vmThread->publicFlags & J9_PUBLIC_FLAGS_HALT_THREAD_EXCLUSIVE) {
52
omrthread_monitor_wait(vmThread->publicFlagsMutex);
53
}
54
55
if (0 != (accessMask & J9_PUBLIC_FLAGS_VM_ACCESS)) {
56
TRIGGER_J9HOOK_VM_ACQUIREVMACCESS(vmThread->javaVM->hookInterface, vmThread);
57
58
/* Now that the hook has been invoked, allow inline VM access */
59
if (0 != (vmThread->publicFlags & J9_PUBLIC_FLAGS_DISABLE_INLINE_VM_ACCESS)) {
60
clearEventFlag(vmThread, J9_PUBLIC_FLAGS_DISABLE_INLINE_VM_ACCESS);
61
}
62
}
63
64
VM_VMAccess::setPublicFlags(vmThread, accessMask);
65
omrthread_monitor_exit(vmThread->publicFlagsMutex);
66
}
67
68
/**
69
* Release VM and/or JNI critical access. Record what was held in accessMask.
70
* This will respond to any pending exclusive VM access request in progress.
71
*
72
* This function is intended for use with reacquireAccess.
73
*
74
* @param vmThread the J9VMThread requesting access
75
* @param accessMask the types of access to re-acquire
76
*/
77
void
78
MM_JNICriticalRegion::releaseAccess(J9VMThread* vmThread, UDATA* accessMask)
79
{
80
#if defined(J9VM_INTERP_ATOMIC_FREE_JNI)
81
// Current thread must have entered the VM before acquiring exclusive
82
Assert_MM_false(vmThread->inNative);
83
#endif /* J9VM_INTERP_ATOMIC_FREE_JNI */
84
if (J9_ARE_ANY_BITS_SET(vmThread->publicFlags, J9_PUBLIC_FLAGS_DEBUG_VM_ACCESS)) {
85
Assert_MM_true(J9_VM_FUNCTION(vmThread, currentVMThread)(vmThread->javaVM) == vmThread);
86
}
87
88
omrthread_monitor_enter(vmThread->publicFlagsMutex);
89
Assert_MM_true(0 != (vmThread->publicFlags & (J9_PUBLIC_FLAGS_VM_ACCESS | J9_PUBLIC_FLAGS_JNI_CRITICAL_ACCESS)));
90
UDATA currentAccess = vmThread->publicFlags & (J9_PUBLIC_FLAGS_VM_ACCESS | J9_PUBLIC_FLAGS_JNI_CRITICAL_ACCESS);
91
Assert_MM_true(0 != currentAccess);
92
VM_VMAccess::clearPublicFlags(vmThread, currentAccess);
93
94
if (0 != (currentAccess & J9_PUBLIC_FLAGS_VM_ACCESS)) {
95
TRIGGER_J9HOOK_VM_RELEASEVMACCESS(vmThread->javaVM->hookInterface, vmThread);
96
97
/* Now that the hook has been invoked, allow inline VM access */
98
if (0 != (vmThread->publicFlags & J9_PUBLIC_FLAGS_DISABLE_INLINE_VM_ACCESS)) {
99
clearEventFlag(vmThread, J9_PUBLIC_FLAGS_DISABLE_INLINE_VM_ACCESS);
100
}
101
}
102
103
if(0 != (vmThread->publicFlags & J9_PUBLIC_FLAGS_HALT_THREAD_EXCLUSIVE)) {
104
J9JavaVM* vm = vmThread->javaVM;
105
PORT_ACCESS_FROM_JAVAVM(vm);
106
UDATA shouldRespond = FALSE;
107
108
omrthread_monitor_enter(vm->exclusiveAccessMutex);
109
110
U_64 timeNow = VM_VMAccess::updateExclusiveVMAccessStats(vmThread, vm, PORTLIB);
111
112
if(0 != (currentAccess & J9_PUBLIC_FLAGS_VM_ACCESS)) {
113
if (!J9_ARE_ANY_BITS_SET(vmThread->publicFlags, J9_PUBLIC_FLAGS_NOT_COUNTED_BY_EXCLUSIVE)) {
114
--vm->exclusiveAccessResponseCount;
115
if(0 == vm->exclusiveAccessResponseCount) {
116
shouldRespond = TRUE;
117
}
118
}
119
}
120
if(0 != (currentAccess & J9_PUBLIC_FLAGS_JNI_CRITICAL_ACCESS)) {
121
--vm->jniCriticalResponseCount;
122
if(0 == vm->jniCriticalResponseCount) {
123
shouldRespond = TRUE;
124
}
125
}
126
if(shouldRespond) {
127
VM_VMAccess::respondToExclusiveRequest(vmThread, vm, PORTLIB, timeNow, J9_EXCLUSIVE_SLOW_REASON_JNICRITICAL);
128
}
129
omrthread_monitor_exit(vm->exclusiveAccessMutex);
130
}
131
132
*accessMask = currentAccess;
133
omrthread_monitor_exit(vmThread->publicFlagsMutex);
134
}
135
136