Beispiel #1
0
        public void dbgDisplayIndex(Scheduler dbgScheduler)
        {
            List<WaitRecord> waitRecords = new List<WaitRecord>(this.waitingVerbs.Values);
            for (int i = 0; i < waitRecords.Count(); i++)
            {
                WaitRecord wr = waitRecords[i];
                List<int> depNums = new List<int>();
                List<BuildObject> unknownDeps = new List<BuildObject>();
                List<string> unscheduledDeps = new List<string>();
                foreach (BuildObject dep in wr.knownDeps)
                {
                    IVerb depOnVerb = dbgScheduler.getParent(dep);
                    if (depOnVerb == null)
                    {
                        unknownDeps.Add(dep);
                    }
                    else if (!this.waitingVerbs.ContainsKey(depOnVerb))
                    {
                        unscheduledDeps.Add(
                            string.Format(
                                "{0} waiting on {1} {2}",
                                dep,
                                depOnVerb,
                                dbgScheduler.dbgGetVerbStatus(depOnVerb)));
                    }
                    else
                    {
                        WaitRecord depWr = this.waitingVerbs[depOnVerb];
                        depNums.Add(waitRecords.IndexOf(depWr));
                    }
                }

                Logger.WriteLine(
                    string.Format(
                        "{0}. {1} waits on ({2}), {3} unknown, {4} unscheduled",
                        i,
                        wr.verb,
                        string.Join(",", depNums),
                        unknownDeps.Count(),
                        unscheduledDeps.Count()));

                this.dbgPreview("Unknown", unknownDeps.Select(it => it.ToString()), 3);
                this.dbgPreview("Unscheduled", unscheduledDeps, 20);
            }
        }
Beispiel #2
0
 /// <summary>
 /// Reports current progress to the scheduler.
 /// </summary>
 /// <param name="dbgScheduler">The scheduler.</param>
 private void dbgUpdateProgress(Scheduler dbgScheduler)
 {
     dbgScheduler.dbgUpdateProgress(this.runnableVerbs.Count(), this.runningTasks);
 }
Beispiel #3
0
        /// <summary>
        /// Called by the scheduler to run the verbs which can be run.
        /// </summary>
        /// <param name="dbgScheduler">
        /// The scheduler calling us (for debugging).
        /// </param>
        /// <returns>A list of tasks (verb runs) that have completed.</returns>
        public List<TaskCompletion> scheduleAndWait(Scheduler dbgScheduler)
        {
            while (true)
            {
                List<TaskCompletion> taskCompletionBatch;

                // Loop until something gets done.
                while (true)
                {
                    this.dbgUpdateProgress(dbgScheduler);

                    this.taskCompletionsLock.AcquireWriterLock(Timeout.Infinite);
                    taskCompletionBatch = this.taskCompletions;
                    this.taskCompletions = new List<TaskCompletion>();
                    this.completionEvent.Reset();
                    this.taskCompletionsLock.ReleaseLock();

                    bool canProcessCompletedTask = taskCompletionBatch.Count() > 0;
                    bool canStartNewTask = (this.runnableVerbs.Count() > 0) && (this.jobParallelism > this.runningTasks);
                    if (!(canProcessCompletedTask || canStartNewTask))
                    {
                        // Nothing will change until a running task finishes. Snooze.
                        if (this.runningTasks == 0)
                        {
                            dbgScheduler.dbgDumpWaitIndex();
                            Util.Assert(false);
                        }

                        this.completionEvent.WaitOne();
                        continue;
                    }

                    break;
                }

                int numCompletedTasks = taskCompletionBatch.Count();
                Say(string.Format("marking {0} tasks completing; runningTasks now {1}", numCompletedTasks, this.runningTasks));
                this.runningTasks -= numCompletedTasks;

                int idleTasks = this.jobParallelism - this.runningTasks;

                if (idleTasks > 0)
                {
                    this.verbStateLock.AcquireWriterLock(Timeout.Infinite);

                    List<IVerb> runnableVerbsBatch = new List<IVerb>(this.runnableVerbs);
                    Say("AsyncRunner toposorting " + runnableVerbsBatch.Count() + " verbs");
                    runnableVerbsBatch.Sort(this.verbToposorter);

                    ////Logger.WriteLine(string.Format("verbToposorter({0}) yields:", runnableVerbsBatch.Count));
                    ////foreach (IVerb verb in runnableVerbsBatch)
                    ////{
                    ////    Logger.WriteLine("  " + verb.ToString() + " @ "+ this.verbToposorter.getDepth(verb));
                    ////}

                    for (int i = 0; i < idleTasks && i < runnableVerbsBatch.Count(); i++)
                    {
                        IVerb verb = runnableVerbsBatch[i];
                        this.startTask(verb);
                        this.runnableVerbs.Remove(verb);
                        this.startedVerbs.Add(verb);
                    }

                    this.verbStateLock.ReleaseLock();
                }

                if (taskCompletionBatch.Count() > 0 || this.runningTasks == 0)
                {
                    // Something actually got done, so the caller could meaningfully schedule more work.
                    return taskCompletionBatch;
                }
            }
        }
Beispiel #4
0
 /// <summary>
 /// Reports current progress to the scheduler.
 /// </summary>
 /// <param name="dbgScheduler">The scheduler.</param>
 private void dbgUpdateProgress(Scheduler dbgScheduler)
 {
     dbgScheduler.dbgUpdateProgress(this.runnableVerbs.Count(), this.runningTasks);
 }
Beispiel #5
0
        /// <summary>
        /// Called by the scheduler to run the verbs which can be run.
        /// </summary>
        /// <param name="dbgScheduler">
        /// The scheduler calling us (for debugging).
        /// </param>
        /// <returns>A list of tasks (verb runs) that have completed.</returns>
        public List <TaskCompletion> scheduleAndWait(Scheduler dbgScheduler)
        {
            while (true)
            {
                List <TaskCompletion> taskCompletionBatch;

                // Loop until something gets done.
                while (true)
                {
                    this.dbgUpdateProgress(dbgScheduler);

                    this.taskCompletionsLock.AcquireWriterLock(Timeout.Infinite);
                    taskCompletionBatch  = this.taskCompletions;
                    this.taskCompletions = new List <TaskCompletion>();
                    this.completionEvent.Reset();
                    this.taskCompletionsLock.ReleaseLock();

                    bool canProcessCompletedTask = taskCompletionBatch.Count() > 0;
                    bool canStartNewTask         = (this.runnableVerbs.Count() > 0) && (this.jobParallelism > this.runningTasks);
                    if (!(canProcessCompletedTask || canStartNewTask))
                    {
                        // Nothing will change until a running task finishes. Snooze.
                        if (this.runningTasks == 0)
                        {
                            dbgScheduler.dbgDumpWaitIndex();
                            Util.Assert(false);
                        }

                        this.completionEvent.WaitOne();
                        continue;
                    }

                    break;
                }

                int numCompletedTasks = taskCompletionBatch.Count();
                Say(string.Format("marking {0} tasks completing; runningTasks now {1}", numCompletedTasks, this.runningTasks));
                this.runningTasks -= numCompletedTasks;

                int idleTasks = this.jobParallelism - this.runningTasks;

                if (idleTasks > 0)
                {
                    this.verbStateLock.AcquireWriterLock(Timeout.Infinite);

                    List <IVerb> runnableVerbsBatch = new List <IVerb>(this.runnableVerbs);
                    Say("AsyncRunner toposorting " + runnableVerbsBatch.Count() + " verbs");
                    runnableVerbsBatch.Sort(this.verbToposorter);

                    ////Logger.WriteLine(string.Format("verbToposorter({0}) yields:", runnableVerbsBatch.Count));
                    ////foreach (IVerb verb in runnableVerbsBatch)
                    ////{
                    ////    Logger.WriteLine("  " + verb.ToString() + " @ "+ this.verbToposorter.getDepth(verb));
                    ////}

                    for (int i = 0; i < idleTasks && i < runnableVerbsBatch.Count(); i++)
                    {
                        IVerb verb = runnableVerbsBatch[i];
                        this.startTask(verb);
                        this.runnableVerbs.Remove(verb);
                        this.startedVerbs.Add(verb);
                    }

                    this.verbStateLock.ReleaseLock();
                }

                if (taskCompletionBatch.Count() > 0 || this.runningTasks == 0)
                {
                    // Something actually got done, so the caller could meaningfully schedule more work.
                    return(taskCompletionBatch);
                }
            }
        }
Beispiel #6
0
        void main(string[] cmdline_args)
        {
            string[] all_args = fetchConfigArgs().Concat(cmdline_args).ToArray();
            logNubuildInvocation(all_args);
            try
            {
                parseArgs(all_args);
            }
            catch (UserError err)
            {
                usage(err.Message);
            }

            Scheduler scheduler = new Scheduler(jobParallelism, GetItemCache(), rejectCachedFailures);

            scheduler.addTargetVerbs(verbs);



            scheduler.parallelSchedule();



            IEnumerable <BuildObject> targets = scheduler.getTargets();

            BuildObject outputTarget = null;

            if (targets.Count() > 0)
            {
                outputTarget = targets.First();
            }
            else
            {
                Logger.WriteLine("No targets requested.");
            }
            if (targets.Count() > 1)
            {
                //- TODO need a better story for relaying failure results. Right now
                //- they get stuck in the results cache, but don't appear where we
                //- can find them. Emit to a log, or to files in nuobj?
                Logger.WriteLine("Multiple targets build. First result follows.");
            }
            if (outputTarget != null)
            {
                Disposition d = scheduler.getObjectDisposition(outputTarget);
                if (d is Fresh)
                {
                    ASCIIPresentater ascii = new ASCIIPresentater();
                    IVerb            verb  = scheduler.getParent(outputTarget);
                    verb.getPresentation().format(ascii);
                    Logger.Write(ascii.ToString());

                    if (this.html_output != null)
                    {
                        HTMLPresentater html = new HTMLPresentater();
                        verb.getPresentation().format(html);

                        try
                        {
                            using (StreamWriter sw = new StreamWriter(this.html_output))
                            {
                                sw.Write(html.ToString());
                            }
                        }
                        catch (Exception e)
                        {
                            Logger.WriteLine("Failed to write html output to file: " + html_output);
                            Logger.WriteLine("Exception was: " + e);
                        }
                    }
                }
                else
                {
                    Logger.WriteLine("Build failed.");
                    foreach (string msg in d.getMessages())
                    {
                        Logger.Write(msg);
                    }
                }
            }
            else if (targets.Count() == 0)
            {
                Logger.WriteLine("No targets requested.");
            }
            else
            {
                Logger.WriteLine("Multiple targets built. Look for results in nuobj/.");
            }

            //- -
            //- We have to explicitly ask the BackgroundWorker thread to exit
            //- as it will prevent the process from exiting until it does.
            //- -
            this.backgroundWorker.StopWork();

            //- -
            //- Report what the background worker accomplished during this run.
            //- -
            this.backgroundWorker.WaitForCompletion();
            Logger.WriteLine(String.Format("Background Worker completed {0} work items out of {1} queued.",
                                           this.backgroundWorker.GetWorkItemsPerformed,
                                           this.backgroundWorker.GetWorkItemsQueued));
            if (this.backgroundWorker.GetWorkItemsFailed != 0)
            {
                Logger.WriteLine(String.Format(
                                     "{0} work item procedures failed (threw an exception).",
                                     this.backgroundWorker.GetWorkItemsFailed));
            }
        }