+
+ // ThreadsManager class is used to handle all the threads related stuff in search,
+ // init, starting, parking and, the most important, launching a slave thread at a
+ // split point are what this class does. All the access to shared thread data is
+ // done through this class, so that we avoid using global variables instead.
+
+ class ThreadsManager {
+ /* As long as the single ThreadsManager object is defined as a global we don't
+ need to explicitly initialize to zero its data members because variables with
+ static storage duration are automatically set to zero before enter main()
+ */
+ public:
+ void init_threads();
+ void exit_threads();
+
+ int active_threads() const { return ActiveThreads; }
+ void set_active_threads(int newActiveThreads) { ActiveThreads = newActiveThreads; }
+ void incrementNodeCounter(int threadID) { threads[threadID].nodes++; }
+ void incrementBetaCounter(Color us, Depth d, int threadID) { threads[threadID].betaCutOffs[us] += unsigned(d); }
+ void print_current_line(SearchStack ss[], int ply, int threadID);
+
+ void resetNodeCounters();
+ void resetBetaCounters();
+ int64_t nodes_searched() const;
+ void get_beta_counters(Color us, int64_t& our, int64_t& their) const;
+ bool available_thread_exists(int master) const;
+ bool thread_is_available(int slave, int master) const;
+ bool thread_should_stop(int threadID) const;
+ void wake_sleeping_threads();
+ void put_threads_to_sleep();
+ void idle_loop(int threadID, SplitPoint* waitSp);
+ bool split(const Position& pos, SearchStack* ss, int ply, Value* alpha, Value* beta, Value* bestValue,
+ const Value futilityValue, Depth depth, int* moves, MovePicker* mp, int master, bool pvNode);
+
+ private:
+ friend void poll();
+
+ int ActiveThreads;
+ volatile bool AllThreadsShouldExit, AllThreadsShouldSleep;
+ Thread threads[MAX_THREADS];
+ SplitPoint SplitPointStack[MAX_THREADS][ACTIVE_SPLIT_POINTS_MAX];
+
+ Lock MPLock, IOLock;
+
+#if !defined(_MSC_VER)
+ pthread_cond_t WaitCond;
+ pthread_mutex_t WaitLock;
+#else
+ HANDLE SitIdleEvent[MAX_THREADS];
+#endif
+
+ };
+
+
+ // RootMove struct is used for moves at the root at the tree. For each