mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-25 14:17:13 +00:00
Fix subtle race with slave allocation
When allocating a slave we set both is_searching and splitPoint under lock protection. Unfortunatly the order in which the variables are set is not defined. This article was very clarifying: http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/ So when in idle loop we test for is_searching and then access splitPoint, it could happen that splitPoint is still not updated leading to a possible crash. Fix the race lock protecting splitPoint access. No functional change. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
+16
-6
@@ -1864,9 +1864,14 @@ void Thread::idle_loop(SplitPoint* sp_master) {
|
||||
{
|
||||
assert(!do_sleep && !do_exit);
|
||||
|
||||
// Copy split point position and search stack and call search()
|
||||
Stack ss[MAX_PLY_PLUS_2];
|
||||
lock_grab(Threads.splitLock);
|
||||
|
||||
assert(is_searching);
|
||||
SplitPoint* sp = splitPoint;
|
||||
|
||||
lock_release(Threads.splitLock);
|
||||
|
||||
Stack ss[MAX_PLY_PLUS_2];
|
||||
Position pos(*sp->pos, threadID);
|
||||
|
||||
memcpy(ss, sp->ss - 1, 4 * sizeof(Stack));
|
||||
@@ -1885,12 +1890,9 @@ void Thread::idle_loop(SplitPoint* sp_master) {
|
||||
|
||||
assert(is_searching);
|
||||
|
||||
// We return from search with lock held
|
||||
is_searching = false;
|
||||
sp->slavesMask &= ~(1ULL << threadID);
|
||||
sp->nodes += pos.nodes_searched();
|
||||
lock_release(sp->lock);
|
||||
|
||||
is_searching = false;
|
||||
|
||||
// Wake up master thread so to allow it to return from the idle loop in
|
||||
// case we are the last slave of the split point.
|
||||
@@ -1898,8 +1900,16 @@ void Thread::idle_loop(SplitPoint* sp_master) {
|
||||
&& threadID != sp->master
|
||||
&& !Threads[sp->master].is_searching)
|
||||
Threads[sp->master].wake_up();
|
||||
|
||||
// After releasing the lock we cannot access anymore any SplitPoint
|
||||
// related data in a reliably way becuase it could have been released
|
||||
// under our feet by the sp master.
|
||||
lock_release(sp->lock);
|
||||
}
|
||||
}
|
||||
// In helpful master concept a master can help only a sub-tree of its split
|
||||
// point, and because here is all finished is not possible master is booked.
|
||||
assert(!is_searching);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user