Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Barrier.cs
Go to the documentation of this file.
3
4namespace System.Threading;
5
6[DebuggerDisplay("Participant Count={ParticipantCount},Participants Remaining={ParticipantsRemaining}")]
7public class Barrier : IDisposable
8{
9 private volatile int _currentTotalCount;
10
11 private long _currentPhase;
12
13 private bool _disposed;
14
16
18
20
22
23 private readonly Action<Barrier> _postPhaseAction;
24
26
27 private int _actionCallerID;
28
30 {
31 get
32 {
33 int currentTotalCount = _currentTotalCount;
34 int num = currentTotalCount & 0x7FFF;
35 int num2 = (currentTotalCount & 0x7FFF0000) >> 16;
36 return num - num2;
37 }
38 }
39
40 public int ParticipantCount => _currentTotalCount & 0x7FFF;
41
43 {
44 get
45 {
46 return Volatile.Read(ref _currentPhase);
47 }
48 internal set
49 {
51 }
52 }
53
54 public Barrier(int participantCount)
55 : this(participantCount, null)
56 {
57 }
58
59 public Barrier(int participantCount, Action<Barrier>? postPhaseAction)
60 {
61 if (participantCount < 0 || participantCount > 32767)
62 {
63 throw new ArgumentOutOfRangeException("participantCount", participantCount, System.SR.Barrier_ctor_ArgumentOutOfRange);
64 }
65 _currentTotalCount = participantCount;
66 _postPhaseAction = postPhaseAction;
67 _oddEvent = new ManualResetEventSlim(initialState: true);
68 _evenEvent = new ManualResetEventSlim(initialState: false);
69 if (postPhaseAction != null)
70 {
72 }
74 }
75
76 private void GetCurrentTotal(int currentTotal, out int current, out int total, out bool sense)
77 {
78 total = currentTotal & 0x7FFF;
79 current = (currentTotal & 0x7FFF0000) >> 16;
80 sense = (currentTotal & int.MinValue) == 0;
81 }
82
83 private bool SetCurrentTotal(int currentTotal, int current, int total, bool sense)
84 {
85 int num = (current << 16) | total;
86 if (!sense)
87 {
88 num |= int.MinValue;
89 }
90 return Interlocked.CompareExchange(ref _currentTotalCount, num, currentTotal) == currentTotal;
91 }
92
93 [UnsupportedOSPlatform("browser")]
94 public long AddParticipant()
95 {
96 try
97 {
98 return AddParticipants(1);
99 }
101 {
103 }
104 }
105
106 [UnsupportedOSPlatform("browser")]
107 public long AddParticipants(int participantCount)
108 {
110 if (participantCount < 1)
111 {
113 }
114 if (participantCount > 32767)
115 {
117 }
119 {
121 }
122 SpinWait spinWait = default(SpinWait);
123 long num = 0L;
124 bool sense;
125 while (true)
126 {
127 int currentTotalCount = _currentTotalCount;
128 GetCurrentTotal(currentTotalCount, out var current, out var total, out sense);
129 if (participantCount + total > 32767)
130 {
132 }
133 if (SetCurrentTotal(currentTotalCount, current, total + participantCount, sense))
134 {
135 break;
136 }
137 spinWait.SpinOnce(-1);
138 }
139 long currentPhaseNumber = CurrentPhaseNumber;
140 num = ((sense != (currentPhaseNumber % 2 == 0)) ? (currentPhaseNumber + 1) : currentPhaseNumber);
141 if (num != currentPhaseNumber)
142 {
143 if (sense)
144 {
145 _oddEvent.Wait();
146 }
147 else
148 {
150 }
151 }
152 else if (sense && _evenEvent.IsSet)
153 {
155 }
156 else if (!sense && _oddEvent.IsSet)
157 {
159 }
160 return num;
161 }
162
163 public void RemoveParticipant()
164 {
166 }
167
168 public void RemoveParticipants(int participantCount)
169 {
171 if (participantCount < 1)
172 {
174 }
176 {
178 }
179 SpinWait spinWait = default(SpinWait);
180 while (true)
181 {
182 int currentTotalCount = _currentTotalCount;
183 GetCurrentTotal(currentTotalCount, out var current, out var total, out var sense);
184 if (total < participantCount)
185 {
187 }
188 if (total - participantCount < current)
189 {
191 }
192 int num = total - participantCount;
193 if (num > 0 && current == num)
194 {
195 if (SetCurrentTotal(currentTotalCount, 0, total - participantCount, !sense))
196 {
197 FinishPhase(sense);
198 break;
199 }
200 }
201 else if (SetCurrentTotal(currentTotalCount, current, total - participantCount, sense))
202 {
203 break;
204 }
205 spinWait.SpinOnce(-1);
206 }
207 }
208
209 [UnsupportedOSPlatform("browser")]
210 public void SignalAndWait()
211 {
213 }
214
215 [UnsupportedOSPlatform("browser")]
220
221 [UnsupportedOSPlatform("browser")]
226
227 [UnsupportedOSPlatform("browser")]
229 {
230 long num = (long)timeout.TotalMilliseconds;
231 if (num < -1 || num > int.MaxValue)
232 {
234 }
235 return SignalAndWait((int)timeout.TotalMilliseconds, cancellationToken);
236 }
237
238 [UnsupportedOSPlatform("browser")]
243
244 [UnsupportedOSPlatform("browser")]
246 {
248 cancellationToken.ThrowIfCancellationRequested();
249 if (millisecondsTimeout < -1)
250 {
252 }
254 {
256 }
257 SpinWait spinWait = default(SpinWait);
258 int current;
259 int total;
260 bool sense;
261 long currentPhaseNumber;
262 while (true)
263 {
264 int currentTotalCount = _currentTotalCount;
265 GetCurrentTotal(currentTotalCount, out current, out total, out sense);
266 currentPhaseNumber = CurrentPhaseNumber;
267 if (total == 0)
268 {
270 }
271 if (current == 0 && sense != (CurrentPhaseNumber % 2 == 0))
272 {
274 }
275 if (current + 1 == total)
276 {
277 if (SetCurrentTotal(currentTotalCount, 0, total, !sense))
278 {
279 if (CdsSyncEtwBCLProvider.Log.IsEnabled())
280 {
281 CdsSyncEtwBCLProvider.Log.Barrier_PhaseFinished(sense, CurrentPhaseNumber);
282 }
283 FinishPhase(sense);
284 return true;
285 }
286 }
287 else if (SetCurrentTotal(currentTotalCount, current + 1, total, sense))
288 {
289 break;
290 }
291 spinWait.SpinOnce(-1);
292 }
293 ManualResetEventSlim currentPhaseEvent = (sense ? _evenEvent : _oddEvent);
294 bool flag = false;
295 bool flag2 = false;
296 try
297 {
298 flag2 = DiscontinuousWait(currentPhaseEvent, millisecondsTimeout, cancellationToken, currentPhaseNumber);
299 }
301 {
302 flag = true;
303 }
305 {
306 if (currentPhaseNumber >= CurrentPhaseNumber)
307 {
308 throw;
309 }
310 flag2 = true;
311 }
312 if (!flag2)
313 {
314 spinWait.Reset();
315 while (true)
316 {
317 int currentTotalCount = _currentTotalCount;
318 GetCurrentTotal(currentTotalCount, out current, out total, out var sense2);
319 if (currentPhaseNumber < CurrentPhaseNumber || sense != sense2)
320 {
321 break;
322 }
323 if (SetCurrentTotal(currentTotalCount, current - 1, total, sense))
324 {
325 if (flag)
326 {
328 }
329 return false;
330 }
331 spinWait.SpinOnce(-1);
332 }
333 WaitCurrentPhase(currentPhaseEvent, currentPhaseNumber);
334 }
335 if (_exception != null)
336 {
338 }
339 return true;
340 }
341
342 private void FinishPhase(bool observedSense)
343 {
344 if (_postPhaseAction != null)
345 {
346 try
347 {
349 if (_ownerThreadContext != null)
350 {
353 }
354 else
355 {
356 _postPhaseAction(this);
357 }
358 _exception = null;
359 return;
360 }
361 catch (Exception exception)
362 {
364 return;
365 }
366 finally
367 {
368 _actionCallerID = 0;
369 SetResetEvents(observedSense);
370 if (_exception != null)
371 {
373 }
374 }
375 }
376 SetResetEvents(observedSense);
377 }
378
379 private static void InvokePostPhaseAction(object obj)
380 {
381 Barrier barrier = (Barrier)obj;
382 barrier._postPhaseAction(barrier);
383 }
384
385 private void SetResetEvents(bool observedSense)
386 {
388 if (observedSense)
389 {
391 _evenEvent.Set();
392 }
393 else
394 {
396 _oddEvent.Set();
397 }
398 }
399
400 private void WaitCurrentPhase(ManualResetEventSlim currentPhaseEvent, long observedPhase)
401 {
402 SpinWait spinWait = default(SpinWait);
403 while (!currentPhaseEvent.IsSet && CurrentPhaseNumber - observedPhase <= 1)
404 {
405 spinWait.SpinOnce();
406 }
407 }
408
409 [UnsupportedOSPlatform("browser")]
410 private bool DiscontinuousWait(ManualResetEventSlim currentPhaseEvent, int totalTimeout, CancellationToken token, long observedPhase)
411 {
412 int num = 100;
413 int num2 = 10000;
414 while (observedPhase == CurrentPhaseNumber)
415 {
416 int num3 = ((totalTimeout == -1) ? num : Math.Min(num, totalTimeout));
417 if (currentPhaseEvent.Wait(num3, token))
418 {
419 return true;
420 }
421 if (totalTimeout != -1)
422 {
423 totalTimeout -= num3;
424 if (totalTimeout <= 0)
425 {
426 return false;
427 }
428 }
429 num = ((num >= num2) ? num2 : Math.Min(num << 1, num2));
430 }
431 WaitCurrentPhase(currentPhaseEvent, observedPhase);
432 return true;
433 }
434
435 public void Dispose()
436 {
438 {
440 }
441 Dispose(disposing: true);
442 GC.SuppressFinalize(this);
443 }
444
445 protected virtual void Dispose(bool disposing)
446 {
447 if (!_disposed)
448 {
449 if (disposing)
450 {
453 }
454 _disposed = true;
455 }
456 }
457
458 private void ThrowIfDisposed()
459 {
460 if (_disposed)
461 {
462 throw new ObjectDisposedException("Barrier", System.SR.Barrier_Dispose);
463 }
464 }
465}
static int CurrentManagedThreadId
static void SuppressFinalize(object obj)
Definition GC.cs:202
Definition GC.cs:8
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static string Barrier_SignalAndWait_InvalidOperation_ThreadsExceeded
Definition SR.cs:38
static string Barrier_AddParticipants_NonPositive_ArgumentOutOfRange
Definition SR.cs:36
static string Barrier_AddParticipants_Overflow_ArgumentOutOfRange
Definition SR.cs:44
static string Barrier_ctor_ArgumentOutOfRange
Definition SR.cs:42
static string Barrier_InvalidOperation_CalledFromPHA
Definition SR.cs:34
static string Barrier_RemoveParticipants_NonPositive_ArgumentOutOfRange
Definition SR.cs:32
static string Barrier_SignalAndWait_ArgumentOutOfRange
Definition SR.cs:26
static string Barrier_Dispose
Definition SR.cs:22
static string Barrier_RemoveParticipants_InvalidOperation
Definition SR.cs:28
static string Barrier_SignalAndWait_InvalidOperation_ZeroTotal
Definition SR.cs:24
static string Barrier_RemoveParticipants_ArgumentOutOfRange
Definition SR.cs:30
static string Common_OperationCanceled
Definition SR.cs:20
Definition SR.cs:7
void FinishPhase(bool observedSense)
Definition Barrier.cs:342
static void InvokePostPhaseAction(object obj)
Definition Barrier.cs:379
Barrier(int participantCount)
Definition Barrier.cs:54
bool SignalAndWait(TimeSpan timeout, CancellationToken cancellationToken)
Definition Barrier.cs:228
void SetResetEvents(bool observedSense)
Definition Barrier.cs:385
void GetCurrentTotal(int currentTotal, out int current, out int total, out bool sense)
Definition Barrier.cs:76
readonly Action< Barrier > _postPhaseAction
Definition Barrier.cs:23
long AddParticipants(int participantCount)
Definition Barrier.cs:107
void RemoveParticipants(int participantCount)
Definition Barrier.cs:168
static ContextCallback s_invokePostPhaseAction
Definition Barrier.cs:21
bool SetCurrentTotal(int currentTotal, int current, int total, bool sense)
Definition Barrier.cs:83
virtual void Dispose(bool disposing)
Definition Barrier.cs:445
volatile int _currentTotalCount
Definition Barrier.cs:9
bool SignalAndWait(int millisecondsTimeout, CancellationToken cancellationToken)
Definition Barrier.cs:245
readonly ManualResetEventSlim _oddEvent
Definition Barrier.cs:15
readonly ManualResetEventSlim _evenEvent
Definition Barrier.cs:17
bool SignalAndWait(TimeSpan timeout)
Definition Barrier.cs:222
bool DiscontinuousWait(ManualResetEventSlim currentPhaseEvent, int totalTimeout, CancellationToken token, long observedPhase)
Definition Barrier.cs:410
bool SignalAndWait(int millisecondsTimeout)
Definition Barrier.cs:239
readonly ExecutionContext _ownerThreadContext
Definition Barrier.cs:19
void WaitCurrentPhase(ManualResetEventSlim currentPhaseEvent, long observedPhase)
Definition Barrier.cs:400
Barrier(int participantCount, Action< Barrier >? postPhaseAction)
Definition Barrier.cs:59
void SignalAndWait(CancellationToken cancellationToken)
Definition Barrier.cs:216
static ? ExecutionContext Capture()
static void Run(ExecutionContext executionContext, ContextCallback callback, object? state)
static int CompareExchange(ref int location1, int value, int comparand)
static bool Read(ref bool location)
Definition Volatile.cs:67
static void Write(ref bool location, bool value)
Definition Volatile.cs:74
delegate void ContextCallback(object? state)