/base/Applications/Tests/MpStress/MpStress.cs
C# | 294 lines | 178 code | 68 blank | 48 comment | 22 complexity | 4c4e1e385ed3f0f168fb83f259edee91 MD5 | raw file
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Microsoft Research Singularity
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //
- // Note: Perform short (bvt) and long running stress of multiprocessor
- // sensitive areas of the system. Used MonitorTest.cs as an
- // application template
- //
-
- using System;
- using System.Threading;
-
- using Microsoft.Singularity.UnitTest;
-
- using Microsoft.Singularity.Channels;
- using Microsoft.Contracts;
- using Microsoft.SingSharp.Reflection;
- using Microsoft.Singularity.Applications;
- using Microsoft.Singularity.Io;
- using Microsoft.Singularity.Configuration;
- [assembly: Transform(typeof(ApplicationResourceTransform))]
-
- namespace Microsoft.Singularity.Applications
- {
- [ConsoleCategory(DefaultAction=true)]
- internal class Parameters {
- [InputEndpoint("data")]
- public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
-
- [OutputEndpoint("data")]
- public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
-
- [LongParameter("cpucount", Default=2, HelpMessage="CPU Count for test")]
- internal long cpuCount;
-
- [LongParameter("passcount", Default=10, HelpMessage="Pass Count for test")]
- internal long passCount;
-
- reflective internal Parameters();
-
- internal int AppMain() {
- return MpStress.AppMain(this);
- }
- }
-
- public class MpStress
- {
- internal static int AppMain(Parameters! config)
- {
- int result;
-
- Console.WriteLine("Running MpStress for CPU Count {0}", config.cpuCount);
-
- ThreadTest tt = new ThreadTest();
-
- result = tt.RunTest(config.cpuCount, config.passCount);
- if (result != 0) {
- return result;
- }
-
- return 0;
- }
- }
-
- public class ThreadTest
- {
-
- public int RunTest(long cpuCount, long passCount) {
-
- // Start the thread create/destroy test
- //ThreadTestsThread threadTests = new ThreadTestsThread(cpuCount);
-
- // Run pulse tests
- PulseTestsThread pulseTests = new PulseTestsThread(cpuCount, passCount);
- pulseTests.RunThread();
-
- // Start the background threads
- //threadTests.RunThread();
-
- // Wait for pulse tests to complete
- ((!)pulseTests.Thread).Join();
-
- return 0;
- }
- }
-
- //
- // Implementation classes represent different thread creation
- // parameters, and actions
- //
-
- public class PrintThread : ThreadRunner
- {
- private long argValue;
-
- public PrintThread(long arg) : base() {
- argValue = arg;
- }
-
- public override void ThreadMain() {
-
- //System.Console.WriteLine("PrintThread: Thread {0}, ThreadIndex {1}\n", Thread.CurrentThread.GetThreadId(), argValue);
-
- // Call some additional "interesting" system calls here in order to disturb
- // the system state, cause lock contention, flesh out races and unprotected code
- // regions, etc.
- //
-
- // This exits the thread
- //Console.Write("-");
- return;
- }
- }
-
- public class ThreadTestsThread : ThreadRunner
- {
- private long cpuCount;
-
- public ThreadTestsThread(long cpuCount) : base() {
- this.cpuCount = cpuCount;
- }
-
- public override void ThreadMain() {
-
- const long Timeout = 1000 * 10; // 10 seconds
- long threadCount = 0;
- PrintThread[] threads;
-
- threadCount = cpuCount * 2;
-
- //
- // Run forever, process will exit when the ApMain thread
- // is done with the test sequence
- //
- for (;;) {
-
- //Console.Write(".");
-
- threads = new PrintThread[threadCount];
- if (threads == null) {
- System.Console.WriteLine("Error allocating Thread[]");
- return;
- }
-
- for (int i = 0; i < threadCount; i++) {
- threads[i] = new PrintThread(i);
- if (threads[i] == null) {
- System.Console.WriteLine("Error creating thread");
- return;
- }
- }
-
- // Start them running
- for (int i = 0; i < threadCount; i++) {
- ((!)threads[i]).RunThread();
- }
-
- TimeSpan timeout = TimeSpan.FromMilliseconds(Timeout);
-
- for (int i = 0; i < threadCount; i++) {
- if (!((!)(((!)threads[i]).Thread)).Join(timeout)) {
- Console.WriteLine("Timeout waiting for thread exit");
- return;
- }
- //Console.Write("+");
- }
- }
- }
- }
-
- public class PulseTestsThread : ThreadRunner
- {
- private long cpuCount;
- private long passes;
- private int threadCount;
- private int maxThreadCount;
- private const int threadsPerCpu = 64;
-
- public PulseTestsThread(long cpuCount, long passes) : base() {
- this.cpuCount = cpuCount;
- this.passes = passes;
- maxThreadCount = threadsPerCpu * (int)cpuCount;
-
- // Limit max threads, otherwise we will overflow the kernel's thread table
- if (maxThreadCount > 512) {
- maxThreadCount = 512;
- }
- }
-
- public override void ThreadMain() {
-
- System.Console.WriteLine("Running PulseTests: Thread {0}\n", Thread.CurrentThread.GetThreadId());
- Console.Write("passes={0}", passes);
- Console.WriteLine(" cpuCount={0}", cpuCount);
-
- for (int pass = 0; pass < passes; pass++) {
-
- Console.WriteLine("pass={0}", pass);
-
- UnitTest.Clear();
- threadCount = 0;
-
- for (int i = 0; i < cpuCount; i++) {
-
- // 50 threads
- if (!CheckMaxThreads(50)) {
- UnitTest.Add("Many Threads PulseAll",
- new UnitTest.TestDelegate(PulseAllTest.ManyThreadsTest));
- }
-
- // 8 threads
- if (!CheckMaxThreads(8)) {
- UnitTest.Add("Few Threads PulseAll",
- new UnitTest.TestDelegate(PulseAllTest.FewThreadsTest));
- }
-
- // 17 threads
- if (!CheckMaxThreads(17)) {
- UnitTest.Add("Low-density Pulse",
- new UnitTest.TestDelegate(PulseTest.LowDensityTest));
- }
-
- // 32 threads
- if (!CheckMaxThreads(32)) {
- UnitTest.Add("Medium-density Pulse",
- new UnitTest.TestDelegate(PulseTest.MediumDensityTest));
- }
-
- // 128 threads
- if (!CheckMaxThreads(128)) {
- UnitTest.Add("High-density Pulse",
- new UnitTest.TestDelegate(PulseTest.HighDensityTest));
- }
- }
-
- Console.WriteLine("{0} PulseThreads", threadCount);
-
- // Wait for the sub-threads to run
- if (UnitTest.Run(true) != UnitTest.Result.Passed) {
- Console.WriteLine("PulseTest failed!\n");
- }
- }
-
- // This exits the thread
- return;
- }
-
- // We must keep total thread count at a reasonable level
- // otherwise we overflow the kernel thread table that is
- // hardcoded at 1024. We will set 512 max threads for now.
- private bool CheckMaxThreads(int count)
- {
- if ((count + threadCount) <= maxThreadCount) {
- threadCount += count;
- return false;
- }
-
- return true;
- }
- }
-
- // Generic class that creates the thread
- public class ThreadRunner
- {
- private Thread thread;
-
- public ThreadRunner() {
- }
-
- public Thread Thread {
- get {
- return thread;
- }
- }
-
- // Creates thread, returns with it running
- public Thread RunThread() {
-
- thread = new Thread(new ThreadStart(ThreadMain));
-
- thread.Start();
-
- return thread;
- }
-
- public virtual void ThreadMain() {
-
- // This exits the thread
- return;
- }
- }
- }