]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Fix compile error under gcc
[stockfish] / src / search.cpp
index fbae76d7720fee3dd5833697b0b70be412428b5c..4654256065bd54612ff03e1c2a6778e65a7f169c 100644 (file)
@@ -280,6 +280,7 @@ namespace {
              const Value futilityValue, Depth depth, int *moves,
              MovePicker *mp, int master, bool pvNode);
   void wake_sleeping_threads();
+  void put_threads_to_sleep();
 
 #if !defined(_MSC_VER)
   void *init_thread(void *threadID);
@@ -335,7 +336,7 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
            int maxNodes, int maxTime, Move searchMoves[]) {
 
   // Initialize global search variables
-  AllThreadsShouldSleep = StopOnPonderhit = AbortSearch = Quit = false;
+  StopOnPonderhit = AbortSearch = Quit = false;
   AspirationFailLow = false;
   NodesSincePoll = 0;
   SearchStartTime = get_system_time();
@@ -521,7 +522,8 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
   if (UseLogFile)
       LogFile.close();
 
-  AllThreadsShouldSleep = true;
+  put_threads_to_sleep();
+
   return !Quit;
 }
 
@@ -606,19 +608,19 @@ void init_threads() {
           Application::exit_with_failure();
       }
 
-      // Wait until the thread has finished launching
-      while (!Threads[i].running);
+      // Wait until the thread has finished launching and is gone to sleep
+      while (!Threads[i].running || !Threads[i].sleeping);
   }
 }
 
 
-/// stop_threads() is called when the program exits. It makes all the
+/// exit_threads() is called when the program exits. It makes all the
 /// helper threads exit cleanly.
 
-void stop_threads() {
+void exit_threads() {
 
   ActiveThreads = THREAD_MAX;  // HACK
-  AllThreadsShouldSleep = false;  // HACK
+  AllThreadsShouldSleep = true;  // HACK
   wake_sleeping_threads();
   AllThreadsShouldExit = true;
   for (int i = 1; i < THREAD_MAX; i++)
@@ -2786,16 +2788,19 @@ namespace {
 
 #if !defined(_MSC_VER)
             pthread_mutex_lock(&WaitLock);
-            if (Idle || threadID >= ActiveThreads)
+            if (AllThreadsShouldSleep || threadID >= ActiveThreads)
                 pthread_cond_wait(&WaitCond, &WaitLock);
 
             pthread_mutex_unlock(&WaitLock);
 #else
             WaitForSingleObject(SitIdleEvent[threadID], INFINITE);
 #endif
-            Threads[threadID].sleeping = false;
         }
 
+        // Out of the while loop to avoid races in case thread is woken up but
+        // while condition still holds true so that is put to sleep again.
+        Threads[threadID].sleeping = false;
+
       // If this thread has been assigned work, launch a search
       if (Threads[threadID].workIsWaiting)
       {
@@ -3047,10 +3052,16 @@ namespace {
 
   void wake_sleeping_threads() {
 
+    assert(AllThreadsShouldSleep);
+
+    AllThreadsShouldSleep = false;
+
     if (ActiveThreads > 1)
     {
         for (int i = 1; i < ActiveThreads; i++)
         {
+            assert(Threads[i].sleeping == true);
+
             Threads[i].idle = true;
             Threads[i].workIsWaiting = false;
         }
@@ -3063,10 +3074,30 @@ namespace {
       for (int i = 1; i < THREAD_MAX; i++)
           SetEvent(SitIdleEvent[i]);
 #endif
+
+      // Wait for the threads to be all woken up
+      for (int i = 1; i < ActiveThreads; i++)
+           while (Threads[i].sleeping);
     }
   }
 
 
+  // put_threads_to_sleep() makes all the threads go to sleep just before
+  // to leave think(), at the end of the search. Threads should have already
+  // finished the job and should be idle.
+
+  void put_threads_to_sleep() {
+
+    assert(!AllThreadsShouldSleep);
+
+    AllThreadsShouldSleep = true;
+
+    // Wait for the threads to be all sleeping
+    for (int i = 1; i < ActiveThreads; i++)
+        while (!Threads[i].sleeping);
+  }
+
+
   // init_thread() is the function which is called when a new thread is
   // launched. It simply calls the idle_loop() function with the supplied
   // threadID. There are two versions of this function; one for POSIX