ThreadPoolTest.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. //
  2. // ThreadPoolTest.cs
  3. //
  4. // Authors:
  5. // Marek Safar <[email protected]>
  6. //
  7. // Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining a copy
  10. // of this software and associated documentation files (the "Software"), to deal
  11. // in the Software without restriction, including without limitation the rights
  12. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. // copies of the Software, and to permit persons to whom the Software is
  14. // furnished to do so, subject to the following conditions:
  15. //
  16. // The above copyright notice and this permission notice shall be included in
  17. // all copies or substantial portions of the Software.
  18. //
  19. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. // THE SOFTWARE.
  26. //
  27. //
  28. using System;
  29. using System.Diagnostics;
  30. using System.Threading;
  31. using NUnit.Framework;
  32. namespace MonoTests.System.Threading
  33. {
  34. [TestFixture]
  35. public class ThreadPoolTests
  36. {
  37. int minWorkerThreads;
  38. int minCompletionPortThreads;
  39. int maxWorkerThreads;
  40. int maxCompletionPortThreads;
  41. [SetUp]
  42. public void SetUp ()
  43. {
  44. ThreadPool.GetMinThreads (out minWorkerThreads, out minCompletionPortThreads);
  45. ThreadPool.GetMaxThreads (out maxWorkerThreads, out maxCompletionPortThreads);
  46. }
  47. [TearDown]
  48. public void TearDown ()
  49. {
  50. ThreadPool.SetMinThreads (minWorkerThreads, minCompletionPortThreads);
  51. ThreadPool.SetMaxThreads (maxWorkerThreads, maxCompletionPortThreads);
  52. }
  53. [Test]
  54. public void RegisterWaitForSingleObject_InvalidArguments ()
  55. {
  56. try {
  57. ThreadPool.RegisterWaitForSingleObject (null, delegate {}, new object (), 100, false);
  58. Assert.Fail ("#1");
  59. } catch (ArgumentNullException) {
  60. }
  61. try {
  62. ThreadPool.RegisterWaitForSingleObject (new Mutex (), null, new object (), 100, false);
  63. Assert.Fail ("#2");
  64. } catch (ArgumentNullException) {
  65. }
  66. }
  67. [Test]
  68. public void UnsafeQueueUserWorkItem_InvalidArguments ()
  69. {
  70. try {
  71. ThreadPool.UnsafeQueueUserWorkItem (null, 1);
  72. Assert.Fail ("#1");
  73. } catch (ArgumentNullException) {
  74. }
  75. }
  76. [Test]
  77. public void QueueUserWorkItem ()
  78. {
  79. int n = 100000;
  80. int total = 0, sum = 0;
  81. for (int i = 0; i < n; ++i) {
  82. if (i % 2 == 0)
  83. ThreadPool.QueueUserWorkItem (_ => { Interlocked.Decrement (ref sum); Interlocked.Increment (ref total); });
  84. else
  85. ThreadPool.QueueUserWorkItem (_ => { Interlocked.Increment (ref sum); Interlocked.Increment (ref total); });
  86. }
  87. var sw = Stopwatch.StartNew ();
  88. while ((total != n || sum != 0) && sw.Elapsed.TotalSeconds < 60)
  89. Thread.Sleep (1000);
  90. Assert.IsTrue (total == n, "#1");
  91. Assert.IsTrue (sum == 0, "#2");
  92. }
  93. event WaitCallback e;
  94. [Test]
  95. public void UnsafeQueueUserWorkItem_MulticastDelegate ()
  96. {
  97. CountdownEvent ev = new CountdownEvent (2);
  98. e += delegate {
  99. ev.Signal ();
  100. };
  101. e += delegate {
  102. ev.Signal ();
  103. };
  104. ThreadPool.UnsafeQueueUserWorkItem (e, null);
  105. Assert.IsTrue (ev.Wait (3000));
  106. }
  107. [Test]
  108. public void SetAndGetMinThreads ()
  109. {
  110. int workerThreads, completionPortThreads;
  111. int workerThreads_new, completionPortThreads_new;
  112. ThreadPool.GetMinThreads (out workerThreads, out completionPortThreads);
  113. Assert.IsTrue (workerThreads > 0, "#1");
  114. Assert.IsTrue (completionPortThreads > 0, "#2");
  115. workerThreads_new = workerThreads == 1 ? 2 : 1;
  116. completionPortThreads_new = completionPortThreads == 1 ? 2 : 1;
  117. ThreadPool.SetMinThreads (workerThreads_new, completionPortThreads_new);
  118. ThreadPool.GetMinThreads (out workerThreads, out completionPortThreads);
  119. Assert.IsTrue (workerThreads == workerThreads_new, "#3");
  120. Assert.IsTrue (completionPortThreads == completionPortThreads_new, "#4");
  121. }
  122. [Test]
  123. public void SetAndGetMaxThreads ()
  124. {
  125. int cpuCount = Environment.ProcessorCount;
  126. int workerThreads, completionPortThreads;
  127. int workerThreads_new, completionPortThreads_new;
  128. ThreadPool.GetMaxThreads (out workerThreads, out completionPortThreads);
  129. Assert.IsTrue (workerThreads > 0, "#1");
  130. Assert.IsTrue (completionPortThreads > 0, "#2");
  131. workerThreads_new = workerThreads == cpuCount ? cpuCount + 1 : cpuCount;
  132. completionPortThreads_new = completionPortThreads == cpuCount ? cpuCount + 1 : cpuCount;
  133. ThreadPool.SetMaxThreads (workerThreads_new, completionPortThreads_new);
  134. ThreadPool.GetMaxThreads (out workerThreads, out completionPortThreads);
  135. Assert.IsTrue (workerThreads == workerThreads_new, "#3");
  136. Assert.IsTrue (completionPortThreads == completionPortThreads_new, "#4");
  137. }
  138. [Test]
  139. public void SetMaxPossibleThreads ()
  140. {
  141. var maxPossibleThreads = 0x7fff;
  142. int maxWt, macCpt;
  143. ThreadPool.SetMaxThreads (maxPossibleThreads, maxPossibleThreads);
  144. ThreadPool.GetMaxThreads (out maxWt, out macCpt);
  145. Assert.AreEqual (maxPossibleThreads, maxWt);
  146. Assert.AreEqual (maxPossibleThreads, macCpt);
  147. ThreadPool.SetMaxThreads (maxPossibleThreads + 1, maxPossibleThreads + 1);
  148. ThreadPool.GetMaxThreads (out maxWt, out macCpt);
  149. Assert.AreEqual (maxPossibleThreads, maxWt);
  150. Assert.AreEqual (maxPossibleThreads, macCpt);
  151. }
  152. [Test]
  153. public void GetAvailableThreads ()
  154. {
  155. ManualResetEvent mre = new ManualResetEvent (false);
  156. var sw = Stopwatch.StartNew ();
  157. int i, workerThreads, completionPortThreads;
  158. try {
  159. Assert.IsTrue (ThreadPool.SetMaxThreads (Environment.ProcessorCount, Environment.ProcessorCount));
  160. while (true) {
  161. ThreadPool.GetAvailableThreads (out workerThreads, out completionPortThreads);
  162. if (workerThreads == 0)
  163. break;
  164. Console.WriteLine ("workerThreads = {0}, completionPortThreads = {1}", workerThreads, completionPortThreads);
  165. if (sw.Elapsed.TotalSeconds >= 10)
  166. Assert.Fail ("did not reach 0 available threads");
  167. ThreadPool.QueueUserWorkItem (GetAvailableThreads_Callback, mre);
  168. Thread.Sleep (1);
  169. }
  170. } finally {
  171. mre.Set ();
  172. }
  173. }
  174. void GetAvailableThreads_Callback (object state)
  175. {
  176. ManualResetEvent mre = (ManualResetEvent) state;
  177. if (mre.WaitOne (0))
  178. return;
  179. ThreadPool.QueueUserWorkItem (GetAvailableThreads_Callback, mre);
  180. ThreadPool.QueueUserWorkItem (GetAvailableThreads_Callback, mre);
  181. ThreadPool.QueueUserWorkItem (GetAvailableThreads_Callback, mre);
  182. ThreadPool.QueueUserWorkItem (GetAvailableThreads_Callback, mre);
  183. mre.WaitOne ();
  184. }
  185. }
  186. }