summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrpj <rpj>2011-03-10 13:40:16 +0000
committerrpj <rpj>2011-03-10 13:40:16 +0000
commit6e3ac5c605d5062279178b3ea0b853d0e9cf7cc9 (patch)
treed9262f28ef4083dfeefbd31bc9b163cf67e102e1
parenteb28d5aa00690b67cc27e4bd93d2c4c251987c85 (diff)
Replace global Critical Sections with MCS Queue locks
-rw-r--r--ChangeLog23
-rw-r--r--global.c12
-rw-r--r--implement.h15
-rw-r--r--pthread_cond_destroy.c12
-rw-r--r--pthread_cond_init.c6
-rw-r--r--pthread_detach.c5
-rw-r--r--pthread_join.c5
-rw-r--r--pthread_kill.c5
-rw-r--r--pthread_mutex_destroy.c12
-rw-r--r--pthread_rwlock_destroy.c5
-rw-r--r--pthread_spin_destroy.c6
-rw-r--r--pthread_timechange_handler_np.c5
-rw-r--r--ptw32_cond_check_need_init.c22
-rw-r--r--ptw32_mutex_check_need_init.c26
-rw-r--r--ptw32_processInitialize.c10
-rw-r--r--ptw32_processTerminate.c15
-rw-r--r--ptw32_reuse.c10
-rw-r--r--ptw32_rwlock_check_need_init.c22
-rw-r--r--ptw32_spinlock_check_need_init.c9
-rwxr-xr-xtests/SIZES.GC2
-rwxr-xr-xtests/SIZES.VC2
21 files changed, 95 insertions, 134 deletions
diff --git a/ChangeLog b/ChangeLog
index ae308b7..363297e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2011-03-09 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * implement.h (ptw32_thread_t_): Add process unique sequence number.
+ * global.c: Replace global Critical Section objects with MCS
+ queue locks.
+ * implement.h: Likewise.
+ * pthread_cond_destroy.c: Likewise.
+ * pthread_cond_init.c: Likewise.
+ * pthread_detach.c: Likewise.
+ * pthread_join.c: Likewise.
+ * pthread_kill.c: Likewise.
+ * pthread_mutex_destroy.c: Likewise.
+ * pthread_rwlock_destroy.c: Likewise.
+ * pthread_spin_destroy.c: Likewise.
+ * pthread_timechange_handler_np.c: Likewise.
+ * ptw32_cond_check_need_init.c: Likewise.
+ * ptw32_mutex_check_need_init.c: Likewise.
+ * ptw32_processInitialize.c: Likewise.
+ * ptw32_processTerminate.c: Likewise.
+ * ptw32_reuse.c: Likewise.
+ * ptw32_rwlock_check_need_init.c: Likewise.
+ * ptw32_spinlock_check_need_init.c: Likewise.
+
2011-03-06 Ross Johnson <ross.johnson at homemail.com.au>
* several (MINGW64): Cast and call fixups for 64 bit compatibility;
diff --git a/global.c b/global.c
index 420b8e4..df4806b 100644
--- a/global.c
+++ b/global.c
@@ -62,37 +62,37 @@ DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD) = NULL;
/*
* Global lock for managing pthread_t struct reuse.
*/
-CRITICAL_SECTION ptw32_thread_reuse_lock;
+ptw32_mcs_lock_t ptw32_thread_reuse_lock;
/*
* Global lock for testing internal state of statically declared mutexes.
*/
-CRITICAL_SECTION ptw32_mutex_test_init_lock;
+ptw32_mcs_lock_t ptw32_mutex_test_init_lock;
/*
* Global lock for testing internal state of PTHREAD_COND_INITIALIZER
* created condition variables.
*/
-CRITICAL_SECTION ptw32_cond_test_init_lock;
+ptw32_mcs_lock_t ptw32_cond_test_init_lock;
/*
* Global lock for testing internal state of PTHREAD_RWLOCK_INITIALIZER
* created read/write locks.
*/
-CRITICAL_SECTION ptw32_rwlock_test_init_lock;
+ptw32_mcs_lock_t ptw32_rwlock_test_init_lock;
/*
* Global lock for testing internal state of PTHREAD_SPINLOCK_INITIALIZER
* created spin locks.
*/
-CRITICAL_SECTION ptw32_spinlock_test_init_lock;
+ptw32_mcs_lock_t ptw32_spinlock_test_init_lock;
/*
* Global lock for condition variable linked list. The list exists
* to wake up CVs when a WM_TIMECHANGE message arrives. See
* w32_TimeChangeHandler.c.
*/
-CRITICAL_SECTION ptw32_cond_list_lock;
+ptw32_mcs_lock_t ptw32_cond_list_lock;
#ifdef _UWIN
/*
diff --git a/implement.h b/implement.h
index aaad665..1cd24f2 100644
--- a/implement.h
+++ b/implement.h
@@ -131,7 +131,8 @@ struct ptw32_thread_t_
#ifdef _UWIN
DWORD dummy[5];
#endif
- DWORD thread;
+ UINT64 seqNumber; /* Process-unique thread sequence number */
+ DWORD thread; /* Win32 thread ID */
HANDLE threadH; /* Win32 thread handle - POSIX thread is invalid if threadH == 0 */
pthread_t ptHandle; /* This thread's permanent pthread_t handle */
ptw32_thread_t * prevReuse; /* Links threads on reuse stack */
@@ -535,12 +536,12 @@ extern int ptw32_concurrency;
extern int ptw32_features;
-extern CRITICAL_SECTION ptw32_thread_reuse_lock;
-extern CRITICAL_SECTION ptw32_mutex_test_init_lock;
-extern CRITICAL_SECTION ptw32_cond_list_lock;
-extern CRITICAL_SECTION ptw32_cond_test_init_lock;
-extern CRITICAL_SECTION ptw32_rwlock_test_init_lock;
-extern CRITICAL_SECTION ptw32_spinlock_test_init_lock;
+extern ptw32_mcs_lock_t ptw32_thread_reuse_lock;
+extern ptw32_mcs_lock_t ptw32_mutex_test_init_lock;
+extern ptw32_mcs_lock_t ptw32_cond_list_lock;
+extern ptw32_mcs_lock_t ptw32_cond_test_init_lock;
+extern ptw32_mcs_lock_t ptw32_rwlock_test_init_lock;
+extern ptw32_mcs_lock_t ptw32_spinlock_test_init_lock;
#ifdef _UWIN
extern int pthread_count;
diff --git a/pthread_cond_destroy.c b/pthread_cond_destroy.c
index 53f7a53..40d4a08 100644
--- a/pthread_cond_destroy.c
+++ b/pthread_cond_destroy.c
@@ -126,7 +126,8 @@ pthread_cond_destroy (pthread_cond_t * cond)
if (*cond != PTHREAD_COND_INITIALIZER)
{
- EnterCriticalSection (&ptw32_cond_list_lock);
+ ptw32_mcs_local_node_t node;
+ ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node);
cv = *cond;
@@ -154,7 +155,7 @@ pthread_cond_destroy (pthread_cond_t * cond)
if (result != 0)
{
- LeaveCriticalSection (&ptw32_cond_list_lock);
+ ptw32_mcs_lock_release(&node);
return result;
}
@@ -213,14 +214,15 @@ pthread_cond_destroy (pthread_cond_t * cond)
(void) free (cv);
}
- LeaveCriticalSection (&ptw32_cond_list_lock);
+ ptw32_mcs_lock_release(&node);
}
else
{
+ ptw32_mcs_local_node_t node;
/*
* See notes in ptw32_cond_check_need_init() above also.
*/
- EnterCriticalSection (&ptw32_cond_test_init_lock);
+ ptw32_mcs_lock_acquire(&ptw32_cond_test_init_lock, &node);
/*
* Check again.
@@ -244,7 +246,7 @@ pthread_cond_destroy (pthread_cond_t * cond)
result = EBUSY;
}
- LeaveCriticalSection (&ptw32_cond_test_init_lock);
+ ptw32_mcs_lock_release(&node);
}
return ((result != 0) ? result : ((result1 != 0) ? result1 : result2));
diff --git a/pthread_cond_init.c b/pthread_cond_init.c
index d2de232..f28fd67 100644
--- a/pthread_cond_init.c
+++ b/pthread_cond_init.c
@@ -138,7 +138,9 @@ FAIL0:
DONE:
if (0 == result)
{
- EnterCriticalSection (&ptw32_cond_list_lock);
+ ptw32_mcs_local_node_t node;
+
+ ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node);
cv->next = NULL;
cv->prev = ptw32_cond_list_tail;
@@ -155,7 +157,7 @@ DONE:
ptw32_cond_list_head = cv;
}
- LeaveCriticalSection (&ptw32_cond_list_lock);
+ ptw32_mcs_lock_release(&node);
}
*cond = cv;
diff --git a/pthread_detach.c b/pthread_detach.c
index b110f2b..19bc24d 100644
--- a/pthread_detach.c
+++ b/pthread_detach.c
@@ -77,8 +77,9 @@ pthread_detach (pthread_t thread)
int result;
BOOL destroyIt = PTW32_FALSE;
ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
+ ptw32_mcs_local_node_t node;
- EnterCriticalSection (&ptw32_thread_reuse_lock);
+ ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
if (NULL == tp
|| thread.x != tp->ptHandle.x)
@@ -120,7 +121,7 @@ pthread_detach (pthread_t thread)
}
}
- LeaveCriticalSection (&ptw32_thread_reuse_lock);
+ ptw32_mcs_lock_release(&node);
if (result == 0)
{
diff --git a/pthread_join.c b/pthread_join.c
index 72a3a74..c49484d 100644
--- a/pthread_join.c
+++ b/pthread_join.c
@@ -85,8 +85,9 @@ pthread_join (pthread_t thread, void **value_ptr)
int result;
pthread_t self;
ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
+ ptw32_mcs_local_node_t node;
- EnterCriticalSection (&ptw32_thread_reuse_lock);
+ ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
if (NULL == tp
|| thread.x != tp->ptHandle.x)
@@ -102,7 +103,7 @@ pthread_join (pthread_t thread, void **value_ptr)
result = 0;
}
- LeaveCriticalSection (&ptw32_thread_reuse_lock);
+ ptw32_mcs_lock_release(&node);
if (result == 0)
{
diff --git a/pthread_kill.c b/pthread_kill.c
index d360187..21939d8 100644
--- a/pthread_kill.c
+++ b/pthread_kill.c
@@ -77,8 +77,9 @@ pthread_kill (pthread_t thread, int sig)
{
int result = 0;
ptw32_thread_t * tp;
+ ptw32_mcs_local_node_t node;
- EnterCriticalSection (&ptw32_thread_reuse_lock);
+ ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
tp = (ptw32_thread_t *) thread.p;
@@ -89,7 +90,7 @@ pthread_kill (pthread_t thread, int sig)
result = ESRCH;
}
- LeaveCriticalSection (&ptw32_thread_reuse_lock);
+ ptw32_mcs_lock_release(&node);
if (0 == result && 0 != sig)
{
diff --git a/pthread_mutex_destroy.c b/pthread_mutex_destroy.c
index 95509b3..c9460dc 100644
--- a/pthread_mutex_destroy.c
+++ b/pthread_mutex_destroy.c
@@ -71,10 +71,6 @@ pthread_mutex_destroy (pthread_mutex_t * mutex)
* be too late invalidating the mutex below since another thread
* may already have entered mutex_lock and the check for a valid
* *mutex != NULL.
- *
- * Note that this would be an unusual situation because it is not
- * common that mutexes are destroyed while they are still in
- * use by other threads.
*/
*mutex = NULL;
@@ -112,10 +108,13 @@ pthread_mutex_destroy (pthread_mutex_t * mutex)
}
else
{
+ ptw32_mcs_local_node_t node;
+
/*
* See notes in ptw32_mutex_check_need_init() above also.
*/
- EnterCriticalSection (&ptw32_mutex_test_init_lock);
+
+ ptw32_mcs_lock_acquire(&ptw32_mutex_test_init_lock, &node);
/*
* Check again.
@@ -138,8 +137,7 @@ pthread_mutex_destroy (pthread_mutex_t * mutex)
*/
result = EBUSY;
}
-
- LeaveCriticalSection (&ptw32_mutex_test_init_lock);
+ ptw32_mcs_lock_release(&node);
}
return (result);
diff --git a/pthread_rwlock_destroy.c b/pthread_rwlock_destroy.c
index d14b447..245a892 100644
--- a/pthread_rwlock_destroy.c
+++ b/pthread_rwlock_destroy.c
@@ -108,10 +108,11 @@ pthread_rwlock_destroy (pthread_rwlock_t * rwlock)
}
else
{
+ ptw32_mcs_local_node_t node;
/*
* See notes in ptw32_rwlock_check_need_init() above also.
*/
- EnterCriticalSection (&ptw32_rwlock_test_init_lock);
+ ptw32_mcs_lock_acquire(&ptw32_rwlock_test_init_lock, &node);
/*
* Check again.
@@ -135,7 +136,7 @@ pthread_rwlock_destroy (pthread_rwlock_t * rwlock)
result = EBUSY;
}
- LeaveCriticalSection (&ptw32_rwlock_test_init_lock);
+ ptw32_mcs_lock_release(&node);
}
return ((result != 0) ? result : ((result1 != 0) ? result1 : result2));
diff --git a/pthread_spin_destroy.c b/pthread_spin_destroy.c
index c9317d2..2ff1425 100644
--- a/pthread_spin_destroy.c
+++ b/pthread_spin_destroy.c
@@ -81,7 +81,9 @@ pthread_spin_destroy (pthread_spinlock_t * lock)
/*
* See notes in ptw32_spinlock_check_need_init() above also.
*/
- EnterCriticalSection (&ptw32_spinlock_test_init_lock);
+ ptw32_mcs_local_node_t node;
+
+ ptw32_mcs_lock_acquire(&ptw32_spinlock_test_init_lock, &node);
/*
* Check again.
@@ -105,7 +107,7 @@ pthread_spin_destroy (pthread_spinlock_t * lock)
result = EBUSY;
}
- LeaveCriticalSection (&ptw32_spinlock_test_init_lock);
+ ptw32_mcs_lock_release(&node);
}
return (result);
diff --git a/pthread_timechange_handler_np.c b/pthread_timechange_handler_np.c
index 12bd135..0f97e74 100644
--- a/pthread_timechange_handler_np.c
+++ b/pthread_timechange_handler_np.c
@@ -90,8 +90,9 @@ pthread_timechange_handler_np (void *arg)
{
int result = 0;
pthread_cond_t cv;
+ ptw32_mcs_local_node_t node;
- EnterCriticalSection (&ptw32_cond_list_lock);
+ ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node);
cv = ptw32_cond_list_head;
@@ -101,7 +102,7 @@ pthread_timechange_handler_np (void *arg)
cv = cv->next;
}
- LeaveCriticalSection (&ptw32_cond_list_lock);
+ ptw32_mcs_lock_release(&node);
return (void *) (size_t) (result != 0 ? EAGAIN : 0);
}
diff --git a/ptw32_cond_check_need_init.c b/ptw32_cond_check_need_init.c
index 31359ad..ec3e8bb 100644
--- a/ptw32_cond_check_need_init.c
+++ b/ptw32_cond_check_need_init.c
@@ -43,29 +43,13 @@ INLINE int
ptw32_cond_check_need_init (pthread_cond_t * cond)
{
int result = 0;
+ ptw32_mcs_local_node_t node;
/*
* The following guarded test is specifically for statically
* initialised condition variables (via PTHREAD_OBJECT_INITIALIZER).
- *
- * Note that by not providing this synchronisation we risk
- * introducing race conditions into applications which are
- * correctly written.
- *
- * Approach
- * --------
- * We know that static condition variables will not be PROCESS_SHARED
- * so we can serialise access to internal state using
- * Win32 Critical Sections rather than Win32 Mutexes.
- *
- * If using a single global lock slows applications down too much,
- * multiple global locks could be created and hashed on some random
- * value associated with each mutex, the pointer perhaps. At a guess,
- * a good value for the optimal number of global locks might be
- * the number of processors + 1.
- *
*/
- EnterCriticalSection (&ptw32_cond_test_init_lock);
+ ptw32_mcs_lock_acquire(&ptw32_cond_test_init_lock, &node);
/*
* We got here possibly under race
@@ -88,7 +72,7 @@ ptw32_cond_check_need_init (pthread_cond_t * cond)
result = EINVAL;
}
- LeaveCriticalSection (&ptw32_cond_test_init_lock);
+ ptw32_mcs_lock_release(&node);
return result;
}
diff --git a/ptw32_mutex_check_need_init.c b/ptw32_mutex_check_need_init.c
index 35ec366..897db3c 100644
--- a/ptw32_mutex_check_need_init.c
+++ b/ptw32_mutex_check_need_init.c
@@ -50,29 +50,9 @@ ptw32_mutex_check_need_init (pthread_mutex_t * mutex)
{
register int result = 0;
register pthread_mutex_t mtx;
+ ptw32_mcs_local_node_t node;
- /*
- * The following guarded test is specifically for statically
- * initialised mutexes (via PTHREAD_MUTEX_INITIALIZER).
- *
- * Note that by not providing this synchronisation we risk
- * introducing race conditions into applications which are
- * correctly written.
- *
- * Approach
- * --------
- * We know that static mutexes will not be PROCESS_SHARED
- * so we can serialise access to internal state using
- * Win32 Critical Sections rather than Win32 Mutexes.
- *
- * If using a single global lock slows applications down too much,
- * multiple global locks could be created and hashed on some random
- * value associated with each mutex, the pointer perhaps. At a guess,
- * a good value for the optimal number of global locks might be
- * the number of processors + 1.
- *
- */
- EnterCriticalSection (&ptw32_mutex_test_init_lock);
+ ptw32_mcs_lock_acquire(&ptw32_mutex_test_init_lock, &node);
/*
* We got here possibly under race
@@ -106,7 +86,7 @@ ptw32_mutex_check_need_init (pthread_mutex_t * mutex)
result = EINVAL;
}
- LeaveCriticalSection (&ptw32_mutex_test_init_lock);
+ ptw32_mcs_lock_release(&node);
return (result);
}
diff --git a/ptw32_processInitialize.c b/ptw32_processInitialize.c
index d13b022..8da3e41 100644
--- a/ptw32_processInitialize.c
+++ b/ptw32_processInitialize.c
@@ -87,16 +87,6 @@ ptw32_processInitialize (void)
ptw32_processTerminate ();
}
- /*
- * Set up the global locks.
- */
- InitializeCriticalSection (&ptw32_thread_reuse_lock);
- InitializeCriticalSection (&ptw32_mutex_test_init_lock);
- InitializeCriticalSection (&ptw32_cond_list_lock);
- InitializeCriticalSection (&ptw32_cond_test_init_lock);
- InitializeCriticalSection (&ptw32_rwlock_test_init_lock);
- InitializeCriticalSection (&ptw32_spinlock_test_init_lock);
-
return (ptw32_processInitialized);
} /* processInitialize */
diff --git a/ptw32_processTerminate.c b/ptw32_processTerminate.c
index d2dfa7a..83f0f23 100644
--- a/ptw32_processTerminate.c
+++ b/ptw32_processTerminate.c
@@ -65,6 +65,7 @@ ptw32_processTerminate (void)
if (ptw32_processInitialized)
{
ptw32_thread_t * tp, * tpNext;
+ ptw32_mcs_local_node_t node;
if (ptw32_selfThreadKey != NULL)
{
@@ -86,7 +87,7 @@ ptw32_processTerminate (void)
ptw32_cleanupKey = NULL;
}
- EnterCriticalSection (&ptw32_thread_reuse_lock);
+ ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
tp = ptw32_threadReuseTop;
while (tp != PTW32_THREAD_REUSE_EMPTY)
@@ -96,17 +97,7 @@ ptw32_processTerminate (void)
tp = tpNext;
}
- LeaveCriticalSection (&ptw32_thread_reuse_lock);
-
- /*
- * Destroy the global locks and other objects.
- */
- DeleteCriticalSection (&ptw32_spinlock_test_init_lock);
- DeleteCriticalSection (&ptw32_rwlock_test_init_lock);
- DeleteCriticalSection (&ptw32_cond_test_init_lock);
- DeleteCriticalSection (&ptw32_cond_list_lock);
- DeleteCriticalSection (&ptw32_mutex_test_init_lock);
- DeleteCriticalSection (&ptw32_thread_reuse_lock);
+ ptw32_mcs_lock_release(&node);
ptw32_processInitialized = PTW32_FALSE;
}
diff --git a/ptw32_reuse.c b/ptw32_reuse.c
index 0e86984..79e4dee 100644
--- a/ptw32_reuse.c
+++ b/ptw32_reuse.c
@@ -76,8 +76,9 @@ pthread_t
ptw32_threadReusePop (void)
{
pthread_t t = {NULL, 0};
+ ptw32_mcs_local_node_t node;
- EnterCriticalSection (&ptw32_thread_reuse_lock);
+ ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
if (PTW32_THREAD_REUSE_EMPTY != ptw32_threadReuseTop)
{
@@ -97,7 +98,7 @@ ptw32_threadReusePop (void)
t = tp->ptHandle;
}
- LeaveCriticalSection (&ptw32_thread_reuse_lock);
+ ptw32_mcs_lock_release(&node);
return t;
@@ -114,8 +115,9 @@ ptw32_threadReusePush (pthread_t thread)
{
ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
pthread_t t;
+ ptw32_mcs_local_node_t node;
- EnterCriticalSection (&ptw32_thread_reuse_lock);
+ ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
t = tp->ptHandle;
memset(tp, 0, sizeof(ptw32_thread_t));
@@ -143,5 +145,5 @@ ptw32_threadReusePush (pthread_t thread)
ptw32_threadReuseBottom = tp;
- LeaveCriticalSection (&ptw32_thread_reuse_lock);
+ ptw32_mcs_lock_release(&node);
}
diff --git a/ptw32_rwlock_check_need_init.c b/ptw32_rwlock_check_need_init.c
index ea2561e..858ee27 100644
--- a/ptw32_rwlock_check_need_init.c
+++ b/ptw32_rwlock_check_need_init.c
@@ -41,29 +41,13 @@ INLINE int
ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock)
{
int result = 0;
+ ptw32_mcs_local_node_t node;
/*
* The following guarded test is specifically for statically
* initialised rwlocks (via PTHREAD_RWLOCK_INITIALIZER).
- *
- * Note that by not providing this synchronisation we risk
- * introducing race conditions into applications which are
- * correctly written.
- *
- * Approach
- * --------
- * We know that static rwlocks will not be PROCESS_SHARED
- * so we can serialise access to internal state using
- * Win32 Critical Sections rather than Win32 Mutexes.
- *
- * If using a single global lock slows applications down too much,
- * multiple global locks could be created and hashed on some random
- * value associated with each mutex, the pointer perhaps. At a guess,
- * a good value for the optimal number of global locks might be
- * the number of processors + 1.
- *
*/
- EnterCriticalSection (&ptw32_rwlock_test_init_lock);
+ ptw32_mcs_lock_acquire(&ptw32_rwlock_test_init_lock, &node);
/*
* We got here possibly under race
@@ -87,7 +71,7 @@ ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock)
result = EINVAL;
}
- LeaveCriticalSection (&ptw32_rwlock_test_init_lock);
+ ptw32_mcs_lock_release(&node);
return result;
}
diff --git a/ptw32_spinlock_check_need_init.c b/ptw32_spinlock_check_need_init.c
index bf45bc3..8808454 100644
--- a/ptw32_spinlock_check_need_init.c
+++ b/ptw32_spinlock_check_need_init.c
@@ -42,16 +42,13 @@ INLINE int
ptw32_spinlock_check_need_init (pthread_spinlock_t * lock)
{
int result = 0;
+ ptw32_mcs_local_node_t node;
/*
* The following guarded test is specifically for statically
* initialised spinlocks (via PTHREAD_SPINLOCK_INITIALIZER).
- *
- * Note that by not providing this synchronisation we risk
- * introducing race conditions into applications which are
- * correctly written.
*/
- EnterCriticalSection (&ptw32_spinlock_test_init_lock);
+ ptw32_mcs_lock_acquire(&ptw32_spinlock_test_init_lock, &node);
/*
* We got here possibly under race
@@ -75,7 +72,7 @@ ptw32_spinlock_check_need_init (pthread_spinlock_t * lock)
result = EINVAL;
}
- LeaveCriticalSection (&ptw32_spinlock_test_init_lock);
+ ptw32_mcs_lock_release(&node);
return (result);
}
diff --git a/tests/SIZES.GC b/tests/SIZES.GC
index 603521b..eddaad7 100755
--- a/tests/SIZES.GC
+++ b/tests/SIZES.GC
@@ -1,7 +1,7 @@
Sizes of pthreads-win32 structs
-------------------------------
pthread_t 8
- ptw32_thread_t 140
+ ptw32_thread_t 152
pthread_attr_t_ 28
sem_t_ 12
pthread_mutex_t_ 24
diff --git a/tests/SIZES.VC b/tests/SIZES.VC
index 603521b..eddaad7 100755
--- a/tests/SIZES.VC
+++ b/tests/SIZES.VC
@@ -1,7 +1,7 @@
Sizes of pthreads-win32 structs
-------------------------------
pthread_t 8
- ptw32_thread_t 140
+ ptw32_thread_t 152
pthread_attr_t_ 28
sem_t_ 12
pthread_mutex_t_ 24