]> git.sesse.net Git - stockfish/commitdiff
Simplify locking in sp_search and sp_search_pv
authorMarco Costalba <mcostalba@gmail.com>
Wed, 27 Jan 2010 16:29:34 +0000 (17:29 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Wed, 27 Jan 2010 16:58:04 +0000 (17:58 +0100)
Avoid to take the lock two times in a tight sequence, the first
in get_next_move() and the second to update sp->moves.

Do all with one lock and so retire the now useless locked version
of get_next_move().

Also fix some theorical race due to comparison sp->bestValue < sp->beta
is done out of lock protection. Finally fix another (harmless but time
waster) race that coudl occur because thread_should_stop() is also
called outside of lock protection.

No functional change.

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

index 14fcd5d9b51309c7adb1b44b358a6ae0da35aa66..b17fb79bb73a2e61730dec7923eb94f01201cf5a 100644 (file)
@@ -99,5 +99,9 @@ typedef CRITICAL_SECTION Lock;
 
 #endif
 
+static inline bool lock_grab_bool(Lock* x) {
+    lock_grab(x);
+    return true;
+}
 
 #endif // !defined(LOCK_H_INCLUDED)
index 8d8060b55571f9b4420ba29a674e791ce48f58e9..16eb16348c1791f2761f36c8f2d96d1ce039c35d 100644 (file)
@@ -254,6 +254,8 @@ void MovePicker::score_evasions_or_checks() {
 /// are no more moves left.
 /// It picks the move with the biggest score from a list of generated moves taking
 /// care not to return the tt move if has already been searched previously.
+/// Note that this function is not thread safe so should be lock protected by
+/// caller when accessed through a shared MovePicker object.
 
 Move MovePicker::get_next_move() {
 
@@ -343,17 +345,3 @@ Move MovePicker::get_next_move() {
   }
 }
 
-/// A variant of get_next_move() which takes a lock as a parameter, used to
-/// prevent multiple threads from picking the same move at a split point.
-
-Move MovePicker::get_next_move(Lock &lock) {
-
-   lock_grab(&lock);
-
-   // Note that it is safe to call many times
-   // get_next_move() when phase == PH_STOP
-   Move m = get_next_move();
-
-   lock_release(&lock);
-   return m;
-}
index a9a3561acf3fd888f4727f7e34649d47892f8a4b..b2bfb5d1d167c36efdeedd47c23427d93abe7036 100644 (file)
@@ -27,7 +27,6 @@
 
 #include "depth.h"
 #include "history.h"
-#include "lock.h"
 #include "position.h"
 
 
@@ -52,7 +51,6 @@ class MovePicker {
 public:
   MovePicker(const Position& p, Move ttm, Depth d, const History& h, SearchStack* ss = NULL);
   Move get_next_move();
-  Move get_next_move(Lock& lock);
   int number_of_evasions() const;
 
 private:
index e64b9a7d5fa2673c693d85d974673b5d48d49c4e..c3c2925fcf70f5dfff640875fd1295be5d924606 100644 (file)
@@ -1874,28 +1874,29 @@ namespace {
     SearchStack* ss = sp->sstack[threadID];
     Value value = -VALUE_INFINITE;
     Move move;
+    int moveCount;
     bool isCheck = pos.is_check();
     bool useFutilityPruning =     sp->depth < SelectiveDepth
                               && !isCheck;
 
     const int FutilityMoveCountMargin = 3 + (1 << (3 * int(sp->depth) / 8));
 
-    while (    sp->bestValue < sp->beta
+    while (    lock_grab_bool(&(sp->lock))
+           &&  sp->bestValue < sp->beta
            && !thread_should_stop(threadID)
-           && (move = sp->mp->get_next_move(sp->lock)) != MOVE_NONE)
+           && (move = sp->mp->get_next_move()) != MOVE_NONE)
     {
+      moveCount = ++sp->moves;
+      lock_release(&(sp->lock));
+
       assert(move_is_ok(move));
 
       bool moveIsCheck = pos.move_is_check(move, ci);
       bool captureOrPromotion = pos.move_is_capture_or_promotion(move);
 
-      lock_grab(&(sp->lock));
-      int moveCount = ++sp->moves;
-      lock_release(&(sp->lock));
-
       ss[sp->ply].currentMove = move;
 
-      // Decide the new search depth.
+      // Decide the new search depth
       bool dangerous;
       Depth ext = extension(pos, move, false, captureOrPromotion, moveIsCheck, false, false, &dangerous);
       Depth newDepth = sp->depth - OnePly + ext;
@@ -1982,7 +1983,7 @@ namespace {
       }
     }
 
-    lock_grab(&(sp->lock));
+    /* Here we have the lock still grabbed */
 
     // If this is the master thread and we have been asked to stop because of
     // a beta cutoff higher up in the tree, stop all slave threads.
@@ -2015,24 +2016,25 @@ namespace {
     CheckInfo ci(pos);
     SearchStack* ss = sp->sstack[threadID];
     Value value = -VALUE_INFINITE;
+    int moveCount;
     Move move;
 
-    while (    sp->alpha < sp->beta
+    while (    lock_grab_bool(&(sp->lock))
+           &&  sp->alpha < sp->beta
            && !thread_should_stop(threadID)
-           && (move = sp->mp->get_next_move(sp->lock)) != MOVE_NONE)
+           && (move = sp->mp->get_next_move()) != MOVE_NONE)
     {
-      bool moveIsCheck = pos.move_is_check(move, ci);
-      bool captureOrPromotion = pos.move_is_capture_or_promotion(move);
+      moveCount = ++sp->moves;
+      lock_release(&(sp->lock));
 
       assert(move_is_ok(move));
 
-      lock_grab(&(sp->lock));
-      int moveCount = ++sp->moves;
-      lock_release(&(sp->lock));
+      bool moveIsCheck = pos.move_is_check(move, ci);
+      bool captureOrPromotion = pos.move_is_capture_or_promotion(move);
 
       ss[sp->ply].currentMove = move;
 
-      // Decide the new search depth.
+      // Decide the new search depth
       bool dangerous;
       Depth ext = extension(pos, move, true, captureOrPromotion, moveIsCheck, false, false, &dangerous);
       Depth newDepth = sp->depth - OnePly + ext;
@@ -2131,7 +2133,7 @@ namespace {
       }
     }
 
-    lock_grab(&(sp->lock));
+    /* Here we have the lock still grabbed */
 
     // If this is the master thread and we have been asked to stop because of
     // a beta cutoff higher up in the tree, stop all slave threads.