ReactOS  0.4.13-dev-257-gfabbd7c
sync.c File Reference
#include "k32_vista.h"
#include <debug.h>
Include dependency graph for sync.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI RtlInitializeConditionVariable (OUT PRTL_CONDITION_VARIABLE ConditionVariable)
 
VOID NTAPI RtlWakeConditionVariable (IN OUT PRTL_CONDITION_VARIABLE ConditionVariable)
 
VOID NTAPI RtlWakeAllConditionVariable (IN OUT PRTL_CONDITION_VARIABLE ConditionVariable)
 
NTSTATUS NTAPI RtlSleepConditionVariableCS (IN OUT PRTL_CONDITION_VARIABLE ConditionVariable, IN OUT PRTL_CRITICAL_SECTION CriticalSection, IN PLARGE_INTEGER TimeOut OPTIONAL)
 
NTSTATUS NTAPI RtlSleepConditionVariableSRW (IN OUT PRTL_CONDITION_VARIABLE ConditionVariable, IN OUT PRTL_SRWLOCK SRWLock, IN PLARGE_INTEGER TimeOut OPTIONAL, IN ULONG Flags)
 
VOID NTAPI RtlInitializeSRWLock (OUT PRTL_SRWLOCK SRWLock)
 
VOID NTAPI RtlAcquireSRWLockShared (IN OUT PRTL_SRWLOCK SRWLock)
 
VOID NTAPI RtlReleaseSRWLockShared (IN OUT PRTL_SRWLOCK SRWLock)
 
VOID NTAPI RtlAcquireSRWLockExclusive (IN OUT PRTL_SRWLOCK SRWLock)
 
VOID NTAPI RtlReleaseSRWLockExclusive (IN OUT PRTL_SRWLOCK SRWLock)
 
VOID WINAPI AcquireSRWLockExclusive (PSRWLOCK Lock)
 
VOID WINAPI AcquireSRWLockShared (PSRWLOCK Lock)
 
VOID WINAPI InitializeConditionVariable (PCONDITION_VARIABLE ConditionVariable)
 
VOID WINAPI InitializeSRWLock (PSRWLOCK Lock)
 
VOID WINAPI ReleaseSRWLockExclusive (PSRWLOCK Lock)
 
VOID WINAPI ReleaseSRWLockShared (PSRWLOCK Lock)
 
FORCEINLINE PLARGE_INTEGER GetNtTimeout (PLARGE_INTEGER Time, DWORD Timeout)
 
BOOL WINAPI SleepConditionVariableCS (PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD Timeout)
 
BOOL WINAPI SleepConditionVariableSRW (PCONDITION_VARIABLE ConditionVariable, PSRWLOCK Lock, DWORD Timeout, ULONG Flags)
 
VOID WINAPI WakeAllConditionVariable (PCONDITION_VARIABLE ConditionVariable)
 
VOID WINAPI WakeConditionVariable (PCONDITION_VARIABLE ConditionVariable)
 
BOOL WINAPI InitializeCriticalSectionEx (OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 3 of file sync.c.

Function Documentation

◆ AcquireSRWLockExclusive()

VOID WINAPI AcquireSRWLockExclusive ( PSRWLOCK  Lock)

Definition at line 54 of file sync.c.

55 {
57 }
VOID NTAPI RtlAcquireSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:589
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75

Referenced by cache_insert(), compound_encode_send_decode(), create_new_rpc_auth(), deleg_lock_update(), delegation_flush_locks(), delegation_recovery_status(), delegation_remove(), delete_stale_component(), device_fetch(), do_open(), file_layout_fetch(), file_layout_recall(), file_layout_return(), get_volume_size_info(), handle_nfs41_set_size(), layout_commit(), nfs41_attr_cache_update(), nfs41_client_delegation_return_lru(), nfs41_client_renew(), nfs41_delegate_open(), nfs41_delegation_recall(), nfs41_delegation_remove_srvopen(), nfs41_delegation_return(), nfs41_delegation_to_open(), nfs41_name_cache_delegreturn(), nfs41_name_cache_insert(), nfs41_name_cache_remove(), nfs41_name_cache_rename(), nfs41_send_compound(), nfs41_session_create(), nfs41_session_free(), nfs41_session_renew(), nfs41_superblock_for_fh(), nfs41_superblock_space_changed(), open_lock_add(), open_lock_delegate(), open_state_rename(), open_unlock_delegate(), open_unlock_remove(), pnfs_data_server_client(), pnfs_layout_io_finished(), pnfs_layout_recall_fenced(), pnfs_layout_state_close(), pnfs_layout_state_open(), pnfs_read(), pnfs_write(), recover_delegation_open(), recover_delegation_want(), recover_locks(), recover_open(), referral_resolve(), rpc_reconnect(), rpc_renew_in_progress(), rpc_should_retry(), and server_addrs_add().

◆ AcquireSRWLockShared()

VOID WINAPI AcquireSRWLockShared ( PSRWLOCK  Lock)

Definition at line 61 of file sync.c.

62 {
64 }
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
VOID NTAPI RtlAcquireSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:323

Referenced by cache_lookup(), cl_addr_compare(), cl_exid_compare(), client_server(), client_supports_pnfs(), compound_encode_send_decode(), deleg_lock_find(), delegation_flush_locks(), delegation_return(), file_layout_return(), get_path_fhs(), get_volume_size_info(), layout_commit(), lock_stateid_arg(), nfs41_attr_cache_lookup(), nfs41_create(), nfs41_create_session(), nfs41_delegation_getattr(), nfs41_delegation_to_open(), nfs41_delegreturn(), nfs41_link(), nfs41_lookup(), nfs41_name_cache_lookup(), nfs41_name_cache_remove_stale(), nfs41_open_stateid_arg(), nfs41_remove(), nfs41_rename(), nfs41_rpc_netaddr(), nfs41_send_compound(), nfs41_server_addrs(), nfs41_session_bump_seq(), nfs41_session_create(), nfs41_session_free_slot(), nfs41_session_get_slot(), nfs41_session_recall_slot(), nfs41_superblock_for_fh(), open_deleg_cmp(), open_lock_delegate(), open_update_cache(), pnfs_data_server_client(), pnfs_layout_state_close(), pnfs_layout_state_open(), recover_delegation_open(), recover_delegation_want(), recover_open(), recover_stateid_delegation(), recover_stateid_lock(), recover_stateid_open(), session_get_lease(), stateid_array(), and thread_next_unit().

◆ GetNtTimeout()

FORCEINLINE PLARGE_INTEGER GetNtTimeout ( PLARGE_INTEGER  Time,
DWORD  Timeout 
)

Definition at line 96 of file sync.c.

97 {
98  if (Timeout == INFINITE) return NULL;
99  Time->QuadPart = (ULONGLONG)Timeout * -10000;
100  return Time;
101 }
smooth NULL
Definition: ftsmooth.c:416
uint64_t ULONGLONG
Definition: typedefs.h:65
static ULONG Timeout
Definition: ping.c:61
#define INFINITE
Definition: serial.h:102
static PLARGE_INTEGER Time
Definition: time.c:105
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by SleepConditionVariableCS(), and SleepConditionVariableSRW().

◆ InitializeConditionVariable()

VOID WINAPI InitializeConditionVariable ( PCONDITION_VARIABLE  ConditionVariable)

Definition at line 68 of file sync.c.

69 {
71 }
VOID NTAPI RtlInitializeConditionVariable(OUT PRTL_CONDITION_VARIABLE ConditionVariable)
Definition: condvar.c:477

Referenced by delegation_create(), layout_state_create(), nfs41_client_create(), and session_alloc().

◆ InitializeCriticalSectionEx()

BOOL WINAPI InitializeCriticalSectionEx ( OUT LPCRITICAL_SECTION  lpCriticalSection,
IN DWORD  dwSpinCount,
IN DWORD  flags 
)

Definition at line 153 of file sync.c.

156 {
158 
159  /* FIXME: Flags ignored */
160 
161  /* Initialize the critical section */
163  (PRTL_CRITICAL_SECTION)lpCriticalSection,
164  dwSpinCount);
165  if (!NT_SUCCESS(Status))
166  {
167  /* Set failure code */
169  return FALSE;
170  }
171 
172  /* Success */
173  return TRUE;
174 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSectionAndSpinCount(_In_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SetLastError(x)
Definition: compat.h:409
Status
Definition: gdiplustypes.h:24
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)

◆ InitializeSRWLock()

VOID WINAPI InitializeSRWLock ( PSRWLOCK  Lock)

Definition at line 75 of file sync.c.

76 {
78 }
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
VOID NTAPI RtlInitializeSRWLock(OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:315

Referenced by cache_init(), create_open_state(), delegation_create(), format_abs_path(), handle_mount(), layout_state_create(), nfs41_client_create(), nfs41_lookup(), nfs41_name_cache_create(), nfs41_rpc_clnt_create(), nfs41_superblock_list_init(), nfs41_symlink_follow(), server_create(), session_alloc(), superblock_create(), and xdr_data_server_list().

◆ ReleaseSRWLockExclusive()

VOID WINAPI ReleaseSRWLockExclusive ( PSRWLOCK  Lock)

Definition at line 82 of file sync.c.

83 {
85 }
VOID NTAPI RtlReleaseSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:708
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75

Referenced by cache_insert(), compound_encode_send_decode(), create_new_rpc_auth(), deleg_lock_update(), delegation_flush_locks(), delegation_recovery_status(), delegation_remove(), delete_stale_component(), device_fetch(), do_open(), file_layout_fetch(), file_layout_recall(), file_layout_return(), get_volume_size_info(), handle_nfs41_set_size(), layout_commit(), nfs41_attr_cache_update(), nfs41_client_delegation_return_lru(), nfs41_client_renew(), nfs41_delegate_open(), nfs41_delegation_recall(), nfs41_delegation_remove_srvopen(), nfs41_delegation_return(), nfs41_delegation_to_open(), nfs41_name_cache_delegreturn(), nfs41_name_cache_insert(), nfs41_name_cache_remove(), nfs41_name_cache_rename(), nfs41_send_compound(), nfs41_session_create(), nfs41_session_free(), nfs41_session_renew(), nfs41_superblock_for_fh(), nfs41_superblock_space_changed(), open_lock_add(), open_lock_delegate(), open_state_rename(), open_unlock_delegate(), open_unlock_remove(), pnfs_data_server_client(), pnfs_layout_io_finished(), pnfs_layout_recall_fenced(), pnfs_layout_state_close(), pnfs_layout_state_open(), pnfs_read(), pnfs_write(), recover_delegation_open(), recover_delegation_want(), recover_locks(), recover_open(), referral_resolve(), rpc_reconnect(), rpc_renew_in_progress(), rpc_should_retry(), and server_addrs_add().

◆ ReleaseSRWLockShared()

VOID WINAPI ReleaseSRWLockShared ( PSRWLOCK  Lock)

Definition at line 89 of file sync.c.

90 {
92 }
VOID NTAPI RtlReleaseSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:524
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75

Referenced by cache_lookup(), cl_addr_compare(), cl_exid_compare(), client_server(), client_supports_pnfs(), deleg_lock_find(), delegation_flush_locks(), delegation_return(), file_layout_return(), get_path_fhs(), get_volume_size_info(), layout_commit(), lock_stateid_arg(), nfs41_attr_cache_lookup(), nfs41_create(), nfs41_create_session(), nfs41_delegation_getattr(), nfs41_delegation_to_open(), nfs41_delegreturn(), nfs41_link(), nfs41_lookup(), nfs41_name_cache_lookup(), nfs41_name_cache_remove_stale(), nfs41_open_stateid_arg(), nfs41_remove(), nfs41_rename(), nfs41_rpc_netaddr(), nfs41_send_compound(), nfs41_server_addrs(), nfs41_session_bump_seq(), nfs41_session_create(), nfs41_session_free_slot(), nfs41_session_get_slot(), nfs41_session_recall_slot(), nfs41_superblock_for_fh(), open_deleg_cmp(), open_lock_delegate(), open_update_cache(), pnfs_data_server_client(), pnfs_layout_state_close(), pnfs_layout_state_open(), recover_delegation_open(), recover_delegation_want(), recover_open(), recover_stateid_delegation(), recover_stateid_lock(), recover_stateid_open(), session_get_lease(), stateid_array(), and thread_next_unit().

◆ RtlAcquireSRWLockExclusive()

VOID NTAPI RtlAcquireSRWLockExclusive ( IN OUT PRTL_SRWLOCK  SRWLock)

Definition at line 589 of file srw.c.

590 {
591  __ALIGNED(16) RTLP_SRWLOCK_WAITBLOCK StackWaitBlock;
593 
596  {
597  LONG_PTR CurrentValue, NewValue;
598 
599  while (1)
600  {
601  CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
602 
603  if (CurrentValue & RTL_SRWLOCK_SHARED)
604  {
605  /* A shared lock is being held right now. We need to add a wait block! */
606 
607  if (CurrentValue & RTL_SRWLOCK_CONTENDED)
608  {
609  goto AddWaitBlock;
610  }
611  else
612  {
613  /* There are no wait blocks so far, we need to add ourselves as the first
614  wait block. We need to keep the shared count! */
615  StackWaitBlock.Exclusive = TRUE;
616  StackWaitBlock.SharedCount = (LONG)(CurrentValue >> RTL_SRWLOCK_BITS);
617  StackWaitBlock.Next = NULL;
618  StackWaitBlock.Last = &StackWaitBlock;
619  StackWaitBlock.Wake = 0;
620 
621  NewValue = (ULONG_PTR)&StackWaitBlock | RTL_SRWLOCK_SHARED | RTL_SRWLOCK_CONTENDED | RTL_SRWLOCK_OWNED;
622 
623  if ((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
624  (PVOID)NewValue,
625  (PVOID)CurrentValue) == CurrentValue)
626  {
628  &StackWaitBlock);
629 
630  /* Successfully acquired the exclusive lock */
631  break;
632  }
633  }
634  }
635  else
636  {
637  if (CurrentValue & RTL_SRWLOCK_OWNED)
638  {
639  /* An exclusive lock is being held right now. We need to add a wait block! */
640 
641  if (CurrentValue & RTL_SRWLOCK_CONTENDED)
642  {
643 AddWaitBlock:
644  StackWaitBlock.Exclusive = TRUE;
645  StackWaitBlock.SharedCount = 0;
646  StackWaitBlock.Next = NULL;
647  StackWaitBlock.Last = &StackWaitBlock;
648  StackWaitBlock.Wake = 0;
649 
650  First = RtlpAcquireWaitBlockLock(SRWLock);
651  if (First != NULL)
652  {
653  Last = First->Last;
654  Last->Next = &StackWaitBlock;
655  First->Last = &StackWaitBlock;
656 
657  RtlpReleaseWaitBlockLock(SRWLock);
658 
660  &StackWaitBlock);
661 
662  /* Successfully acquired the exclusive lock */
663  break;
664  }
665  }
666  else
667  {
668  /* There are no wait blocks so far, we need to add ourselves as the first
669  wait block. We need to keep the shared count! */
670  StackWaitBlock.Exclusive = TRUE;
671  StackWaitBlock.SharedCount = 0;
672  StackWaitBlock.Next = NULL;
673  StackWaitBlock.Last = &StackWaitBlock;
674  StackWaitBlock.Wake = 0;
675 
676  NewValue = (ULONG_PTR)&StackWaitBlock | RTL_SRWLOCK_OWNED | RTL_SRWLOCK_CONTENDED;
677  if ((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
678  (PVOID)NewValue,
679  (PVOID)CurrentValue) == CurrentValue)
680  {
682  &StackWaitBlock);
683 
684  /* Successfully acquired the exclusive lock */
685  break;
686  }
687  }
688  }
689  else
690  {
691  if (!InterlockedBitTestAndSetPointer(&SRWLock->Ptr,
693  {
694  /* We managed to get hold of a simple exclusive lock! */
695  break;
696  }
697  }
698  }
699 
700  YieldProcessor();
701  }
702  }
703 }
#define TRUE
Definition: types.h:120
#define InterlockedBitTestAndSetPointer(ptr, val)
Definition: srw.c:29
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
typedef __ALIGNED(16) struct _EX_PUSH_LOCK_WAIT_BLOCK
Definition: extypes.h:483
volatile struct _RTLP_SRWLOCK_WAITBLOCK * Next
Definition: srw.c:63
FORCEINLINE VOID YieldProcessor(VOID)
Definition: ke.h:32
WCHAR First[]
Definition: FormatMessage.c:11
#define RTL_SRWLOCK_CONTENDED
Definition: srw.c:40
long LONG
Definition: pedump.c:60
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
volatile struct _RTLP_SRWLOCK_WAITBLOCK * Last
Definition: srw.c:60
smooth NULL
Definition: ftsmooth.c:416
#define RTL_SRWLOCK_BITS
Definition: srw.c:45
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define RTL_SRWLOCK_OWNED
Definition: srw.c:39
#define RTL_SRWLOCK_SHARED
Definition: srw.c:41
BOOLEAN Exclusive
Definition: srw.c:77
#define RTL_SRWLOCK_OWNED_BIT
Definition: srw.c:35
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define ULONG_PTR
Definition: config.h:101
static PRTLP_SRWLOCK_WAITBLOCK NTAPI RtlpAcquireWaitBlockLock(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:197
static VOID NTAPI RtlpAcquireSRWLockExclusiveWait(IN OUT PRTL_SRWLOCK SRWLock, IN PRTLP_SRWLOCK_WAITBLOCK WaitBlock)
Definition: srw.c:230
static VOID NTAPI RtlpReleaseWaitBlockLock(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:188

Referenced by AcquireSRWLockExclusive().

◆ RtlAcquireSRWLockShared()

VOID NTAPI RtlAcquireSRWLockShared ( IN OUT PRTL_SRWLOCK  SRWLock)

Definition at line 323 of file srw.c.

324 {
325  __ALIGNED(16) RTLP_SRWLOCK_WAITBLOCK StackWaitBlock;
326  RTLP_SRWLOCK_SHARED_WAKE SharedWake;
327  LONG_PTR CurrentValue, NewValue;
328  PRTLP_SRWLOCK_WAITBLOCK First, Shared, FirstWait;
329 
330  while (1)
331  {
332  CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
333 
334  if (CurrentValue & RTL_SRWLOCK_SHARED)
335  {
336  /* NOTE: It is possible that the RTL_SRWLOCK_OWNED bit is set! */
337 
338  if (CurrentValue & RTL_SRWLOCK_CONTENDED)
339  {
340  /* There's other waiters already, lock the wait blocks and
341  increment the shared count */
342  First = RtlpAcquireWaitBlockLock(SRWLock);
343  if (First != NULL)
344  {
345  FirstWait = NULL;
346 
347  if (First->Exclusive)
348  {
349  /* We need to setup a new wait block! Although
350  we're currently in a shared lock and we're acquiring
351  a shared lock, there are exclusive locks queued. We need
352  to wait until those are released. */
353  Shared = First->Last;
354 
355  if (Shared->Exclusive)
356  {
357  StackWaitBlock.Exclusive = FALSE;
358  StackWaitBlock.SharedCount = 1;
359  StackWaitBlock.Next = NULL;
360  StackWaitBlock.Last = &StackWaitBlock;
361  StackWaitBlock.SharedWakeChain = &SharedWake;
362 
363  Shared->Next = &StackWaitBlock;
364  First->Last = &StackWaitBlock;
365 
366  Shared = &StackWaitBlock;
367  FirstWait = &StackWaitBlock;
368  }
369  else
370  {
371  Shared->LastSharedWake->Next = &SharedWake;
372  Shared->SharedCount++;
373  }
374  }
375  else
376  {
377  Shared = First;
378  Shared->LastSharedWake->Next = &SharedWake;
379  Shared->SharedCount++;
380  }
381 
382  SharedWake.Next = NULL;
383  SharedWake.Wake = 0;
384 
385  Shared->LastSharedWake = &SharedWake;
386 
387  RtlpReleaseWaitBlockLock(SRWLock);
388 
390  FirstWait,
391  &SharedWake);
392 
393  /* Successfully incremented the shared count, we acquired the lock */
394  break;
395  }
396  }
397  else
398  {
399  /* This is a fastest path, just increment the number of
400  current shared locks */
401 
402  /* Since the RTL_SRWLOCK_SHARED bit is set, the RTL_SRWLOCK_OWNED bit also has
403  to be set! */
404 
405  ASSERT(CurrentValue & RTL_SRWLOCK_OWNED);
406 
407  NewValue = (CurrentValue >> RTL_SRWLOCK_BITS) + 1;
408  NewValue = (NewValue << RTL_SRWLOCK_BITS) | (CurrentValue & RTL_SRWLOCK_MASK);
409 
410  if ((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
411  (PVOID)NewValue,
412  (PVOID)CurrentValue) == CurrentValue)
413  {
414  /* Successfully incremented the shared count, we acquired the lock */
415  break;
416  }
417  }
418  }
419  else
420  {
421  if (CurrentValue & RTL_SRWLOCK_OWNED)
422  {
423  /* The resource is currently acquired exclusively */
424  if (CurrentValue & RTL_SRWLOCK_CONTENDED)
425  {
426  SharedWake.Next = NULL;
427  SharedWake.Wake = 0;
428 
429  /* There's other waiters already, lock the wait blocks and
430  increment the shared count. If the last block in the chain
431  is an exclusive lock, add another block. */
432 
433  StackWaitBlock.Exclusive = FALSE;
434  StackWaitBlock.SharedCount = 0;
435  StackWaitBlock.Next = NULL;
436  StackWaitBlock.Last = &StackWaitBlock;
437  StackWaitBlock.SharedWakeChain = &SharedWake;
438 
439  First = RtlpAcquireWaitBlockLock(SRWLock);
440  if (First != NULL)
441  {
442  Shared = First->Last;
443  if (Shared->Exclusive)
444  {
445  Shared->Next = &StackWaitBlock;
446  First->Last = &StackWaitBlock;
447 
448  Shared = &StackWaitBlock;
449  FirstWait = &StackWaitBlock;
450  }
451  else
452  {
453  FirstWait = NULL;
454  Shared->LastSharedWake->Next = &SharedWake;
455  }
456 
457  Shared->SharedCount++;
458  Shared->LastSharedWake = &SharedWake;
459 
460  RtlpReleaseWaitBlockLock(SRWLock);
461 
463  FirstWait,
464  &SharedWake);
465 
466  /* Successfully incremented the shared count, we acquired the lock */
467  break;
468  }
469  }
470  else
471  {
472  SharedWake.Next = NULL;
473  SharedWake.Wake = 0;
474 
475  /* We need to setup the first wait block. Currently an exclusive lock is
476  held, change the lock to contended mode. */
477  StackWaitBlock.Exclusive = FALSE;
478  StackWaitBlock.SharedCount = 1;
479  StackWaitBlock.Next = NULL;
480  StackWaitBlock.Last = &StackWaitBlock;
481  StackWaitBlock.SharedWakeChain = &SharedWake;
482  StackWaitBlock.LastSharedWake = &SharedWake;
483 
484  NewValue = (ULONG_PTR)&StackWaitBlock | RTL_SRWLOCK_OWNED | RTL_SRWLOCK_CONTENDED;
485  if ((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
486  (PVOID)NewValue,
487  (PVOID)CurrentValue) == CurrentValue)
488  {
490  &StackWaitBlock,
491  &SharedWake);
492 
493  /* Successfully set the shared count, we acquired the lock */
494  break;
495  }
496  }
497  }
498  else
499  {
500  /* This is a fast path, we can simply try to set the shared count to 1 */
502 
503  /* The RTL_SRWLOCK_CONTENDED bit should never be set if neither the
504  RTL_SRWLOCK_SHARED nor the RTL_SRWLOCK_OWNED bit is set */
505  ASSERT(!(CurrentValue & RTL_SRWLOCK_CONTENDED));
506 
507  if ((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
508  (PVOID)NewValue,
509  (PVOID)CurrentValue) == CurrentValue)
510  {
511  /* Successfully set the shared count, we acquired the lock */
512  break;
513  }
514  }
515  }
516 
517  YieldProcessor();
518  }
519 }
volatile struct _RTLP_SRWLOCK_SHARED_WAKE * Next
Definition: srw.c:50
PRTLP_SRWLOCK_SHARED_WAKE LastSharedWake
Definition: srw.c:73
typedef __ALIGNED(16) struct _EX_PUSH_LOCK_WAIT_BLOCK
Definition: extypes.h:483
volatile struct _RTLP_SRWLOCK_WAITBLOCK * Next
Definition: srw.c:63
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:265
FORCEINLINE VOID YieldProcessor(VOID)
Definition: ke.h:32
WCHAR First[]
Definition: FormatMessage.c:11
while(1)
Definition: macro.lex.yy.c:740
#define RTL_SRWLOCK_CONTENDED
Definition: srw.c:40
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
volatile struct _RTLP_SRWLOCK_WAITBLOCK * Last
Definition: srw.c:60
smooth NULL
Definition: ftsmooth.c:416
#define RTL_SRWLOCK_BITS
Definition: srw.c:45
#define RTL_SRWLOCK_MASK
Definition: srw.c:43
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define RTL_SRWLOCK_OWNED
Definition: srw.c:39
PRTLP_SRWLOCK_SHARED_WAKE SharedWakeChain
Definition: srw.c:72
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define RTL_SRWLOCK_SHARED
Definition: srw.c:41
BOOLEAN Exclusive
Definition: srw.c:77
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define ULONG_PTR
Definition: config.h:101
static PRTLP_SRWLOCK_WAITBLOCK NTAPI RtlpAcquireWaitBlockLock(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:197
static VOID NTAPI RtlpReleaseWaitBlockLock(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:188

Referenced by AcquireSRWLockShared().

◆ RtlInitializeConditionVariable()

VOID NTAPI RtlInitializeConditionVariable ( OUT PRTL_CONDITION_VARIABLE  ConditionVariable)

Definition at line 477 of file condvar.c.

478 {
479  ConditionVariable->Ptr = NULL;
480 }
smooth NULL
Definition: ftsmooth.c:416

Referenced by InitializeConditionVariable().

◆ RtlInitializeSRWLock()

VOID NTAPI RtlInitializeSRWLock ( OUT PRTL_SRWLOCK  SRWLock)

Definition at line 315 of file srw.c.

316 {
317  SRWLock->Ptr = NULL;
318 }
smooth NULL
Definition: ftsmooth.c:416

Referenced by InitializeSRWLock().

◆ RtlReleaseSRWLockExclusive()

VOID NTAPI RtlReleaseSRWLockExclusive ( IN OUT PRTL_SRWLOCK  SRWLock)

Definition at line 708 of file srw.c.

709 {
710  LONG_PTR CurrentValue, NewValue;
711  PRTLP_SRWLOCK_WAITBLOCK WaitBlock;
712 
713  while (1)
714  {
715  CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
716 
717  if (!(CurrentValue & RTL_SRWLOCK_OWNED))
718  {
720  }
721 
722  if (!(CurrentValue & RTL_SRWLOCK_SHARED))
723  {
724  if (CurrentValue & RTL_SRWLOCK_CONTENDED)
725  {
726  /* There's a wait block, we need to wake the next pending
727  acquirer (exclusive or shared) */
728  WaitBlock = RtlpAcquireWaitBlockLock(SRWLock);
729  if (WaitBlock != NULL)
730  {
732  WaitBlock);
733 
734  /* We released the lock */
735  break;
736  }
737  }
738  else
739  {
740  /* This is a fast path, we can simply clear the RTL_SRWLOCK_OWNED
741  bit. All other bits should be 0 now because this is a simple
742  exclusive lock and no one is waiting. */
743 
744  ASSERT(!(CurrentValue & ~RTL_SRWLOCK_OWNED));
745 
746  NewValue = 0;
747  if ((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
748  (PVOID)NewValue,
749  (PVOID)CurrentValue) == CurrentValue)
750  {
751  /* We released the lock */
752  break;
753  }
754  }
755  }
756  else
757  {
758  /* The RTL_SRWLOCK_SHARED bit must not be present now,
759  not even in the contended case! */
761  }
762 
763  YieldProcessor();
764  }
765 }
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
FORCEINLINE VOID YieldProcessor(VOID)
Definition: ke.h:32
#define RTL_SRWLOCK_CONTENDED
Definition: srw.c:40
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
smooth NULL
Definition: ftsmooth.c:416
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define RTL_SRWLOCK_OWNED
Definition: srw.c:39
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define RTL_SRWLOCK_SHARED
Definition: srw.c:41
static VOID NTAPI RtlpReleaseWaitBlockLockExclusive(IN OUT PRTL_SRWLOCK SRWLock, IN PRTLP_SRWLOCK_WAITBLOCK FirstWaitBlock)
Definition: srw.c:83
#define STATUS_RESOURCE_NOT_OWNED
Definition: ntstatus.h:723
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
static PRTLP_SRWLOCK_WAITBLOCK NTAPI RtlpAcquireWaitBlockLock(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:197

Referenced by ReleaseSRWLockExclusive().

◆ RtlReleaseSRWLockShared()

VOID NTAPI RtlReleaseSRWLockShared ( IN OUT PRTL_SRWLOCK  SRWLock)

Definition at line 524 of file srw.c.

525 {
526  LONG_PTR CurrentValue, NewValue;
527  PRTLP_SRWLOCK_WAITBLOCK WaitBlock;
528  BOOLEAN LastShared;
529 
530  while (1)
531  {
532  CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
533 
534  if (CurrentValue & RTL_SRWLOCK_SHARED)
535  {
536  if (CurrentValue & RTL_SRWLOCK_CONTENDED)
537  {
538  /* There's a wait block, we need to wake a pending
539  exclusive acquirer if this is the last shared release */
540  WaitBlock = RtlpAcquireWaitBlockLock(SRWLock);
541  if (WaitBlock != NULL)
542  {
543  LastShared = (--WaitBlock->SharedCount == 0);
544 
545  if (LastShared)
547  WaitBlock);
548  else
549  RtlpReleaseWaitBlockLock(SRWLock);
550 
551  /* We released the lock */
552  break;
553  }
554  }
555  else
556  {
557  /* This is a fast path, we can simply decrement the shared
558  count and store the pointer */
559  NewValue = CurrentValue >> RTL_SRWLOCK_BITS;
560 
561  if (--NewValue != 0)
562  {
563  NewValue = (NewValue << RTL_SRWLOCK_BITS) | RTL_SRWLOCK_SHARED | RTL_SRWLOCK_OWNED;
564  }
565 
566  if ((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
567  (PVOID)NewValue,
568  (PVOID)CurrentValue) == CurrentValue)
569  {
570  /* Successfully released the lock */
571  break;
572  }
573  }
574  }
575  else
576  {
577  /* The RTL_SRWLOCK_SHARED bit has to be present now,
578  even in the contended case! */
580  }
581 
582  YieldProcessor();
583  }
584 }
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
FORCEINLINE VOID YieldProcessor(VOID)
Definition: ke.h:32
#define RTL_SRWLOCK_CONTENDED
Definition: srw.c:40
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define RTL_SRWLOCK_BITS
Definition: srw.c:45
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define RTL_SRWLOCK_OWNED
Definition: srw.c:39
#define RTL_SRWLOCK_SHARED
Definition: srw.c:41
static VOID NTAPI RtlpReleaseWaitBlockLockLastShared(IN OUT PRTL_SRWLOCK SRWLock, IN PRTLP_SRWLOCK_WAITBLOCK FirstWaitBlock)
Definition: srw.c:153
#define STATUS_RESOURCE_NOT_OWNED
Definition: ntstatus.h:723
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
static PRTLP_SRWLOCK_WAITBLOCK NTAPI RtlpAcquireWaitBlockLock(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:197
static VOID NTAPI RtlpReleaseWaitBlockLock(IN OUT PRTL_SRWLOCK SRWLock)
Definition: srw.c:188

Referenced by ReleaseSRWLockShared().

◆ RtlSleepConditionVariableCS()

NTSTATUS NTAPI RtlSleepConditionVariableCS ( IN OUT PRTL_CONDITION_VARIABLE  ConditionVariable,
IN OUT PRTL_CRITICAL_SECTION  CriticalSection,
IN PLARGE_INTEGER TimeOut  OPTIONAL 
)

◆ RtlSleepConditionVariableSRW()

NTSTATUS NTAPI RtlSleepConditionVariableSRW ( IN OUT PRTL_CONDITION_VARIABLE  ConditionVariable,
IN OUT PRTL_SRWLOCK  SRWLock,
IN PLARGE_INTEGER TimeOut  OPTIONAL,
IN ULONG  Flags 
)

◆ RtlWakeAllConditionVariable()

VOID NTAPI RtlWakeAllConditionVariable ( IN OUT PRTL_CONDITION_VARIABLE  ConditionVariable)

Definition at line 491 of file condvar.c.

492 {
493  InternalWake(ConditionVariable, TRUE);
494 }
static VOID InternalWake(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable, IN BOOLEAN ReleaseAll)
Definition: condvar.c:259
#define TRUE
Definition: types.h:120

Referenced by WakeAllConditionVariable().

◆ RtlWakeConditionVariable()

VOID NTAPI RtlWakeConditionVariable ( IN OUT PRTL_CONDITION_VARIABLE  ConditionVariable)

Definition at line 484 of file condvar.c.

485 {
486  InternalWake(ConditionVariable, FALSE);
487 }
static VOID InternalWake(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable, IN BOOLEAN ReleaseAll)
Definition: condvar.c:259

Referenced by WakeConditionVariable().

◆ SleepConditionVariableCS()

BOOL WINAPI SleepConditionVariableCS ( PCONDITION_VARIABLE  ConditionVariable,
PCRITICAL_SECTION  CriticalSection,
DWORD  Timeout 
)

Definition at line 105 of file sync.c.

106 {
109 
112  {
114  return FALSE;
115  }
116  return TRUE;
117 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
CRITICAL_SECTION CriticalSection
Definition: iprtprio.c:40
NTSTATUS NTAPI RtlSleepConditionVariableCS(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable, IN OUT PRTL_CRITICAL_SECTION CriticalSection, IN PLARGE_INTEGER TimeOut OPTIONAL)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SetLastError(x)
Definition: compat.h:409
FORCEINLINE PLARGE_INTEGER GetNtTimeout(PLARGE_INTEGER Time, DWORD Timeout)
Definition: sync.c:96
Status
Definition: gdiplustypes.h:24
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
static ULONG Timeout
Definition: ping.c:61
static PLARGE_INTEGER Time
Definition: time.c:105

Referenced by nfs41_recover_stateid(), nfs41_recovery_start_or_wait(), and nfs41_session_get_slot().

◆ SleepConditionVariableSRW()

BOOL WINAPI SleepConditionVariableSRW ( PCONDITION_VARIABLE  ConditionVariable,
PSRWLOCK  Lock,
DWORD  Timeout,
ULONG  Flags 
)

Definition at line 121 of file sync.c.

122 {
125 
128  {
130  return FALSE;
131  }
132  return TRUE;
133 }
NTSTATUS NTAPI RtlSleepConditionVariableSRW(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable, IN OUT PRTL_SRWLOCK SRWLock, IN PLARGE_INTEGER TimeOut OPTIONAL, IN ULONG Flags)
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SetLastError(x)
Definition: compat.h:409
FORCEINLINE PLARGE_INTEGER GetNtTimeout(PLARGE_INTEGER Time, DWORD Timeout)
Definition: sync.c:96
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
Status
Definition: gdiplustypes.h:24
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
static ULONG Timeout
Definition: ping.c:61
static PLARGE_INTEGER Time
Definition: time.c:105

Referenced by file_layout_return(), layout_fetch(), nfs41_delegate_open(), nfs41_delegation_return(), nfs41_delegation_to_open(), and nfs41_open_stateid_arg().

◆ WakeAllConditionVariable()

VOID WINAPI WakeAllConditionVariable ( PCONDITION_VARIABLE  ConditionVariable)

Definition at line 137 of file sync.c.

138 {
140 }
VOID NTAPI RtlWakeAllConditionVariable(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable)
Definition: condvar.c:491

Referenced by delegation_remove(), init_slot_table(), nfs41_delegation_to_open(), nfs41_recovery_finish(), nfs41_session_free_slot(), and resize_slot_table().

◆ WakeConditionVariable()

VOID WINAPI WakeConditionVariable ( PCONDITION_VARIABLE  ConditionVariable)

Definition at line 144 of file sync.c.

145 {
147 }
VOID NTAPI RtlWakeConditionVariable(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable)
Definition: condvar.c:484

Referenced by file_layout_return(), and layout_fetch().