summaryrefslogtreecommitdiff
path: root/pthread_once.c
diff options
context:
space:
mode:
authorrpj <rpj>2004-09-13 04:32:16 +0000
committerrpj <rpj>2004-09-13 04:32:16 +0000
commit531ca4db4794aab863a898b4d079ccd59b424b25 (patch)
tree0fb6d71aef115a8a01cd0252363f369517deed3c /pthread_once.c
parent4b0d69122798d07ac700941d3b649f1653750ce2 (diff)
Clarify behaviour and remove some redundant code - see ChangeLogs
Diffstat (limited to 'pthread_once.c')
-rw-r--r--pthread_once.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/pthread_once.c b/pthread_once.c
index d37ee3d..34dacea 100644
--- a/pthread_once.c
+++ b/pthread_once.c
@@ -86,6 +86,18 @@ pthread_once (pthread_once_t * once_control, void (*init_routine) (void))
result = 0;
}
+ /*
+ * The race condition involving once_control->done is harmless.
+ * The problem experienced in MPU environments with multibyte variables
+ * is also not a problem because the value (initially zero i.e. PTW32_FALSE)
+ * is only ever tested for non-zero. In the event of a race occuring, the
+ * worst result is that up to N-1 threads (N = number of CPUs) may enter the
+ * while loop and yield their run state unnecessarily, and this can only
+ * ever occur at most once.
+ *
+ * The alternatives are to use a condition variable (overkill?), or
+ * InterlockedCompareExchange() to test/set once_control->done.
+ */
if (!once_control->done)
{
if (InterlockedIncrement (&(once_control->started)) == 0)