private StatusKind ForkThreadNode(ForkNode forkNode, bool main) { var forkPredicateResult = (IForkPredicateResult)forkNode.PredicateResult; var startNode = (PredicateNode)forkNode.ExecutionPath.Nodes[forkNode.NodeIndex]; var threadParent = ForkThreadParent(); for (var i = 1; i >= 0; i--) { var predicateEntry = i == 0 ? forkPredicateResult.First : forkPredicateResult.Second; var predicateNode = _processResources.ForkPredicateNodePool.Get().Mount(predicateEntry); var predicateExecutionPath = _processResources.ForkExecutionPathPool.Get().Mount(startNode, predicateNode); predicateNode.CopyLookup(forkNode); if (startNode.ForkPathIndex == -1) { lock (startNode) { if (startNode.ForkPathIndex == -1) { _automata.RegisterExecutionPath(predicateExecutionPath); startNode.ForkPathIndex = predicateExecutionPath.Id; } else { predicateExecutionPath.Id = startNode.ForkPathIndex; } } } else { predicateExecutionPath.Id = startNode.ForkPathIndex; } predicateNode.ForkPathIndex = startNode.ForkPathIndex; var contextState = _currentThread.ContextState != null?Context.CloneContextStateInternal(_currentThread.ContextState) : null; var thread = new Thread(threadParent, forkNode, _currentThread.InstructionStream, _currentThread.InstructionPointer, contextState); thread.EnsureStartExecutionQueue(); thread.EnqueueStartPath(predicateExecutionPath); // ReSharper disable once ForCanBeConvertedToForeach for (var j = 0; j < forkNode.ForkExecutionPaths.Count; j++) { thread.EnqueueStartPath(forkNode.ForkExecutionPaths[j]); } _parallelThreads.PushRef(ref thread); } if (main) { _mainThread = _currentThread; } else { _currentThread.Dispose(this); } forkNode.Release(); return(StatusKind.Fork); }