Fix a race on Limits::ponder
authorJoost VandeVondele <Joost.VandeVondele@gmail.com>
Thu, 27 Jul 2017 06:31:25 +0000 (08:31 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Thu, 10 Aug 2017 17:46:46 +0000 (10:46 -0700)
commit5410424e3d036b43715c7989aa99e449cdcde18e
tree09340bff2c8bf044603c22aebfa22d90f9a10239
parent750dfa0521472e86c67f870fe7ca413d670cafe2
Fix a race on Limits::ponder

Limits::ponder was used as a signal between uci and search threads,
but is not an atomic variable, leading to the following race as
flagged by a sanitized binary.

Expect input:
```
 spawn  ./stockfish
 send "uci\n"
 expect "uciok"
 send "setoption name Ponder value true\n"
 send "go wtime 4000 btime 4000\n"
 expect "bestmove"
 send "position startpos e2e4 d7d5\n"
 send "go wtime 4000 btime 4000 ponder\n"
 sleep 0.01
 send "ponderhit\n"
 expect "bestmove"
 send "quit\n"
 expect eof
```

Race:
```
WARNING: ThreadSanitizer: data race (pid=7191)
  Read of size 4 at 0x0000005c2260 by thread T1:

  Previous write of size 4 at 0x0000005c2260 by main thread:

  Location is global 'Search::Limits' of size 88 at 0x0000005c2220 (stockfish+0x0000005c2260)
```

The reason of teh race is that ponder is not just set in UCI go()
assignment but also is signaled by an async ponderhit in uci.cpp:

      else if (token == "ponderhit")
          Search::Limits.ponder = 0; // Switch to normal search

The fix is to add an atomic bool to the threads structure to
signal the ponder status, letting Search::Limits to reflect just
what was passed to 'go'.

No functional change.
src/search.cpp
src/search.h
src/thread.cpp
src/thread.h
src/uci.cpp