static void Main()
        {
            DateTime time1 = DateTime.Now;

            s_channel = new Channel <int>();

            MicroThread t2 = new MicroThread(run2);

            t2.Start();

            MicroThread t3 = new MicroThread(run2);

            t3.Start();

            MicroThread t1 = new MicroThread(run1);

            t1.Start();

            Console.WriteLine("Starting producer/consumer test, loops {0}", s_loops);

            Scheduler.Run();

            DateTime time2 = DateTime.Now;

            Console.WriteLine("total {0}", res);
            Console.WriteLine("time {0}ms", (time2 - time1).TotalMilliseconds);
            Console.WriteLine("END");
        }
示例#2
0
        protected MicroThread[] TestBase(string testName, BaseTests baseTests, Func <Action, Task> asyncFunction, int parallelCount, MicroThreadFlags flags = MicroThreadFlags.None)
        {
            var scheduler    = new Scheduler();
            int completed    = 0;
            var microThreads = new MicroThread[parallelCount];

            // Run two microthreads at the same time
            for (int i = 0; i < parallelCount; ++i)
            {
                microThreads[i] = scheduler.Add(() => asyncFunction(() => { Interlocked.Increment(ref completed); CheckStackForSchedulerStep(); }), flags);
            }

            // Simulation of main loop
            for (int i = 0; i < 1000 && scheduler.MicroThreads.Count() > 0; ++i)
            {
                baseTests.SharedCounter = i;
                scheduler.Run();
                Thread.Sleep(10);
            }

            // Check both microthreads completed
            Assert.That(completed, Is.EqualTo(parallelCount));

            return(microThreads);
        }
        //static long s_totalYields = 0;

        static int Main(string[] args)
        {
            if (args.Length != 2)
            {
                Console.WriteLine("usage: YieldTest <numthreads> <numloops>");
                return(1);
            }

            s_threads = Int32.Parse(args[0]);
            s_loops   = Int32.Parse(args[1]);

            for (int i = 0; i < s_threads; i++)
            {
                MicroThread t = new MicroThread(Run);
                t.Start();
            }

            DateTime t1 = DateTime.Now;

            Scheduler.Run();

            DateTime t2 = DateTime.Now;
            TimeSpan ts = t2 - t1;

            //Console.WriteLine("Total yields {0}", s_totalYields);
            Console.WriteLine("{0} threads * {1} loops = {2} yields in {3:F2}s, {4:F0} yields/s", s_threads, s_loops, s_threads * s_loops,
                              ts.TotalSeconds, (s_threads * s_loops) / ts.TotalSeconds);

            /*
             * long mem = System.GC.GetTotalMemory(false);
             * Console.WriteLine("Mem {0:F2}M", mem / 1000000.0);
             */
            return(0);
        }
示例#4
0
 private void AddMicroThread(MicroThread microThread)
 {
     Dispatcher.BeginInvoke((Action) delegate
     {
         microThreads.Add(new MicroThreadViewModel(microThread));
     }, null);
 }
        static void Main(string[] args)
        {
            if (args.Length == 0 || args[0] == "server")
            {
                MicroThread pt = new MicroThread(ServerPrintRun);
                pt.Start();

                Server.s_bufferSize = s_blockSize;
                MicroThread t = new MicroThread(Server.ListenRun);
                t.Start();
                Scheduler.Run();
            }
            else
            {
                Console.WriteLine("Starting {0} threads, sending {1} {2} byte blocks", s_threads, s_blocks, s_blockSize);

                MicroThread pt = new MicroThread(ClientPrintRun);
                pt.Start();

                for (int i = 0; i < s_threads; i++)
                {
                    Client      c = new Client(s_blocks, s_blockSize);
                    MicroThread t = new MicroThread(c.Run);
                    t.Start();
                }

                DateTime t1 = DateTime.Now;
                Scheduler.Run();
                DateTime t2 = DateTime.Now;

                Console.WriteLine();
                Console.WriteLine("TOTAL {0} MB/s", (Client.s_totalBlocksSent / 1000.0 / 1000.0 * s_blockSize) / ((TimeSpan)(t2 - t1)).TotalSeconds);
            }
        }
        public void MicroThreadTest()
        {
            MicroThread microA = new MicroThread();
            MicroThread microB = new MicroThread();

            microA.MainThread.Mark();
            microA.MyThread.Mark();
            microB.MainThread.Mark();
            microB.MyThread.Mark();

            Assert.AreEqual(false, microA.Done);
            Assert.AreEqual(false, microB.Done);

            microA.DoWork(() =>
            {
                int count = 0;
                while (count < 100)
                {
                    ++count;
                    if (count % 10 == 0)
                    {
                        microA.Yield();
                    }
                }
            });

            MicroBJob jobB = new MicroBJob();

            jobB.MicroThread = microB;

            microB.DoWork(jobB.Work);

            Assert.AreEqual(false, microA.Done);
            Assert.AreEqual(false, microB.Done);

            int yields = 0;

            while (yields < 20)
            {
                if (!microA.Done)
                {
                    microA.Resume();
                }
                if (!microB.Done)
                {
                    microB.Resume();
                }
                if (microA.Done && microB.Done)
                {
                    break;
                }
                ++yields;
            }

            Assert.AreEqual(true, microA.Done);
            Assert.AreEqual(true, microB.Done);
            Assert.AreEqual(100, jobB.Count);
            Assert.AreEqual(9, yields);
        }
示例#7
0
        static void Main()
        {
            MicroThread t = new MicroThread(MainRun);

            t.Start();

            Scheduler.Run();
        }
示例#8
0
    static void Main()
    {
        MicroThread t1 = new MicroThread(Run1);
        MicroThread t2 = new MicroThread(Run2);

        t1.Start();
        t2.Start();
        Scheduler.Run();
    }
        public MicroThreadViewModel(MicroThread microThread)
        {
            if (microThread == null)
                throw new ArgumentNullException("microThread");

            if (microThread.Scheduler == null)
                throw new ArgumentException("Invalid Scheduler in MicroThread " + microThread.Id);

            this.microThread = microThread;

            // New MicroThread system doesn't have any PropertyChanged event yet.
            throw new NotImplementedException();
            //this.microThread.Scheduler.MicroThreadStateChanged += OnMicroThreadStateChanged;
        }
示例#10
0
        private void RetryableMatchEvent(EventBean theEvent, ICollection <FilterHandle> matches)
        {
            // Install lock backoff exception handler that retries the evaluation.
            try
            {
                _eventTypeIndex.MatchEvent(theEvent, matches);
            }
            catch (FilterLockBackoffException ex)
            {
                // retry on lock back-off
                // lock-backoff may occur when stateful evaluations take place such as bool expressions that are subqueries
                // statements that contain subqueries in pattern filter expression can themselves modify filters, leading to a theoretically possible deadlock
                long delayNs = 10;
                while (true)
                {
                    try
                    {
                        // yield
                        try
                        {
                            Thread.Sleep(0);
                        }
                        catch (ThreadInterruptedException e)
                        {
                            Thread.CurrentThread.Interrupt();
                        }

                        // delay
                        MicroThread.SleepNano(delayNs);
                        if (delayNs < 1000000000)
                        {
                            delayNs = delayNs * 2;
                        }

                        // evaluate
                        matches.Clear();
                        _eventTypeIndex.MatchEvent(theEvent, matches);
                        break;
                    }
                    catch (FilterLockBackoffException ex2)
                    {
                        // retried
                    }
                }
            }
        }
示例#11
0
        static void MainRun()
        {
            int started = 0;

            while (true)
            {
                if (Scheduler.ThreadCount < 100)
                {
                    MicroThread t = new MicroThread(Work);
                    t.Start();
                    started++;
                }

                Console.WriteLine("Threads {0}, started {1}", Scheduler.ThreadCount, started);

                Scheduler.Yield();
            }
        }
示例#12
0
        public MicroThreadViewModel(MicroThread microThread)
        {
            if (microThread == null)
            {
                throw new ArgumentNullException("microThread");
            }

            if (microThread.Scheduler == null)
            {
                throw new ArgumentException("Invalid Scheduler in MicroThread " + microThread.Id);
            }

            this.microThread = microThread;

            // New MicroThread system doesn't have any PropertyChanged event yet.
            throw new NotImplementedException();
            //this.microThread.Scheduler.MicroThreadStateChanged += OnMicroThreadStateChanged;
        }
        static void Main()
        {
            DateTime time1 = DateTime.Now;

            MicroThread t = new MicroThread(loop);

            t.Start();

            Console.WriteLine("Starting yield test, loops {0}", s_loops);

            Scheduler.Run();

            DateTime time2 = DateTime.Now;

            Console.WriteLine("END {0}", res);

            TimeSpan ts = time2 - time1;

            Console.WriteLine("time {0}ms", ts.TotalMilliseconds);
        }
        static int Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("usage: SleepTest <numthreads>");
                return(1);
            }

            s_threads = Int32.Parse(args[0]);

            for (int i = 0; i < s_threads; i++)
            {
                Sleeper     s = new Sleeper();
                MicroThread t = new MicroThread(s.Run);
                t.Start();
            }

            Scheduler.Run();

            return(0);
        }
示例#15
0
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            MyForm f = new MyForm();

            f.Show();

            new MicroThread(WindowRun).Start();

            for (int i = 0; i < 200; i++)
            {
                Dot         d = new Dot(i, 0, Color.Red, f);
                MicroThread t = new MicroThread(d.Run);
                t.Start();
            }

            Scheduler.Run();

            //			Application.Run(f);
        }
示例#16
0
        public static void ListenRun()
        {
            MicroSocket listenSocket = new MicroSocket();

            IPEndPoint ep = new IPEndPoint(IPAddress.Any, 12345);

            listenSocket.Bind(ep);
            listenSocket.Listen(10);

            while (true)
            {
                MicroSocket socket = listenSocket.Accept();

                //Console.WriteLine("Accepted a new socket");
                //Console.Write(".");

                s_connectedSockets++;

                Server      server = new Server(socket);
                MicroThread t      = new MicroThread(server.SocketRun);
                t.Start();
            }
        }
示例#17
0
        private BuildResultCode BuildSlave()
        {
            // Mount build path
            ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(builderOptions.BuildDirectory);

            VirtualFileSystem.CreateDirectory(VirtualFileSystem.ApplicationDatabasePath);

            // Open WCF channel with master builder
            var namedPipeBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
            {
                SendTimeout = TimeSpan.FromSeconds(300.0), MaxReceivedMessageSize = int.MaxValue
            };
            var processBuilderRemote = ChannelFactory <IProcessBuilderRemote> .CreateChannel(namedPipeBinding, new EndpointAddress(builderOptions.SlavePipe));

            try
            {
                RegisterRemoteLogger(processBuilderRemote);

                // Make sure to laod all assemblies containing serializers
                // TODO: Review how costly it is to do so, and possibily find a way to restrict what needs to be loaded (i.e. only app plugins?)
                foreach (var assemblyLocation in processBuilderRemote.GetAssemblyContainerLoadedAssemblies())
                {
                    AssemblyContainer.Default.LoadAssemblyFromPath(assemblyLocation, builderOptions.Logger);
                }

                // Create scheduler
                var scheduler = new Scheduler();

                var status = ResultStatus.NotProcessed;

                // Schedule command
                string buildPath = builderOptions.BuildDirectory;

                Builder.OpenObjectDatabase(buildPath, VirtualFileSystem.ApplicationDatabaseIndexName);

                var         logger      = builderOptions.Logger;
                MicroThread microthread = scheduler.Add(async() =>
                {
                    // Deserialize command and parameters
                    Command command = processBuilderRemote.GetCommandToExecute();

                    // Run command
                    var inputHashes    = FileVersionTracker.GetDefault();
                    var builderContext = new BuilderContext(inputHashes, null);

                    var commandContext = new RemoteCommandContext(processBuilderRemote, command, builderContext, logger);
                    MicrothreadLocalDatabases.MountDatabase(commandContext.GetOutputObjectsGroups());
                    command.PreCommand(commandContext);
                    status = await command.DoCommand(commandContext);
                    command.PostCommand(commandContext, status);

                    // Returns result to master builder
                    processBuilderRemote.RegisterResult(commandContext.ResultEntry);
                });

                while (true)
                {
                    scheduler.Run();

                    // Exit loop if no more micro threads
                    lock (scheduler.MicroThreads)
                    {
                        if (!scheduler.MicroThreads.Any())
                        {
                            break;
                        }
                    }

                    Thread.Sleep(0);
                }

                // Rethrow any exception that happened in microthread
                if (microthread.Exception != null)
                {
                    builderOptions.Logger.Fatal(microthread.Exception.ToString());
                    return(BuildResultCode.BuildError);
                }

                if (status == ResultStatus.Successful || status == ResultStatus.NotTriggeredWasSuccessful)
                {
                    return(BuildResultCode.Successful);
                }

                return(BuildResultCode.BuildError);
            }
            finally
            {
                // Close WCF channel
                // ReSharper disable SuspiciousTypeConversion.Global
                ((IClientChannel)processBuilderRemote).Close();
                // ReSharper restore SuspiciousTypeConversion.Global
            }
        }
示例#18
0
        private BuildResultCode BuildSlave()
        {
            // Mount build path
            ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(builderOptions.BuildDirectory);

            VirtualFileSystem.CreateDirectory(VirtualFileSystem.ApplicationDatabasePath);

            // Open ServiceWire Client Channel
            using (var client = new NpClient <IProcessBuilderRemote>(new NpEndPoint(builderOptions.SlavePipe), new StrideServiceWireSerializer()))
            {
                RegisterRemoteLogger(client);

                // Make sure to laod all assemblies containing serializers
                // TODO: Review how costly it is to do so, and possibily find a way to restrict what needs to be loaded (i.e. only app plugins?)
                foreach (var assemblyLocation in client.Proxy.GetAssemblyContainerLoadedAssemblies())
                {
                    AssemblyContainer.Default.LoadAssemblyFromPath(assemblyLocation, builderOptions.Logger);
                }

                // Create scheduler
                var scheduler = new Scheduler();

                var status = ResultStatus.NotProcessed;

                // Schedule command
                string buildPath = builderOptions.BuildDirectory;

                Builder.OpenObjectDatabase(buildPath, VirtualFileSystem.ApplicationDatabaseIndexName);

                var         logger      = builderOptions.Logger;
                MicroThread microthread = scheduler.Add(async() =>
                {
                    // Deserialize command and parameters
                    Command command = client.Proxy.GetCommandToExecute();

                    // Run command
                    var inputHashes    = FileVersionTracker.GetDefault();
                    var builderContext = new BuilderContext(inputHashes, null);

                    var commandContext = new RemoteCommandContext(client.Proxy, command, builderContext, logger);
                    MicrothreadLocalDatabases.MountDatabase(commandContext.GetOutputObjectsGroups());
                    command.PreCommand(commandContext);
                    status = await command.DoCommand(commandContext);
                    command.PostCommand(commandContext, status);

                    // Returns result to master builder
                    client.Proxy.RegisterResult(commandContext.ResultEntry);
                });

                while (true)
                {
                    scheduler.Run();

                    // Exit loop if no more micro threads
                    lock (scheduler.MicroThreads)
                    {
                        if (!scheduler.MicroThreads.Any())
                        {
                            break;
                        }
                    }

                    Thread.Sleep(0);
                }

                // Rethrow any exception that happened in microthread
                if (microthread.Exception != null)
                {
                    builderOptions.Logger.Fatal(microthread.Exception.ToString());
                    return(BuildResultCode.BuildError);
                }

                if (status == ResultStatus.Successful || status == ResultStatus.NotTriggeredWasSuccessful)
                {
                    return(BuildResultCode.Successful);
                }

                return(BuildResultCode.BuildError);
            }
        }
示例#19
0
        private BuildResultCode BuildSlave()
        {
            // Mount build path
            ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(builderOptions.BuildDirectory);

            PrepareDatabases();

            VirtualFileSystem.CreateDirectory(VirtualFileSystem.ApplicationDatabasePath);

            // Open WCF channel with master builder
            var namedPipeBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
            {
                SendTimeout = TimeSpan.FromSeconds(300.0)
            };
            var processBuilderRemote = ChannelFactory <IProcessBuilderRemote> .CreateChannel(namedPipeBinding, new EndpointAddress(builderOptions.SlavePipe));

            try
            {
                RegisterRemoteLogger(processBuilderRemote);

                // Create scheduler
                var scheduler = new Scheduler();

                var status = ResultStatus.NotProcessed;

                // Schedule command
                string buildPath    = builderOptions.BuildDirectory;
                string buildProfile = builderOptions.BuildProfile;

                Builder.SetupBuildPath(buildPath, VirtualFileSystem.ApplicationDatabaseIndexName);

                var         logger      = builderOptions.Logger;
                MicroThread microthread = scheduler.Add(async() =>
                {
                    // Deserialize command and parameters
                    Command command = processBuilderRemote.GetCommandToExecute();
                    BuildParameterCollection parameters = processBuilderRemote.GetBuildParameters();

                    // Run command
                    var inputHashes    = FileVersionTracker.GetDefault();
                    var builderContext = new BuilderContext(buildPath, buildProfile, inputHashes, parameters, 0, null);

                    var commandContext = new RemoteCommandContext(processBuilderRemote, command, builderContext, logger);
                    IndexFileCommand.MountDatabase(commandContext.GetOutputObjectsGroups());
                    command.PreCommand(commandContext);
                    status = await command.DoCommand(commandContext);
                    command.PostCommand(commandContext, status);

                    // Returns result to master builder
                    processBuilderRemote.RegisterResult(commandContext.ResultEntry);
                });

                while (true)
                {
                    scheduler.Run();

                    // Exit loop if no more micro threads
                    lock (scheduler.MicroThreads)
                    {
                        if (!scheduler.MicroThreads.Any())
                        {
                            break;
                        }
                    }

                    Thread.Sleep(0);
                }

                // Rethrow any exception that happened in microthread
                if (microthread.Exception != null)
                {
                    builderOptions.Logger.Fatal(microthread.Exception.ToString());
                    return(BuildResultCode.BuildError);
                }

                if (status == ResultStatus.Successful || status == ResultStatus.NotTriggeredWasSuccessful)
                {
                    return(BuildResultCode.Successful);
                }

                return(BuildResultCode.BuildError);
            }
            finally
            {
                // Close WCF channel
                // ReSharper disable SuspiciousTypeConversion.Global
                ((IClientChannel)processBuilderRemote).Close();
                // ReSharper restore SuspiciousTypeConversion.Global
            }
        }
示例#20
0
        private void ScheduleBuildStep(BuilderContext builderContext, BuildStep instigator, BuildStep buildStep, IDictionary <string, string> variables)
        {
            if (buildStep.ExecutionId == 0)
            {
                if (buildStep.Parent != null && buildStep.Parent != instigator)
                {
                    throw new InvalidOperationException("Scheduling a BuildStep with a different instigator that its parent");
                }
                if (buildStep.Parent == null)
                {
                    buildStep.Parent = instigator;
                }

                // Compute content dependencies before scheduling the build
                GenerateDependencies(buildStep);

                // TODO: Big review of the log infrastructure of CompilerApp & BuildEngine!
                // Create a logger that redirects to various places (BuildStep.Logger, timestampped log, global log, etc...)
                var buildStepLogger = new BuildStepLogger(buildStep, Logger, startTime);
                var logger          = (Logger)buildStepLogger;
                // Apply user-registered callbacks to the logger
                buildStep.TransformExecuteContextLogger?.Invoke(ref logger);

                // Create execute context
                var executeContext = new ExecuteContext(this, builderContext, buildStep, logger)
                {
                    Variables = new Dictionary <string, string>(variables)
                };
                //buildStep.ExpandStrings(executeContext);

                if (runMode == Mode.Build)
                {
                    MicroThread microThread = scheduler.Create();

                    // Set priority from this build step, if we have one.
                    if (buildStep.Priority.HasValue)
                    {
                        microThread.Priority = buildStep.Priority.Value;
                    }

                    buildStep.ExecutionId = microThread.Id;

                    microThread.Name = buildStep.ToString();

                    // Default:
                    // Schedule continuations as early as possible to help EnumerableBuildStep finish when all its task are finished.
                    // Otherwise, it would wait for all leaf to finish first before finishing parent EnumerableBuildStep.
                    // This should also reduce memory usage, and might improve cache coherency as well.
                    microThread.ScheduleMode = ScheduleMode.First;

                    microThread.Start(async() =>
                    {
                        // Wait for prerequisites
                        await Task.WhenAll(buildStep.PrerequisiteSteps.Select(x => x.ExecutedAsync()).ToArray());

                        // Check for failed prerequisites
                        var status = ResultStatus.NotProcessed;

                        if (buildStep.ArePrerequisitesSuccessful)
                        {
                            try
                            {
                                var outputObjectsGroups = executeContext.GetOutputObjectsGroups();
                                MicrothreadLocalDatabases.MountDatabase(outputObjectsGroups);

                                // Execute
                                status = await buildStep.Execute(executeContext, builderContext);
                            }
                            catch (TaskCanceledException e)
                            {
                                // Benlitz: I'm NOT SURE this is the correct explanation, it might be a more subtle race condition, but I can't manage to reproduce it again
                                executeContext.Logger.Warning("A child task of build step " + buildStep + " triggered a TaskCanceledException that was not caught by the parent task. The command has not handled cancellation gracefully.");
                                executeContext.Logger.Warning(e.Message);
                                status = ResultStatus.Cancelled;
                            }
                            catch (Exception e)
                            {
                                executeContext.Logger.Error("Exception in command " + buildStep + ": " + e);
                                status = ResultStatus.Failed;
                            }
                            finally
                            {
                                MicrothreadLocalDatabases.UnmountDatabase();

                                // Ensure the command set at least the result status
                                if (status == ResultStatus.NotProcessed)
                                {
                                    throw new InvalidDataException("The build step " + buildStep + " returned ResultStatus.NotProcessed after completion.");
                                }
                            }
                            if (microThread.Exception != null)
                            {
                                executeContext.Logger.Error("Exception in command " + buildStep + ": " + microThread.Exception);
                                status = ResultStatus.Failed;
                            }
                        }
                        else
                        {
                            status = ResultStatus.NotTriggeredPrerequisiteFailed;
                        }

                        //if (completedTask.IsCanceled)
                        //{
                        //    completedStep.Status = ResultStatus.Cancelled;
                        //}
                        var logType    = LogMessageType.Info;
                        string logText = null;

                        switch (status)
                        {
                        case ResultStatus.Successful:
                            logType = LogMessageType.Verbose;
                            logText = "BuildStep {0} was successful.".ToFormat(buildStep.ToString());
                            break;

                        case ResultStatus.Failed:
                            logType = LogMessageType.Error;
                            logText = "BuildStep {0} failed.".ToFormat(buildStep.ToString());
                            break;

                        case ResultStatus.NotTriggeredPrerequisiteFailed:
                            logType = LogMessageType.Error;
                            logText = "BuildStep {0} failed of previous failed prerequisites.".ToFormat(buildStep.ToString());
                            break;

                        case ResultStatus.Cancelled:
                            logType = LogMessageType.Warning;
                            logText = "BuildStep {0} cancelled.".ToFormat(buildStep.ToString());
                            break;

                        case ResultStatus.NotTriggeredWasSuccessful:
                            logType = LogMessageType.Verbose;
                            logText = "BuildStep {0} is up-to-date and has been skipped".ToFormat(buildStep.ToString());
                            break;

                        case ResultStatus.NotProcessed:
                            throw new InvalidDataException("BuildStep has neither succeeded, failed, nor been cancelled");
                        }
                        if (logText != null)
                        {
                            var logMessage = new LogMessage(null, logType, logText);
                            executeContext.Logger.Log(logMessage);
                        }

                        buildStep.RegisterResult(executeContext, status);
                        stepCounter.AddStepResult(status);
                    });
                }
                else
                {
                    buildStep.Clean(executeContext, builderContext, runMode == Mode.CleanAndDelete);
                }
            }
        }
示例#21
0
        public void MicroThreadTest()
        {
            MicroThread microA = new MicroThread();
            MicroThread microB = new MicroThread();

            microA.MainThread.Mark();
            microA.MyThread.Mark();
            microB.MainThread.Mark();
            microB.MyThread.Mark();

            Assert.AreEqual(false, microA.Done);
            Assert.AreEqual(false, microB.Done);

            microA.DoWork(() =>
            {
                int count = 0;
                while (count < 100) {
                    ++count;
                    if (count % 10 == 0) {
                        microA.Yield();
                    }
                }
            });

            MicroBJob jobB = new MicroBJob();
            jobB.MicroThread = microB;

            microB.DoWork(jobB.Work);

            Assert.AreEqual(false, microA.Done);
            Assert.AreEqual(false, microB.Done);

            int yields = 0;
            while (yields < 20) {
                if (!microA.Done) microA.Resume();
                if (!microB.Done) microB.Resume();
                if (microA.Done && microB.Done) break;
                ++yields;
            }

            Assert.AreEqual(true, microA.Done);
            Assert.AreEqual(true, microB.Done);
            Assert.AreEqual(100, jobB.Count);
            Assert.AreEqual(9, yields);
        }
        public static void AddTask(this ScriptComponent script, Func <Task> task, long priority = 0L)
        {
            MicroThread t = script.Script.AddTask(task, priority);

            script.Entity.GetOrCreate <TaskDisposer>().Tasks.Add(t);
        }
示例#23
0
        private void OnRunScriptCommand()
        {
            MicroThread mt = AssemblyParent.Parent.EngineContext.ScriptManager.RunScript(scriptEntry, null);

            MicroThread = new MicroThreadViewModel(mt);
        }
示例#24
0
        private void ScheduleBuildStep(BuilderContext builderContext, BuildStep instigator, BuildStep buildStep, IDictionary <string, string> variables)
        {
            if (buildStep.ExecutionId == 0)
            {
                if (buildStep.Parent != null && buildStep.Parent != instigator)
                {
                    throw new InvalidOperationException("Scheduling a BuildStep with a different instigator that its parent");
                }
                if (buildStep.Parent == null)
                {
                    buildStep.Parent = instigator;
                }

                var executeContext = new ExecuteContext(this, builderContext, buildStep)
                {
                    Variables = new Dictionary <string, string>(variables)
                };
                //buildStep.ExpandStrings(executeContext);

                if (runMode == Mode.Build)
                {
                    MicroThread microThread = scheduler.Create();

                    // Find priority from this build step, or one of its parent.
                    var buildStepPriority = buildStep;
                    while (buildStepPriority != null)
                    {
                        if (buildStepPriority.Priority.HasValue)
                        {
                            microThread.Priority = buildStepPriority.Priority.Value;
                            break;
                        }

                        buildStepPriority = buildStepPriority.Parent;
                    }

                    buildStep.ExecutionId = microThread.Id;

                    foreach (var threadMonitor in threadMonitors)
                    {
                        threadMonitor.RegisterBuildStep(buildStep, ((BuildStepLogger)executeContext.Logger).StepLogger);
                    }

                    microThread.Name = buildStep.ToString();

                    // Default:
                    // Schedule continuations as early as possible to help EnumerableBuildStep finish when all its task are finished.
                    // Otherwise, it would wait for all leaf to finish first before finishing parent EnumerableBuildStep.
                    // This should also reduce memory usage, and might improve cache coherency as well.
                    microThread.ScheduleMode = ScheduleMode.First;

                    microThread.Start(async() =>
                    {
                        // Wait for prerequisites
                        await Task.WhenAll(buildStep.PrerequisiteSteps.Select(x => x.ExecutedAsync()).ToArray());

                        // Check for failed prerequisites
                        var status = ResultStatus.NotProcessed;

                        if (buildStep.ArePrerequisitesSuccessful)
                        {
                            try
                            {
                                IndexFileCommand.MountDatabases(executeContext);

                                // Execute
                                status = await buildStep.Execute(executeContext, builderContext);
                            }
                            catch (TaskCanceledException e)
                            {
                                // Benlitz: I'm NOT SURE this is the correct explanation, it might be a more subtle race condition, but I can't manage to reproduce it again
                                executeContext.Logger.Warning("A child task of build step " + buildStep + " triggered a TaskCanceledException that was not caught by the parent task. The command has not handled cancellation gracefully.");
                                executeContext.Logger.Warning(e.Message);
                                status = ResultStatus.Cancelled;
                            }
                            catch (Exception e)
                            {
                                executeContext.Logger.Error("Exception in command " + buildStep + ": " + e);
                                status = ResultStatus.Failed;
                            }
                            finally
                            {
                                IndexFileCommand.UnmountDatabases(executeContext);

                                // Ensure the command set at least the result status
                                if (status == ResultStatus.NotProcessed)
                                {
                                    throw new InvalidDataException("The build step " + buildStep + " returned ResultStatus.NotProcessed after completion.");
                                }
                            }
                            if (microThread.Exception != null)
                            {
                                executeContext.Logger.Error("Exception in command " + buildStep + ": " + microThread.Exception);
                                status = ResultStatus.Failed;
                            }
                        }
                        else
                        {
                            status = ResultStatus.NotTriggeredPrerequisiteFailed;
                        }

                        buildStep.RegisterResult(executeContext, status);
                        stepCounter.AddStepResult(status);

                        //if (completedTask.IsCanceled)
                        //{
                        //    completedStep.Status = ResultStatus.Cancelled;
                        //}
                        var logType    = LogMessageType.Info;
                        string logText = null;

                        switch (buildStep.Status)
                        {
                        case ResultStatus.Successful:
                            logType = LogMessageType.Info;
                            logText = "BuildStep {0} was successful.".ToFormat(buildStep.ToString());
                            break;

                        case ResultStatus.Failed:
                            logType = LogMessageType.Error;
                            logText = "BuildStep {0} failed.".ToFormat(buildStep.ToString());
                            break;

                        case ResultStatus.Cancelled:
                            logType = LogMessageType.Warning;
                            logText = "BuildStep {0} cancelled.".ToFormat(buildStep.ToString());
                            break;

                        case ResultStatus.NotProcessed:
                            throw new InvalidDataException("BuildStep has neither succeeded, failed, nor been cancelled");
                        }
                        if (logText != null)
                        {
                            var logMessage = new LogMessage(buildStep.Module, logType, logText);
                            executeContext.Logger.Log(logMessage);
                        }
                    });
                }
                else
                {
                    buildStep.Clean(executeContext, builderContext, runMode == Mode.CleanAndDelete);
                }
            }
        }
示例#25
0
        public static BuildResultCode BuildSlave(BuilderOptions options)
        {
            // Mount build path
            ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(options.BuildDirectory);

            PrepareDatabases(options);

            try
            {
                VirtualFileSystem.CreateDirectory("/data/");
                VirtualFileSystem.CreateDirectory("/data/db/");
            }
            catch (Exception)
            {
                throw new OptionException("Invalid Build database path", "database");
            }

            // Open WCF channel with master builder
            var namedPipeBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
            {
                SendTimeout = TimeSpan.FromSeconds(300.0)
            };
            var processBuilderRemote = ChannelFactory <IProcessBuilderRemote> .CreateChannel(namedPipeBinding, new EndpointAddress(options.SlavePipe));

            try
            {
                RegisterRemoteLogger(processBuilderRemote);

                // Create scheduler
                var scheduler = new Scheduler();

                var status = ResultStatus.NotProcessed;

                // Schedule command
                string      buildPath   = options.BuildDirectory;
                Logger      logger      = options.Logger;
                MicroThread microthread = scheduler.Add(async() =>
                {
                    // Deserialize command and parameters
                    Command command = processBuilderRemote.GetCommandToExecute();
                    BuildParameterCollection parameters = processBuilderRemote.GetBuildParameters();

                    // Run command
                    var inputHashes    = new DictionaryStore <InputVersionKey, ObjectId>(VirtualFileSystem.OpenStream("/data/db/InputHashes", VirtualFileMode.OpenOrCreate, VirtualFileAccess.ReadWrite, VirtualFileShare.ReadWrite));
                    var builderContext = new BuilderContext(buildPath, inputHashes, parameters, 0, null);

                    var commandContext = new RemoteCommandContext(processBuilderRemote, command, builderContext, logger);
                    command.PreCommand(commandContext);
                    status = await command.DoCommand(commandContext);
                    command.PostCommand(commandContext, status);

                    // Returns result to master builder
                    processBuilderRemote.RegisterResult(commandContext.ResultEntry);
                });

                while (true)
                {
                    scheduler.Run();

                    // Exit loop if no more micro threads
                    lock (scheduler.MicroThreads)
                    {
                        if (!scheduler.MicroThreads.Any())
                        {
                            break;
                        }
                    }

                    Thread.Sleep(0);
                }

                // Rethrow any exception that happened in microthread
                if (microthread.Exception != null)
                {
                    options.Logger.Fatal(microthread.Exception.ToString());
                    return(BuildResultCode.BuildError);
                }

                if (status == ResultStatus.Successful || status == ResultStatus.NotTriggeredWasSuccessful)
                {
                    return(BuildResultCode.Successful);
                }

                return(BuildResultCode.BuildError);
            }
            finally
            {
                // Close WCF channel
                // ReSharper disable SuspiciousTypeConversion.Global
                ((IClientChannel)processBuilderRemote).Close();
                // ReSharper restore SuspiciousTypeConversion.Global
            }
        }
示例#26
0
 private void AddMicroThread(MicroThread microThread)
 {
     Dispatcher.BeginInvoke((Action)delegate
     {
         microThreads.Add(new MicroThreadViewModel(microThread));
     }, null);
 }