< prev index next >

src/hotspot/os/windows/threadCritical_windows.cpp

Print this page
*** 33,14 ***
  
  //
  // See threadCritical.hpp for details of this class.
  //
  
! static bool initialized = false;
! static volatile int lock_count = -1;
  static HANDLE lock_event;
! static DWORD lock_owner = -1;
  
  //
  // Note that Microsoft's critical region code contains a race
  // condition, and is not suitable for use. A thread holding the
  // critical section cannot safely suspend a thread attempting
--- 33,14 ---
  
  //
  // See threadCritical.hpp for details of this class.
  //
  
! static INIT_ONCE initialized = INIT_ONCE_STATIC_INIT;
! static int lock_count = 0;
  static HANDLE lock_event;
! static DWORD lock_owner = 0;
  
  //
  // Note that Microsoft's critical region code contains a race
  // condition, and is not suitable for use. A thread holding the
  // critical section cannot safely suspend a thread attempting

*** 49,50 ***
  //
  // I experiemented with the use of ordinary windows mutex objects
  // and found them ~30 times slower than the critical region code.
  //
  
  ThreadCritical::ThreadCritical() {
!   DWORD current_thread = GetCurrentThreadId();
  
    if (lock_owner != current_thread) {
      // Grab the lock before doing anything.
!     while (Atomic::cmpxchg(&lock_count, -1, 0) != -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.");
      lock_owner = current_thread;
-   } else {
-     // Atomicity isn't required. Bump the recursion count.
-     lock_count++;
    }
! 
!   assert(lock_owner == GetCurrentThreadId(), "Lock acquired illegally.");
  }
  
  ThreadCritical::~ThreadCritical() {
    assert(lock_owner == GetCurrentThreadId(), "unlock attempt by wrong thread");
    assert(lock_count >= 0, "Attempt to unlock when already unlocked");
  
    if (lock_count == 0) {
      // We're going to unlock
!     lock_owner = -1;
-     lock_count = -1;
      // 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--;
    }
  }
--- 49,38 ---
  //
  // I experiemented with the use of ordinary windows mutex objects
  // 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() {
!   InitOnceExecuteOnce(&initialized, &initialize, NULL, NULL);
  
+   DWORD current_thread = GetCurrentThreadId();
    if (lock_owner != current_thread) {
      // Grab the lock before doing anything.
!     DWORD ret = WaitForSingleObject(lock_event,  INFINITE);
!     assert(ret == WAIT_OBJECT_0, "unexpected return value from WaitForSingleObject");
      lock_owner = current_thread;
    }
!   // 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 = 0;
      // No lost wakeups, lock_event stays signaled until reset.
      DWORD ret = SetEvent(lock_event);
      assert(ret != 0, "unexpected return value from SetEvent");
    }
  }
< prev index next >