ReactOS 0.4.16-dev-91-g764881a
srw.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * PURPOSE: Slim Reader/Writer (SRW) Routines
5 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
6 *
7 * NOTES: The algorithms used in this implementation
8 * may be different from Vista's implementation.
9 * Since applications should treat the RTL_SRWLOCK
10 * structure as opaque data, it should not matter.
11 * The algorithms are probably not as optimized.
12 */
13
14/* INCLUDES *****************************************************************/
15
16#include <rtl_vista.h>
17
18#define NDEBUG
19#include <debug.h>
20
21/* FUNCTIONS *****************************************************************/
22
23#ifdef _WIN64
24#define InterlockedBitTestAndSetPointer(ptr,val) InterlockedBitTestAndSet64((PLONGLONG)ptr,(LONGLONG)val)
25#define InterlockedAddPointer(ptr,val) InterlockedAdd64((PLONGLONG)ptr,(LONGLONG)val)
26#define InterlockedAndPointer(ptr,val) InterlockedAnd64((PLONGLONG)ptr,(LONGLONG)val)
27#define InterlockedOrPointer(ptr,val) InterlockedOr64((PLONGLONG)ptr,(LONGLONG)val)
28#define _ONE 1LL
29#else
30#define InterlockedBitTestAndSetPointer(ptr,val) InterlockedBitTestAndSet((PLONG)ptr,(LONG)val)
31#define InterlockedAddPointer(ptr,val) InterlockedAdd((PLONG)ptr,(LONG)val)
32#define InterlockedAndPointer(ptr,val) InterlockedAnd((PLONG)ptr,(LONG)val)
33#define InterlockedOrPointer(ptr,val) InterlockedOr((PLONG)ptr,(LONG)val)
34#define _ONE 1L
35#endif
36
37#define RTL_SRWLOCK_OWNED_BIT 0
38#define RTL_SRWLOCK_CONTENDED_BIT 1
39#define RTL_SRWLOCK_SHARED_BIT 2
40#define RTL_SRWLOCK_CONTENTION_LOCK_BIT 3
41#define RTL_SRWLOCK_OWNED (_ONE << RTL_SRWLOCK_OWNED_BIT)
42#define RTL_SRWLOCK_CONTENDED (_ONE << RTL_SRWLOCK_CONTENDED_BIT)
43#define RTL_SRWLOCK_SHARED (_ONE << RTL_SRWLOCK_SHARED_BIT)
44#define RTL_SRWLOCK_CONTENTION_LOCK (_ONE << RTL_SRWLOCK_CONTENTION_LOCK_BIT)
45#define RTL_SRWLOCK_MASK (RTL_SRWLOCK_OWNED | RTL_SRWLOCK_CONTENDED | \
46 RTL_SRWLOCK_SHARED | RTL_SRWLOCK_CONTENTION_LOCK)
47#define RTL_SRWLOCK_BITS 4
48
50{
54
56{
57 /* SharedCount is the number of shared acquirers. */
59
60 /* Last points to the last wait block in the chain. The value
61 is only valid when read from the first wait block. */
62 volatile struct _RTLP_SRWLOCK_WAITBLOCK *Last;
63
64 /* Next points to the next wait block in the chain. */
65 volatile struct _RTLP_SRWLOCK_WAITBLOCK *Next;
66
67 union
68 {
69 /* Wake is only valid for exclusive wait blocks */
71 /* The wake chain is only valid for shared wait blocks */
72 struct
73 {
76 };
77 };
78
81
82
83static VOID
86 IN PRTLP_SRWLOCK_WAITBLOCK FirstWaitBlock)
87{
89 LONG_PTR NewValue;
90
91 /* NOTE: We're currently in an exclusive lock in contended mode. */
92
93 Next = FirstWaitBlock->Next;
94 if (Next != NULL)
95 {
96 /* There's more blocks chained, we need to update the pointers
97 in the next wait block and update the wait block pointer. */
99 if (!FirstWaitBlock->Exclusive)
100 {
101 /* The next wait block has to be an exclusive lock! */
102 ASSERT(Next->Exclusive);
103
104 /* Save the shared count */
105 Next->SharedCount = FirstWaitBlock->SharedCount;
106
107 NewValue |= RTL_SRWLOCK_SHARED;
108 }
109
110 Next->Last = FirstWaitBlock->Last;
111 }
112 else
113 {
114 /* Convert the lock to a simple lock. */
115 if (FirstWaitBlock->Exclusive)
116 NewValue = RTL_SRWLOCK_OWNED;
117 else
118 {
119 ASSERT(FirstWaitBlock->SharedCount > 0);
120
121 NewValue = ((LONG_PTR)FirstWaitBlock->SharedCount << RTL_SRWLOCK_BITS) |
123 }
124 }
125
126 (void)InterlockedExchangePointer(&SRWLock->Ptr, (PVOID)NewValue);
127
128 if (FirstWaitBlock->Exclusive)
129 {
130 (void)InterlockedOr(&FirstWaitBlock->Wake,
131 TRUE);
132 }
133 else
134 {
135 PRTLP_SRWLOCK_SHARED_WAKE WakeChain, NextWake;
136
137 /* If we were the first one to acquire the shared
138 lock, we now need to wake all others... */
139 WakeChain = FirstWaitBlock->SharedWakeChain;
140 do
141 {
142 NextWake = WakeChain->Next;
143
144 (void)InterlockedOr((PLONG)&WakeChain->Wake,
145 TRUE);
146
147 WakeChain = NextWake;
148 } while (WakeChain != NULL);
149 }
150}
151
152
153static VOID
154NTAPI
156 IN PRTLP_SRWLOCK_WAITBLOCK FirstWaitBlock)
157{
159 LONG_PTR NewValue;
160
161 /* NOTE: We're currently in a shared lock in contended mode. */
162
163 /* The next acquirer to be unwaited *must* be an exclusive lock! */
164 ASSERT(FirstWaitBlock->Exclusive);
165
166 Next = FirstWaitBlock->Next;
167 if (Next != NULL)
168 {
169 /* There's more blocks chained, we need to update the pointers
170 in the next wait block and update the wait block pointer. */
172
173 Next->Last = FirstWaitBlock->Last;
174 }
175 else
176 {
177 /* Convert the lock to a simple exclusive lock. */
178 NewValue = RTL_SRWLOCK_OWNED;
179 }
180
181 (void)InterlockedExchangePointer(&SRWLock->Ptr, (PVOID)NewValue);
182
183 (void)InterlockedOr(&FirstWaitBlock->Wake,
184 TRUE);
185}
186
187
188static VOID
189NTAPI
191{
192 InterlockedAndPointer(&SRWLock->Ptr,
194}
195
196
198NTAPI
200{
201 LONG_PTR PrevValue;
202 PRTLP_SRWLOCK_WAITBLOCK WaitBlock;
203
204 while (1)
205 {
206 PrevValue = InterlockedOrPointer(&SRWLock->Ptr,
208
209 if (!(PrevValue & RTL_SRWLOCK_CONTENTION_LOCK))
210 break;
211
213 }
214
215 if (!(PrevValue & RTL_SRWLOCK_CONTENDED) ||
216 (PrevValue & ~RTL_SRWLOCK_MASK) == 0)
217 {
218 /* Too bad, looks like the wait block was removed in the
219 meanwhile, unlock again */
221 return NULL;
222 }
223
224 WaitBlock = (PRTLP_SRWLOCK_WAITBLOCK)(PrevValue & ~RTL_SRWLOCK_MASK);
225
226 return WaitBlock;
227}
228
229
230static VOID
231NTAPI
233 IN PRTLP_SRWLOCK_WAITBLOCK WaitBlock)
234{
235 LONG_PTR CurrentValue;
236
237 while (1)
238 {
239 CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
240 if (!(CurrentValue & RTL_SRWLOCK_SHARED))
241 {
242 if (CurrentValue & RTL_SRWLOCK_CONTENDED)
243 {
244 if (WaitBlock->Wake != 0)
245 {
246 /* Our wait block became the first one
247 in the chain, we own the lock now! */
248 break;
249 }
250 }
251 else
252 {
253 /* The last wait block was removed and/or we're
254 finally a simple exclusive lock. This means we
255 don't need to wait anymore, we acquired the lock! */
256 break;
257 }
258 }
259
261 }
262}
263
264
265static VOID
266NTAPI
270{
271 if (FirstWait != NULL)
272 {
273 while (WakeChain->Wake == 0)
274 {
276 }
277 }
278 else
279 {
280 LONG_PTR CurrentValue;
281
282 while (1)
283 {
284 CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
285 if (CurrentValue & RTL_SRWLOCK_SHARED)
286 {
287 /* The RTL_SRWLOCK_OWNED bit always needs to be set when
288 RTL_SRWLOCK_SHARED is set! */
289 ASSERT(CurrentValue & RTL_SRWLOCK_OWNED);
290
291 if (CurrentValue & RTL_SRWLOCK_CONTENDED)
292 {
293 if (WakeChain->Wake != 0)
294 {
295 /* Our wait block became the first one
296 in the chain, we own the lock now! */
297 break;
298 }
299 }
300 else
301 {
302 /* The last wait block was removed and/or we're
303 finally a simple shared lock. This means we
304 don't need to wait anymore, we acquired the lock! */
305 break;
306 }
307 }
308
310 }
311 }
312}
313
314
315VOID
316NTAPI
318{
319 SRWLock->Ptr = NULL;
320}
321
322
323VOID
324NTAPI
326{
327 __ALIGNED(16) RTLP_SRWLOCK_WAITBLOCK StackWaitBlock;
328 RTLP_SRWLOCK_SHARED_WAKE SharedWake;
329 LONG_PTR CurrentValue, NewValue;
330 PRTLP_SRWLOCK_WAITBLOCK First, Shared, FirstWait;
331
332 while (1)
333 {
334 CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
335
336 if (CurrentValue & RTL_SRWLOCK_SHARED)
337 {
338 /* NOTE: It is possible that the RTL_SRWLOCK_OWNED bit is set! */
339
340 if (CurrentValue & RTL_SRWLOCK_CONTENDED)
341 {
342 /* There's other waiters already, lock the wait blocks and
343 increment the shared count */
345 if (First != NULL)
346 {
347 FirstWait = NULL;
348
349 if (First->Exclusive)
350 {
351 /* We need to setup a new wait block! Although
352 we're currently in a shared lock and we're acquiring
353 a shared lock, there are exclusive locks queued. We need
354 to wait until those are released. */
355 Shared = First->Last;
356
357 if (Shared->Exclusive)
358 {
359 StackWaitBlock.Exclusive = FALSE;
360 StackWaitBlock.SharedCount = 1;
361 StackWaitBlock.Next = NULL;
362 StackWaitBlock.Last = &StackWaitBlock;
363 StackWaitBlock.SharedWakeChain = &SharedWake;
364
365 Shared->Next = &StackWaitBlock;
366 First->Last = &StackWaitBlock;
367
368 Shared = &StackWaitBlock;
369 FirstWait = &StackWaitBlock;
370 }
371 else
372 {
373 Shared->LastSharedWake->Next = &SharedWake;
374 Shared->SharedCount++;
375 }
376 }
377 else
378 {
379 Shared = First;
380 Shared->LastSharedWake->Next = &SharedWake;
381 Shared->SharedCount++;
382 }
383
384 SharedWake.Next = NULL;
385 SharedWake.Wake = 0;
386
387 Shared->LastSharedWake = &SharedWake;
388
390
392 FirstWait,
393 &SharedWake);
394
395 /* Successfully incremented the shared count, we acquired the lock */
396 break;
397 }
398 }
399 else
400 {
401 /* This is a fastest path, just increment the number of
402 current shared locks */
403
404 /* Since the RTL_SRWLOCK_SHARED bit is set, the RTL_SRWLOCK_OWNED bit also has
405 to be set! */
406
407 ASSERT(CurrentValue & RTL_SRWLOCK_OWNED);
408
409 NewValue = (CurrentValue >> RTL_SRWLOCK_BITS) + 1;
410 NewValue = (NewValue << RTL_SRWLOCK_BITS) | (CurrentValue & RTL_SRWLOCK_MASK);
411
413 (PVOID)NewValue,
414 (PVOID)CurrentValue) == CurrentValue)
415 {
416 /* Successfully incremented the shared count, we acquired the lock */
417 break;
418 }
419 }
420 }
421 else
422 {
423 if (CurrentValue & RTL_SRWLOCK_OWNED)
424 {
425 /* The resource is currently acquired exclusively */
426 if (CurrentValue & RTL_SRWLOCK_CONTENDED)
427 {
428 SharedWake.Next = NULL;
429 SharedWake.Wake = 0;
430
431 /* There's other waiters already, lock the wait blocks and
432 increment the shared count. If the last block in the chain
433 is an exclusive lock, add another block. */
434
435 StackWaitBlock.Exclusive = FALSE;
436 StackWaitBlock.SharedCount = 0;
437 StackWaitBlock.Next = NULL;
438 StackWaitBlock.Last = &StackWaitBlock;
439 StackWaitBlock.SharedWakeChain = &SharedWake;
440
442 if (First != NULL)
443 {
444 Shared = First->Last;
445 if (Shared->Exclusive)
446 {
447 Shared->Next = &StackWaitBlock;
448 First->Last = &StackWaitBlock;
449
450 Shared = &StackWaitBlock;
451 FirstWait = &StackWaitBlock;
452 }
453 else
454 {
455 FirstWait = NULL;
456 Shared->LastSharedWake->Next = &SharedWake;
457 }
458
459 Shared->SharedCount++;
460 Shared->LastSharedWake = &SharedWake;
461
463
465 FirstWait,
466 &SharedWake);
467
468 /* Successfully incremented the shared count, we acquired the lock */
469 break;
470 }
471 }
472 else
473 {
474 SharedWake.Next = NULL;
475 SharedWake.Wake = 0;
476
477 /* We need to setup the first wait block. Currently an exclusive lock is
478 held, change the lock to contended mode. */
479 StackWaitBlock.Exclusive = FALSE;
480 StackWaitBlock.SharedCount = 1;
481 StackWaitBlock.Next = NULL;
482 StackWaitBlock.Last = &StackWaitBlock;
483 StackWaitBlock.SharedWakeChain = &SharedWake;
484 StackWaitBlock.LastSharedWake = &SharedWake;
485
486 NewValue = (ULONG_PTR)&StackWaitBlock | RTL_SRWLOCK_OWNED | RTL_SRWLOCK_CONTENDED;
488 (PVOID)NewValue,
489 (PVOID)CurrentValue) == CurrentValue)
490 {
492 &StackWaitBlock,
493 &SharedWake);
494
495 /* Successfully set the shared count, we acquired the lock */
496 break;
497 }
498 }
499 }
500 else
501 {
502 /* This is a fast path, we can simply try to set the shared count to 1 */
504
505 /* The RTL_SRWLOCK_CONTENDED bit should never be set if neither the
506 RTL_SRWLOCK_SHARED nor the RTL_SRWLOCK_OWNED bit is set */
507 ASSERT(!(CurrentValue & RTL_SRWLOCK_CONTENDED));
508
510 (PVOID)NewValue,
511 (PVOID)CurrentValue) == CurrentValue)
512 {
513 /* Successfully set the shared count, we acquired the lock */
514 break;
515 }
516 }
517 }
518
520 }
521}
522
523
524VOID
525NTAPI
527{
528 LONG_PTR CurrentValue, NewValue;
529 PRTLP_SRWLOCK_WAITBLOCK WaitBlock;
530 BOOLEAN LastShared;
531
532 while (1)
533 {
534 CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
535
536 if (CurrentValue & RTL_SRWLOCK_SHARED)
537 {
538 if (CurrentValue & RTL_SRWLOCK_CONTENDED)
539 {
540 /* There's a wait block, we need to wake a pending
541 exclusive acquirer if this is the last shared release */
542 WaitBlock = RtlpAcquireWaitBlockLock(SRWLock);
543 if (WaitBlock != NULL)
544 {
545 LastShared = (--WaitBlock->SharedCount == 0);
546
547 if (LastShared)
549 WaitBlock);
550 else
552
553 /* We released the lock */
554 break;
555 }
556 }
557 else
558 {
559 /* This is a fast path, we can simply decrement the shared
560 count and store the pointer */
561 NewValue = CurrentValue >> RTL_SRWLOCK_BITS;
562
563 if (--NewValue != 0)
564 {
565 NewValue = (NewValue << RTL_SRWLOCK_BITS) | RTL_SRWLOCK_SHARED | RTL_SRWLOCK_OWNED;
566 }
567
569 (PVOID)NewValue,
570 (PVOID)CurrentValue) == CurrentValue)
571 {
572 /* Successfully released the lock */
573 break;
574 }
575 }
576 }
577 else
578 {
579 /* The RTL_SRWLOCK_SHARED bit has to be present now,
580 even in the contended case! */
582 }
583
585 }
586}
587
588
589VOID
590NTAPI
592{
593 __ALIGNED(16) RTLP_SRWLOCK_WAITBLOCK StackWaitBlock;
595
596 if (InterlockedBitTestAndSetPointer(&SRWLock->Ptr,
598 {
599 LONG_PTR CurrentValue, NewValue;
600
601 while (1)
602 {
603 CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
604
605 if (CurrentValue & RTL_SRWLOCK_SHARED)
606 {
607 /* A shared lock is being held right now. We need to add a wait block! */
608
609 if (CurrentValue & RTL_SRWLOCK_CONTENDED)
610 {
611 goto AddWaitBlock;
612 }
613 else
614 {
615 /* There are no wait blocks so far, we need to add ourselves as the first
616 wait block. We need to keep the shared count! */
617 StackWaitBlock.Exclusive = TRUE;
618 StackWaitBlock.SharedCount = (LONG)(CurrentValue >> RTL_SRWLOCK_BITS);
619 StackWaitBlock.Next = NULL;
620 StackWaitBlock.Last = &StackWaitBlock;
621 StackWaitBlock.Wake = 0;
622
624
626 (PVOID)NewValue,
627 (PVOID)CurrentValue) == CurrentValue)
628 {
630 &StackWaitBlock);
631
632 /* Successfully acquired the exclusive lock */
633 break;
634 }
635 }
636 }
637 else
638 {
639 if (CurrentValue & RTL_SRWLOCK_OWNED)
640 {
641 /* An exclusive lock is being held right now. We need to add a wait block! */
642
643 if (CurrentValue & RTL_SRWLOCK_CONTENDED)
644 {
645AddWaitBlock:
646 StackWaitBlock.Exclusive = TRUE;
647 StackWaitBlock.SharedCount = 0;
648 StackWaitBlock.Next = NULL;
649 StackWaitBlock.Last = &StackWaitBlock;
650 StackWaitBlock.Wake = 0;
651
653 if (First != NULL)
654 {
655 Last = First->Last;
656 Last->Next = &StackWaitBlock;
657 First->Last = &StackWaitBlock;
658
660
662 &StackWaitBlock);
663
664 /* Successfully acquired the exclusive lock */
665 break;
666 }
667 }
668 else
669 {
670 /* There are no wait blocks so far, we need to add ourselves as the first
671 wait block. We need to keep the shared count! */
672 StackWaitBlock.Exclusive = TRUE;
673 StackWaitBlock.SharedCount = 0;
674 StackWaitBlock.Next = NULL;
675 StackWaitBlock.Last = &StackWaitBlock;
676 StackWaitBlock.Wake = 0;
677
678 NewValue = (ULONG_PTR)&StackWaitBlock | RTL_SRWLOCK_OWNED | RTL_SRWLOCK_CONTENDED;
680 (PVOID)NewValue,
681 (PVOID)CurrentValue) == CurrentValue)
682 {
684 &StackWaitBlock);
685
686 /* Successfully acquired the exclusive lock */
687 break;
688 }
689 }
690 }
691 else
692 {
693 if (!InterlockedBitTestAndSetPointer(&SRWLock->Ptr,
695 {
696 /* We managed to get hold of a simple exclusive lock! */
697 break;
698 }
699 }
700 }
701
703 }
704 }
705}
706
707
708VOID
709NTAPI
711{
712 LONG_PTR CurrentValue, NewValue;
713 PRTLP_SRWLOCK_WAITBLOCK WaitBlock;
714
715 while (1)
716 {
717 CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
718
719 if (!(CurrentValue & RTL_SRWLOCK_OWNED))
720 {
722 }
723
724 if (!(CurrentValue & RTL_SRWLOCK_SHARED))
725 {
726 if (CurrentValue & RTL_SRWLOCK_CONTENDED)
727 {
728 /* There's a wait block, we need to wake the next pending
729 acquirer (exclusive or shared) */
730 WaitBlock = RtlpAcquireWaitBlockLock(SRWLock);
731 if (WaitBlock != NULL)
732 {
734 WaitBlock);
735
736 /* We released the lock */
737 break;
738 }
739 }
740 else
741 {
742 /* This is a fast path, we can simply clear the RTL_SRWLOCK_OWNED
743 bit. All other bits should be 0 now because this is a simple
744 exclusive lock and no one is waiting. */
745
746 ASSERT(!(CurrentValue & ~RTL_SRWLOCK_OWNED));
747
748 NewValue = 0;
750 (PVOID)NewValue,
751 (PVOID)CurrentValue) == CurrentValue)
752 {
753 /* We released the lock */
754 break;
755 }
756 }
757 }
758 else
759 {
760 /* The RTL_SRWLOCK_SHARED bit must not be present now,
761 not even in the contended case! */
763 }
764
766 }
767}
768
770NTAPI
772{
773
774 LONG_PTR CompareValue, NewValue, GotValue;
775
776 do
777 {
778 CompareValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
779 NewValue = ((CompareValue >> RTL_SRWLOCK_BITS) + 1) | RTL_SRWLOCK_SHARED | RTL_SRWLOCK_OWNED;
780
781 /* Only increment shared count if there is no waiter */
782 CompareValue &= ~RTL_SRWLOCK_MASK | RTL_SRWLOCK_SHARED | RTL_SRWLOCK_OWNED;
783 } while (
784 ((GotValue = (LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr, (LONG_PTR*)NewValue, (LONG_PTR*)CompareValue)) != CompareValue)
785 && (((GotValue & RTL_SRWLOCK_MASK) == (RTL_SRWLOCK_SHARED | RTL_SRWLOCK_OWNED)) || (GotValue == 0)));
786
787 return ((GotValue & RTL_SRWLOCK_MASK) == (RTL_SRWLOCK_SHARED | RTL_SRWLOCK_OWNED)) || (GotValue == 0);
788}
789
791NTAPI
793{
795}
WCHAR First[]
Definition: FormatMessage.c:11
unsigned char BOOLEAN
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ULONG_PTR
Definition: config.h:101
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
#define InterlockedOr
Definition: interlocked.h:224
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
typedef __ALIGNED(16) struct _EX_PUSH_LOCK_WAIT_BLOCK
Definition: extypes.h:483
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
#define STATUS_RESOURCE_NOT_OWNED
Definition: ntstatus.h:737
long LONG
Definition: pedump.c:60
#define YieldProcessor
Definition: ke.h:48
static VOID NTAPI RtlpReleaseWaitBlockLockLastShared(IN OUT PRTL_SRWLOCK SRWLock, IN PRTLP_SRWLOCK_WAITBLOCK FirstWaitBlock)
Definition: srw.c:155
struct _RTLP_SRWLOCK_SHARED_WAKE * PRTLP_SRWLOCK_SHARED_WAKE
#define RTL_SRWLOCK_CONTENDED
Definition: srw.c:42
static VOID NTAPI RtlpAcquireSRWLockSharedWait(IN OUT PRTL_SRWLOCK SRWLock, IN OUT PRTLP_SRWLOCK_WAITBLOCK FirstWait OPTIONAL, IN OUT PRTLP_SRWLOCK_SHARED_WAKE WakeChain)
Definition: srw.c:267
static VOID NTAPI RtlpReleaseWaitBlockLock(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:190
#define RTL_SRWLOCK_BITS
Definition: srw.c:47
#define RTL_SRWLOCK_CONTENTION_LOCK
Definition: srw.c:44
static VOID NTAPI RtlpAcquireSRWLockExclusiveWait(IN OUT PRTL_SRWLOCK SRWLock, IN PRTLP_SRWLOCK_WAITBLOCK WaitBlock)
Definition: srw.c:232
#define RTL_SRWLOCK_SHARED
Definition: srw.c:43
#define RTL_SRWLOCK_OWNED
Definition: srw.c:41
#define InterlockedOrPointer(ptr, val)
Definition: srw.c:33
struct _RTLP_SRWLOCK_WAITBLOCK * PRTLP_SRWLOCK_WAITBLOCK
static VOID NTAPI RtlpReleaseWaitBlockLockExclusive(IN OUT PRTL_SRWLOCK SRWLock, IN PRTLP_SRWLOCK_WAITBLOCK FirstWaitBlock)
Definition: srw.c:85
VOID NTAPI RtlReleaseSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:710
BOOLEAN NTAPI RtlTryAcquireSRWLockExclusive(PRTL_SRWLOCK SRWLock)
Definition: srw.c:792
VOID NTAPI RtlInitializeSRWLock(OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:317
#define InterlockedBitTestAndSetPointer(ptr, val)
Definition: srw.c:30
#define RTL_SRWLOCK_OWNED_BIT
Definition: srw.c:37
VOID NTAPI RtlAcquireSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:591
struct _RTLP_SRWLOCK_SHARED_WAKE RTLP_SRWLOCK_SHARED_WAKE
BOOLEAN NTAPI RtlTryAcquireSRWLockShared(PRTL_SRWLOCK SRWLock)
Definition: srw.c:771
#define InterlockedAndPointer(ptr, val)
Definition: srw.c:32
#define RTL_SRWLOCK_MASK
Definition: srw.c:45
VOID NTAPI RtlReleaseSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:526
VOID NTAPI RtlAcquireSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:325
struct _RTLP_SRWLOCK_WAITBLOCK RTLP_SRWLOCK_WAITBLOCK
static PRTLP_SRWLOCK_WAITBLOCK NTAPI RtlpAcquireWaitBlockLock(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:199
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
volatile struct _RTLP_SRWLOCK_SHARED_WAKE * Next
Definition: srw.c:52
volatile struct _RTLP_SRWLOCK_WAITBLOCK * Last
Definition: srw.c:62
BOOLEAN Exclusive
Definition: srw.c:79
PRTLP_SRWLOCK_SHARED_WAKE SharedWakeChain
Definition: srw.c:74
volatile struct _RTLP_SRWLOCK_WAITBLOCK * Next
Definition: srw.c:65
PRTLP_SRWLOCK_SHARED_WAKE LastSharedWake
Definition: srw.c:75
PVOID Ptr
Definition: rtltypes.h:292
#define LONG_PTR
Definition: treelist.c:79
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
#define OUT
Definition: typedefs.h:40