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,
+ bool split(const Position& pos, SearchStack* ss, int ply, Value* alpha, const Value beta, Value* bestValue,
const Value futilityValue, Depth depth, int* moves, MovePicker* mp, int master, bool pvNode);
private:
// Wake up sleeping threads
TM.wake_sleeping_threads();
- for (int i = 1; i < TM.active_threads(); i++)
- assert(TM.thread_is_available(i, 0));
-
// Set thinking time
int myTime = time[side_to_move];
int myIncrement = increment[side_to_move];
&& TM.available_thread_exists(threadID)
&& !AbortSearch
&& !TM.thread_should_stop(threadID)
- && TM.split(pos, ss, ply, &alpha, &beta, &bestValue, VALUE_NONE,
+ && TM.split(pos, ss, ply, &alpha, beta, &bestValue, VALUE_NONE,
depth, &moveCount, &mp, threadID, true))
break;
}
&& TM.available_thread_exists(threadID)
&& !AbortSearch
&& !TM.thread_should_stop(threadID)
- && TM.split(pos, ss, ply, &beta, &beta, &bestValue, futilityValue, //FIXME: SMP & futilityValue
+ && TM.split(pos, ss, ply, NULL, beta, &bestValue, futilityValue, //FIXME: SMP & futilityValue
depth, &moveCount, &mp, threadID, false))
break;
}
// If we are not thinking, wait for a condition to be signaled
// instead of wasting CPU time polling for work.
while ( threadID != 0
- && !AllThreadsShouldExit
&& (AllThreadsShouldSleep || threadID >= ActiveThreads))
{
threads[threadID].state = THREAD_SLEEPING;
#if !defined(_MSC_VER)
pthread_mutex_lock(&WaitLock);
- pthread_cond_wait(&WaitCond, &WaitLock);
+ if (AllThreadsShouldSleep || threadID >= ActiveThreads)
+ pthread_cond_wait(&WaitCond, &WaitLock);
pthread_mutex_unlock(&WaitLock);
#else
WaitForSingleObject(SitIdleEvent[threadID], INFINITE);
#endif
- // State is already changed by wake_sleeping_threads()
- assert(threads[threadID].state == THREAD_AVAILABLE || threadID >= ActiveThreads);
}
+ // If thread has just woken up, mark it as available
+ if (threads[threadID].state == THREAD_SLEEPING)
+ threads[threadID].state = THREAD_AVAILABLE;
+
// If this thread has been assigned work, launch a search
if (threads[threadID].state == THREAD_WORKISWAITING)
{
// finished their work at this split point, return from the idle loop.
if (waitSp != NULL && waitSp->cpus == 0)
{
- assert( threads[threadID].state == THREAD_AVAILABLE
- || threads[threadID].state == THREAD_SEARCHING);
+ assert(threads[threadID].state == THREAD_AVAILABLE);
threads[threadID].state = THREAD_SEARCHING;
return;
// splitPoint->cpus becomes 0), split() returns true.
bool ThreadsManager::split(const Position& p, SearchStack* sstck, int ply,
- Value* alpha, Value* beta, Value* bestValue, const Value futilityValue,
+ Value* alpha, const Value beta, Value* bestValue, const Value futilityValue,
Depth depth, int* moves, MovePicker* mp, int master, bool pvNode) {
assert(p.is_ok());
assert(sstck != NULL);
assert(ply >= 0 && ply < PLY_MAX);
assert(*bestValue >= -VALUE_INFINITE && *bestValue <= *alpha);
- assert(!pvNode || *alpha < *beta);
- assert(*beta <= VALUE_INFINITE);
+ assert(!pvNode || *alpha < beta);
+ assert(beta <= VALUE_INFINITE);
assert(depth > Depth(0));
assert(master >= 0 && master < ActiveThreads);
assert(ActiveThreads > 1);
splitPoint->stopRequest = false;
splitPoint->ply = ply;
splitPoint->depth = depth;
- splitPoint->alpha = pvNode ? *alpha : (*beta - 1);
- splitPoint->beta = *beta;
+ splitPoint->alpha = pvNode ? *alpha : beta - 1;
+ splitPoint->beta = beta;
splitPoint->pvNode = pvNode;
splitPoint->bestValue = *bestValue;
splitPoint->futilityValue = futilityValue;
if (pvNode)
*alpha = splitPoint->alpha;
- *beta = splitPoint->beta;
*bestValue = splitPoint->bestValue;
threads[master].activeSplitPoints--;
threads[master].splitPoint = splitPoint->parent;
return;
for (int i = 1; i < ActiveThreads; i++)
- {
assert(threads[i].state == THREAD_SLEEPING);
- threads[i].state = THREAD_AVAILABLE;
- }
-
#if !defined(_MSC_VER)
pthread_mutex_lock(&WaitLock);
pthread_cond_broadcast(&WaitCond);