34 //
35 // See threadCritical.hpp for details of this class.
36 //
37
38 static bool initialized = false;
39 static volatile jint lock_count = -1;
40 static HANDLE lock_event;
41 static DWORD lock_owner = -1;
42
43 //
44 // Note that Microsoft's critical region code contains a race
45 // condition, and is not suitable for use. A thread holding the
46 // critical section cannot safely suspend a thread attempting
47 // to enter the critical region. The failure mode is that both
48 // threads are permanently suspended.
49 //
50 // I experiemented with the use of ordinary windows mutex objects
51 // and found them ~30 times slower than the critical region code.
52 //
53
54 void ThreadCritical::initialize() {
55 }
56
57 void ThreadCritical::release() {
58 assert(lock_owner == -1, "Mutex being deleted while owned.");
59 assert(lock_count == -1, "Mutex being deleted while recursively locked");
60 assert(lock_event != NULL, "Sanity check");
61 CloseHandle(lock_event);
62 }
63
64 ThreadCritical::ThreadCritical() {
65 DWORD current_thread = GetCurrentThreadId();
66
67 if (lock_owner != current_thread) {
68 // Grab the lock before doing anything.
69 while (Atomic::cmpxchg(0, &lock_count, -1) != -1) {
70 if (initialized) {
71 DWORD ret = WaitForSingleObject(lock_event, INFINITE);
72 assert(ret == WAIT_OBJECT_0, "unexpected return value from WaitForSingleObject");
73 }
74 }
75
76 // Make sure the event object is allocated.
77 if (!initialized) {
78 // Locking will not work correctly unless this is autoreset.
79 lock_event = CreateEvent(NULL, false, false, NULL);
80 initialized = true;
81 }
82
83 assert(lock_owner == -1, "Lock acquired illegally.");
|
34 //
35 // See threadCritical.hpp for details of this class.
36 //
37
38 static bool initialized = false;
39 static volatile jint lock_count = -1;
40 static HANDLE lock_event;
41 static DWORD lock_owner = -1;
42
43 //
44 // Note that Microsoft's critical region code contains a race
45 // condition, and is not suitable for use. A thread holding the
46 // critical section cannot safely suspend a thread attempting
47 // to enter the critical region. The failure mode is that both
48 // threads are permanently suspended.
49 //
50 // I experiemented with the use of ordinary windows mutex objects
51 // and found them ~30 times slower than the critical region code.
52 //
53
54 ThreadCritical::ThreadCritical() {
55 DWORD current_thread = GetCurrentThreadId();
56
57 if (lock_owner != current_thread) {
58 // Grab the lock before doing anything.
59 while (Atomic::cmpxchg(0, &lock_count, -1) != -1) {
60 if (initialized) {
61 DWORD ret = WaitForSingleObject(lock_event, INFINITE);
62 assert(ret == WAIT_OBJECT_0, "unexpected return value from WaitForSingleObject");
63 }
64 }
65
66 // Make sure the event object is allocated.
67 if (!initialized) {
68 // Locking will not work correctly unless this is autoreset.
69 lock_event = CreateEvent(NULL, false, false, NULL);
70 initialized = true;
71 }
72
73 assert(lock_owner == -1, "Lock acquired illegally.");
|