2 using System.Collections.Generic;
3 using System.Threading;
4 using System.Diagnostics;
9 static bool stop_please;
10 const int TEST_DURATION = 1000;
12 static object very_contended_object = new object ();
14 static bool Ok (ref int loops) {
23 static void MonitorEnterInALoop (int loops)
25 while (Ok (ref loops)) {
26 if (Monitor.TryEnter (very_contended_object, 100)) {
28 Monitor.Exit (very_contended_object);
33 static void AllocObjectInALoop (int loops) {
34 while (Ok (ref loops)) {
35 var a = new object ();
36 var b = new byte [100];
40 static void AllocDomainInALoop (int loops) {
42 while (Ok (ref loops)) {
43 var a = AppDomain.CreateDomain ("test_domain_" + ++count);
48 static void FileIO (int loops) {
49 while (Ok (ref loops)) {
50 var dir = Path.GetTempFileName () + "_" + Thread.CurrentThread.ManagedThreadId;
51 Directory.CreateDirectory (dir);
52 Directory.Delete (dir);
57 static void Timer_Elapsed(object sender, EventArgs e)
59 HashSet<string> h = new HashSet<string>();
60 for (int j = 0; j < 500; j++)
66 //From sgen-new-threads-dont-join-stw
67 static void TimerStress (int loops) {
68 while (Ok (ref loops)) {
69 System.Timers.Timer timer = new System.Timers.Timer();
70 timer.Elapsed += Timer_Elapsed;
71 timer.AutoReset = false;
77 //from sgen-weakref-stress
78 static void WeakRefStress (int loops) {
79 while (Ok (ref loops)) {
80 for (int j = 0; j < 500; ++j) {
81 new WeakReference (new object ());
85 static Tuple<Action<int>,string>[] available_tests = new [] {
86 Tuple.Create (new Action<int> (MonitorEnterInALoop), "monitor"),
87 Tuple.Create (new Action<int> (AllocObjectInALoop), "alloc"),
88 Tuple.Create (new Action<int> (AllocDomainInALoop), "appdomain"),
89 Tuple.Create (new Action<int> (FileIO), "file-io"),
90 Tuple.Create (new Action<int> (TimerStress), "timers"),
91 Tuple.Create (new Action<int> (WeakRefStress), "weakref"),
94 static void GcPump (int timeInMillis)
96 var sw = Stopwatch.StartNew ();
100 } while (sw.ElapsedMilliseconds < timeInMillis);
104 const int minTpSteps = 1;
105 const int maxTpSteps = 30;
107 static void QueueStuffUsingTpl (int threadCount) {
109 int maxPending = threadCount * 2;
110 int generatorIdx = 0;
111 Random rand = new Random (0);
113 while (!stop_please) {
114 while (pendingJobs < maxPending) {
115 var task = available_tests [generatorIdx++ % available_tests.Length].Item1;
116 int steps = rand.Next(minTpSteps, maxTpSteps);
117 ThreadPool.QueueUserWorkItem (_ => {
119 Interlocked.Decrement (ref pendingJobs);
121 Interlocked.Increment (ref pendingJobs);
125 while (pendingJobs > 0)
129 static void DynamicLoadGenerator (int threadCount, int timeInMillis) {
130 var t = new Thread (() => QueueStuffUsingTpl (threadCount));
133 GcPump (timeInMillis);
138 static void StaticLoadGenerator (int threadCount, int testIndex, int timeInMillis) {
139 List<Thread> threads = new List<Thread> ();
141 for (int i = 0; i < threadCount; ++i) {
142 var dele = (testIndex >= 0 ? available_tests [testIndex] : available_tests [i % available_tests.Length]).Item1;
143 var t = new Thread (() => dele (-1));
148 GcPump (timeInMillis);
150 foreach (var t in threads)
154 static int ParseTestName (string name) {
155 for (int i = 0; i < available_tests.Length; ++i) {
156 if (available_tests[i].Item2 == name)
159 Console.WriteLine ("Invalid test name {0}", name);
160 Environment.Exit (2);
164 static int Main (string[] args) {
165 int threadCount = Environment.ProcessorCount - 1;
166 int timeInMillis = TEST_DURATION;
168 bool tpLoadGenerator = false;
169 string testName = "static";
172 for (int j = 0; j < args.Length;) {
173 if ((args [j] == "--duration") || (args [j] == "-d")) {
174 timeInMillis = Int32.Parse (args [j + 1]);
176 } else if ((args [j] == "--test") || (args [j] == "-t")) {
177 if (args [j + 1] == "static")
179 else if (args [j + 1] == "tp")
180 tpLoadGenerator = true;
182 testIndex = ParseTestName (testName = args [j + 1]);
184 } else if ((args [j] == "--thread-count") || (args [j] == "-tc")) {
185 threadCount = Int32.Parse (args [j + 1]);
188 Console.WriteLine ("Unknown argument: " + args [j]);
193 if (tpLoadGenerator) {
194 Console.WriteLine ("tp window {0} duration {1}", threadCount, timeInMillis);
195 DynamicLoadGenerator (threadCount, timeInMillis);
197 Console.WriteLine ("thread count {0} duration {1} test {2}", threadCount, timeInMillis, testName);
198 StaticLoadGenerator (threadCount, testIndex, timeInMillis);