Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
SpinLock.cs
Go to the documentation of this file.
3
4namespace System.Threading;
5
6[DebuggerTypeProxy(typeof(SystemThreading_SpinLockDebugView))]
7[DebuggerDisplay("IsHeld = {IsHeld}")]
8public struct SpinLock
9{
11 {
13
15 {
16 get
17 {
18 try
19 {
21 }
23 {
24 return null;
25 }
26 }
27 }
28
29 public int? OwnerThreadID
30 {
31 get
32 {
34 {
35 return _spinLock._owner;
36 }
37 return null;
38 }
39 }
40
41 public bool IsHeld => _spinLock.IsHeld;
42
44 {
45 _spinLock = spinLock;
46 }
47 }
48
49 private volatile int _owner;
50
51 public bool IsHeld
52 {
53 get
54 {
56 {
57 return _owner != 0;
58 }
59 return (_owner & 1) != 0;
60 }
61 }
62
64 {
65 get
66 {
68 {
70 }
71 return (_owner & 0x7FFFFFFF) == Environment.CurrentManagedThreadId;
72 }
73 }
74
75 public bool IsThreadOwnerTrackingEnabled => (_owner & int.MinValue) == 0;
76
77 [MethodImpl(MethodImplOptions.AggressiveInlining)]
78 private static int CompareExchange(ref int location, int value, int comparand, ref bool success)
79 {
80 int num = Interlocked.CompareExchange(ref location, value, comparand);
81 success = num == comparand;
82 return num;
83 }
84
85 public SpinLock(bool enableThreadOwnerTracking)
86 {
87 _owner = 0;
88 if (!enableThreadOwnerTracking)
89 {
90 _owner |= int.MinValue;
91 }
92 }
93
94 public void Enter(ref bool lockTaken)
95 {
96 int owner = _owner;
97 if (lockTaken || (owner & -2147483647) != int.MinValue || CompareExchange(ref _owner, owner | 1, owner, ref lockTaken) != owner)
98 {
99 ContinueTryEnter(-1, ref lockTaken);
100 }
101 }
102
103 public void TryEnter(ref bool lockTaken)
104 {
105 int owner = _owner;
106 if (((owner & int.MinValue) == 0) | lockTaken)
107 {
108 ContinueTryEnter(0, ref lockTaken);
109 }
110 else if (((uint)owner & (true ? 1u : 0u)) != 0)
111 {
112 lockTaken = false;
113 }
114 else
115 {
116 CompareExchange(ref _owner, owner | 1, owner, ref lockTaken);
117 }
118 }
119
120 public void TryEnter(TimeSpan timeout, ref bool lockTaken)
121 {
122 long num = (long)timeout.TotalMilliseconds;
123 if (num < -1 || num > int.MaxValue)
124 {
126 }
127 TryEnter((int)timeout.TotalMilliseconds, ref lockTaken);
128 }
129
130 public void TryEnter(int millisecondsTimeout, ref bool lockTaken)
131 {
132 int owner = _owner;
133 if (((millisecondsTimeout < -1) | lockTaken) || (owner & -2147483647) != int.MinValue || CompareExchange(ref _owner, owner | 1, owner, ref lockTaken) != owner)
134 {
136 }
137 }
138
139 private void ContinueTryEnter(int millisecondsTimeout, ref bool lockTaken)
140 {
141 if (lockTaken)
142 {
143 lockTaken = false;
145 }
146 if (millisecondsTimeout < -1)
147 {
149 }
150 uint startTime = 0u;
152 {
153 startTime = TimeoutHelper.GetTime();
154 }
156 {
158 return;
159 }
160 int num = int.MaxValue;
161 int owner = _owner;
162 if ((owner & 1) == 0)
163 {
164 if (CompareExchange(ref _owner, owner | 1, owner, ref lockTaken) == owner || millisecondsTimeout == 0)
165 {
166 return;
167 }
168 }
169 else
170 {
171 if (millisecondsTimeout == 0)
172 {
173 return;
174 }
175 if ((owner & 0x7FFFFFFE) != 2147483646)
176 {
177 num = (Interlocked.Add(ref _owner, 2) & 0x7FFFFFFE) >> 1;
178 }
179 }
180 SpinWait spinWait = default(SpinWait);
181 if (num > Environment.ProcessorCount)
182 {
183 spinWait.Count = 10;
184 }
185 do
186 {
187 spinWait.SpinOnce(40);
188 owner = _owner;
189 if ((owner & 1) == 0)
190 {
191 int value = (((owner & 0x7FFFFFFE) == 0) ? (owner | 1) : ((owner - 2) | 1));
192 if (CompareExchange(ref _owner, value, owner, ref lockTaken) == owner)
193 {
194 return;
195 }
196 }
197 }
198 while (spinWait.Count % 10 != 0 || millisecondsTimeout == -1 || TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) > 0);
200 }
201
202 private void DecrementWaiters()
203 {
204 SpinWait spinWait = default(SpinWait);
205 while (true)
206 {
207 int owner = _owner;
208 if (((uint)owner & 0x7FFFFFFEu) != 0 && Interlocked.CompareExchange(ref _owner, owner - 2, owner) != owner)
209 {
210 spinWait.SpinOnce();
211 continue;
212 }
213 break;
214 }
215 }
216
217 private void ContinueTryEnterWithThreadTracking(int millisecondsTimeout, uint startTime, ref bool lockTaken)
218 {
219 int currentManagedThreadId = Environment.CurrentManagedThreadId;
220 if (_owner == currentManagedThreadId)
221 {
223 }
224 SpinWait spinWait = default(SpinWait);
225 while (true)
226 {
227 spinWait.SpinOnce();
228 if (_owner == 0 && CompareExchange(ref _owner, currentManagedThreadId, 0, ref lockTaken) == 0)
229 {
230 break;
231 }
232 switch (millisecondsTimeout)
233 {
234 case -1:
235 continue;
236 case 0:
237 return;
238 }
239 if (spinWait.NextSpinWillYield && TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0)
240 {
241 return;
242 }
243 }
244 }
245
246 public void Exit()
247 {
248 if ((_owner & int.MinValue) == 0)
249 {
250 ExitSlowPath(useMemoryBarrier: true);
251 }
252 else
253 {
255 }
256 }
257
258 public void Exit(bool useMemoryBarrier)
259 {
260 int owner = _owner;
261 if ((owner & int.MinValue) != 0 && !useMemoryBarrier)
262 {
263 _owner = owner & -2;
264 }
265 else
266 {
267 ExitSlowPath(useMemoryBarrier);
268 }
269 }
270
271 private void ExitSlowPath(bool useMemoryBarrier)
272 {
273 bool flag = (_owner & int.MinValue) == 0;
274 if (flag && !IsHeldByCurrentThread)
275 {
277 }
278 if (useMemoryBarrier)
279 {
280 if (flag)
281 {
283 }
284 else
285 {
287 }
288 }
289 else if (flag)
290 {
291 _owner = 0;
292 }
293 else
294 {
295 int owner = _owner;
296 _owner = owner & -2;
297 }
298 }
299}
static int ProcessorCount
static int CurrentManagedThreadId
static string SpinLock_Exit_SynchronizationLockException
Definition SR.cs:1910
static string SpinLock_TryEnter_LockRecursionException
Definition SR.cs:1916
static string SpinLock_IsHeldByCurrentThread
Definition SR.cs:1912
static string SpinLock_TryEnter_ArgumentOutOfRange
Definition SR.cs:1914
static string SpinLock_TryReliableEnter_ArgumentException
Definition SR.cs:1918
Definition SR.cs:7
static int CompareExchange(ref int location1, int value, int comparand)
static int Exchange(ref int location1, int value)
static int Decrement(ref int location)
static int Add(ref int location1, int value)
static int UpdateTimeOut(uint startTime, int originalWaitMillisecondsTimeout)
void TryEnter(ref bool lockTaken)
Definition SpinLock.cs:103
void Enter(ref bool lockTaken)
Definition SpinLock.cs:94
SpinLock(bool enableThreadOwnerTracking)
Definition SpinLock.cs:85
void ContinueTryEnterWithThreadTracking(int millisecondsTimeout, uint startTime, ref bool lockTaken)
Definition SpinLock.cs:217
void ContinueTryEnter(int millisecondsTimeout, ref bool lockTaken)
Definition SpinLock.cs:139
void TryEnter(int millisecondsTimeout, ref bool lockTaken)
Definition SpinLock.cs:130
void ExitSlowPath(bool useMemoryBarrier)
Definition SpinLock.cs:271
static int CompareExchange(ref int location, int value, int comparand, ref bool success)
Definition SpinLock.cs:78
void Exit(bool useMemoryBarrier)
Definition SpinLock.cs:258
void TryEnter(TimeSpan timeout, ref bool lockTaken)
Definition SpinLock.cs:120