Fix kernel-mode executive atom implementation (mostly add SEH and tidy up the code...
[reactos.git] / reactos / ntoskrnl / ex / list.c
index 398cb10..fd2e678 100644 (file)
@@ -5,10 +5,9 @@
  * FILE:            ntoskrnl/ex/list.c
  * PURPOSE:         Manages double linked lists, single linked lists and
  *                  sequenced lists
+ *
  * PROGRAMMERS:     David Welch (welch@mcmail.com)
  *                  Casper S. Hornstrup (chorns@users.sourceforge.net)
- * UPDATE HISTORY:
- *   02-07-2001 CSH Implemented sequenced lists
  */
 
 /* INCLUDES *****************************************************************/
@@ -17,8 +16,6 @@
 #define NDEBUG
 #include <internal/debug.h>
 
-static KSPIN_LOCK ExpGlobalListLock = { 0, };
-
 /* FUNCTIONS *************************************************************/
 
 /*
@@ -447,8 +444,26 @@ PSLIST_ENTRY
 FASTCALL
 InterlockedPopEntrySList(IN PSLIST_HEADER ListHead)
 {
-  return (PSLIST_ENTRY) ExInterlockedPopEntrySList(ListHead,
-    &ExpGlobalListLock);
+  SLIST_HEADER newslh, oldslh;
+  PSLIST_ENTRY le;
+
+  do
+  {
+    oldslh = *(volatile SLIST_HEADER *)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);
+  } while(ExfInterlockedCompareExchange64((PLONGLONG)&ListHead->Alignment,
+                                          (PLONGLONG)&newslh.Alignment,
+                                          (PLONGLONG)&oldslh.Alignment) != (LONGLONG)oldslh.Alignment);
+
+  return le;
 }
 
 
@@ -458,11 +473,23 @@ InterlockedPopEntrySList(IN PSLIST_HEADER ListHead)
 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 = *(volatile SLIST_HEADER *)ListHead;
+    newslh.Depth = oldslh.Depth + 1;
+    newslh.Sequence = oldslh.Sequence + 1;
+    ListEntry->Next = oldslh.Next.Next;
+  } while(ExfInterlockedCompareExchange64((PLONGLONG)&ListHead->Alignment,
+                                          (PLONGLONG)&newslh.Alignment,
+                                          (PLONGLONG)&oldslh.Alignment) != (LONGLONG)oldslh.Alignment);
+
+  return oldslh.Next.Next;
 }
 
 /* EOF */