mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-25 19:46:55 +08:00
Fix races in gensfen as detected with thread sanitizer.
RootInTB was an incorrectly shared global, probably leading to wrong scoreing Minor: setting TB global state from input by all threads (all threads write same values) setting Limits global state by all threads (idem) thread counting for finalization CI can be enabled once races are fixed in the learner, manually goes like: ``` make clean && make -j2 ARCH=x86-64-modern sanitize=thread optimize=no debug=yes build ../tests/instrumented_learn.sh --sanitizer-thread ``` Needs some review.
This commit is contained in:
committed by
nodchip
parent
184bde47dc
commit
e8472b5fbe
@@ -3,6 +3,7 @@
|
||||
#include "tt.h"
|
||||
#include "uci.h"
|
||||
#include "types.h"
|
||||
#include "search.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
@@ -23,6 +24,27 @@ void MultiThink::go_think()
|
||||
// Call the derived class's init().
|
||||
init();
|
||||
|
||||
// init global vars
|
||||
Tablebases::init();
|
||||
|
||||
// About Search::Limits
|
||||
// Be careful because this member variable is global and affects other threads.
|
||||
{
|
||||
auto& limits = Search::Limits;
|
||||
|
||||
// Make the search equivalent to the "go infinite" command. (Because it is troublesome if time management is done)
|
||||
limits.infinite = true;
|
||||
|
||||
// Since PV is an obstacle when displayed, erase it.
|
||||
limits.silent = true;
|
||||
|
||||
// If you use this, it will be compared with the accumulated nodes of each thread. Therefore, do not use it.
|
||||
limits.nodes = 0;
|
||||
|
||||
// depth is also processed by the one passed as an argument of Learner::search().
|
||||
limits.depth = 0;
|
||||
}
|
||||
|
||||
// The loop upper limit is set with set_loop_max().
|
||||
loop_count = 0;
|
||||
done_count = 0;
|
||||
@@ -32,12 +54,11 @@ void MultiThink::go_think()
|
||||
auto thread_num = (size_t)Options["Threads"];
|
||||
|
||||
// Secure end flag of worker thread
|
||||
thread_finished.resize(thread_num);
|
||||
threads_finished=0;
|
||||
|
||||
// start worker thread
|
||||
for (size_t i = 0; i < thread_num; ++i)
|
||||
{
|
||||
thread_finished[i] = 0;
|
||||
threads.push_back(std::thread([i, this]
|
||||
{
|
||||
// exhaust all processor threads.
|
||||
@@ -47,7 +68,7 @@ void MultiThink::go_think()
|
||||
this->thread_worker(i);
|
||||
|
||||
// Set the end flag because the thread has ended
|
||||
this->thread_finished[i] = 1;
|
||||
this->threads_finished++;
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -61,11 +82,7 @@ void MultiThink::go_think()
|
||||
// function to determine if all threads have finished
|
||||
auto threads_done = [&]()
|
||||
{
|
||||
// returns false if no one is finished
|
||||
for (auto& f : thread_finished)
|
||||
if (!f)
|
||||
return false;
|
||||
return true;
|
||||
return threads_finished == thread_num;
|
||||
};
|
||||
|
||||
// Call back if the callback function is set.
|
||||
|
||||
@@ -96,10 +96,7 @@ private:
|
||||
std::mutex loop_mutex;
|
||||
|
||||
// Thread end flag.
|
||||
// vector<bool> may not be reflected properly when trying to rewrite from multiple threads...
|
||||
typedef uint8_t Flag;
|
||||
std::vector<Flag> thread_finished;
|
||||
|
||||
std::atomic<uint64_t> threads_finished;
|
||||
};
|
||||
|
||||
// Mechanism to process task during idle time.
|
||||
|
||||
Reference in New Issue
Block a user