From 050f24f8779ed38146ae6a76762bbc88e594d484 Mon Sep 17 00:00:00 2001 From: belliash Date: Mon, 13 Feb 2023 22:36:03 +0100 Subject: [PATCH] Implement routines for atomically work with linked lists --- sdk/xtdk/rtlfuncs.h | 13 ++++++ sdk/xtdk/xtbase.h | 12 +++-- sdk/xtdk/xtstruct.h | 2 +- xtoskrnl/rtl/atomic.c | 100 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 5 deletions(-) diff --git a/sdk/xtdk/rtlfuncs.h b/sdk/xtdk/rtlfuncs.h index 0e61e2c..cc476ac 100644 --- a/sdk/xtdk/rtlfuncs.h +++ b/sdk/xtdk/rtlfuncs.h @@ -125,6 +125,10 @@ PVOID RtlAtomicExchangePointer(IN VOLATILE PVOID *Address, IN PVOID Exchange); +XTFASTCALL +PSINGLE_LIST_ENTRY +RtlAtomicFlushSingleList(IN PSINGLE_LIST_HEADER Header); + XTFASTCALL CHAR RtlAtomicIncrement8(IN VOLATILE PCHAR Address); @@ -161,6 +165,15 @@ LONGLONG RtlAtomicOr64(IN VOLATILE PLONGLONG Address, IN LONGLONG Mask); +XTFASTCALL +PSINGLE_LIST_ENTRY +RtlAtomicPopEntrySingleList(IN PSINGLE_LIST_HEADER Header); + +XTFASTCALL +PSINGLE_LIST_ENTRY +RtlAtomicPushEntrySingleList(IN PSINGLE_LIST_HEADER Header, + IN PSINGLE_LIST_ENTRY Entry); + XTFASTCALL CHAR RtlAtomicXor8(IN VOLATILE PCHAR Address, diff --git a/sdk/xtdk/xtbase.h b/sdk/xtdk/xtbase.h index e959861..70bcf48 100644 --- a/sdk/xtdk/xtbase.h +++ b/sdk/xtdk/xtbase.h @@ -57,11 +57,15 @@ typedef struct _SINGLE_LIST_ENTRY } SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; /* Header for a sequenced single linked list union definition */ -typedef struct _SINGLE_LIST_HEADER +typedef union _SINGLE_LIST_HEADER { - SINGLE_LIST_ENTRY Next; - USHORT Depth; - USHORT Sequence; + ULONGLONG Alignment; + struct + { + SINGLE_LIST_ENTRY Next; + USHORT Depth; + USHORT Sequence; + }; } SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER; /* 128-bit 16-byte aligned XMM register */ diff --git a/sdk/xtdk/xtstruct.h b/sdk/xtdk/xtstruct.h index c4b813b..155bfc9 100644 --- a/sdk/xtdk/xtstruct.h +++ b/sdk/xtdk/xtstruct.h @@ -226,7 +226,6 @@ typedef struct _PECOFF_IMAGE_ROM_OPTIONAL_HEADER PECOFF_IMAGE_ROM_OPTIONAL_HEADE typedef struct _PECOFF_IMAGE_SECTION_HEADER PECOFF_IMAGE_SECTION_HEADER, *PPECOFF_IMAGE_SECTION_HEADER; typedef struct _PECOFF_IMAGE_VXD_HEADER PECOFF_IMAGE_VXD_HEADER, *PPECOFF_IMAGE_VXD_HEADER; typedef struct _SINGLE_LIST_ENTRY SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; -typedef struct _SINGLE_LIST_HEADER SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER; typedef struct _STRING STRING, *PSTRING; typedef struct _STRING32 STRING32, *PSTRING32; typedef struct _STRING64 STRING64, *PSTRING64; @@ -243,6 +242,7 @@ typedef union _EFI_HASH_OUTPUT EFI_HASH_OUTPUT, *PEFI_HASH_OUTPUT; typedef union _EFI_IP_ADDRESS EFI_IP_ADDRESS, *PEFI_IP_ADDRESS; typedef union _EFI_PXE_BASE_CODE_PACKET EFI_PXE_BASE_CODE_PACKET, *PEFI_PXE_BASE_CODE_PACKET; typedef union _LARGE_INTEGER LARGE_INTEGER, *PLARGE_INTEGER; +typedef union _SINGLE_LIST_HEADER SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER; typedef union _ULARGE_INTEGER ULARGE_INTEGER, *PULARGE_INTEGER; #endif /* __XTDK_XTSTRUCT_H */ diff --git a/xtoskrnl/rtl/atomic.c b/xtoskrnl/rtl/atomic.c index 9558ba8..9881623 100644 --- a/xtoskrnl/rtl/atomic.c +++ b/xtoskrnl/rtl/atomic.c @@ -475,6 +475,23 @@ RtlAtomicExchangePointer(IN VOLATILE PVOID *Address, return (PVOID)__sync_lock_test_and_set(Address, Exchange); } +/** + * Removes all entries from single linked list. + * + * @param Header + * Supplies a pointer to the header of linked list. + * + * @return This routine returns a pointer to the original list, or NULL if the list was already empty. + * + * @since XT 1.0 + */ +XTFASTCALL +PSINGLE_LIST_ENTRY +RtlAtomicFlushSingleList(IN PSINGLE_LIST_HEADER Header) +{ + return (PSINGLE_LIST_ENTRY)RtlAtomicExchange64((PLONGLONG)&Header->Alignment, (LONGLONG)NULL); +} + /** * Performs atomically increment of the 8-bit value. * @@ -627,6 +644,89 @@ RtlAtomicOr64(IN VOLATILE PLONGLONG Address, return __sync_fetch_and_or(Address, Mask); } +/** + * Removes and returns the first entry from single linked list. + * + * @param Header + * Supplies a pointer to the header of a single linked list. + * + * @return This routine returns a pointer to the removed element, or NULL if the list was empty. + * + * @since XT 1.0 + */ +XTFASTCALL +PSINGLE_LIST_ENTRY +RtlAtomicPopEntrySingleList(IN PSINGLE_LIST_HEADER Header) +{ + PSINGLE_LIST_ENTRY ListHead, FirstEntry, NextEntry; + + /* Save header and first entry */ + ListHead = (PVOID)Header; + FirstEntry = ListHead->Next; + do + { + /* Check if list is not empty */ + if(!FirstEntry) + { + /* Empty list */ + return NULL; + } + + /* Update link */ + NextEntry = FirstEntry; + + /* Compare and exchange */ + FirstEntry = (PVOID)RtlAtomicCompareExchange64((PLONGLONG)ListHead, + (LONGLONG)FirstEntry->Next, + (LONGLONG)FirstEntry); + } while(FirstEntry != NextEntry); + + /* Return removed element */ + return FirstEntry; +} + +/** + * Inserts new entry at the beginning of single linked list. + * + * @param Header + * Supplies a pointer to the header of linked list. + * + * @param Entry + * Supplies a pointer to entry, that will be inserted into linked list. + * + * @return This routine returns a pointer to original heading, or NULL if the list was originally empty. + * + * @since XT 1.0 + */ +XTFASTCALL +PSINGLE_LIST_ENTRY +RtlAtomicPushEntrySingleList(IN PSINGLE_LIST_HEADER Header, + IN PSINGLE_LIST_ENTRY Entry) +{ + PSINGLE_LIST_ENTRY ListHead, ListEntry, FirstEntry, NextEntry; + + /* Save header and new entry */ + ListHead = (PVOID)Header; + ListEntry = (PVOID)Entry; + + /* Save next link in new first element */ + FirstEntry = ListHead->Next; + do + { + /* Update links */ + ListEntry->Next = FirstEntry; + NextEntry = FirstEntry; + + /* Compare and exchange */ + FirstEntry = (PVOID)RtlAtomicCompareExchange64((PLONGLONG)ListHead, + (LONGLONG)ListEntry, + (LONGLONG)FirstEntry); + } while(FirstEntry != NextEntry); + + /* Return original first element */ + return FirstEntry; +} + /** * Performs an atomic bitwise XOR operation on the 8-bit value. *