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 1e70be60a7f43adb774e2d8af4d77e62d881aa43..7873e7dc552d5ec0cadb8db902df5fe186b31eb6 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 2e08b550482a47b8686b579d27fb6106e6af273d..694dd643892ba437880f563e15b2b7bd85c2c640 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 208cb0b1279d07f23f0b530c8b599b1444ab9bcb..d095aefeb6a6f875746a67ab68d782e32d031e28 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 8c0a66653e7f516f58f17e12de68d64d4181116e..093b9512f82626ff231a7945489e0137b3b5eab9 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();