// Multi-threads related variables
Depth MinimumSplitDepth;
int MaxThreadsPerSplitPoint;
- bool UseSleepingMaster;
ThreadsManager ThreadsMgr;
// Node counters, used only by thread[0] but try to keep in different cache
MaxThreadsPerSplitPoint = Options["Maximum Number of Threads per Split Point"].value<int>();
MultiPV = Options["MultiPV"].value<int>();
UseLogFile = Options["Use Search Log"].value<bool>();
- UseSleepingMaster = Options["Use Sleeping Master"].value<bool>();
if (UseLogFile)
LogFile.open(Options["Search Log Filename"].value<std::string>().c_str(), std::ios::out | std::ios::app);
int t = current_search_time();
// Poll for input
- if (Bioskey())
+ if (data_available())
{
// We are line oriented, don't read single chars
std::string command;
assert(threadID >= 0 && threadID < MAX_THREADS);
- int i;
- bool allFinished = false;
-
while (true)
{
// Slave threads can exit as soon as AllThreadsShouldExit raises,
// instead of wasting CPU time polling for work.
while ( threadID >= ActiveThreads
|| threads[threadID].state == THREAD_INITIALIZING
- || (threads[threadID].state == THREAD_AVAILABLE && (!sp || UseSleepingMaster)))
+ || (!sp && threads[threadID].state == THREAD_AVAILABLE))
{
- lock_grab(&MPLock);
+ assert(!sp);
+ assert(threadID != 0);
+
+ if (AllThreadsShouldExit)
+ break;
- // Test with lock held to avoid races with wake_sleeping_thread()
- for (i = 0; sp && i < ActiveThreads && !sp->slaves[i]; i++) {}
- allFinished = (i == ActiveThreads);
+ lock_grab(&MPLock);
- // Retest sleep conditions under lock protection
- if ( AllThreadsShouldExit
- || allFinished
- || !( threadID >= ActiveThreads
- || threads[threadID].state == THREAD_INITIALIZING
- || (threads[threadID].state == THREAD_AVAILABLE && (!sp || UseSleepingMaster))))
+ // Retest condition under lock protection
+ if (!( threadID >= ActiveThreads
+ || threads[threadID].state == THREAD_INITIALIZING
+ || (!sp && threads[threadID].state == THREAD_AVAILABLE)))
{
lock_release(&MPLock);
- break;
+ continue;
}
// Put thread to sleep
assert(threads[threadID].state == THREAD_SEARCHING);
threads[threadID].state = THREAD_AVAILABLE;
-
- // 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.
- if (UseSleepingMaster && threadID != tsp->master && threads[tsp->master].state == THREAD_AVAILABLE)
- wake_sleeping_thread(tsp->master);
}
// If this thread is the master of a split point and all slaves have
// finished their work at this split point, return from the idle loop.
- for (i = 0; sp && i < ActiveThreads && !sp->slaves[i]; i++) {}
- allFinished = (i == ActiveThreads);
+ int i = 0;
+ for ( ; sp && i < ActiveThreads && !sp->slaves[i]; i++) {}
- if (allFinished)
+ if (i == ActiveThreads)
{
// Because sp->slaves[] is reset under lock protection,
// be sure sp->lock has been released before to return.
if (!ok)
{
cout << "Failed to create thread number " << i << endl;
- Application::exit_with_failure();
+ exit(EXIT_FAILURE);
}
// Wait until the thread has finished launching and is gone to sleep
// Initialize the split point object
splitPoint.parent = masterThread.splitPoint;
- splitPoint.master = master;
splitPoint.stopRequest = false;
splitPoint.ply = ply;
splitPoint.depth = depth;