SpinLockTests.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. //
  2. // SpinLockTests.cs
  3. //
  4. // Author:
  5. // Jérémie "Garuma" Laval <[email protected]>
  6. //
  7. // Copyright (c) 2010 Jérémie "Garuma" Laval
  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. using System;
  27. using System.Threading;
  28. using NUnit.Framework;
  29. using MonoTests.System.Threading.Tasks;
  30. namespace MonoTests.System.Threading
  31. {
  32. [TestFixture]
  33. public class SpinLockTests
  34. {
  35. SpinLock sl;
  36. [SetUp]
  37. public void Setup ()
  38. {
  39. sl = new SpinLock (true);
  40. }
  41. [Test, ExpectedException (typeof (LockRecursionException))]
  42. public void RecursionExceptionTest ()
  43. {
  44. sl = new SpinLock (true);
  45. bool taken = false, taken2 = false;
  46. sl.Enter (ref taken);
  47. Assert.IsTrue (taken, "#1");
  48. sl.Enter (ref taken2);
  49. }
  50. [Test]
  51. public void SimpleEnterExitSchemeTest ()
  52. {
  53. bool taken = false;
  54. for (int i = 0; i < 50000; i++) {
  55. sl.Enter (ref taken);
  56. Assert.IsTrue (taken, "#" + i.ToString ());
  57. sl.Exit ();
  58. taken = false;
  59. }
  60. }
  61. [Test]
  62. public void SemanticCorrectnessTest ()
  63. {
  64. sl = new SpinLock (false);
  65. bool taken = false;
  66. bool taken2 = false;
  67. sl.Enter (ref taken);
  68. Assert.IsTrue (taken, "#1");
  69. sl.TryEnter (ref taken2);
  70. Assert.IsFalse (taken2, "#2");
  71. sl.Exit ();
  72. sl.TryEnter (ref taken2);
  73. Assert.IsTrue (taken2, "#3");
  74. sl.Exit ();
  75. Assert.IsFalse (sl.IsHeld);
  76. }
  77. [Test, ExpectedException (typeof (ArgumentException))]
  78. public void FirstTakenParameterTest ()
  79. {
  80. bool taken = true;
  81. sl.Enter (ref taken);
  82. }
  83. [Test, ExpectedException (typeof (ArgumentException))]
  84. public void SecondTakenParameterTest ()
  85. {
  86. bool taken = true;
  87. sl.TryEnter (ref taken);
  88. }
  89. internal class SpinLockWrapper
  90. {
  91. public SpinLock Lock = new SpinLock (false);
  92. }
  93. [Test]
  94. [Category ("MultiThreaded")]
  95. public void LockUnicityTest ()
  96. {
  97. ParallelTestHelper.Repeat (delegate {
  98. int currentCount = 0;
  99. bool fail = false;
  100. SpinLockWrapper wrapper = new SpinLockWrapper ();
  101. ParallelTestHelper.ParallelStressTest (wrapper, delegate {
  102. bool taken = false;
  103. wrapper.Lock.Enter (ref taken);
  104. int current = currentCount++;
  105. if (current != 0)
  106. fail = true;
  107. SpinWait sw = new SpinWait ();
  108. for (int i = 0; i < 200; i++)
  109. sw.SpinOnce ();
  110. currentCount -= 1;
  111. wrapper.Lock.Exit ();
  112. }, 4);
  113. Assert.IsFalse (fail);
  114. }, 200);
  115. }
  116. [Test]
  117. public void IsHeldByCurrentThreadTest ()
  118. {
  119. bool lockTaken = false;
  120. sl.Enter (ref lockTaken);
  121. Assert.IsTrue (lockTaken, "#1");
  122. Assert.IsTrue (sl.IsHeldByCurrentThread, "#2");
  123. lockTaken = false;
  124. sl = new SpinLock (true);
  125. sl.Enter (ref lockTaken);
  126. Assert.IsTrue (lockTaken, "#3");
  127. Assert.IsTrue (sl.IsHeldByCurrentThread, "#4");
  128. }
  129. }
  130. }