Fix some races
authorJoona Kiiski <joona.kiiski@gmail.com>
Mon, 22 Feb 2010 13:15:55 +0000 (15:15 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Tue, 23 Feb 2010 06:22:56 +0000 (07:22 +0100)
Resurrect extra check for sleeping in POSIX code.
This necessary to prevent ugly races between
thread_broadcast and thread_cond_wait.

After thread has woken up, it marks itself as available.
Another thread must not do this, because of possible race.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/search.cpp

index 38bd98e09dfd011083acf9735b5452775d34e659..974267a635eb01eed4431ae61a84e6cf0c70ce9c 100644 (file)
@@ -442,9 +442,6 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
   // Wake up sleeping threads
   TM.wake_sleeping_threads();
 
-  for (int i = 1; i < TM.active_threads(); i++)
-      assert(TM.thread_is_available(i, 0));
-
   // Set thinking time
   int myTime = time[side_to_move];
   int myIncrement = increment[side_to_move];
@@ -2595,22 +2592,24 @@ namespace {
         // If we are not thinking, wait for a condition to be signaled
         // instead of wasting CPU time polling for work.
         while (    threadID != 0
-               && !AllThreadsShouldExit
                && (AllThreadsShouldSleep || threadID >= ActiveThreads))
         {
             threads[threadID].state = THREAD_SLEEPING;
 
 #if !defined(_MSC_VER)
             pthread_mutex_lock(&WaitLock);
-            pthread_cond_wait(&WaitCond, &WaitLock);
+            if (AllThreadsShouldSleep || threadID >= ActiveThreads)
+                pthread_cond_wait(&WaitCond, &WaitLock);
             pthread_mutex_unlock(&WaitLock);
 #else
             WaitForSingleObject(SitIdleEvent[threadID], INFINITE);
 #endif
-            // State is already changed by wake_sleeping_threads()
-            assert(threads[threadID].state == THREAD_AVAILABLE || threadID >= ActiveThreads);
         }
 
+        // If thread has just woken up, mark it as available
+        if (threads[threadID].state == THREAD_SLEEPING)
+            threads[threadID].state = THREAD_AVAILABLE;
+
         // If this thread has been assigned work, launch a search
         if (threads[threadID].state == THREAD_WORKISWAITING)
         {
@@ -2933,12 +2932,8 @@ namespace {
         return;
 
     for (int i = 1; i < ActiveThreads; i++)
-    {
         assert(threads[i].state == THREAD_SLEEPING);
 
-        threads[i].state = THREAD_AVAILABLE;
-    }
-
 #if !defined(_MSC_VER)
     pthread_mutex_lock(&WaitLock);
     pthread_cond_broadcast(&WaitCond);