mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 06:55:55 +00:00
[RTL] Implement x64 version of RtlInterlockedPushListSList
This commit is contained in:
parent
20a6cff4dd
commit
f4d4b31c61
1 changed files with 72 additions and 3 deletions
|
@ -104,9 +104,78 @@ RtlInterlockedPushListSList(
|
||||||
_In_ ULONG Count)
|
_In_ ULONG Count)
|
||||||
{
|
{
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
UNIMPLEMENTED;
|
SLIST_HEADER OldSListHead, NewSListHead;
|
||||||
DbgBreakPoint();
|
PSLIST_ENTRY FirstEntry;
|
||||||
return NULL;
|
|
||||||
|
ASSERT(((ULONG_PTR)SListHead & 0xF) == 0);
|
||||||
|
ASSERT(((ULONG_PTR)List & 0xF) == 0);
|
||||||
|
|
||||||
|
if (RtlpUse16ByteSLists)
|
||||||
|
{
|
||||||
|
BOOLEAN exchanged;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Capture the current SListHead */
|
||||||
|
OldSListHead = *SListHead;
|
||||||
|
|
||||||
|
/* Link the last list entry */
|
||||||
|
FirstEntry = (PSLIST_ENTRY)(SListHead->Region & ~0xFLL);
|
||||||
|
ListEnd->Next = FirstEntry;
|
||||||
|
|
||||||
|
/* Set up new SListHead */
|
||||||
|
NewSListHead = OldSListHead;
|
||||||
|
NewSListHead.Header16.Depth += Count;
|
||||||
|
NewSListHead.Header16.Sequence++;
|
||||||
|
NewSListHead.Region = (ULONG64)List;
|
||||||
|
NewSListHead.Header16.HeaderType = 1;
|
||||||
|
NewSListHead.Header16.Init = 1;
|
||||||
|
|
||||||
|
/* Atomically exchange the SlistHead with the new one */
|
||||||
|
exchanged = _InterlockedCompareExchange128((PULONG64)SListHead,
|
||||||
|
NewSListHead.Region,
|
||||||
|
NewSListHead.Alignment,
|
||||||
|
(PULONG64)&OldSListHead);
|
||||||
|
} while (!exchanged);
|
||||||
|
|
||||||
|
return FirstEntry;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ULONG64 Compare;
|
||||||
|
|
||||||
|
/* ListHead and List must be in the same region */
|
||||||
|
ASSERT(((ULONG64)SListHead & 0xFFFFF80000000000ull) ==
|
||||||
|
((ULONG64)List & 0xFFFFF80000000000ull));
|
||||||
|
|
||||||
|
/* Read the header */
|
||||||
|
OldSListHead = *SListHead;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Construct the address from the header bits and the list head pointer */
|
||||||
|
FirstEntry = (PSLIST_ENTRY)((OldSListHead.Header8.NextEntry << 4) |
|
||||||
|
((ULONG64)SListHead & 0xFFFFF80000000000ull));
|
||||||
|
|
||||||
|
/* Link the last list entry */
|
||||||
|
ListEnd->Next = FirstEntry;
|
||||||
|
|
||||||
|
/* Create a new header */
|
||||||
|
NewSListHead = OldSListHead;
|
||||||
|
NewSListHead.Header8.NextEntry = (ULONG64)List >> 4;
|
||||||
|
NewSListHead.Header8.Depth += Count;
|
||||||
|
NewSListHead.Header8.Sequence++;
|
||||||
|
|
||||||
|
/* Try to exchange atomically */
|
||||||
|
Compare = OldSListHead.Alignment;
|
||||||
|
OldSListHead.Alignment = InterlockedCompareExchange64((PLONG64)&SListHead->Alignment,
|
||||||
|
NewSListHead.Alignment,
|
||||||
|
Compare);
|
||||||
|
} while (OldSListHead.Alignment != Compare);
|
||||||
|
|
||||||
|
/* Return the old first entry */
|
||||||
|
return FirstEntry;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
SLIST_HEADER OldHeader, NewHeader;
|
SLIST_HEADER OldHeader, NewHeader;
|
||||||
ULONGLONG Compare;
|
ULONGLONG Compare;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue