Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/os/windows/vm/threadCritical_windows.cpp
32284 views
1
/*
2
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#include "precompiled.hpp"
26
#include "runtime/thread.inline.hpp"
27
#include "runtime/threadCritical.hpp"
28
29
// OS-includes here
30
# include <windows.h>
31
# include <winbase.h>
32
33
//
34
// See threadCritical.hpp for details of this class.
35
//
36
37
static bool initialized = false;
38
static volatile jint lock_count = -1;
39
static HANDLE lock_event;
40
static DWORD lock_owner = -1;
41
42
//
43
// Note that Microsoft's critical region code contains a race
44
// condition, and is not suitable for use. A thread holding the
45
// critical section cannot safely suspend a thread attempting
46
// to enter the critical region. The failure mode is that both
47
// threads are permanently suspended.
48
//
49
// I experiemented with the use of ordinary windows mutex objects
50
// and found them ~30 times slower than the critical region code.
51
//
52
53
void ThreadCritical::initialize() {
54
}
55
56
void ThreadCritical::release() {
57
assert(lock_owner == -1, "Mutex being deleted while owned.");
58
assert(lock_count == -1, "Mutex being deleted while recursively locked");
59
assert(lock_event != NULL, "Sanity check");
60
CloseHandle(lock_event);
61
}
62
63
ThreadCritical::ThreadCritical() {
64
DWORD current_thread = GetCurrentThreadId();
65
66
if (lock_owner != current_thread) {
67
// Grab the lock before doing anything.
68
while (Atomic::cmpxchg(0, &lock_count, -1) != -1) {
69
if (initialized) {
70
DWORD ret = WaitForSingleObject(lock_event, INFINITE);
71
assert(ret == WAIT_OBJECT_0, "unexpected return value from WaitForSingleObject");
72
}
73
}
74
75
// Make sure the event object is allocated.
76
if (!initialized) {
77
// Locking will not work correctly unless this is autoreset.
78
lock_event = CreateEvent(NULL, false, false, NULL);
79
initialized = true;
80
}
81
82
assert(lock_owner == -1, "Lock acquired illegally.");
83
lock_owner = current_thread;
84
} else {
85
// Atomicity isn't required. Bump the recursion count.
86
lock_count++;
87
}
88
89
assert(lock_owner == GetCurrentThreadId(), "Lock acquired illegally.");
90
}
91
92
ThreadCritical::~ThreadCritical() {
93
assert(lock_owner == GetCurrentThreadId(), "unlock attempt by wrong thread");
94
assert(lock_count >= 0, "Attempt to unlock when already unlocked");
95
96
if (lock_count == 0) {
97
// We're going to unlock
98
lock_owner = -1;
99
lock_count = -1;
100
// No lost wakeups, lock_event stays signaled until reset.
101
DWORD ret = SetEvent(lock_event);
102
assert(ret != 0, "unexpected return value from SetEvent");
103
} else {
104
// Just unwinding a recursive lock;
105
lock_count--;
106
}
107
}
108
109