]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Be sure threads are woken in wake_sleeping_threads()
[stockfish] / src / search.cpp
index c13431bc9721d418b1eabded12b677df2bb7ba23..22bc0156705121a9a02adfcd8b59c1ff66e21997 100644 (file)
@@ -164,8 +164,8 @@ namespace {
   int32_t FutilityMarginsMatrix[14][64]; // [depth][moveNumber]
   int FutilityMoveCountArray[32]; // [depth]
 
-  inline Value futility_margin(Depth d, int mn) { return (Value) (d < 14? FutilityMarginsMatrix[Max(d, 0)][Min(mn, 63)] : 2*VALUE_INFINITE); }
-  inline int futility_move_count(Depth d) { return (d < 32? FutilityMoveCountArray[d] : 512); }
+  inline Value futility_margin(Depth d, int mn) { return Value(d < 7*OnePly ? FutilityMarginsMatrix[Max(d, 0)][Min(mn, 63)] : 2 * VALUE_INFINITE); }
+  inline int futility_move_count(Depth d) { return d < 16*OnePly ? FutilityMoveCountArray[d] : 512; }
 
   /// Variables initialized by UCI options
 
@@ -219,9 +219,8 @@ namespace {
   Thread Threads[THREAD_MAX];
   Lock MPLock;
   Lock IOLock;
-  bool AllThreadsShouldExit = false;
+  bool AllThreadsShouldExit, AllThreadsShouldSleep;
   SplitPoint SplitPointStack[THREAD_MAX][ACTIVE_SPLIT_POINTS_MAX];
-  bool Idle = true;
 
 #if !defined(_MSC_VER)
   pthread_cond_t WaitCond;
@@ -336,7 +335,7 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
            int maxNodes, int maxTime, Move searchMoves[]) {
 
   // Initialize global search variables
-  Idle = StopOnPonderhit = AbortSearch = Quit = false;
+  AllThreadsShouldSleep = StopOnPonderhit = AbortSearch = Quit = false;
   AspirationFailLow = false;
   NodesSincePoll = 0;
   SearchStartTime = get_system_time();
@@ -522,13 +521,12 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
   if (UseLogFile)
       LogFile.close();
 
-  Idle = true;
+  AllThreadsShouldSleep = true;
   return !Quit;
 }
 
 
-/// init_search() is called during startup. It initializes various
-/// lookup tables.
+/// init_search() is called during startup. It initializes various lookup tables
 
 void init_search() {
 
@@ -568,9 +566,6 @@ void init_threads() {
   pthread_t pthread[1];
 #endif
 
-  for (i = 0; i < THREAD_MAX; i++)
-      Threads[i].activeSplitPoints = 0;
-
   // Initialize global locks
   lock_init(&MPLock, NULL);
   lock_init(&IOLock, NULL);
@@ -585,14 +580,15 @@ void init_threads() {
       SitIdleEvent[i] = CreateEvent(0, FALSE, FALSE, 0);
 #endif
 
+  // Will be set just before program exits to properly end the threads
+  AllThreadsShouldExit = false;
+
+  // Threads will be put to sleep as soon as created
+  AllThreadsShouldSleep = true;
+
   // All threads except the main thread should be initialized to idle state
   for (i = 1; i < THREAD_MAX; i++)
-  {
-      Threads[i].stop = false;
-      Threads[i].workIsWaiting = false;
       Threads[i].idle = true;
-      Threads[i].running = false;
-  }
 
   // Launch the helper threads
   for (i = 1; i < THREAD_MAX; i++)
@@ -622,7 +618,7 @@ void init_threads() {
 void stop_threads() {
 
   ActiveThreads = THREAD_MAX;  // HACK
-  Idle = false;  // HACK
+  AllThreadsShouldSleep = false;  // HACK
   wake_sleeping_threads();
   AllThreadsShouldExit = true;
   for (int i = 1; i < THREAD_MAX; i++)
@@ -654,7 +650,6 @@ void SearchStack::init(int ply) {
   currentMove = threatMove = MOVE_NONE;
   reduction = Depth(0);
   eval = VALUE_NONE;
-  evalInfo = NULL;
 }
 
 void SearchStack::initKillers() {
@@ -1387,10 +1382,7 @@ namespace {
         if (tte && (tte->type() & VALUE_TYPE_EVAL))
             staticValue = value_from_tt(tte->value(), ply);
         else
-        {
             staticValue = evaluate(pos, ei, threadID);
-            ss[ply].evalInfo = &ei;
-        }
 
         ss[ply].eval = staticValue;
         futilityValue = staticValue + futility_margin(depth, 0); //FIXME: Remove me, only for split
@@ -1544,7 +1536,8 @@ namespace {
 
           // Value based pruning
           Depth predictedDepth = newDepth - nonpv_reduction(depth, moveCount); //FIXME: We are ignoring condition: depth >= 3*OnePly, BUG??
-          futilityValueScaled = ss[ply].eval + futility_margin(predictedDepth, moveCount) + H.gain(pos.piece_on(move_from(move)), move_to(move)) + 45;
+          futilityValueScaled =  ss[ply].eval + futility_margin(predictedDepth, moveCount)
+                               + H.gain(pos.piece_on(move_from(move)), move_to(move)) + 45;
 
           if (futilityValueScaled < beta)
           {
@@ -2780,16 +2773,17 @@ namespace {
 
     Threads[threadID].running = true;
 
-    while (true)
+    while (!AllThreadsShouldExit || threadID == 0)
     {
-        if (AllThreadsShouldExit && threadID != 0)
-            break;
-
         // If we are not thinking, wait for a condition to be signaled
         // instead of wasting CPU time polling for work.
-        while (threadID != 0 && (Idle || threadID >= ActiveThreads))
+        while (    threadID != 0
+               && !AllThreadsShouldExit
+               && (AllThreadsShouldSleep || threadID >= ActiveThreads))
         {
 
+            Threads[threadID].sleeping = true;
+
 #if !defined(_MSC_VER)
             pthread_mutex_lock(&WaitLock);
             if (Idle || threadID >= ActiveThreads)
@@ -2801,6 +2795,10 @@ namespace {
 #endif
         }
 
+        // 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)
       {
@@ -3056,6 +3054,8 @@ namespace {
     {
         for (int i = 1; i < ActiveThreads; i++)
         {
+            assert(Threads[i].sleeping == true);
+
             Threads[i].idle = true;
             Threads[i].workIsWaiting = false;
         }
@@ -3068,6 +3068,10 @@ 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);
     }
   }