[SRE] Improved token fixups processing.
[mono.git] / mcs / class / corlib / Test / System.Threading / SpinLockTests.cs
1 #if NET_4_0
2 //
3 // SpinLockTests.cs
4 //
5 // Author:
6 //       Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
7 //
8 // Copyright (c) 2010 Jérémie "Garuma" Laval
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to deal
12 // in the Software without restriction, including without limitation the rights
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 // copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 // THE SOFTWARE.
27
28 using System;
29 using System.Threading;
30
31 using NUnit.Framework;
32
33 using MonoTests.System.Threading.Tasks;
34
35 namespace MonoTests.System.Threading
36 {
37         [TestFixture]
38         public class SpinLockTests
39         {
40                 SpinLock sl;
41
42                 [SetUp]
43                 public void Setup ()
44                 {
45                         sl = new SpinLock (true);
46                 }
47
48                 [Test, ExpectedException (typeof (LockRecursionException))]
49                 public void RecursionExceptionTest ()
50                 {
51                         sl = new SpinLock (true);
52                         bool taken = false, taken2 = false;
53
54                         sl.Enter (ref taken);
55                         Assert.IsTrue (taken, "#1");
56                         sl.Enter (ref taken2);
57                 }
58
59                 [Test]
60                 public void SimpleEnterExitSchemeTest ()
61                 {
62                         bool taken = false;
63
64                         for (int i = 0; i < 50000; i++) {
65                                 sl.Enter (ref taken);
66                                 Assert.IsTrue (taken, "#" + i.ToString ());
67                                 sl.Exit ();
68                                 taken = false;
69                         }
70                 }
71
72                 [Test]
73                 public void SemanticCorrectnessTest ()
74                 {
75                         sl = new SpinLock (false);
76
77                         bool taken = false;
78                         bool taken2 = false;
79
80                         sl.Enter (ref taken);
81                         Assert.IsTrue (taken, "#1");
82                         sl.TryEnter (ref taken2);
83                         Assert.IsFalse (taken2, "#2");
84                         sl.Exit ();
85
86                         sl.TryEnter (ref taken2);
87                         Assert.IsTrue (taken2, "#3");
88
89                         sl.Exit ();
90                         Assert.IsFalse (sl.IsHeld);
91                 }
92
93                 [Test, ExpectedException (typeof (ArgumentException))]
94                 public void FirstTakenParameterTest ()
95                 {
96                         bool taken = true;
97
98                         sl.Enter (ref taken);
99                 }
100
101                 [Test, ExpectedException (typeof (ArgumentException))]
102                 public void SecondTakenParameterTest ()
103                 {
104                         bool taken = true;
105
106                         sl.TryEnter (ref taken);
107                 }
108
109                 internal class SpinLockWrapper
110                 {
111                         public SpinLock Lock = new SpinLock (false);
112                 }
113
114                 [Test]
115                 public void LockUnicityTest ()
116                 {
117                         ParallelTestHelper.Repeat (delegate {
118                                 int currentCount = 0;
119                                 bool fail = false;
120                                 SpinLockWrapper wrapper = new SpinLockWrapper ();
121
122                                 ParallelTestHelper.ParallelStressTest (wrapper, delegate {
123                                         bool taken = false;
124                                         wrapper.Lock.Enter (ref taken);
125                                         int current = currentCount++;
126                                         if (current != 0)
127                                                 fail = true;
128
129                                         SpinWait sw = new SpinWait ();
130                                         for (int i = 0; i < 200; i++)
131                                                 sw.SpinOnce ();
132                                         currentCount -= 1;
133
134                                         wrapper.Lock.Exit ();
135                                 }, 4);
136
137                                 Assert.IsFalse (fail);
138                         }, 200);
139                 }
140
141                 [Test]
142                 public void IsHeldByCurrentThreadTest ()
143                 {
144                         bool lockTaken = false;
145
146                         sl.Enter (ref lockTaken);
147                         Assert.IsTrue (lockTaken, "#1");
148                         Assert.IsTrue (sl.IsHeldByCurrentThread, "#2");
149
150                         lockTaken = false;
151                         sl = new SpinLock (true);
152
153                         sl.Enter (ref lockTaken);
154                         Assert.IsTrue (lockTaken, "#3");
155                         Assert.IsTrue (sl.IsHeldByCurrentThread, "#4");
156                 }
157         }
158 }
159 #endif