Fix uninitialized memory usage
authorJoost VandeVondele <Joost.VandeVondele@gmail.com>
Thu, 31 Aug 2017 07:34:32 +0000 (09:34 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Fri, 1 Sep 2017 18:16:56 +0000 (20:16 +0200)
After increasing the number of threads, the histories were not cleared,
resulting in uninitialized memory usage.

This patch fixes this by clearing threads histories in Thread c'tor as
is the idomatic way.

This fixes issue 1227

No functional change.

src/search.cpp
src/search.h
src/thread.cpp
src/thread.h

index 1e70be6..7873e7d 100644 (file)
@@ -75,9 +75,6 @@ namespace {
   int FutilityMoveCounts[2][16]; // [improving][depth]
   int Reductions[2][2][64][64];  // [pv][improving][depth][moveNumber]
 
-  // Threshold used for countermoves based pruning
-  const int CounterMovePruneThreshold = 0;
-
   template <bool PvNode> Depth reduction(bool i, Depth d, int mn) {
     return Reductions[PvNode][i][std::min(d / ONE_PLY, 63)][std::min(mn, 63)] * ONE_PLY;
   }
@@ -219,16 +216,7 @@ void Search::clear() {
   TT.clear();
 
   for (Thread* th : Threads)
-  {
-      th->counterMoves.fill(MOVE_NONE);
-      th->mainHistory.fill(0);
-
-      for (auto& to : th->contHistory)
-          for (auto& h : to)
-              h.fill(0);
-
-      th->contHistory[NO_PIECE][0].fill(CounterMovePruneThreshold - 1);
-  }
+      th->clear();
 
   Threads.main()->callsCnt = 0;
   Threads.main()->previousScore = VALUE_INFINITE;
index 2e08b55..694dd64 100644 (file)
@@ -31,6 +31,10 @@ class Position;
 
 namespace Search {
 
+/// Threshold used for countermoves based pruning
+const int CounterMovePruneThreshold = 0;
+
+
 /// Stack struct keeps track of the information we need to remember from nodes
 /// shallower and deeper in the tree during the search. Each search thread has
 /// its own array of Stack objects, indexed by the current ply.
index 208cb0b..d095aef 100644 (file)
@@ -35,6 +35,7 @@ ThreadPool Threads; // Global object
 Thread::Thread(size_t n) : idx(n), stdThread(&Thread::idle_loop, this) {
 
   wait_for_search_finished();
+  clear(); // Zero-init histories (based on std::array)
 }
 
 
@@ -51,6 +52,20 @@ Thread::~Thread() {
 }
 
 
+/// Thread::clear() reset histories, usually before a new game
+
+void Thread::clear() {
+
+  counterMoves.fill(MOVE_NONE);
+  mainHistory.fill(0);
+
+  for (auto& to : contHistory)
+      for (auto& h : to)
+          h.fill(0);
+
+  contHistory[NO_PIECE][0].fill(Search::CounterMovePruneThreshold - 1);
+}
+
 /// Thread::start_searching() wakes up the thread that will start the search
 
 void Thread::start_searching() {
index 8c0a666..093b951 100644 (file)
@@ -52,6 +52,7 @@ public:
   explicit Thread(size_t);
   virtual ~Thread();
   virtual void search();
+  void clear();
   void idle_loop();
   void start_searching();
   void wait_for_search_finished();