-void ThreadsManager::split(Position& pos, SearchStack* ss, Value* alpha, const Value beta,
- Value* bestValue, Depth depth, Move threatMove,
- int moveCount, MovePicker* mp, bool pvNode) {
- assert(pos.is_ok());
- assert(*bestValue >= -VALUE_INFINITE);
- assert(*bestValue <= *alpha);
- assert(*alpha < beta);
- assert(beta <= VALUE_INFINITE);
- assert(depth > DEPTH_ZERO);
- assert(pos.thread() >= 0 && pos.thread() < activeThreads);
- assert(activeThreads > 1);
-
- int i, master = pos.thread();
- Thread& masterThread = threads[master];
-
- lock_grab(&mpLock);
-
- // If no other thread is available to help us, or if we have too many
- // active split points, don't split.
- if ( !available_thread_exists(master)
- || masterThread.activeSplitPoints >= MAX_ACTIVE_SPLIT_POINTS)
- {
- lock_release(&mpLock);
- return;
- }
-
- // Pick the next available split point object from the split point stack
- SplitPoint& splitPoint = masterThread.splitPoints[masterThread.activeSplitPoints++];
-
- // Initialize the split point object
- splitPoint.parent = masterThread.splitPoint;
- splitPoint.master = master;
- splitPoint.betaCutoff = false;
- splitPoint.depth = depth;
- splitPoint.threatMove = threatMove;
- splitPoint.alpha = *alpha;
- splitPoint.beta = beta;
- splitPoint.pvNode = pvNode;
- splitPoint.bestValue = *bestValue;
- splitPoint.mp = mp;
- splitPoint.moveCount = moveCount;
- splitPoint.pos = &pos;
- splitPoint.nodes = 0;
- splitPoint.ss = ss;
- for (i = 0; i < activeThreads; i++)
- splitPoint.slaves[i] = 0;
-
- masterThread.splitPoint = &splitPoint;
-
- // If we are here it means we are not available
- assert(masterThread.state != THREAD_AVAILABLE);
-
- int workersCnt = 1; // At least the master is included
-
- // Allocate available threads setting state to THREAD_BOOKED
- for (i = 0; !Fake && i < activeThreads && workersCnt < maxThreadsPerSplitPoint; i++)
- if (thread_is_available(i, master))
+void Thread::split(Position& pos, const Stack* ss, Value alpha, Value beta, Value* bestValue,
+ Move* bestMove, Depth depth, int moveCount,
+ MovePicker* movePicker, int nodeType, bool cutNode) {
+
+ assert(pos.pos_is_ok());
+ assert(-VALUE_INFINITE < *bestValue && *bestValue <= alpha && alpha < beta && beta <= VALUE_INFINITE);
+ assert(depth >= Threads.minimumSplitDepth);
+ assert(searching);
+ assert(splitPointsSize < MAX_SPLITPOINTS_PER_THREAD);
+
+ // Pick the next available split point from the split point stack
+ SplitPoint& sp = splitPoints[splitPointsSize];
+
+ sp.masterThread = this;
+ sp.parentSplitPoint = activeSplitPoint;
+ sp.slavesMask = 0, sp.slavesMask.set(idx);
+ sp.depth = depth;
+ sp.bestValue = *bestValue;
+ sp.bestMove = *bestMove;
+ sp.alpha = alpha;
+ sp.beta = beta;
+ sp.nodeType = nodeType;
+ sp.cutNode = cutNode;
+ sp.movePicker = movePicker;
+ sp.moveCount = moveCount;
+ sp.pos = &pos;
+ sp.nodes = 0;
+ sp.cutoff = false;
+ sp.ss = ss;
+
+ // Try to allocate available threads and ask them to start searching setting
+ // 'searching' flag. This must be done under lock protection to avoid concurrent
+ // allocation of the same slave by another master.
+ Threads.mutex.lock();
+ sp.mutex.lock();
+
+ ++splitPointsSize;
+ activeSplitPoint = &sp;
+ activePosition = NULL;
+
+ if (!Fake)
+ for (Thread* slave; (slave = Threads.available_slave(this)) != NULL; )