]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Do not return from idle_loop() with lock held
[stockfish] / src / search.cpp
index b2b2414ae68eb47f6d2de2101e5bcc198d7f9aa7..17e54e4cd3cbedc32a9656f314fa8ac1514790f2 100644 (file)
@@ -82,7 +82,7 @@ namespace {
     bool thread_should_stop(int threadID) const;
     void wake_sleeping_threads();
     void put_threads_to_sleep();
-    void idle_loop(int threadID, SplitPoint* waitSp);
+    void idle_loop(int threadID, SplitPoint* sp);
     bool split(const Position& pos, SearchStack* ss, int ply, Value* alpha, const Value beta, Value* bestValue,
                Depth depth, bool mateThreat, int* moves, MovePicker* mp, int master, bool pvNode);
 
@@ -1301,6 +1301,9 @@ namespace {
 
     if (tte && ok_to_use_TT(tte, depth, beta, ply))
     {
+        // Refresh tte entry to avoid aging
+        TT.store(posKey, tte->value(), tte->type(), tte->depth(), ttMove);
+
         ss[ply].currentMove = ttMove; // Can be MOVE_NONE
         return value_from_tt(tte->value(), ply);
     }
@@ -2633,10 +2636,10 @@ namespace {
 
 
   // idle_loop() is where the threads are parked when they have no work to do.
-  // The parameter "waitSp", if non-NULL, is a pointer to an active SplitPoint
+  // The parameter 'sp', if non-NULL, is a pointer to an active SplitPoint
   // object for which the current thread is the master.
 
-  void ThreadsManager::idle_loop(int threadID, SplitPoint* waitSp) {
+  void ThreadsManager::idle_loop(int threadID, SplitPoint* sp) {
 
     assert(threadID >= 0 && threadID < MAX_THREADS);
 
@@ -2646,7 +2649,7 @@ namespace {
         // master should exit as last one.
         if (AllThreadsShouldExit)
         {
-            assert(!waitSp);
+            assert(!sp);
             threads[threadID].state = THREAD_TERMINATED;
             return;
         }
@@ -2655,7 +2658,7 @@ namespace {
         // instead of wasting CPU time polling for work.
         while (AllThreadsShouldSleep || threadID >= ActiveThreads)
         {
-            assert(!waitSp);
+            assert(!sp);
             assert(threadID != 0);
             threads[threadID].state = THREAD_SLEEPING;
 
@@ -2692,8 +2695,13 @@ namespace {
 
         // If this thread is the master of a split point and all threads have
         // finished their work at this split point, return from the idle loop.
-        if (waitSp != NULL && waitSp->cpus == 0)
+        if (sp && sp->cpus == 0)
         {
+            // Because sp->cpus is decremented under lock protection,
+            // be sure sp->lock has been released before to proceed.
+            lock_grab(&(sp->lock));
+            lock_release(&(sp->lock));
+
             assert(threads[threadID].state == THREAD_AVAILABLE);
 
             threads[threadID].state = THREAD_SEARCHING;