https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6a4c6ea5d03dd304d3b7f…
commit 6a4c6ea5d03dd304d3b7f3de59b19bb4c8f1420a
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Fri Jan 29 18:41:38 2021 +0100
Commit: Jérôme Gardou <jerome.gardou(a)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;
+}