Fix a race when extracting PV from TT
authorMarco Costalba <mcostalba@gmail.com>
Fri, 17 Feb 2012 19:38:17 +0000 (20:38 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sat, 18 Feb 2012 09:20:07 +0000 (10:20 +0100)
Because TT table is shared tte->move() could change
under our feet, in particular we could validate
tte->move() then the move is changed by another
thread and we call pos.do_move() with a move different
from the original validated one !

This leads to a very rare but reproducible crash once
every about 20K games.

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

index 5706b959f2d9ffeb1e0a121a001a7a44c31b5c3b..d4826946fb043b98b5e8ec4cc2d77d1e0e5315d8 100644 (file)
@@ -1767,14 +1767,14 @@ void RootMove::extract_pv_from_tt(Position& pos) {
   pos.do_move(m, *st++);
 
   while (   (tte = TT.probe(pos.key())) != NULL
-         && tte->move() != MOVE_NONE
-         && pos.is_pseudo_legal(tte->move())
-         && pos.pl_move_is_legal(tte->move(), pos.pinned_pieces())
+         && (m = tte->move()) != MOVE_NONE // Local copy, TT entry could change
+         && pos.is_pseudo_legal(m)
+         && pos.pl_move_is_legal(m, pos.pinned_pieces())
          && ply < MAX_PLY
          && (!pos.is_draw<false>() || ply < 2))
   {
-      pv.push_back(tte->move());
-      pos.do_move(tte->move(), *st++);
+      pv.push_back(m);
+      pos.do_move(m, *st++);
       ply++;
   }
   pv.push_back(MOVE_NONE);