39 static volatile int 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.");
74 lock_owner = current_thread;
75 } else {
76 // Atomicity isn't required. Bump the recursion count.
77 lock_count++;
78 }
79
|
39 static volatile int 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(&lock_count, -1, 0) != -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.");
74 lock_owner = current_thread;
75 } else {
76 // Atomicity isn't required. Bump the recursion count.
77 lock_count++;
78 }
79
|