https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6a4c6ea5d03dd304d3b7f3de59b19bb4c8f1420a

commit 6a4c6ea5d03dd304d3b7f3de59b19bb4c8f1420a
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Fri Jan 29 18:41:38 2021 +0100
Commit:     Jérôme Gardou <[email protected]>
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;
+}

Reply via email to