Author: pschweitzer
Date: Tue May 30 21:35:05 2017
New Revision: 74703

URL: http://svn.reactos.org/svn/reactos?rev=74703&view=rev
Log:
[NTDLL_VISTA]
Create a new NTDLL library that exports some of the NTDLL Vista+ functions.
This new NTDLL includes at the time of commit:
- SRW locks implementation that was originally built in RTL but never used ;
- Condition variables implementation which is a new code in ReactOS trunk.

Condition variables is an implementation of Stephan Röger, with minor formatting
changes by Timo Kreuzer and various changes by myself.

CORE-7546
CORE-8204

Added:
    trunk/reactos/dll/win32/ntdll_vista/
    trunk/reactos/dll/win32/ntdll_vista/CMakeLists.txt   (with props)
    trunk/reactos/dll/win32/ntdll_vista/DllMain.c   (with props)
    trunk/reactos/dll/win32/ntdll_vista/condvar.c   (with props)
    trunk/reactos/dll/win32/ntdll_vista/ntdll_vista.spec   (with props)
    trunk/reactos/dll/win32/ntdll_vista/rtl_vista.h   (with props)
    trunk/reactos/dll/win32/ntdll_vista/srw.c
      - copied, changed from r74702, trunk/reactos/sdk/lib/rtl/srw.c
Removed:
    trunk/reactos/sdk/lib/rtl/srw.c
Modified:
    trunk/reactos/dll/win32/CMakeLists.txt
    trunk/reactos/sdk/lib/rtl/CMakeLists.txt

Modified: trunk/reactos/dll/win32/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/CMakeLists.txt?rev=74703&r1=74702&r2=74703&view=diff
==============================================================================
--- trunk/reactos/dll/win32/CMakeLists.txt      [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/CMakeLists.txt      [iso-8859-1] Tue May 30 
21:35:05 2017
@@ -134,6 +134,7 @@
 add_subdirectory(netid)
 add_subdirectory(newdev)
 add_subdirectory(npptools)
+add_subdirectory(ntdll_vista)
 add_subdirectory(ntdsapi)
 add_subdirectory(ntlanman)
 add_subdirectory(ntmarta)

Added: trunk/reactos/dll/win32/ntdll_vista/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ntdll_vista/CMakeLists.txt?rev=74703
==============================================================================
--- trunk/reactos/dll/win32/ntdll_vista/CMakeLists.txt  (added)
+++ trunk/reactos/dll/win32/ntdll_vista/CMakeLists.txt  [iso-8859-1] Tue May 30 
21:35:05 2017
@@ -0,0 +1,17 @@
+
+remove_definitions(-D_WIN32_WINNT=0x502 -DWINVER=0x502)
+add_definitions(-D_WIN32_WINNT=0x600 -DWINVER=0x600)
+
+spec2def(ntdll_vista.dll ntdll_vista.spec ADD_IMPORTLIB)
+
+list(APPEND SOURCE
+    DllMain.c
+    condvar.c
+    srw.c
+    ${CMAKE_CURRENT_BINARY_DIR}/ntdll_vista.def)
+
+add_library(ntdll_vista SHARED ${SOURCE})
+set_module_type(ntdll_vista win32dll ENTRYPOINT DllMain 12)
+add_importlibs(ntdll_vista ntdll kernel32)
+add_dependencies(ntdll_vista psdk)
+add_cd_file(TARGET ntdll_vista DESTINATION reactos/system32 FOR all)

Propchange: trunk/reactos/dll/win32/ntdll_vista/CMakeLists.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/ntdll_vista/DllMain.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ntdll_vista/DllMain.c?rev=74703
==============================================================================
--- trunk/reactos/dll/win32/ntdll_vista/DllMain.c       (added)
+++ trunk/reactos/dll/win32/ntdll_vista/DllMain.c       [iso-8859-1] Tue May 30 
21:35:05 2017
@@ -0,0 +1,36 @@
+#include <stdarg.h>
+
+#define WIN32_NO_STATUS
+
+#include <windef.h>
+#include <winbase.h>
+#include <winreg.h>
+#include <winuser.h>
+#include <winwlx.h>
+
+#define NDEBUG
+#include <debug.h>
+
+VOID
+RtlpInitializeKeyedEvent(VOID);
+
+VOID
+RtlpCloseKeyedEvent(VOID);
+
+BOOL
+WINAPI
+DllMain(HANDLE hDll,
+        DWORD dwReason,
+        LPVOID lpReserved)
+{
+    if (dwReason == DLL_PROCESS_ATTACH)
+    {
+        DisableThreadLibraryCalls(hDll);
+        RtlpInitializeKeyedEvent();
+    }
+    else if (dwReason == DLL_PROCESS_DETACH)
+    {
+        RtlpCloseKeyedEvent();
+    }
+    return TRUE;
+}

Propchange: trunk/reactos/dll/win32/ntdll_vista/DllMain.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/ntdll_vista/condvar.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ntdll_vista/condvar.c?rev=74703
==============================================================================
--- trunk/reactos/dll/win32/ntdll_vista/condvar.c       (added)
+++ trunk/reactos/dll/win32/ntdll_vista/condvar.c       [iso-8859-1] Tue May 30 
21:35:05 2017
@@ -0,0 +1,525 @@
+/*
+ * COPYRIGHT:         See COPYING in the top level directory
+ * PROJECT:           ReactOS system libraries
+ * PURPOSE:           Condition Variable Routines
+ * PROGRAMMERS:       Thomas Weidenmueller <[email protected]>
+ *                    Stephan A. R�ger
+ */
+
+/* NOTE: This functionality can be optimized for releasing single
+   threads or for releasing all waiting threads at once. This
+   implementation is optimized for releasing a single thread at a time.
+   It wakes up sleeping threads in FIFO order. */
+
+/* INCLUDES ******************************************************************/
+
+#include <rtl_vista.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* INTERNAL TYPES ************************************************************/
+
+#define COND_VAR_UNUSED_FLAG         ((ULONG_PTR)1)
+#define COND_VAR_LOCKED_FLAG         ((ULONG_PTR)2)
+#define COND_VAR_FLAGS_MASK          ((ULONG_PTR)3)
+#define COND_VAR_ADDRESS_MASK        (~COND_VAR_FLAGS_MASK)
+
+typedef struct _COND_VAR_WAIT_ENTRY
+{
+    /* ListEntry must have an alignment of at least 32-bits, since we
+       want COND_VAR_ADDRESS_MASK to cover all of the address. */
+    LIST_ENTRY ListEntry;
+    PVOID WaitKey;
+    BOOLEAN ListRemovalHandled;
+} COND_VAR_WAIT_ENTRY, * PCOND_VAR_WAIT_ENTRY;
+
+#define CONTAINING_COND_VAR_WAIT_ENTRY(address, field) \
+    CONTAINING_RECORD(address, COND_VAR_WAIT_ENTRY, field)
+
+/* GLOBALS *******************************************************************/
+
+static HANDLE CondVarKeyedEventHandle = NULL;
+
+/* INTERNAL FUNCTIONS ********************************************************/
+
+FORCEINLINE
+ULONG_PTR
+InternalCmpXChgCondVarAcq(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+                          IN ULONG_PTR Exchange,
+                          IN ULONG_PTR Comperand)
+{
+    return 
(ULONG_PTR)InterlockedCompareExchangePointerAcquire(&ConditionVariable->Ptr,
+                                                               (PVOID)Exchange,
+                                                               
(PVOID)Comperand);
+}
+
+FORCEINLINE
+ULONG_PTR
+InternalCmpXChgCondVarRel(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+                          IN ULONG_PTR Exchange,
+                          IN ULONG_PTR Comperand)
+{
+    return 
(ULONG_PTR)InterlockedCompareExchangePointerRelease(&ConditionVariable->Ptr,
+                                                               (PVOID)Exchange,
+                                                               
(PVOID)Comperand);
+}
+
+FORCEINLINE
+BOOLEAN *
+InternalGetListRemovalHandledFlag(IN PCOND_VAR_WAIT_ENTRY Entry)
+{
+    return (BOOLEAN *)&Entry->ListRemovalHandled;
+}
+
+static
+PCOND_VAR_WAIT_ENTRY
+InternalLockCondVar(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+                    IN PCOND_VAR_WAIT_ENTRY InsertEntry OPTIONAL,
+                    IN BOOLEAN * AbortIfLocked OPTIONAL)
+{
+    /* InsertEntry and AbortIfLocked may be NULL on entry. This routine
+       will return NULL if the lock was not acquired. Otherwise it has
+       successfully acquired the lock and the return value is a valid
+       reference to the list head associated with ConditionVariable.
+       The caller must in this case call InternalUnlockCondVar later
+       in order to unlock the condition variable.
+
+       If InsertEntry is NULL and there are no entries on the list, this
+       routine will not acquire the lock and return NULL. If InsertEntry
+       is not NULL this routine ensures that InsertEntry will be on the
+       list when it returns successfully.
+
+       If the lock is owned by another thread and AbortIfLocked is NULL,
+       this routine will block until it acquires the lock. If AbortIfLocked
+       is not NULL and the lock is owned by another thread, this routine
+       will periodically check if *AbortIfLocked is nonzero and if so, will
+       return NULL instead of continuing the wait. */
+
+    ULONG_PTR OldVal = (ULONG_PTR)ConditionVariable->Ptr;
+
+    for (;;)
+    {
+        ULONG_PTR NewVal, LockRes;
+        PLIST_ENTRY OldListHead;
+
+        if (OldVal & COND_VAR_LOCKED_FLAG)
+        {
+            /* The locked flag is set, indicating someone else currently
+               holds the lock. We'll spin until this flag becomes
+               clear or we're asked to abort. */
+            YieldProcessor();
+
+            if ((AbortIfLocked != NULL) && *AbortIfLocked)
+            {
+                /* The caller wants us to abort in this case. */
+                return NULL;
+            }
+
+            /* Refresh OldVal and try again. */
+            OldVal = *(ULONG_PTR *)&ConditionVariable->Ptr;
+            continue;
+        }
+
+        /* Retrieve the list head currently associated with the
+           condition variable. */
+        OldListHead = (PLIST_ENTRY)(OldVal & COND_VAR_ADDRESS_MASK);
+        if (InsertEntry == NULL)
+        {
+            /* The caller doesn't want to put any entry on the list. */
+            if (OldListHead == NULL)
+            {
+                /* The list is empty, so there is nothing to lock. */
+                return NULL;
+            }
+
+            /* The list isn't empty. In this case we need to preserve
+               all of OldVal. */
+            NewVal = OldVal;
+        }
+        else
+        {
+            /* Let InsertEntry be the new list head. Preserve only the
+               bits inside the COND_VAR_FLAGS_MASK range. */
+            NewVal = ((OldVal & COND_VAR_FLAGS_MASK) |
+                      (ULONG_PTR)&InsertEntry->ListEntry);
+        }
+
+        /* Set the flag that indicates someone is holding the lock and
+           try to update the condition variable thread-safe. */
+        NewVal |= COND_VAR_LOCKED_FLAG;
+        LockRes = InternalCmpXChgCondVarAcq(ConditionVariable, NewVal, OldVal);
+        if (LockRes == OldVal)
+        {
+            /* We successfully updated ConditionVariable the way we
+               wanted and now hold the lock. */
+            if (InsertEntry == NULL)
+            {
+                /* We know that OldVal contains a valid address in
+                   this case. */
+                ASSERT(OldListHead != NULL);
+                return CONTAINING_COND_VAR_WAIT_ENTRY(OldListHead, ListEntry);
+            }
+
+            /* InsertEntry is not on the list yet, so add it. In any
+               case InsertEntry will be the new list head. */
+            if (OldListHead == NULL)
+            {
+                /* List was empty before. */
+                InitializeListHead(&InsertEntry->ListEntry);
+            }
+            else
+            {
+                /* Make InsertEntry the last entry of the old list.
+                   As InsertEntry will take the role as new list head,
+                   OldListHead will become the second entry 
(InsertEntry->Flink)
+                   on the new list. */
+                InsertTailList(OldListHead, &InsertEntry->ListEntry);
+            }
+
+            return InsertEntry;
+        }
+
+        /* We didn't manage to update ConditionVariable, so try again. */
+        OldVal = LockRes;
+    }
+}
+
+static
+VOID
+InternalUnlockCondVar(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+                      IN PCOND_VAR_WAIT_ENTRY RemoveEntry OPTIONAL)
+{
+    /* This routine assumes that the lock is being held on entry.
+       RemoveEntry may be NULL. If it is not NULL, this routine
+       assumes that RemoveEntry is on the list and will remove it
+       before releasing the lock. */
+    ULONG_PTR OldVal = (ULONG_PTR)ConditionVariable->Ptr;
+    PLIST_ENTRY NewHeadEntry;
+
+    ASSERT((OldVal & COND_VAR_LOCKED_FLAG) &&
+           (OldVal & COND_VAR_ADDRESS_MASK));
+
+    NewHeadEntry = (PLIST_ENTRY)(OldVal & COND_VAR_ADDRESS_MASK);
+    if (RemoveEntry != NULL)
+    {
+        /* We have to drop RemoveEntry from the list. */
+        if (&RemoveEntry->ListEntry == NewHeadEntry)
+        {
+            /* RemoveEntry is the list head. */
+            if (!IsListEmpty(NewHeadEntry))
+            {
+                /* The second entry in the list will become the new
+                   list head. It's from the thread that arrived
+                   right before the owner of RemoveEntry. */
+                NewHeadEntry = NewHeadEntry->Flink;
+                RemoveEntryList(&RemoveEntry->ListEntry);
+            }
+            else
+            {
+                /* The list will be empty, so discard the list. */
+                NewHeadEntry = NULL;
+            }
+        }
+        else
+        {
+            /* RemoveEntry is not the list head. The current list head
+               will remain. */
+            RemoveEntryList(&RemoveEntry->ListEntry);
+        }
+
+        /* Indicate to the owner of RemoveEntry that the entry
+           was removed from the list. RemoveEntry may not be touched
+           from here on. We don't use volatile semantics here since
+           the cache will anyway be flushed soon when we update
+           ConditionVariable. */
+        RemoveEntry->ListRemovalHandled = TRUE;
+    }
+
+    /* Now unlock thread-safe, while preserving any flags within the
+       COND_VAR_FLAGS_MASK range except for COND_VAR_LOCKED_FLAG. */
+    for (;;)
+    {
+        ULONG_PTR NewVal = ((OldVal & (COND_VAR_FLAGS_MASK ^ 
COND_VAR_LOCKED_FLAG)) |
+                            (ULONG_PTR)NewHeadEntry);
+        ULONG_PTR LockRes = InternalCmpXChgCondVarRel(ConditionVariable, 
NewVal, OldVal);
+        if (LockRes == OldVal)
+        {
+            /* We unlocked. */
+            break;
+        }
+
+        /* Try again. */
+        OldVal = LockRes;
+    }
+}
+
+static
+VOID
+InternalWake(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+             IN BOOLEAN ReleaseAll)
+{
+    /* If ReleaseAll is zero on entry, one thread at most will be woken.
+       Otherwise all waiting threads are woken. Wakeups happen in FIFO
+       order. */
+    PCOND_VAR_WAIT_ENTRY CONST HeadEntry = 
InternalLockCondVar(ConditionVariable, NULL, NULL);
+    PCOND_VAR_WAIT_ENTRY Entry;
+    PCOND_VAR_WAIT_ENTRY NextEntry;
+    LARGE_INTEGER Timeout;
+    PCOND_VAR_WAIT_ENTRY RemoveOnUnlockEntry;
+
+    ASSERT(CondVarKeyedEventHandle != NULL);
+
+    if (HeadEntry == NULL)
+    {
+        /* There is noone there to wake up. In this case do nothing
+           and return immediately. We don't stockpile releases. */
+        return;
+    }
+
+    Timeout.QuadPart = 0;
+    RemoveOnUnlockEntry = NULL;
+
+    /* Release sleeping threads. We will iterate from the last entry on
+       the list to the first. Note that the loop condition is always
+       true for the initial test. */
+    for (Entry = CONTAINING_COND_VAR_WAIT_ENTRY(HeadEntry->ListEntry.Blink, 
ListEntry);
+         Entry != NULL;
+         Entry = NextEntry)
+    {
+        NTSTATUS Status;
+
+        if (HeadEntry == Entry)
+        {
+            /* After the current entry we've iterated through the
+               entire list in backward direction. Then exit.*/
+            NextEntry = NULL;
+        }
+        else
+        {
+            /* Store away the next reference right now, since we may
+               not touch Entry anymore at the end of the block. */
+            NextEntry = CONTAINING_COND_VAR_WAIT_ENTRY(Entry->ListEntry.Blink, 
ListEntry);
+        }
+
+        /* Wake the thread associated with this event. We will
+           immediately return if we failed (zero timeout). */
+        Status = NtReleaseKeyedEvent(CondVarKeyedEventHandle,
+                                     &Entry->WaitKey,
+                                     FALSE,
+                                     &Timeout);
+
+        if (!NT_SUCCESS(Status))
+        {
+            /* We failed to wake a thread. We'll keep trying. */
+            ASSERT(STATUS_INVALID_HANDLE != Status);
+            continue;
+        }
+
+        /* We've woken a thread and will make sure this thread
+           is removed from the list. */
+        if (HeadEntry == Entry)
+        {
+            /* This is the list head. We can't remove it as easily as
+               other entries and will pass it to the unlock routine
+               later (we will exit the loop after this round anyway). */
+            RemoveOnUnlockEntry = HeadEntry;
+        }
+        else
+        {
+            /* We can remove the entry right away. */
+            RemoveEntryList(&Entry->ListEntry);
+
+            /* Now tell the woken thread that removal from the list was
+               already taken care of here so that this thread can resume
+               its normal operation more quickly. We may not touch
+               Entry after signaling this, since it may lie in invalid
+               memory from there on. */
+            *InternalGetListRemovalHandledFlag(Entry) = TRUE;
+        }
+
+        if (!ReleaseAll)
+        {
+            /* We've successfully woken one thread as the caller
+               demanded. */
+            break;
+        }
+    }
+
+    InternalUnlockCondVar(ConditionVariable, RemoveOnUnlockEntry);
+}
+
+VOID
+NTAPI
+RtlAcquireSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock);
+VOID
+NTAPI
+RtlAcquireSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock);
+VOID
+NTAPI
+RtlReleaseSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock);
+VOID
+NTAPI
+RtlReleaseSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock);
+
+static
+NTSTATUS
+InternalSleep(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+              IN OUT PRTL_CRITICAL_SECTION CriticalSection OPTIONAL,
+              IN OUT PRTL_SRWLOCK SRWLock OPTIONAL,
+              IN ULONG SRWFlags,
+              IN const LARGE_INTEGER * TimeOut OPTIONAL)
+{
+    /* Either CriticalSection or SRWLock must be NULL, but not both.
+       These caller provided lock must be held on entry and will be
+       held again on return. */
+
+    COND_VAR_WAIT_ENTRY OwnEntry;
+    NTSTATUS Status;
+
+    ASSERT(CondVarKeyedEventHandle != NULL);
+    ASSERT((CriticalSection == NULL) != (SRWLock == NULL));
+
+    RtlZeroMemory(&OwnEntry, sizeof(OwnEntry));
+
+    /* Put OwnEntry on the list. */
+    InternalLockCondVar(ConditionVariable, &OwnEntry, NULL);
+    InternalUnlockCondVar(ConditionVariable, NULL);
+
+    /* We can now drop the caller provided lock as a preparation for
+       going to sleep. */
+    if (CriticalSection == NULL)
+    {
+        if (0 == (RTL_CONDITION_VARIABLE_LOCKMODE_SHARED & SRWFlags))
+        {
+            RtlReleaseSRWLockExclusive(SRWLock);
+        }
+        else
+        {
+            RtlReleaseSRWLockShared(SRWLock);
+        }
+    }
+    else
+    {
+        RtlLeaveCriticalSection(CriticalSection);
+    }
+
+    /* Now sleep using the caller provided timeout. */
+    Status = NtWaitForKeyedEvent(CondVarKeyedEventHandle,
+                                 &OwnEntry.WaitKey,
+                                 FALSE,
+                                 (PLARGE_INTEGER)TimeOut);
+
+    ASSERT(STATUS_INVALID_HANDLE != Status);
+
+    if (!*InternalGetListRemovalHandledFlag(&OwnEntry))
+    {
+        /* Remove OwnEntry from the list again, since it still seems to
+           be on the list. We will know for sure once we've acquired
+           the lock. */
+        if (InternalLockCondVar(ConditionVariable,
+                                NULL,
+                                InternalGetListRemovalHandledFlag(&OwnEntry)))
+        {
+            /* Unlock and potentially remove OwnEntry. Self-removal is
+               usually only necessary when a timeout occurred. */
+            InternalUnlockCondVar(ConditionVariable,
+                                  !OwnEntry.ListRemovalHandled ?
+                                  &OwnEntry : NULL);
+        }
+    }
+
+#if _DEBUG
+    /* Clear OwnEntry to aid in detecting bugs. */
+    RtlZeroMemory(&OwnEntry, sizeof(OwnEntry));
+#endif
+
+    /* Reacquire the caller provided lock, as we are about to return. */
+    if (CriticalSection == NULL)
+    {
+        if (0 == (RTL_CONDITION_VARIABLE_LOCKMODE_SHARED & SRWFlags))
+        {
+            RtlAcquireSRWLockExclusive(SRWLock);
+        }
+        else
+        {
+            RtlAcquireSRWLockShared(SRWLock);
+        }
+    }
+    else
+    {
+        RtlEnterCriticalSection(CriticalSection);
+    }
+
+    /* Return whatever NtWaitForKeyedEvent returned. */
+    return Status;
+}
+
+VOID
+RtlpInitializeKeyedEvent(VOID)
+{
+    ASSERT(CondVarKeyedEventHandle == NULL);
+    NtCreateKeyedEvent(&CondVarKeyedEventHandle, EVENT_ALL_ACCESS, NULL, 0);
+}
+
+VOID
+RtlpCloseKeyedEvent(VOID)
+{
+    ASSERT(CondVarKeyedEventHandle != NULL);
+    NtClose(CondVarKeyedEventHandle);
+    CondVarKeyedEventHandle = NULL;
+}
+
+/* EXPORTED FUNCTIONS ********************************************************/
+
+VOID
+NTAPI
+RtlInitializeConditionVariable(OUT PRTL_CONDITION_VARIABLE ConditionVariable)
+{
+    ConditionVariable->Ptr = NULL;
+}
+
+VOID
+NTAPI
+RtlWakeConditionVariable(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable)
+{
+    InternalWake(ConditionVariable, FALSE);
+}
+
+VOID
+NTAPI
+RtlWakeAllConditionVariable(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable)
+{
+    InternalWake(ConditionVariable, TRUE);
+}
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlSleepConditionVariableCS(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+                            IN OUT PRTL_CRITICAL_SECTION CriticalSection,
+                            IN const LARGE_INTEGER * TimeOut OPTIONAL)
+{
+    return InternalSleep(ConditionVariable,
+                         CriticalSection,
+                         (PRTL_SRWLOCK)NULL,
+                         0,
+                         TimeOut);
+}
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlSleepConditionVariableSRW(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+                             IN OUT PRTL_SRWLOCK SRWLock,
+                             IN const LARGE_INTEGER * TimeOut OPTIONAL,
+                             IN ULONG Flags)
+{
+    return InternalSleep(ConditionVariable,
+                         (PRTL_CRITICAL_SECTION)NULL,
+                         SRWLock,
+                         Flags,
+                         TimeOut);
+}
+
+/* EOF */

Propchange: trunk/reactos/dll/win32/ntdll_vista/condvar.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/ntdll_vista/ntdll_vista.spec
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ntdll_vista/ntdll_vista.spec?rev=74703
==============================================================================
--- trunk/reactos/dll/win32/ntdll_vista/ntdll_vista.spec        (added)
+++ trunk/reactos/dll/win32/ntdll_vista/ntdll_vista.spec        [iso-8859-1] 
Tue May 30 21:35:05 2017
@@ -0,0 +1,10 @@
+@ stdcall RtlInitializeConditionVariable(ptr)
+@ stdcall RtlWakeConditionVariable(ptr)
+@ stdcall RtlWakeAllConditionVariable(ptr)
+@ stdcall RtlSleepConditionVariableCS(ptr ptr ptr)
+@ stdcall RtlSleepConditionVariableSRW(ptr ptr ptr long)
+@ stdcall RtlInitializeSRWLock(ptr)
+@ stdcall RtlAcquireSRWLockShared(ptr)
+@ stdcall RtlReleaseSRWLockShared(ptr)
+@ stdcall RtlAcquireSRWLockExclusive(ptr)
+@ stdcall RtlReleaseSRWLockExclusive(ptr)

Propchange: trunk/reactos/dll/win32/ntdll_vista/ntdll_vista.spec
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/ntdll_vista/rtl_vista.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ntdll_vista/rtl_vista.h?rev=74703
==============================================================================
--- trunk/reactos/dll/win32/ntdll_vista/rtl_vista.h     (added)
+++ trunk/reactos/dll/win32/ntdll_vista/rtl_vista.h     [iso-8859-1] Tue May 30 
21:35:05 2017
@@ -0,0 +1,57 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS System Libraries
+ * FILE:            lib/rtl/rtl.h
+ * PURPOSE:         Run-Time Libary Header
+ * PROGRAMMER:      Alex Ionescu
+ */
+
+#ifndef RTL_H
+#define RTL_H
+
+/* We're a core NT DLL, we don't import syscalls */
+#define _INC_SWPRINTF_INL_
+#undef __MSVCRT__
+
+/* C Headers */
+#include <stdlib.h>
+#include <stdio.h>
+
+/* PSDK/NDK Headers */
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+#define COBJMACROS
+#define CONST_VTABLE
+#include <windef.h>
+#include <winbase.h>
+#include <winreg.h>
+#include <objbase.h>
+#include <ntintsafe.h>
+#include <ndk/exfuncs.h>
+#include <ndk/iofuncs.h>
+#include <ndk/kefuncs.h>
+#include <ndk/ldrfuncs.h>
+#include <ndk/mmfuncs.h>
+#include <ndk/obfuncs.h>
+#include <ndk/psfuncs.h>
+#include <ndk/rtlfuncs.h>
+#include <ndk/setypes.h>
+#include <ndk/sefuncs.h>
+#include <ndk/umfuncs.h>
+
+/* SEH support with PSEH */
+#include <pseh/pseh2.h>
+
+/* Use intrinsics for x86 and x64 */
+#if defined(_M_IX86) || defined(_M_AMD64)
+#define InterlockedCompareExchange _InterlockedCompareExchange
+#define InterlockedIncrement _InterlockedIncrement
+#define InterlockedDecrement _InterlockedDecrement
+#define InterlockedExchangeAdd _InterlockedExchangeAdd
+#define InterlockedExchange _InterlockedExchange
+#define InterlockedBitTestAndSet _interlockedbittestandset
+#define InterlockedBitTestAndSet64 _interlockedbittestandset64
+#endif
+
+#endif /* RTL_H */

Propchange: trunk/reactos/dll/win32/ntdll_vista/rtl_vista.h
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: trunk/reactos/dll/win32/ntdll_vista/srw.c (from r74702, 
trunk/reactos/sdk/lib/rtl/srw.c)
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ntdll_vista/srw.c?p2=trunk/reactos/dll/win32/ntdll_vista/srw.c&p1=trunk/reactos/sdk/lib/rtl/srw.c&r1=74702&r2=74703&rev=74703&view=diff
==============================================================================
--- trunk/reactos/sdk/lib/rtl/srw.c     [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/ntdll_vista/srw.c   [iso-8859-1] Tue May 30 
21:35:05 2017
@@ -13,7 +13,7 @@
 
 /* INCLUDES *****************************************************************/
 
-#include <rtl.h>
+#include <rtl_vista.h>
 
 #define NDEBUG
 #include <debug.h>

Modified: trunk/reactos/sdk/lib/rtl/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/rtl/CMakeLists.txt?rev=74703&r1=74702&r2=74703&view=diff
==============================================================================
--- trunk/reactos/sdk/lib/rtl/CMakeLists.txt    [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/rtl/CMakeLists.txt    [iso-8859-1] Tue May 30 
21:35:05 2017
@@ -16,7 +16,6 @@
     bitmap.c
     bootdata.c
     compress.c
-    condvar.c
     crc32.c
     critical.c
     dbgbuffer.c
@@ -56,7 +55,6 @@
     security.c
     slist.c
     sid.c
-    srw.c
     splaytree.c
     thread.c
     time.c

Removed: trunk/reactos/sdk/lib/rtl/srw.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/rtl/srw.c?rev=74702
==============================================================================
--- trunk/reactos/sdk/lib/rtl/srw.c     [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/rtl/srw.c     (removed)
@@ -1,765 +0,0 @@
-/*
- * COPYRIGHT:         See COPYING in the top level directory
- * PROJECT:           ReactOS system libraries
- * PURPOSE:           Slim Reader/Writer (SRW) Routines
- * PROGRAMMER:        Thomas Weidenmueller <[email protected]>
- *
- * NOTES:             The algorithms used in this implementation
- *                    may be different from Vista's implementation.
- *                    Since applications should treat the RTL_SRWLOCK
- *                    structure as opaque data, it should not matter.
- *                    The algorithms are probably not as optimized.
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <rtl.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-#ifdef _WIN64
-#define InterlockedBitTestAndSetPointer(ptr,val) 
InterlockedBitTestAndSet64((PLONGLONG)ptr,(LONGLONG)val)
-#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)
-#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)
-#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_MASK    (RTL_SRWLOCK_OWNED | RTL_SRWLOCK_CONTENDED | \
-                             RTL_SRWLOCK_SHARED | RTL_SRWLOCK_CONTENTION_LOCK)
-#define RTL_SRWLOCK_BITS    4
-
-typedef struct _RTLP_SRWLOCK_SHARED_WAKE
-{
-    LONG Wake;
-    volatile struct _RTLP_SRWLOCK_SHARED_WAKE *Next;
-} volatile RTLP_SRWLOCK_SHARED_WAKE, *PRTLP_SRWLOCK_SHARED_WAKE;
-
-typedef struct _RTLP_SRWLOCK_WAITBLOCK
-{
-    /* SharedCount is the number of shared acquirers. */
-    LONG SharedCount;
-
-    /* Last points to the last wait block in the chain. The value
-       is only valid when read from the first wait block. */
-    volatile struct _RTLP_SRWLOCK_WAITBLOCK *Last;
-
-    /* Next points to the next wait block in the chain. */
-    volatile struct _RTLP_SRWLOCK_WAITBLOCK *Next;
-
-    union
-    {
-        /* Wake is only valid for exclusive wait blocks */
-        LONG Wake;
-        /* The wake chain is only valid for shared wait blocks */
-        struct
-        {
-            PRTLP_SRWLOCK_SHARED_WAKE SharedWakeChain;
-            PRTLP_SRWLOCK_SHARED_WAKE LastSharedWake;
-        };
-    };
-
-    BOOLEAN Exclusive;
-} volatile RTLP_SRWLOCK_WAITBLOCK, *PRTLP_SRWLOCK_WAITBLOCK;
-
-
-static VOID
-NTAPI
-RtlpReleaseWaitBlockLockExclusive(IN OUT PRTL_SRWLOCK SRWLock,
-                                  IN PRTLP_SRWLOCK_WAITBLOCK FirstWaitBlock)
-{
-    PRTLP_SRWLOCK_WAITBLOCK Next;
-    LONG_PTR NewValue;
-
-    /* NOTE: We're currently in an exclusive lock in contended mode. */
-
-    Next = FirstWaitBlock->Next;
-    if (Next != NULL)
-    {
-        /* There's more blocks chained, we need to update the pointers
-           in the next wait block and update the wait block pointer. */
-        NewValue = (LONG_PTR)Next | RTL_SRWLOCK_OWNED | RTL_SRWLOCK_CONTENDED;
-        if (!FirstWaitBlock->Exclusive)
-        {
-            /* The next wait block has to be an exclusive lock! */
-            ASSERT(Next->Exclusive);
-
-            /* Save the shared count */
-            Next->SharedCount = FirstWaitBlock->SharedCount;
-
-            NewValue |= RTL_SRWLOCK_SHARED;
-        }
-
-        Next->Last = FirstWaitBlock->Last;
-    }
-    else
-    {
-        /* Convert the lock to a simple lock. */
-        if (FirstWaitBlock->Exclusive)
-            NewValue = RTL_SRWLOCK_OWNED;
-        else
-        {
-            ASSERT(FirstWaitBlock->SharedCount > 0);
-
-            NewValue = ((LONG_PTR)FirstWaitBlock->SharedCount << 
RTL_SRWLOCK_BITS) |
-                       RTL_SRWLOCK_SHARED | RTL_SRWLOCK_OWNED;
-        }
-    }
-
-    (void)InterlockedExchangePointer(&SRWLock->Ptr, (PVOID)NewValue);
-
-    if (FirstWaitBlock->Exclusive)
-    {
-        (void)InterlockedOr(&FirstWaitBlock->Wake,
-                            TRUE);
-    }
-    else
-    {
-        PRTLP_SRWLOCK_SHARED_WAKE WakeChain, NextWake;
-
-        /* If we were the first one to acquire the shared
-           lock, we now need to wake all others... */
-        WakeChain = FirstWaitBlock->SharedWakeChain;
-        do
-        {
-            NextWake = WakeChain->Next;
-
-            (void)InterlockedOr((PLONG)&WakeChain->Wake,
-                                TRUE);
-
-            WakeChain = NextWake;
-        } while (WakeChain != NULL);
-    }
-}
-
-
-static VOID
-NTAPI
-RtlpReleaseWaitBlockLockLastShared(IN OUT PRTL_SRWLOCK SRWLock,
-                                   IN PRTLP_SRWLOCK_WAITBLOCK FirstWaitBlock)
-{
-    PRTLP_SRWLOCK_WAITBLOCK Next;
-    LONG_PTR NewValue;
-
-    /* NOTE: We're currently in a shared lock in contended mode. */
-
-    /* The next acquirer to be unwaited *must* be an exclusive lock! */
-    ASSERT(FirstWaitBlock->Exclusive);
-
-    Next = FirstWaitBlock->Next;
-    if (Next != NULL)
-    {
-        /* There's more blocks chained, we need to update the pointers
-           in the next wait block and update the wait block pointer. */
-        NewValue = (LONG_PTR)Next | RTL_SRWLOCK_OWNED | RTL_SRWLOCK_CONTENDED;
-
-        Next->Last = FirstWaitBlock->Last;
-    }
-    else
-    {
-        /* Convert the lock to a simple exclusive lock. */
-        NewValue = RTL_SRWLOCK_OWNED;
-    }
-
-    (void)InterlockedExchangePointer(&SRWLock->Ptr, (PVOID)NewValue);
-
-    (void)InterlockedOr(&FirstWaitBlock->Wake,
-                        TRUE);
-}
-
-
-static VOID
-NTAPI
-RtlpReleaseWaitBlockLock(IN OUT PRTL_SRWLOCK SRWLock)
-{
-    InterlockedAndPointer(&SRWLock->Ptr,
-                          ~RTL_SRWLOCK_CONTENTION_LOCK);
-}
-
-
-static PRTLP_SRWLOCK_WAITBLOCK
-NTAPI
-RtlpAcquireWaitBlockLock(IN OUT PRTL_SRWLOCK SRWLock)
-{
-    LONG_PTR PrevValue;
-    PRTLP_SRWLOCK_WAITBLOCK WaitBlock;
-
-    while (1)
-    {
-        PrevValue = InterlockedOrPointer(&SRWLock->Ptr,
-                                         RTL_SRWLOCK_CONTENTION_LOCK);
-
-        if (!(PrevValue & RTL_SRWLOCK_CONTENTION_LOCK))
-            break;
-
-        YieldProcessor();
-    }
-
-    if (!(PrevValue & RTL_SRWLOCK_CONTENDED) ||
-        (PrevValue & ~RTL_SRWLOCK_MASK) == 0)
-    {
-        /* Too bad, looks like the wait block was removed in the
-           meanwhile, unlock again */
-        RtlpReleaseWaitBlockLock(SRWLock);
-        return NULL;
-    }
-
-    WaitBlock = (PRTLP_SRWLOCK_WAITBLOCK)(PrevValue & ~RTL_SRWLOCK_MASK);
-
-    return WaitBlock;
-}
-
-
-static VOID
-NTAPI
-RtlpAcquireSRWLockExclusiveWait(IN OUT PRTL_SRWLOCK SRWLock,
-                                IN PRTLP_SRWLOCK_WAITBLOCK WaitBlock)
-{
-    LONG_PTR CurrentValue;
-
-    while (1)
-    {
-        CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
-        if (!(CurrentValue & RTL_SRWLOCK_SHARED))
-        {
-            if (CurrentValue & RTL_SRWLOCK_CONTENDED)
-            {
-                if (WaitBlock->Wake != 0)
-                {
-                    /* Our wait block became the first one
-                       in the chain, we own the lock now! */
-                    break;
-                }
-            }
-            else
-            {
-                /* The last wait block was removed and/or we're
-                   finally a simple exclusive lock. This means we
-                   don't need to wait anymore, we acquired the lock! */
-                break;
-            }
-        }
-
-        YieldProcessor();
-    }
-}
-
-
-static VOID
-NTAPI
-RtlpAcquireSRWLockSharedWait(IN OUT PRTL_SRWLOCK SRWLock,
-                             IN OUT PRTLP_SRWLOCK_WAITBLOCK FirstWait  
OPTIONAL,
-                             IN OUT PRTLP_SRWLOCK_SHARED_WAKE WakeChain)
-{
-    if (FirstWait != NULL)
-    {
-        while (WakeChain->Wake == 0)
-        {
-            YieldProcessor();
-        }
-    }
-    else
-    {
-        LONG_PTR CurrentValue;
-
-        while (1)
-        {
-            CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
-            if (CurrentValue & RTL_SRWLOCK_SHARED)
-            {
-                /* The RTL_SRWLOCK_OWNED bit always needs to be set when
-                   RTL_SRWLOCK_SHARED is set! */
-                ASSERT(CurrentValue & RTL_SRWLOCK_OWNED);
-
-                if (CurrentValue & RTL_SRWLOCK_CONTENDED)
-                {
-                    if (WakeChain->Wake != 0)
-                    {
-                        /* Our wait block became the first one
-                           in the chain, we own the lock now! */
-                        break;
-                    }
-                }
-                else
-                {
-                    /* The last wait block was removed and/or we're
-                       finally a simple shared lock. This means we
-                       don't need to wait anymore, we acquired the lock! */
-                    break;
-                }
-            }
-
-            YieldProcessor();
-        }
-    }
-}
-
-
-VOID
-NTAPI
-RtlInitializeSRWLock(OUT PRTL_SRWLOCK SRWLock)
-{
-    SRWLock->Ptr = NULL;
-}
-
-
-VOID
-NTAPI
-RtlAcquireSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock)
-{
-    __ALIGNED(16) RTLP_SRWLOCK_WAITBLOCK StackWaitBlock;
-    RTLP_SRWLOCK_SHARED_WAKE SharedWake;
-    LONG_PTR CurrentValue, NewValue;
-    PRTLP_SRWLOCK_WAITBLOCK First, Shared, FirstWait;
-
-    while (1)
-    {
-        CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
-
-        if (CurrentValue & RTL_SRWLOCK_SHARED)
-        {
-            /* NOTE: It is possible that the RTL_SRWLOCK_OWNED bit is set! */
-
-            if (CurrentValue & RTL_SRWLOCK_CONTENDED)
-            {
-                /* There's other waiters already, lock the wait blocks and
-                   increment the shared count */
-                First = RtlpAcquireWaitBlockLock(SRWLock);
-                if (First != NULL)
-                {
-                    FirstWait = NULL;
-
-                    if (First->Exclusive)
-                    {
-                        /* We need to setup a new wait block! Although
-                           we're currently in a shared lock and we're acquiring
-                           a shared lock, there are exclusive locks queued. We 
need
-                           to wait until those are released. */
-                        Shared = First->Last;
-
-                        if (Shared->Exclusive)
-                        {
-                            StackWaitBlock.Exclusive = FALSE;
-                            StackWaitBlock.SharedCount = 1;
-                            StackWaitBlock.Next = NULL;
-                            StackWaitBlock.Last = &StackWaitBlock;
-                            StackWaitBlock.SharedWakeChain = &SharedWake;
-
-                            Shared->Next = &StackWaitBlock;
-                            First->Last = &StackWaitBlock;
-
-                            Shared = &StackWaitBlock;
-                            FirstWait = &StackWaitBlock;
-                        }
-                        else
-                        {
-                            Shared->LastSharedWake->Next = &SharedWake;
-                            Shared->SharedCount++;
-                        }
-                    }
-                    else
-                    {
-                        Shared = First;
-                        Shared->LastSharedWake->Next = &SharedWake;
-                        Shared->SharedCount++;
-                    }
-
-                    SharedWake.Next = NULL;
-                    SharedWake.Wake = 0;
-
-                    Shared->LastSharedWake = &SharedWake;
-
-                    RtlpReleaseWaitBlockLock(SRWLock);
-
-                    RtlpAcquireSRWLockSharedWait(SRWLock,
-                                                 FirstWait,
-                                                 &SharedWake);
-
-                    /* Successfully incremented the shared count, we acquired 
the lock */
-                    break;
-                }
-            }
-            else
-            {
-                /* This is a fastest path, just increment the number of
-                   current shared locks */
-
-                /* Since the RTL_SRWLOCK_SHARED bit is set, the 
RTL_SRWLOCK_OWNED bit also has
-                   to be set! */
-
-                ASSERT(CurrentValue & RTL_SRWLOCK_OWNED);
-
-                NewValue = (CurrentValue >> RTL_SRWLOCK_BITS) + 1;
-                NewValue = (NewValue << RTL_SRWLOCK_BITS) | (CurrentValue & 
RTL_SRWLOCK_MASK);
-
-                if ((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
-                                                                
(PVOID)NewValue,
-                                                                
(PVOID)CurrentValue) == CurrentValue)
-                {
-                    /* Successfully incremented the shared count, we acquired 
the lock */
-                    break;
-                }
-            }
-        }
-        else
-        {
-            if (CurrentValue & RTL_SRWLOCK_OWNED)
-            {
-                /* The resource is currently acquired exclusively */
-                if (CurrentValue & RTL_SRWLOCK_CONTENDED)
-                {
-                    SharedWake.Next = NULL;
-                    SharedWake.Wake = 0;
-
-                    /* There's other waiters already, lock the wait blocks and
-                       increment the shared count. If the last block in the 
chain
-                       is an exclusive lock, add another block. */
-
-                    StackWaitBlock.Exclusive = FALSE;
-                    StackWaitBlock.SharedCount = 0;
-                    StackWaitBlock.Next = NULL;
-                    StackWaitBlock.Last = &StackWaitBlock;
-                    StackWaitBlock.SharedWakeChain = &SharedWake;
-
-                    First = RtlpAcquireWaitBlockLock(SRWLock);
-                    if (First != NULL)
-                    {
-                        Shared = First->Last;
-                        if (Shared->Exclusive)
-                        {
-                            Shared->Next = &StackWaitBlock;
-                            First->Last = &StackWaitBlock;
-
-                            Shared = &StackWaitBlock;
-                            FirstWait = &StackWaitBlock;
-                        }
-                        else
-                        {
-                            FirstWait = NULL;
-                            Shared->LastSharedWake->Next = &SharedWake;
-                        }
-
-                        Shared->SharedCount++;
-                        Shared->LastSharedWake = &SharedWake;
-
-                        RtlpReleaseWaitBlockLock(SRWLock);
-
-                        RtlpAcquireSRWLockSharedWait(SRWLock,
-                                                     FirstWait,
-                                                     &SharedWake);
-
-                        /* Successfully incremented the shared count, we 
acquired the lock */
-                        break;
-                    }
-                }
-                else
-                {
-                    SharedWake.Next = NULL;
-                    SharedWake.Wake = 0;
-
-                    /* We need to setup the first wait block. Currently an 
exclusive lock is
-                       held, change the lock to contended mode. */
-                    StackWaitBlock.Exclusive = FALSE;
-                    StackWaitBlock.SharedCount = 1;
-                    StackWaitBlock.Next = NULL;
-                    StackWaitBlock.Last = &StackWaitBlock;
-                    StackWaitBlock.SharedWakeChain = &SharedWake;
-                    StackWaitBlock.LastSharedWake = &SharedWake;
-
-                    NewValue = (ULONG_PTR)&StackWaitBlock | RTL_SRWLOCK_OWNED 
| RTL_SRWLOCK_CONTENDED;
-                    if 
((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
-                                                                    
(PVOID)NewValue,
-                                                                    
(PVOID)CurrentValue) == CurrentValue)
-                    {
-                        RtlpAcquireSRWLockSharedWait(SRWLock,
-                                                     &StackWaitBlock,
-                                                     &SharedWake);
-
-                        /* Successfully set the shared count, we acquired the 
lock */
-                        break;
-                    }
-                }
-            }
-            else
-            {
-                /* This is a fast path, we can simply try to set the shared 
count to 1 */
-                NewValue = (1 << RTL_SRWLOCK_BITS) | RTL_SRWLOCK_SHARED | 
RTL_SRWLOCK_OWNED;
-
-                /* The RTL_SRWLOCK_CONTENDED bit should never be set if 
neither the
-                   RTL_SRWLOCK_SHARED nor the RTL_SRWLOCK_OWNED bit is set */
-                ASSERT(!(CurrentValue & RTL_SRWLOCK_CONTENDED));
-
-                if ((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
-                                                                
(PVOID)NewValue,
-                                                                
(PVOID)CurrentValue) == CurrentValue)
-                {
-                    /* Successfully set the shared count, we acquired the lock 
*/
-                    break;
-                }
-            }
-        }
-
-        YieldProcessor();
-    }
-}
-
-
-VOID
-NTAPI
-RtlReleaseSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock)
-{
-    LONG_PTR CurrentValue, NewValue;
-    PRTLP_SRWLOCK_WAITBLOCK WaitBlock;
-    BOOLEAN LastShared;
-
-    while (1)
-    {
-        CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
-
-        if (CurrentValue & RTL_SRWLOCK_SHARED)
-        {
-            if (CurrentValue & RTL_SRWLOCK_CONTENDED)
-            {
-                /* There's a wait block, we need to wake a pending
-                   exclusive acquirer if this is the last shared release */
-                WaitBlock = RtlpAcquireWaitBlockLock(SRWLock);
-                if (WaitBlock != NULL)
-                {
-                    LastShared = (--WaitBlock->SharedCount == 0);
-
-                    if (LastShared)
-                        RtlpReleaseWaitBlockLockLastShared(SRWLock,
-                                                           WaitBlock);
-                    else
-                        RtlpReleaseWaitBlockLock(SRWLock);
-
-                    /* We released the lock */
-                    break;
-                }
-            }
-            else
-            {
-                /* This is a fast path, we can simply decrement the shared
-                   count and store the pointer */
-                NewValue = CurrentValue >> RTL_SRWLOCK_BITS;
-
-                if (--NewValue != 0)
-                {
-                    NewValue = (NewValue << RTL_SRWLOCK_BITS) | 
RTL_SRWLOCK_SHARED | RTL_SRWLOCK_OWNED;
-                }
-
-                if ((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
-                                                                
(PVOID)NewValue,
-                                                                
(PVOID)CurrentValue) == CurrentValue)
-                {
-                    /* Successfully released the lock */
-                    break;
-                }
-            }
-        }
-        else
-        {
-            /* The RTL_SRWLOCK_SHARED bit has to be present now,
-               even in the contended case! */
-            RtlRaiseStatus(STATUS_RESOURCE_NOT_OWNED);
-        }
-
-        YieldProcessor();
-    }
-}
-
-
-VOID
-NTAPI
-RtlAcquireSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock)
-{
-    __ALIGNED(16) RTLP_SRWLOCK_WAITBLOCK StackWaitBlock;
-    PRTLP_SRWLOCK_WAITBLOCK First, Last;
-
-    if (InterlockedBitTestAndSetPointer(&SRWLock->Ptr,
-                                        RTL_SRWLOCK_OWNED_BIT))
-    {
-        LONG_PTR CurrentValue, NewValue;
-
-        while (1)
-        {
-            CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
-
-            if (CurrentValue & RTL_SRWLOCK_SHARED)
-            {
-                /* A shared lock is being held right now. We need to add a 
wait block! */
-
-                if (CurrentValue & RTL_SRWLOCK_CONTENDED)
-                {
-                    goto AddWaitBlock;
-                }
-                else
-                {
-                    /* There are no wait blocks so far, we need to add 
ourselves as the first
-                       wait block. We need to keep the shared count! */
-                    StackWaitBlock.Exclusive = TRUE;
-                    StackWaitBlock.SharedCount = (LONG)(CurrentValue >> 
RTL_SRWLOCK_BITS);
-                    StackWaitBlock.Next = NULL;
-                    StackWaitBlock.Last = &StackWaitBlock;
-                    StackWaitBlock.Wake = 0;
-
-                    NewValue = (ULONG_PTR)&StackWaitBlock | RTL_SRWLOCK_SHARED 
| RTL_SRWLOCK_CONTENDED | RTL_SRWLOCK_OWNED;
-
-                    if 
((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
-                                                                    
(PVOID)NewValue,
-                                                                    
(PVOID)CurrentValue) == CurrentValue)
-                    {
-                        RtlpAcquireSRWLockExclusiveWait(SRWLock,
-                                                        &StackWaitBlock);
-
-                        /* Successfully acquired the exclusive lock */
-                        break;
-                    }
-                }
-            }
-            else
-            {
-                if (CurrentValue & RTL_SRWLOCK_OWNED)
-                {
-                    /* An exclusive lock is being held right now. We need to 
add a wait block! */
-
-                    if (CurrentValue & RTL_SRWLOCK_CONTENDED)
-                    {
-AddWaitBlock:
-                        StackWaitBlock.Exclusive = TRUE;
-                        StackWaitBlock.SharedCount = 0;
-                        StackWaitBlock.Next = NULL;
-                        StackWaitBlock.Last = &StackWaitBlock;
-                        StackWaitBlock.Wake = 0;
-
-                        First = RtlpAcquireWaitBlockLock(SRWLock);
-                        if (First != NULL)
-                        {
-                            Last = First->Last;
-                            Last->Next = &StackWaitBlock;
-                            First->Last = &StackWaitBlock;
-
-                            RtlpReleaseWaitBlockLock(SRWLock);
-
-                            RtlpAcquireSRWLockExclusiveWait(SRWLock,
-                                                            &StackWaitBlock);
-
-                            /* Successfully acquired the exclusive lock */
-                            break;
-                        }
-                    }
-                    else
-                    {
-                        /* There are no wait blocks so far, we need to add 
ourselves as the first
-                           wait block. We need to keep the shared count! */
-                        StackWaitBlock.Exclusive = TRUE;
-                        StackWaitBlock.SharedCount = 0;
-                        StackWaitBlock.Next = NULL;
-                        StackWaitBlock.Last = &StackWaitBlock;
-                        StackWaitBlock.Wake = 0;
-
-                        NewValue = (ULONG_PTR)&StackWaitBlock | 
RTL_SRWLOCK_OWNED | RTL_SRWLOCK_CONTENDED;
-                        if 
((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
-                                                                        
(PVOID)NewValue,
-                                                                        
(PVOID)CurrentValue) == CurrentValue)
-                        {
-                            RtlpAcquireSRWLockExclusiveWait(SRWLock,
-                                                            &StackWaitBlock);
-
-                            /* Successfully acquired the exclusive lock */
-                            break;
-                        }
-                    }
-                }
-                else
-                {
-                    if (!InterlockedBitTestAndSetPointer(&SRWLock->Ptr,
-                                                         
RTL_SRWLOCK_OWNED_BIT))
-                    {
-                        /* We managed to get hold of a simple exclusive lock! 
*/
-                        break;
-                    }
-                }
-            }
-
-            YieldProcessor();
-        }
-    }
-}
-
-
-VOID
-NTAPI
-RtlReleaseSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock)
-{
-    LONG_PTR CurrentValue, NewValue;
-    PRTLP_SRWLOCK_WAITBLOCK WaitBlock;
-
-    while (1)
-    {
-        CurrentValue = *(volatile LONG_PTR *)&SRWLock->Ptr;
-
-        if (!(CurrentValue & RTL_SRWLOCK_OWNED))
-        {
-            RtlRaiseStatus(STATUS_RESOURCE_NOT_OWNED);
-        }
-
-        if (!(CurrentValue & RTL_SRWLOCK_SHARED))
-        {
-            if (CurrentValue & RTL_SRWLOCK_CONTENDED)
-            {
-                /* There's a wait block, we need to wake the next pending
-                   acquirer (exclusive or shared) */
-                WaitBlock = RtlpAcquireWaitBlockLock(SRWLock);
-                if (WaitBlock != NULL)
-                {
-                    RtlpReleaseWaitBlockLockExclusive(SRWLock,
-                                                      WaitBlock);
-
-                    /* We released the lock */
-                    break;
-                }
-            }
-            else
-            {
-                /* This is a fast path, we can simply clear the 
RTL_SRWLOCK_OWNED
-                   bit. All other bits should be 0 now because this is a simple
-                   exclusive lock and no one is waiting. */
-
-                ASSERT(!(CurrentValue & ~RTL_SRWLOCK_OWNED));
-
-                NewValue = 0;
-                if ((LONG_PTR)InterlockedCompareExchangePointer(&SRWLock->Ptr,
-                                                                
(PVOID)NewValue,
-                                                                
(PVOID)CurrentValue) == CurrentValue)
-                {
-                    /* We released the lock */
-                    break;
-                }
-            }
-        }
-        else
-        {
-            /* The RTL_SRWLOCK_SHARED bit must not be present now,
-               not even in the contended case! */
-            RtlRaiseStatus(STATUS_RESOURCE_NOT_OWNED);
-        }
-
-        YieldProcessor();
-    }
-}


Reply via email to