int ActiveThreads;
volatile bool AllThreadsShouldExit;
Thread threads[MAX_THREADS];
- Lock MPLock, WaitLock;
+ Lock MPLock;
WaitCondition WaitCond[MAX_THREADS];
};
init_eval(ThreadsMgr.active_threads());
}
- // Wake up needed threads
- for (int i = 1; i < newActiveThreads; i++)
- ThreadsMgr.wake_sleeping_thread(i);
-
// Set thinking time
int myTime = time[pos.side_to_move()];
int myIncrement = increment[pos.side_to_move()];
if (UseLogFile)
LogFile.close();
- // This makes all the threads to go to sleep
- ThreadsMgr.set_active_threads(1);
-
return !Quit;
}
// If we are not thinking, wait for a condition to be signaled
// instead of wasting CPU time polling for work.
while ( threadID >= ActiveThreads
- || threads[threadID].state == THREAD_INITIALIZING)
+ || threads[threadID].state == THREAD_INITIALIZING
+ || (!sp && threads[threadID].state == THREAD_AVAILABLE))
{
assert(!sp);
assert(threadID != 0);
if (AllThreadsShouldExit)
break;
- threads[threadID].state = THREAD_AVAILABLE;
+ lock_grab(&MPLock);
-#if !defined(_MSC_VER)
- lock_grab(&WaitLock);
- if (threadID >= ActiveThreads)
- pthread_cond_wait(&WaitCond[threadID], &WaitLock);
- lock_release(&WaitLock);
-#else
- WaitForSingleObject(WaitCond[threadID], INFINITE);
-#endif
+ // Retest condition under lock protection
+ if (!( threadID >= ActiveThreads
+ || threads[threadID].state == THREAD_INITIALIZING
+ || (!sp && threads[threadID].state == THREAD_AVAILABLE)))
+ {
+ lock_release(&MPLock);
+ continue;
+ }
+
+ // Put thread to sleep
+ threads[threadID].state = THREAD_AVAILABLE;
+ cond_wait(&WaitCond[threadID], &MPLock);
+ lock_release(&MPLock);
}
// If this thread has been assigned work, launch a search
// Initialize global locks
lock_init(&MPLock);
- lock_init(&WaitLock);
for (i = 0; i < MAX_THREADS; i++)
-#if !defined(_MSC_VER)
- pthread_cond_init(&WaitCond[i], NULL);
-#else
- WaitCond[i] = CreateEvent(0, FALSE, FALSE, 0);
-#endif
+ cond_init(&WaitCond[i]);
// Initialize splitPoints[] locks
for (i = 0; i < MAX_THREADS; i++)
for (int j = 0; j < MAX_ACTIVE_SPLIT_POINTS; j++)
lock_destroy(&(threads[i].splitPoints[j].lock));
- lock_destroy(&WaitLock);
lock_destroy(&MPLock);
// Now we can safely destroy the wait conditions
assert(i == master || threads[i].state == THREAD_BOOKED);
threads[i].state = THREAD_WORKISWAITING; // This makes the slave to exit from idle_loop()
+ if (i != master)
+ wake_sleeping_thread(i);
}
// Everything is set up. The master thread enters the idle loop, from
void ThreadsManager::wake_sleeping_thread(int threadID) {
- assert(threadID > 0);
- assert(threads[threadID].state == THREAD_AVAILABLE);
-
-#if !defined(_MSC_VER)
- pthread_mutex_lock(&WaitLock);
- pthread_cond_signal(&WaitCond[threadID]);
- pthread_mutex_unlock(&WaitLock);
-#else
- SetEvent(WaitCond[threadID]);
-#endif
+ lock_grab(&MPLock);
+ cond_signal(&WaitCond[threadID]);
+ lock_release(&MPLock);
}