+ delete timer;
+ lock_destroy(splitLock);
+ cond_destroy(sleepCond);
+}
+
+
+// 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 in advance all possible
+// threads, with included pawns and material tables, if only few are used.
+
+void ThreadsManager::read_uci_options() {
+
+ maxThreadsPerSplitPoint = Options["Max Threads per Split Point"];
+ minimumSplitDepth = Options["Min Split Depth"] * ONE_PLY;
+ useSleepingThreads = Options["Use Sleeping Threads"];
+ int requested = Options["Threads"];
+
+ assert(requested > 0);
+
+ while (size() < requested)
+ threads.push_back(new Thread(&Thread::idle_loop));
+
+ while (size() > requested)
+ {
+ delete threads.back();
+ threads.pop_back();
+ }
+}
+
+
+// wake_up() is called before a new search to start the threads that are waiting
+// on the sleep condition and to reset maxPly. When useSleepingThreads is set
+// threads will be woken up at split time.
+
+void ThreadsManager::wake_up() const {
+
+ for (int i = 0; i < size(); i++)
+ {
+ threads[i]->maxPly = 0;
+
+ if (!useSleepingThreads)
+ threads[i]->wake_up();
+ }
+}
+
+
+// sleep() is called after the search finishes to ask all the threads but the
+// main one to go waiting on a sleep condition.
+
+void ThreadsManager::sleep() const {
+
+ for (int i = 1; i < size(); i++) // Main thread will go to sleep by itself
+ threads[i]->do_sleep = true; // to avoid a race with start_searching()