Exemplo n.º 1
0
 private static void RunSingleTestSet(TestConfiguration config, string fileName, Func <TestConfiguration, Qoollo.Turbo.Threading.ThreadPools.ThreadPoolBase> poolConstructor, bool waitForCompletion = true, bool doDispose = true)
 {
     Qoollo.Turbo.Threading.ThreadPools.ThreadPoolBase pool = null;
     try
     {
         pool = poolConstructor(config);
         {
             var    testRes = RunTestOnPool(pool, config, waitForCompletion);
             string msg     = pool.GetType().Name + config.ToString() + "  ==  " + testRes.TotalMilliseconds.ToString() + "ms";
             Console.WriteLine(msg);
             if (fileName != null)
             {
                 File.AppendAllLines(fileName, new string[] { msg });
             }
         }
     }
     finally
     {
         if (doDispose && pool != null)
         {
             pool.Dispose();
         }
     }
 }
Exemplo n.º 2
0
        private static TimeSpan RunTestOnPool(Qoollo.Turbo.Threading.ThreadPools.ThreadPoolBase pool, TestConfiguration config, bool waitForCompletion = true)
        {
            var    taskActiveTimeDev  = (int)(config.ActiveTaskAvgTime.Ticks / 4);
            var    taskPassiveTimeDev = (int)(config.PassiveTaskAvgTime.Ticks / 4);
            Random rndGenerator       = new Random();

            int executedTaskCounter = 0;
            int completedTaskCount  = 0;


            Action taskAction = null;

            taskAction = () =>
            {
                if (config.PassiveTaskAvgTime > TimeSpan.Zero)
                {
                    TimeSpan taskTime = config.PassiveTaskAvgTime;
                    if (config.UseDeviance)
                    {
                        lock (rndGenerator)
                            taskTime += TimeSpan.FromTicks(rndGenerator.Next(-taskPassiveTimeDev, taskPassiveTimeDev));
                    }

                    int taskTimeMs = CalcRandSleep(rndGenerator, taskTime.TotalMilliseconds);

                    if (taskTimeMs > 0)
                    {
                        Thread.Sleep(taskTimeMs);
                    }
                    else if (taskTimeMs == 0)
                    {
                        Thread.Yield();
                    }
                }

                // ----
                if (config.ActiveTaskAvgTime > TimeSpan.Zero)
                {
                    TimeSpan taskTime = config.ActiveTaskAvgTime;
                    if (config.UseDeviance)
                    {
                        lock (rndGenerator)
                            taskTime += TimeSpan.FromTicks(rndGenerator.Next(-taskActiveTimeDev, taskActiveTimeDev));
                    }

                    int taskTimeMs = CalcRandSleep(rndGenerator, taskTime.TotalMilliseconds);

                    if (taskTimeMs > 0)
                    {
                        Stopwatch sw111 = Stopwatch.StartNew();
                        while (sw111.ElapsedMilliseconds < taskTimeMs)
                        {
                            SpinWaitHelper.SpinWait(2000);
                        }
                    }
                    else if (taskTimeMs == 0)
                    {
                        Thread.Yield();
                    }
                }

                // ----

                if (config.SpawnFromPool)
                {
                    if (Interlocked.Increment(ref executedTaskCounter) <= config.TaskCount)
                    {
                        //pool.RunAsTask(taskAction);
                        pool.Run(taskAction);
                    }
                }

                Interlocked.Increment(ref completedTaskCount);
            };

            Barrier bar = new Barrier(config.SpawnThreadCount + 1);

            Random spawnRndGenerator = new Random();
            int    spawnTimeDev      = (int)(config.SpawnPeriod.Ticks / 4);

            Thread[]    spawnThreads = new Thread[config.SpawnThreadCount];
            ThreadStart spawnAction  = () =>
            {
                bar.SignalAndWait();

                long expectedSleep = 0;
                long realSleep     = 0;
                int  curSpawned    = 0;
                while ((curSpawned = Interlocked.Increment(ref executedTaskCounter)) <= config.TaskCount)
                {
                    //pool.RunAsTask(taskAction);
                    pool.Run(taskAction);

                    TimeSpan spawnSleep = config.SpawnPeriod;
                    if (config.UseDeviance)
                    {
                        lock (spawnRndGenerator)
                            spawnSleep += TimeSpan.FromTicks(spawnRndGenerator.Next(-spawnTimeDev, spawnTimeDev));
                    }

                    int spawnSleepMs = CalcRandSleep(spawnRndGenerator, spawnSleep.TotalMilliseconds);

                    if (spawnSleepMs > 0)
                    {
                        expectedSleep += spawnSleepMs;

                        int startTick = Environment.TickCount;
                        if (realSleep <= expectedSleep)
                        {
                            Thread.Sleep(spawnSleepMs);
                        }

                        realSleep += (Environment.TickCount - startTick);
                    }
                }
            };


            for (int i = 0; i < spawnThreads.Length; i++)
            {
                spawnThreads[i] = new Thread(spawnAction);
            }

            for (int i = 0; i < spawnThreads.Length; i++)
            {
                spawnThreads[i].Start();
            }


            bar.SignalAndWait();
            Stopwatch sw = Stopwatch.StartNew();

            if (waitForCompletion)
            {
                SpinWait.SpinUntil(() => Volatile.Read(ref completedTaskCount) >= config.TaskCount);
            }
            else
            {
                SpinWait.SpinUntil(() => Volatile.Read(ref executedTaskCounter) >= config.TaskCount);
            }

            sw.Stop();

            if (waitForCompletion && completedTaskCount != config.TaskCount)
            {
                throw new Exception("completedTaskCount != config.TaskCount");
            }

            return(sw.Elapsed);
        }