Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 17 additions & 29 deletions src/hotspot/os/windows/threadCritical_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
// See threadCritical.hpp for details of this class.
//

static bool initialized = false;
static volatile int lock_count = -1;
static INIT_ONCE initialized = INIT_ONCE_STATIC_INIT;
static int lock_count = 0;
static HANDLE lock_event;
static DWORD lock_owner = -1;
static DWORD lock_owner = 0;

//
// Note that Microsoft's critical region code contains a race
Expand All @@ -51,48 +51,36 @@ static DWORD lock_owner = -1;
// and found them ~30 times slower than the critical region code.
//

static BOOL WINAPI initialize(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) {
lock_event = CreateEvent(NULL, false, true, NULL);
assert(lock_event != NULL, "unexpected return value from CreateEvent");
return true;
}

ThreadCritical::ThreadCritical() {
DWORD current_thread = GetCurrentThreadId();
InitOnceExecuteOnce(&initialized, &initialize, NULL, NULL);

DWORD current_thread = GetCurrentThreadId();
if (lock_owner != current_thread) {
// Grab the lock before doing anything.
while (Atomic::cmpxchg(0, &lock_count, -1) != -1) {
if (initialized) {
DWORD ret = WaitForSingleObject(lock_event, INFINITE);
assert(ret == WAIT_OBJECT_0, "unexpected return value from WaitForSingleObject");
}
}

// Make sure the event object is allocated.
if (!initialized) {
// Locking will not work correctly unless this is autoreset.
lock_event = CreateEvent(NULL, false, false, NULL);
initialized = true;
}

assert(lock_owner == -1, "Lock acquired illegally.");
DWORD ret = WaitForSingleObject(lock_event, INFINITE);
assert(ret == WAIT_OBJECT_0, "unexpected return value from WaitForSingleObject");
lock_owner = current_thread;
} else {
// Atomicity isn't required. Bump the recursion count.
lock_count++;
}

assert(lock_owner == GetCurrentThreadId(), "Lock acquired illegally.");
// Atomicity isn't required. Bump the recursion count.
lock_count++;
}

ThreadCritical::~ThreadCritical() {
assert(lock_owner == GetCurrentThreadId(), "unlock attempt by wrong thread");
assert(lock_count >= 0, "Attempt to unlock when already unlocked");

lock_count--;
if (lock_count == 0) {
// We're going to unlock
lock_owner = -1;
lock_count = -1;
lock_owner = 0;
// No lost wakeups, lock_event stays signaled until reset.
DWORD ret = SetEvent(lock_event);
assert(ret != 0, "unexpected return value from SetEvent");
} else {
// Just unwinding a recursive lock;
lock_count--;
}
}