1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-29 16:23:09 +00:00

Change thread API to use one wait condition per thread

This is the native way done in Windows and we will use it
for future work, so change Linux to do the same.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2010-10-17 07:55:57 +01:00
parent dcf2edfdea
commit 1fdb436e78

View file

@ -82,7 +82,7 @@ namespace {
bool available_thread_exists(int master) const; bool available_thread_exists(int master) const;
bool thread_is_available(int slave, int master) const; bool thread_is_available(int slave, int master) const;
bool thread_should_stop(int threadID) const; bool thread_should_stop(int threadID) const;
void wake_sleeping_threads(); void wake_sleeping_thread(int threadID);
void put_threads_to_sleep(); void put_threads_to_sleep();
void idle_loop(int threadID, SplitPoint* sp); void idle_loop(int threadID, SplitPoint* sp);
@ -100,7 +100,7 @@ namespace {
Lock MPLock, WaitLock; Lock MPLock, WaitLock;
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
pthread_cond_t WaitCond; pthread_cond_t WaitCond[MAX_THREADS];
#else #else
HANDLE SitIdleEvent[MAX_THREADS]; HANDLE SitIdleEvent[MAX_THREADS];
#endif #endif
@ -472,8 +472,9 @@ bool think(const Position& pos, bool infinite, bool ponder, int time[], int incr
init_eval(ThreadsMgr.active_threads()); init_eval(ThreadsMgr.active_threads());
} }
// Wake up sleeping threads // Wake up needed threads
ThreadsMgr.wake_sleeping_threads(); for (int i = 1; i < newActiveThreads; i++)
ThreadsMgr.wake_sleeping_thread(i);
// Set thinking time // Set thinking time
int myTime = time[pos.side_to_move()]; int myTime = time[pos.side_to_move()];
@ -2239,7 +2240,7 @@ split_point_start: // At split points actual search starts from here
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
lock_grab(&WaitLock); lock_grab(&WaitLock);
if (AllThreadsShouldSleep || threadID >= ActiveThreads) if (AllThreadsShouldSleep || threadID >= ActiveThreads)
pthread_cond_wait(&WaitCond, &WaitLock); pthread_cond_wait(&WaitCond[threadID], &WaitLock);
lock_release(&WaitLock); lock_release(&WaitLock);
#else #else
WaitForSingleObject(SitIdleEvent[threadID], INFINITE); WaitForSingleObject(SitIdleEvent[threadID], INFINITE);
@ -2313,10 +2314,10 @@ split_point_start: // At split points actual search starts from here
lock_init(&MPLock); lock_init(&MPLock);
lock_init(&WaitLock); lock_init(&WaitLock);
#if !defined(_MSC_VER)
pthread_cond_init(&WaitCond, NULL);
#else
for (i = 0; i < MAX_THREADS; i++) for (i = 0; i < MAX_THREADS; i++)
#if !defined(_MSC_VER)
pthread_cond_init(&WaitCond[i], NULL);
#else
SitIdleEvent[i] = CreateEvent(0, FALSE, FALSE, 0); SitIdleEvent[i] = CreateEvent(0, FALSE, FALSE, 0);
#endif #endif
@ -2364,14 +2365,15 @@ split_point_start: // At split points actual search starts from here
void ThreadsManager::exit_threads() { void ThreadsManager::exit_threads() {
ActiveThreads = MAX_THREADS; // Wake up all the threads AllThreadsShouldExit = true; // Let the woken up threads to exit idle_loop()
AllThreadsShouldExit = true; // Let the woken up threads to exit idle_loop() ActiveThreads = MAX_THREADS; // Avoid any woken up thread comes back to sleep
AllThreadsShouldSleep = true; // Avoid an assert in wake_sleeping_threads()
wake_sleeping_threads();
// Wait for thread termination // Wake up all the threads and waits for termination
for (int i = 1; i < MAX_THREADS; i++) for (int i = 1; i < MAX_THREADS; i++)
{
wake_sleeping_thread(i);
while (threads[i].state != THREAD_TERMINATED) {} while (threads[i].state != THREAD_TERMINATED) {}
}
// Now we can safely destroy the locks // Now we can safely destroy the locks
for (int i = 0; i < MAX_THREADS; i++) for (int i = 0; i < MAX_THREADS; i++)
@ -2562,28 +2564,23 @@ split_point_start: // At split points actual search starts from here
} }
// wake_sleeping_threads() wakes up all sleeping threads when it is time // wake_sleeping_thread() wakes up all sleeping threads when it is time
// to start a new search from the root. // to start a new search from the root.
void ThreadsManager::wake_sleeping_threads() { void ThreadsManager::wake_sleeping_thread(int threadID) {
assert(AllThreadsShouldSleep); assert(threadID > 0);
assert(ActiveThreads > 0); assert(threads[threadID].state == THREAD_SLEEPING);
AllThreadsShouldSleep = false; AllThreadsShouldSleep = false; // Avoid the woken up thread comes back to sleep
if (ActiveThreads == 1)
return;
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
pthread_mutex_lock(&WaitLock); pthread_mutex_lock(&WaitLock);
pthread_cond_broadcast(&WaitCond); pthread_cond_signal(&WaitCond[threadID]);
pthread_mutex_unlock(&WaitLock); pthread_mutex_unlock(&WaitLock);
#else #else
for (int i = 1; i < MAX_THREADS; i++) SetEvent(SitIdleEvent[threadID]);
SetEvent(SitIdleEvent[i]);
#endif #endif
} }
@ -2593,7 +2590,7 @@ split_point_start: // At split points actual search starts from here
void ThreadsManager::put_threads_to_sleep() { void ThreadsManager::put_threads_to_sleep() {
assert(!AllThreadsShouldSleep); assert(!AllThreadsShouldSleep || ActiveThreads == 1);
// This makes the threads to go to sleep // This makes the threads to go to sleep
AllThreadsShouldSleep = true; AllThreadsShouldSleep = true;