InterlockedPushEntrySList() and InterlockedPopEntrySList() shouldn't serialize access to the list with semaphores
Modified: trunk/reactos/ntoskrnl/ex/list.c
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
Modified: trunk/reactos/ntoskrnl/mm/i386/memsafe.s
Modified: trunk/reactos/ntoskrnl/mm/i386/pfault.c

Modified: trunk/reactos/ntoskrnl/ex/list.c
--- trunk/reactos/ntoskrnl/ex/list.c	2005-02-21 21:40:31 UTC (rev 13708)
+++ trunk/reactos/ntoskrnl/ex/list.c	2005-02-22 01:07:41 UTC (rev 13709)
@@ -16,8 +16,6 @@
 #define NDEBUG
 #include <internal/debug.h>
 
-static KSPIN_LOCK ExpGlobalListLock = { 0, };
-
 /* FUNCTIONS *************************************************************/
 
 /*
@@ -446,8 +444,31 @@
 FASTCALL
 InterlockedPopEntrySList(IN PSLIST_HEADER ListHead)
 {
-  return (PSLIST_ENTRY) ExInterlockedPopEntrySList(ListHead,
-    &ExpGlobalListLock);
+  SLIST_HEADER newslh, oldslh;
+  PSLIST_ENTRY le;
+  
+  do
+  {
+    oldslh = *ListHead;
+    le = oldslh.Next.Next;
+    if(le == NULL)
+    {
+      /* nothing to do */
+      return NULL;
+    }
+    newslh.Sequence = oldslh.Sequence + 1;
+    newslh.Depth = oldslh.Depth - 1;
+    newslh.Next.Next = MmSafeReadPtr(&le->Next);
+    if(newslh.Next.Next == NULL)
+    {
+      /* try again */
+      continue;
+    }
+  } while(ExfInterlockedCompareExchange64(&ListHead->Alignment,
+                                          &newslh.Alignment,
+                                          &oldslh.Alignment) != oldslh.Alignment);
+
+  return le;
 }
 
 
@@ -457,11 +478,23 @@
 PSLIST_ENTRY
 FASTCALL
 InterlockedPushEntrySList(IN PSLIST_HEADER ListHead,
-  IN PSLIST_ENTRY ListEntry)
+                          IN PSLIST_ENTRY ListEntry)
 {
-  return (PSLIST_ENTRY) ExInterlockedPushEntrySList(ListHead,
-    ListEntry,
-    &ExpGlobalListLock);
+  SLIST_HEADER newslh, oldslh;
+  
+  newslh.Next.Next = ListEntry;
+  
+  do
+  {
+    oldslh = *ListHead;
+    newslh.Depth = oldslh.Depth + 1;
+    newslh.Sequence = oldslh.Sequence + 1;
+    ListEntry->Next = oldslh.Next.Next;
+  } while(ExfInterlockedCompareExchange64(&ListHead->Alignment,
+                                          &newslh.Alignment,
+                                          &oldslh.Alignment) != oldslh.Alignment);
+
+  return oldslh.Next.Next;
 }
 
 /* EOF */

Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
--- trunk/reactos/ntoskrnl/include/internal/mm.h	2005-02-21 21:40:31 UTC (rev 13708)
+++ trunk/reactos/ntoskrnl/include/internal/mm.h	2005-02-22 01:07:41 UTC (rev 13709)
@@ -563,6 +563,8 @@
 
 NTSTATUS MmSafeCopyToUser(PVOID Dest, const VOID *Src, ULONG Count);
 
+PVOID FASTCALL MmSafeReadPtr(PVOID Source);
+
 /* pageop.c ******************************************************************/
 
 VOID

Modified: trunk/reactos/ntoskrnl/mm/i386/memsafe.s
--- trunk/reactos/ntoskrnl/mm/i386/memsafe.s	2005-02-21 21:40:31 UTC (rev 13708)
+++ trunk/reactos/ntoskrnl/mm/i386/memsafe.s	2005-02-22 01:07:41 UTC (rev 13709)
@@ -4,6 +4,9 @@
 .globl _MmSafeCopyToUser
 .globl _MmSafeCopyToUserUnsafeStart
 .globl _MmSafeCopyToUserRestart
+.globl @MmSafeReadPtr@4
+.globl _MmSafeReadPtrStart
+.globl _MmSafeReadPtrEnd
 
 	/*
 	 * NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, 
@@ -83,3 +86,16 @@
 	popl    %ebp
 	ret
 
+/*****************************************************************************/
+
+	/*
+	 * PVOID FASTCALL MmSafeReadPtr(PVOID Source)
+	 */
+@MmSafeReadPtr@4:
+_MmSafeReadPtrStart:
+	/*
+	 * If we incur a pagefault, eax will be set NULL
+	 */
+	movl	(%ecx),%eax
+_MmSafeReadPtrEnd:
+	ret

Modified: trunk/reactos/ntoskrnl/mm/i386/pfault.c
--- trunk/reactos/ntoskrnl/mm/i386/pfault.c	2005-02-21 21:40:31 UTC (rev 13708)
+++ trunk/reactos/ntoskrnl/mm/i386/pfault.c	2005-02-22 01:07:41 UTC (rev 13709)
@@ -20,6 +20,8 @@
 extern VOID MmSafeCopyFromUserRestart(VOID);
 extern VOID MmSafeCopyToUserUnsafeStart(VOID);
 extern VOID MmSafeCopyToUserRestart(VOID);
+extern VOID MmSafeReadPtrStart(VOID);
+extern VOID MmSafeReadPtrEnd(VOID);
 
 extern ULONG MmGlobalKernelPageDirectory[1024];
 
@@ -90,5 +92,14 @@
       (*Eax) = STATUS_ACCESS_VIOLATION;
       return(STATUS_SUCCESS);
    }
+   if (!NT_SUCCESS(Status) && (Mode == KernelMode) &&
+         ((*Eip) >= (ULONG_PTR)MmSafeReadPtrStart) &&
+         ((*Eip) <= (ULONG_PTR)MmSafeReadPtrEnd))
+   {
+      (*Eip) = (ULONG_PTR)MmSafeReadPtrEnd;
+      (*Eax) = 0;
+      return(STATUS_SUCCESS);
+   }
+
    return(Status);
 }