Esempio n. 1
0
            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);
            }