Author: tkreuzer
Date: Sat May 2 22:20:38 2015
New Revision: 67522
URL:
http://svn.reactos.org/svn/reactos?rev=67522&view=rev
Log:
[RTL]
- Implement C versions of RtlInterlockedPushEntrySList, RtlInterlockedPushListSList,
RtlInterlockedPopEntrySList and RtlInterlockedFlushSList.
- RtlInterlockedPushListSList is fastcall, not stdcall
Modified:
trunk/reactos/dll/ntdll/def/ntdll.spec
trunk/reactos/lib/rtl/interlck.c
trunk/reactos/lib/rtl/slist.c
trunk/reactos/ntoskrnl/ke/amd64/stubs.c
Modified: trunk/reactos/dll/ntdll/def/ntdll.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/def/ntdll.spec?r…
==============================================================================
--- trunk/reactos/dll/ntdll/def/ntdll.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/def/ntdll.spec [iso-8859-1] Sat May 2 22:20:38 2015
@@ -3,7 +3,7 @@
;@ stdcall RtlConvertVariantToProperty(ptr long ptr ptr ptr long ptr)
@ fastcall RtlActivateActivationContextUnsafeFast(ptr ptr)
@ fastcall RtlDeactivateActivationContextUnsafeFast(ptr)
-@ stdcall RtlInterlockedPushListSList(ptr ptr ptr long)
+@ fastcall RtlInterlockedPushListSList(ptr ptr ptr long)
@ fastcall -arch=i386 RtlUlongByteSwap(long)
@ fastcall -ret64 RtlUlonglongByteSwap(double)
@ fastcall -arch=i386 RtlUshortByteSwap(long)
Modified: trunk/reactos/lib/rtl/interlck.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/interlck.c?rev=675…
==============================================================================
--- trunk/reactos/lib/rtl/interlck.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/interlck.c [iso-8859-1] Sat May 2 22:20:38 2015
@@ -15,17 +15,6 @@
/* FUNCTIONS ***************************************************************/
-PSLIST_ENTRY
-NTAPI
-RtlInterlockedPushListSList(IN PSLIST_HEADER ListHead,
- IN PSLIST_ENTRY List,
- IN PSLIST_ENTRY ListEnd,
- IN ULONG Count)
-{
- UNIMPLEMENTED;
- return NULL;
-}
-
LONGLONG
NTAPI
RtlInterlockedCompareExchange64(LONGLONG volatile *Destination,
Modified: trunk/reactos/lib/rtl/slist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/slist.c?rev=67522&…
==============================================================================
--- trunk/reactos/lib/rtl/slist.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/slist.c [iso-8859-1] Sat May 2 22:20:38 2015
@@ -4,6 +4,7 @@
* PURPOSE: Slist Routines
* FILE: lib/rtl/slist.c
* PROGRAMERS: Stefan Ginsberg (stefan__100__(a)hotmail.com)
+ * Timo Kreuzer (timo.kreuzer(a)reactos.org)
*/
/* INCLUDES *****************************************************************/
@@ -13,35 +14,53 @@
#define NDEBUG
#include <debug.h>
+#ifdef _WIN64
+BOOLEAN RtlpUse16ByteSLists = -1;
+#endif
+
/* FUNCTIONS ***************************************************************/
VOID
NTAPI
-RtlInitializeSListHead(IN PSLIST_HEADER ListHead)
-{
-#ifdef _WIN64
- ListHead->Alignment = 0;
- ListHead->Region = 0;
- ListHead->Header8.Init = 1;
- // ListHead->Header8.HeaderType = 1; // FIXME: depending on cmpxchg16b support?
-#else
- ListHead->Alignment = 0;
-#endif
-}
-
-PSLIST_ENTRY
-NTAPI
-RtlFirstEntrySList(IN const SLIST_HEADER *ListHead)
-{
-#ifdef _WIN64
- if (ListHead->Header8.HeaderType)
- {
- return (PVOID)(ListHead->Region & ~0xF);
+RtlInitializeSListHead(
+ _Out_ PSLIST_HEADER SListHead)
+{
+#if defined(_WIN64)
+ /* Make sure the header is 16 byte aligned */
+ if (((ULONG_PTR)SListHead & 0xf) != 0)
+ {
+ DPRINT1("Unaligned SListHead: 0x%p\n", SListHead);
+ RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT);
+ }
+
+ /* Initialize the Region member */
+#if defined(_IA64_)
+ /* On Itanium we store the region in the list head */
+ SListHead->Region = (ULONG_PTR)SListHead & VRN_MASK;
+#else
+ /* On amd64 we don't need to store anything */
+ SListHead->Region = 0;
+#endif /* _IA64_ */
+#endif /* _WIN64 */
+
+ SListHead->Alignment = 0;
+}
+
+PSLIST_ENTRY
+NTAPI
+RtlFirstEntrySList(
+ _In_ const SLIST_HEADER *SListHead)
+{
+#if defined(_WIN64)
+ /* Check if the header is initialized as 16 byte header */
+ if (SListHead->Header16.HeaderType)
+ {
+ return (PVOID)(SListHead->Region & ~0xFLL);
}
else
{
union {
- PVOID P;
+ ULONG64 Region;
struct {
ULONG64 Reserved:4;
ULONG64 NextEntry:39;
@@ -49,23 +68,230 @@
} Bits;
} Pointer;
- Pointer.P = (PVOID)ListHead;
- Pointer.Bits.NextEntry = ListHead->Header8.NextEntry;
- return Pointer.P;
- }
-#else
- return ListHead->Next.Next;
+#if defined(_IA64_)
+ /* On Itanium we stored the region in the list head */
+ Pointer.Region = SListHead->Region;;
+#else
+ /* On amd64 we just use the list head itself */
+ Pointer.Region = (ULONG64)SListHead;
+#endif
+ Pointer.Bits.NextEntry = SListHead->Header8.NextEntry;
+ return (PVOID)Pointer.Region;
+ }
+#else
+ return SListHead->Next.Next;
#endif
}
WORD
NTAPI
-RtlQueryDepthSList(IN PSLIST_HEADER ListHead)
+RtlQueryDepthSList(
+ _In_ PSLIST_HEADER SListHead)
+{
+#if defined(_WIN64)
+ return (USHORT)(SListHead->Alignment & 0xffff);
+#else
+ return SListHead->Depth;
+#endif
+}
+
+PSLIST_ENTRY
+FASTCALL
+RtlInterlockedPushListSList(
+ _Inout_ PSLIST_HEADER SListHead,
+ _Inout_ __drv_aliasesMem PSLIST_ENTRY List,
+ _Inout_ PSLIST_ENTRY ListEnd,
+ _In_ ULONG Count)
{
#ifdef _WIN64
- return ListHead->Header8.HeaderType ?
- (WORD)ListHead->Header16.Sequence : (WORD)ListHead->Header8.Sequence;
-#else
- return ListHead->Depth;
-#endif
-}
+ UNIMPLEMENTED;
+ DbgBreakPoint();
+ return NULL;
+#else
+ SLIST_HEADER OldHeader, NewHeader;
+ ULONGLONG Compare;
+
+ /* Read the header */
+ OldHeader = *SListHead;
+
+ do
+ {
+ /* Link the last list entry */
+ ListEnd->Next = OldHeader.Next.Next;
+
+ /* Create a new header */
+ NewHeader = OldHeader;
+ NewHeader.Next.Next = List;
+ NewHeader.Depth += Count;
+ NewHeader.Sequence++;
+
+ /* Try to exchange atomically */
+ Compare = OldHeader.Alignment;
+ OldHeader.Alignment =
InterlockedCompareExchange64((PLONGLONG)&SListHead->Alignment,
+ NewHeader.Alignment,
+ Compare);
+ }
+ while (OldHeader.Alignment != Compare);
+
+ /* Return the old first entry */
+ return OldHeader.Next.Next;
+#endif /* _WIN64 */
+}
+
+
+#if !defined(_M_IX86) && !defined(_M_AMD64)
+
+_WARN("C based S-List functions can bugcheck, if not handled properly in
kernel")
+
+#ifdef _WIN64
+#error "No generic S-List functions for WIN64!"
+#endif
+
+/* This variable must be used in kernel mode to prevent the system from
+ bugchecking on non-present kernel memory. If this variable is set to TRUE
+ an exception needs to be dispatched. */
+BOOLEAN RtlpExpectSListFault;
+
+PSLIST_ENTRY
+NTAPI
+RtlInterlockedPushEntrySList(
+ _Inout_ PSLIST_HEADER SListHead,
+ _Inout_ __drv_aliasesMem PSLIST_ENTRY SListEntry)
+{
+ SLIST_HEADER OldHeader, NewHeader;
+ ULONGLONG Compare;
+
+ /* Read the header */
+ OldHeader = *SListHead;
+
+ do
+ {
+ /* Link the list entry */
+ SListEntry->Next = OldHeader.Next.Next;
+
+ /* Create a new header */
+ NewHeader = OldHeader;
+ NewHeader.Next.Next = SListEntry;
+ NewHeader.Depth++;
+ NewHeader.Sequence++;
+
+ /* Try to exchange atomically */
+ Compare = OldHeader.Alignment;
+ OldHeader.Alignment =
InterlockedCompareExchange64((PLONGLONG)&SListHead->Alignment,
+ NewHeader.Alignment,
+ Compare);
+ }
+ while (OldHeader.Alignment != Compare);
+
+ /* Return the old first entry */
+ return OldHeader.Next.Next;
+}
+
+PSLIST_ENTRY
+NTAPI
+RtlInterlockedPopEntrySList(
+ _Inout_ PSLIST_HEADER SListHead)
+{
+ SLIST_HEADER OldHeader, NewHeader;
+ ULONGLONG Compare;
+
+restart:
+
+ /* Read the header */
+ OldHeader = *SListHead;
+
+ do
+ {
+ /* Check for empty list */
+ if (OldHeader.Next.Next == NULL)
+ {
+ return NULL;
+ }
+
+ /* Create a new header */
+ NewHeader = OldHeader;
+
+ /* HACK to let the kernel know that we are doing slist-magic */
+ RtlpExpectSListFault = TRUE;
+
+ /* Wrapped in SEH, since OldHeader.Next.Next can already be freed */
+ _SEH2_TRY
+ {
+ NewHeader.Next = *OldHeader.Next.Next;
+ }
+ _SEH2_EXCEPT((SListHead->Next.Next != OldHeader.Next.Next) ?
+ EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
+ {
+ /* We got an exception and the list head changed.
+ Restart the whole operation. */
+ RtlpExpectSListFault = FALSE;
+ goto restart;
+ }
+ _SEH2_END;
+
+ /* We are done */
+ RtlpExpectSListFault = FALSE;
+
+ /* Adjust depth */
+ NewHeader.Depth--;
+
+ /* Try to exchange atomically */
+ Compare = OldHeader.Alignment;
+ OldHeader.Alignment =
InterlockedCompareExchange64((PLONGLONG)SListHead->Alignment,
+ NewHeader.Alignment,
+ Compare);
+ }
+ while (OldHeader.Alignment != Compare);
+
+ return OldHeader.Next.Next;
+}
+
+PSLIST_ENTRY
+NTAPI
+RtlInterlockedFlushSList(
+ _Inout_ PSLIST_HEADER SListHead)
+{
+ SLIST_HEADER OldHeader, NewHeader;
+ ULONGLONG Compare;
+
+ /* Read the header */
+ OldHeader = *SListHead;
+
+ do
+ {
+ /* Check for empty list */
+ if (OldHeader.Next.Next == NULL)
+ {
+ return NULL;
+ }
+
+ /* Create a new header (keep the sequence number) */
+ NewHeader = OldHeader;
+ NewHeader.Next.Next = NULL;
+ NewHeader.Depth = 0;
+
+ /* Try to exchange atomically */
+ Compare = OldHeader.Alignment;
+ OldHeader.Alignment =
InterlockedCompareExchange64((PLONGLONG)&SListHead->Alignment,
+ NewHeader.Alignment,
+ Compare);
+ }
+ while (OldHeader.Alignment != Compare);
+
+ /* Return the old first entry */
+ return OldHeader.Next.Next;
+
+}
+
+#ifdef _MSC_VER
+#pragma comment(linker,
"/alternatename:ExpInterlockedPopEntrySList=RtlInterlockedPopEntrySList")
+#pragma comment(linker,
"/alternatename:ExpInterlockedPushEntrySList=RtlInterlockedPushEntrySList")
+#pragma comment(linker,
"/alternatename:ExpInterlockedFlushSList=RtlInterlockedFlushSList")
+#else
+#pragma redefine_extname RtlInterlockedPopEntrySList ExpInterlockedPopEntrySList
+#pragma redefine_extname RtlInterlockedPushEntrySList ExpInterlockedPushEntrySList
+#pragma redefine_extname RtlInterlockedFlushSList ExpInterlockedFlushSList
+#endif
+
+#endif
+
Modified: trunk/reactos/ntoskrnl/ke/amd64/stubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/stubs.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/amd64/stubs.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/amd64/stubs.c [iso-8859-1] Sat May 2 22:20:38 2015
@@ -453,15 +453,6 @@
return STATUS_UNSUCCESSFUL;
}
-#undef ExQueryDepthSList
-NTKERNELAPI
-USHORT
-ExQueryDepthSList(IN PSLIST_HEADER ListHead)
-{
- return (USHORT)(ListHead->Alignment & 0xffff);
-}
-
-
ULONG ProcessCount;
BOOLEAN CcPfEnablePrefetcher;