]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Destroy all locks before to exit
[stockfish] / src / search.cpp
index b269962f9558f006899b5aca06d8973b1153e1c6..b3418b257351f6bbe051a913427c6357598b1e95 100644 (file)
@@ -94,11 +94,10 @@ namespace {
     Thread threads[MAX_THREADS];
     SplitPoint SplitPointStack[MAX_THREADS][ACTIVE_SPLIT_POINTS_MAX];
 
-    Lock MPLock;
+    Lock MPLock, WaitLock;
 
 #if !defined(_MSC_VER)
     pthread_cond_t WaitCond;
-    pthread_mutex_t WaitLock;
 #else
     HANDLE SitIdleEvent[MAX_THREADS];
 #endif
@@ -162,7 +161,10 @@ namespace {
 
   // Step 6. Razoring
 
+  // Maximum depth for razoring
   const Depth RazorDepth = 4 * OnePly;
+
+  // Dynamic razoring margin based on depth
   inline Value razor_margin(Depth d) { return Value(0x200 + 0x10 * d); }
 
   // Step 8. Null move search with verification search
@@ -171,8 +173,12 @@ namespace {
   // evaluation of the position is more than NullMoveMargin below beta.
   const Value NullMoveMargin = Value(0x200);
 
+  // Maximum depth for use of dynamic threat detection when null move fails low
+  const Depth ThreatDepth = 5 * OnePly;
+
   // Step 9. Internal iterative deepening
 
+  // Minimum depth for use of internal iterative deepening
   const Depth IIDDepthAtPVNodes = 5 * OnePly;
   const Depth IIDDepthAtNonPVNodes = 8 * OnePly;
 
@@ -188,6 +194,7 @@ namespace {
   Depth CheckExtension[2], SingleEvasionExtension[2], PawnPushTo7thExtension[2];
   Depth PassedPawnExtension[2], PawnEndgameExtension[2], MateThreatExtension[2];
 
+  // Minimum depth for use of singular extension
   const Depth SingularExtensionDepthAtPVNodes = 6 * OnePly;
   const Depth SingularExtensionDepthAtNonPVNodes = 8 * OnePly;
 
@@ -195,36 +202,35 @@ namespace {
   // remaining ones we will extend it.
   const Value SingularExtensionMargin = Value(0x20);
 
+  // Step 12. Futility pruning
 
+  // Futility margin for quiescence search
+  const Value FutilityMarginQS = Value(0x80);
 
-  // Search depth at iteration 1
-  const Depth InitialDepth = OnePly;
+  // Futility lookup tables (initialized at startup) and their getter functions
+  int32_t FutilityMarginsMatrix[14][64]; // [depth][moveNumber]
+  int FutilityMoveCountArray[32]; // [depth]
 
-  // Easy move margin. An easy move candidate must be at least this much
-  // better than the second best move.
-  const Value EasyMoveMargin = Value(0x200);
+  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; }
 
-  /// Lookup tables initialized at startup
+  // Step 14. Reduced search
 
-  // Reduction lookup tables and their getter functions
+  // Reduction lookup tables (initialized at startup) and their getter functions
   int8_t    PVReductionMatrix[64][64]; // [depth][moveNumber]
   int8_t NonPVReductionMatrix[64][64]; // [depth][moveNumber]
 
   inline Depth    pv_reduction(Depth d, int mn) { return (Depth)    PVReductionMatrix[Min(d / 2, 63)][Min(mn, 63)]; }
   inline Depth nonpv_reduction(Depth d, int mn) { return (Depth) NonPVReductionMatrix[Min(d / 2, 63)][Min(mn, 63)]; }
 
-  // Futility lookup tables and their getter functions
-  const Value FutilityMarginQS = Value(0x80);
-  int32_t FutilityMarginsMatrix[14][64]; // [depth][moveNumber]
-  int FutilityMoveCountArray[32]; // [depth]
+  // Step. Common adjustments
 
-  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
+  // Search depth at iteration 1
+  const Depth InitialDepth = OnePly;
 
-  // Depth limit for use of dynamic threat detection
-  Depth ThreatDepth;
+  // Easy move margin. An easy move candidate must be at least this much
+  // better than the second best move.
+  const Value EasyMoveMargin = Value(0x200);
 
   // Last seconds noise filtering (LSN)
   const bool UseLSNFiltering = true;
@@ -232,6 +238,9 @@ namespace {
   const Value LSNValue = value_from_centipawns(200);
   bool loseOnTime = false;
 
+
+  /// Global variables
+
   // Iteration counters
   int Iteration;
 
@@ -426,8 +435,6 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
   MateThreatExtension[1] = Depth(get_option_value_int("Mate Threat Extension (PV nodes)"));
   MateThreatExtension[0] = Depth(get_option_value_int("Mate Threat Extension (non-PV nodes)"));
 
-  ThreatDepth   = get_option_value_int("Threat Depth") * OnePly;
-
   Chess960 = get_option_value_bool("UCI_Chess960");
   ShowCurrentLine = get_option_value_bool("UCI_ShowCurrLine");
   UseLogFile = get_option_value_bool("Use Search Log");
@@ -1432,7 +1439,7 @@ namespace {
     // Loop through all legal moves until no moves remain or a beta cutoff occurs
 
     // Initialize a MovePicker object for the current position
-    MovePicker mp = MovePicker(pos, ttMove, depth, H, &ss[ply]);
+    MovePicker mp = MovePicker(pos, ttMove, depth, H, &ss[ply], beta);
     CheckInfo ci(pos);
 
     while (   bestValue < beta
@@ -1492,7 +1499,7 @@ namespace {
               continue;
 
           // Value based pruning
-          Depth predictedDepth = newDepth - nonpv_reduction(depth, moveCount); //FIXME: We are ignoring condition: depth >= 3*OnePly, BUG??
+          Depth predictedDepth = newDepth - nonpv_reduction(depth, moveCount); // We illogically ignore reduction condition depth >= 3*OnePly
           futilityValueScaled =  ss[ply].eval + futility_margin(predictedDepth, moveCount)
                                + H.gain(pos.piece_on(move_from(move)), move_to(move)) + 45;
 
@@ -2585,7 +2592,7 @@ namespace {
   DWORD WINAPI init_thread(LPVOID threadID) {
 
     TM.idle_loop(*(int*)threadID, NULL);
-    return NULL;
+    return 0;
   }
 
 #endif
@@ -2657,10 +2664,10 @@ namespace {
             threads[threadID].state = THREAD_SLEEPING;
 
 #if !defined(_MSC_VER)
-            pthread_mutex_lock(&WaitLock);
+            lock_grab(&WaitLock);
             if (AllThreadsShouldSleep || threadID >= ActiveThreads)
                 pthread_cond_wait(&WaitCond, &WaitLock);
-            pthread_mutex_unlock(&WaitLock);
+            lock_release(&WaitLock);
 #else
             WaitForSingleObject(SitIdleEvent[threadID], INFINITE);
 #endif
@@ -2715,6 +2722,14 @@ namespace {
 
     // Initialize global locks
     lock_init(&MPLock, NULL);
+    lock_init(&WaitLock, NULL);
+
+#if !defined(_MSC_VER)
+    pthread_cond_init(&WaitCond, NULL);
+#else
+    for (i = 0; i < MAX_THREADS; i++)
+        SitIdleEvent[i] = CreateEvent(0, FALSE, FALSE, 0);
+#endif
 
     // Initialize SplitPointStack locks
     for (i = 0; i < MAX_THREADS; i++)
@@ -2724,14 +2739,6 @@ namespace {
             lock_init(&(SplitPointStack[i][j].lock), NULL);
         }
 
-#if !defined(_MSC_VER)
-    pthread_mutex_init(&WaitLock, NULL);
-    pthread_cond_init(&WaitCond, NULL);
-#else
-    for (i = 0; i < MAX_THREADS; i++)
-        SitIdleEvent[i] = CreateEvent(0, FALSE, FALSE, 0);
-#endif
-
     // Will be set just before program exits to properly end the threads
     AllThreadsShouldExit = false;
 
@@ -2751,8 +2758,7 @@ namespace {
 #if !defined(_MSC_VER)
         ok = (pthread_create(pthread, NULL, init_thread, (void*)(&i)) == 0);
 #else
-        DWORD iID[1];
-        ok = (CreateThread(NULL, 0, init_thread, (LPVOID)(&i), 0, iID) != NULL);
+        ok = (CreateThread(NULL, 0, init_thread, (LPVOID)(&i), 0, NULL) != NULL);
 #endif
 
         if (!ok)
@@ -2787,6 +2793,9 @@ namespace {
     for (int i = 0; i < MAX_THREADS; i++)
         for (int j = 0; j < ACTIVE_SPLIT_POINTS_MAX; j++)
             lock_destroy(&(SplitPointStack[i][j].lock));
+
+    lock_destroy(&WaitLock);
+    lock_destroy(&MPLock);
   }
 
 
@@ -2991,9 +3000,6 @@ namespace {
     if (ActiveThreads == 1)
         return;
 
-    for (int i = 1; i < ActiveThreads; i++)
-        assert(threads[i].state == THREAD_SLEEPING);
-
 #if !defined(_MSC_VER)
     pthread_mutex_lock(&WaitLock);
     pthread_cond_broadcast(&WaitCond);