https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6a4c6ea5d03dd304d3b7f3...
commit 6a4c6ea5d03dd304d3b7f3de59b19bb4c8f1420a Author: Jérôme Gardou jerome.gardou@reactos.org AuthorDate: Fri Jan 29 18:41:38 2021 +0100 Commit: Jérôme Gardou jerome.gardou@reactos.org CommitDate: Fri Jan 29 18:42:54 2021 +0100
[RTL] Implement RtlTryAcquireSRWLockExclusive & RtlTryAcquireSRWLockShared --- sdk/include/ndk/rtlfuncs.h | 43 +++++++++++++++++++++++++++++++++++++++++++ sdk/lib/rtl/srw.c | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/sdk/include/ndk/rtlfuncs.h b/sdk/include/ndk/rtlfuncs.h index c2a823f17f6..7817278a17f 100644 --- a/sdk/include/ndk/rtlfuncs.h +++ b/sdk/include/ndk/rtlfuncs.h @@ -4888,6 +4888,49 @@ RtlGetNativeSystemInformation( _Out_opt_ PULONG ReturnLength );
+#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) || (defined(__REACTOS__) && defined(_NTDLLBUILD_)) +/* Put NTSYSAPI back when this will be really exported. Only statically linked for now */ +// NTSYSAPI +VOID +NTAPI +RtlInitializeSRWLock(OUT PRTL_SRWLOCK SRWLock); + +// NTSYSAPI +VOID +NTAPI +RtlAcquireSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock); + +// NTSYSAPI +VOID +NTAPI +RtlAcquireSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock); + +// NTSYSAPI +VOID +NTAPI +RtlReleaseSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock); + +// NTSYSAPI +VOID +NTAPI +RtlReleaseSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock); + +#endif /* Win vista or Reactos Ntdll build */ + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN7) || (defined(__REACTOS__) && defined(_NTDLLBUILD_)) + +// NTSYSAPI +BOOLEAN +NTAPI +RtlTryAcquireSRWLockShared(PRTL_SRWLOCK SRWLock); + +// NTSYSAPI +BOOLEAN +NTAPI +RtlTryAcquireSRWLockExclusive(PRTL_SRWLOCK SRWLock); + +#endif /* Win7 or Reactos Ntdll build */ + #endif // NTOS_MODE_USER
NTSYSAPI diff --git a/sdk/lib/rtl/srw.c b/sdk/lib/rtl/srw.c index 31730174888..8b5b47ce59f 100644 --- a/sdk/lib/rtl/srw.c +++ b/sdk/lib/rtl/srw.c @@ -25,21 +25,23 @@ #define InterlockedAddPointer(ptr,val) InterlockedAdd64((PLONGLONG)ptr,(LONGLONG)val) #define InterlockedAndPointer(ptr,val) InterlockedAnd64((PLONGLONG)ptr,(LONGLONG)val) #define InterlockedOrPointer(ptr,val) InterlockedOr64((PLONGLONG)ptr,(LONGLONG)val) +#define _ONE 1LL #else #define InterlockedBitTestAndSetPointer(ptr,val) InterlockedBitTestAndSet((PLONG)ptr,(LONG)val) #define InterlockedAddPointer(ptr,val) InterlockedAdd((PLONG)ptr,(LONG)val) #define InterlockedAndPointer(ptr,val) InterlockedAnd((PLONG)ptr,(LONG)val) #define InterlockedOrPointer(ptr,val) InterlockedOr((PLONG)ptr,(LONG)val) +#define _ONE 1L #endif
#define RTL_SRWLOCK_OWNED_BIT 0 #define RTL_SRWLOCK_CONTENDED_BIT 1 #define RTL_SRWLOCK_SHARED_BIT 2 #define RTL_SRWLOCK_CONTENTION_LOCK_BIT 3 -#define RTL_SRWLOCK_OWNED (1 << RTL_SRWLOCK_OWNED_BIT) -#define RTL_SRWLOCK_CONTENDED (1 << RTL_SRWLOCK_CONTENDED_BIT) -#define RTL_SRWLOCK_SHARED (1 << RTL_SRWLOCK_SHARED_BIT) -#define RTL_SRWLOCK_CONTENTION_LOCK (1 << RTL_SRWLOCK_CONTENTION_LOCK_BIT) +#define RTL_SRWLOCK_OWNED (_ONE << RTL_SRWLOCK_OWNED_BIT) +#define RTL_SRWLOCK_CONTENDED (_ONE << RTL_SRWLOCK_CONTENDED_BIT) +#define RTL_SRWLOCK_SHARED (_ONE << RTL_SRWLOCK_SHARED_BIT) +#define RTL_SRWLOCK_CONTENTION_LOCK (_ONE << RTL_SRWLOCK_CONTENTION_LOCK_BIT) #define RTL_SRWLOCK_MASK (RTL_SRWLOCK_OWNED | RTL_SRWLOCK_CONTENDED | \ RTL_SRWLOCK_SHARED | RTL_SRWLOCK_CONTENTION_LOCK) #define RTL_SRWLOCK_BITS 4 @@ -763,3 +765,31 @@ RtlReleaseSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock) YieldProcessor(); } } + +BOOLEAN +NTAPI +RtlTryAcquireSRWLockShared(PRTL_SRWLOCK SRWLock) +{ + + LONG_PTR CompareValue, NewValue, GotValue; + + do + { + CompareValue = *(volatile LONG_PTR *)&SRWLock->Ptr; + NewValue = ((CompareValue >> RTL_SRWLOCK_BITS) + 1) | RTL_SRWLOCK_SHARED | RTL_SRWLOCK_OWNED; + + /* Only increment shared count if there is no waiter */ + CompareValue &= ~RTL_SRWLOCK_MASK | RTL_SRWLOCK_SHARED | RTL_SRWLOCK_OWNED; + } while ( + ((GotValue = (LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr, (LONG_PTR*)NewValue, (LONG_PTR*)CompareValue)) != CompareValue) + && (((GotValue & RTL_SRWLOCK_MASK) == (RTL_SRWLOCK_SHARED | RTL_SRWLOCK_OWNED)) || (GotValue == 0))); + + return ((GotValue & RTL_SRWLOCK_MASK) == (RTL_SRWLOCK_SHARED | RTL_SRWLOCK_OWNED)) || (GotValue == 0); +} + +BOOLEAN +NTAPI +RtlTryAcquireSRWLockExclusive(PRTL_SRWLOCK SRWLock) +{ + return InterlockedCompareExchangePointer(&SRWLock->Ptr, (ULONG_PTR*)(ULONG_PTR)RTL_SRWLOCK_SHARED, 0) == 0; +}