+ assert(searching);
+
+ searching = false;
+ }
+ }
+}
+
+
+// ThreadPool::init() is called at startup to create and launch requested threads,
+// that will go immediately to sleep. We cannot use a c'tor because Threads is a
+// static object and we need a fully initialized engine at this point due to
+// allocation of Endgames in Thread c'tor.
+
+void ThreadPool::init() {
+
+ timer = new_thread<TimerThread>();
+ push_back(new_thread<MainThread>());
+ read_uci_options();
+}
+
+
+// ThreadPool::exit() terminates the threads before the program exits. Cannot be
+// done in d'tor because threads must be terminated before freeing us.
+
+void ThreadPool::exit() {
+
+ delete_thread(timer); // As first because check_time() accesses threads data
+
+ for (Thread* th : *this)
+ delete_thread(th);
+}
+
+
+// ThreadPool::read_uci_options() updates internal threads parameters from the
+// corresponding UCI options and creates/destroys threads to match the requested
+// number. Thread objects are dynamically allocated to avoid creating all possible
+// threads in advance (which include pawns and material tables), even if only a
+// few are to be used.
+
+void ThreadPool::read_uci_options() {
+
+ minimumSplitDepth = Options["Min Split Depth"] * ONE_PLY;
+ size_t requested = Options["Threads"];
+
+ assert(requested > 0);
+
+ // If zero (default) then set best minimum split depth automatically
+ if (!minimumSplitDepth)
+ minimumSplitDepth = requested < 8 ? 4 * ONE_PLY : 7 * ONE_PLY;
+
+ while (size() < requested)
+ push_back(new_thread<Thread>());
+
+ while (size() > requested)
+ {
+ delete_thread(back());
+ pop_back();
+ }
+}
+
+
+// ThreadPool::available_slave() tries to find an idle thread which is available
+// as a slave for the thread 'master'.
+
+Thread* ThreadPool::available_slave(const Thread* master) const {
+
+ for (Thread* th : *this)
+ if (th->available_to(master))
+ return th;
+
+ return nullptr;
+}
+
+
+// ThreadPool::wait_for_think_finished() waits for main thread to finish the search