From 5a86d61b78e822a33a2d437aaa634b64e2d89eb0 Mon Sep 17 00:00:00 2001 From: belliash Date: Sun, 12 Feb 2023 22:46:58 +0100 Subject: [PATCH] Implement routines for performing atomic operations --- sdk/xtdk/rtlfuncs.h | 107 ++++++++++ xtoskrnl/CMakeLists.txt | 1 + xtoskrnl/rtl/atomic.c | 460 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 568 insertions(+) create mode 100644 xtoskrnl/rtl/atomic.c diff --git a/sdk/xtdk/rtlfuncs.h b/sdk/xtdk/rtlfuncs.h index bab140e..455db2c 100644 --- a/sdk/xtdk/rtlfuncs.h +++ b/sdk/xtdk/rtlfuncs.h @@ -14,6 +14,113 @@ #include +XTFASTCALL +CHAR +RtlAtomicCompareExchange8(IN VOLATILE PCHAR Address, + IN CHAR Comperand, + IN CHAR Exchange); + +XTFASTCALL +SHORT +RtlAtomicCompareExchange16(IN VOLATILE PSHORT Address, + IN SHORT Comperand, + IN SHORT Exchange); + +XTFASTCALL +LONG +RtlAtomicCompareExchange32(IN VOLATILE PLONG Address, + IN LONG Comperand, + IN LONG Exchange); + +XTFASTCALL +LONGLONG +RtlAtomicCompareExchange64(IN VOLATILE PLONGLONG Address, + IN LONGLONG Comperand, + IN LONGLONG Exchange); + +XTFASTCALL +PVOID +RtlAtomicCompareExchangePointer(IN VOLATILE PVOID *Address, + IN PVOID Comperand, + IN PVOID Exchange); + +XTFASTCALL +CHAR +RtlAtomicDecrement8(IN VOLATILE PCHAR Address); + +XTFASTCALL +SHORT +RtlAtomicDecrement16(IN VOLATILE PSHORT Address); + +XTFASTCALL +LONG +RtlAtomicDecrement32(IN VOLATILE PLONG Address); + +XTFASTCALL +LONGLONG +RtlAtomicDecrement64(IN VOLATILE PLONGLONG Address); + +XTFASTCALL +CHAR +RtlAtomicExchange8(IN VOLATILE PCHAR Address, + IN CHAR Exchange); + +XTFASTCALL +SHORT +RtlAtomicExchange16(IN VOLATILE PSHORT Address, + IN SHORT Exchange); + +XTFASTCALL +LONG +RtlAtomicExchange32(IN VOLATILE PLONG Address, + IN LONG Exchange); + +XTFASTCALL +LONGLONG +RtlAtomicExchange64(IN VOLATILE PLONGLONG Address, + IN LONGLONG Exchange); + +XTFASTCALL +CHAR +RtlAtomicExchangeAdd8(IN VOLATILE PCHAR Address, + IN CHAR Value); + +XTFASTCALL +SHORT +RtlAtomicExchangeAdd16(IN VOLATILE PSHORT Address, + IN SHORT Value); + +XTFASTCALL +LONG +RtlAtomicExchangeAdd32(IN VOLATILE PLONG Address, + IN LONG Value); + +XTFASTCALL +LONGLONG +RtlAtomicExchangeAdd64(IN VOLATILE PLONGLONG Address, + IN LONGLONG Value); + +XTFASTCALL +PVOID +RtlAtomicExchangePointer(IN VOLATILE PVOID *Address, + IN PVOID Exchange); + +XTFASTCALL +CHAR +RtlAtomicIncrement8(IN VOLATILE PCHAR Address); + +XTFASTCALL +SHORT +RtlAtomicIncrement16(IN VOLATILE PSHORT Address); + +XTFASTCALL +LONG +RtlAtomicIncrement32(IN VOLATILE PLONG Address); + +XTFASTCALL +LONGLONG +RtlAtomicIncrement64(IN VOLATILE PLONGLONG Address); + XTAPI SIZE_T RtlCompareMemory(IN PCVOID LeftBuffer, diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index bc9d777..9711620 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -19,6 +19,7 @@ list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.c ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.c ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.c + ${XTOSKRNL_SOURCE_DIR}/rtl/atomic.c ${XTOSKRNL_SOURCE_DIR}/rtl/byteswap.c ${XTOSKRNL_SOURCE_DIR}/rtl/memory.c ${XTOSKRNL_SOURCE_DIR}/rtl/plist.c diff --git a/xtoskrnl/rtl/atomic.c b/xtoskrnl/rtl/atomic.c new file mode 100644 index 0000000..8a71420 --- /dev/null +++ b/xtoskrnl/rtl/atomic.c @@ -0,0 +1,460 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/rtl/atomic.c + * DESCRIPTION: Atomic operations support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Performs atomically compare exchange operation on the 8-bit value. + * + * @param Address + * Supplies the address of the value to compare and potentially exchange. + * + * @param Comperand + * Supplies the value to compare against. + * + * @param Exchange + * Supplies the value to write if the comparison returns equality. + * + * @return This routine returns the original value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +CHAR +RtlAtomicCompareExchange8(IN VOLATILE PCHAR Address, + IN CHAR Comperand, + IN CHAR Exchange) +{ + return __sync_val_compare_and_swap(Address, Comperand, Exchange); +} + +/** + * Performs atomically compare exchange operation on the 16-bit value. + * + * @param Address + * Supplies the address of the value to compare and potentially exchange. + * + * @param Comperand + * Supplies the value to compare against. + * + * @param Exchange + * Supplies the value to write if the comparison returns equality. + * + * @return This routine returns the original value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +SHORT +RtlAtomicCompareExchange16(IN VOLATILE PSHORT Address, + IN SHORT Comperand, + IN SHORT Exchange) +{ + return __sync_val_compare_and_swap(Address, Comperand, Exchange); +} + +/** + * Performs atomically compare exchange operation on the 32-bit value. + * + * @param Address + * Supplies the address of the value to compare and potentially exchange. + * + * @param Comperand + * Supplies the value to compare against. + * + * @param Exchange + * Supplies the value to write if the comparison returns equality. + * + * @return This routine returns the original value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +LONG +RtlAtomicCompareExchange32(IN VOLATILE PLONG Address, + IN LONG Comperand, + IN LONG Exchange) +{ + return __sync_val_compare_and_swap(Address, Comperand, Exchange); +} + +/** + * Performs atomically compare exchange operation on the 64-bit value. + * + * @param Address + * Supplies the address of the value to compare and potentially exchange. + * + * @param Comperand + * Supplies the value to compare against. + * + * @param Exchange + * Supplies the value to write if the comparison returns equality. + * + * @return This routine returns the original value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +LONGLONG +RtlAtomicCompareExchange64(IN VOLATILE PLONGLONG Address, + IN LONGLONG Comperand, + IN LONGLONG Exchange) +{ + return __sync_val_compare_and_swap(Address, Comperand, Exchange); +} + +/** + * Performs atomically compare exchange operation. + * + * @param Address + * Supplies the address of the value to compare and potentially exchange. + * + * @param Comperand + * Supplies a pointer to the value to compare against. + * + * @param Exchange + * Supplies a pointer to the value to write if the comparison returns equality. + * + * @return This routine returns the original value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +PVOID +RtlAtomicCompareExchangePointer(IN VOLATILE PVOID *Address, + IN PVOID Comperand, + IN PVOID Exchange) +{ + return (PVOID)__sync_val_compare_and_swap(Address, Comperand, Exchange); +} + +/** + * Performs atomically decrement of the 8-bit value. + * + * @param Address + * Supplies the address of the value to decrement. + * + * @return This routine returns the decremented value. + * + * @since XT 1.0 + */ +XTFASTCALL +CHAR +RtlAtomicDecrement8(IN VOLATILE PCHAR Address) +{ + return __sync_sub_and_fetch(Address, 1); +} + +/** + * Performs atomically decrement of the 16-bit value. + * + * @param Address + * Supplies the address of the value to decrement. + * + * @return This routine returns the decremented value. + * + * @since XT 1.0 + */ +XTFASTCALL +SHORT +RtlAtomicDecrement16(IN VOLATILE PSHORT Address) +{ + return __sync_sub_and_fetch(Address, 1); +} + +/** + * Performs atomically decrement of the 32-bit value. + * + * @param Address + * Supplies the address of the value to decrement. + * + * @return This routine returns the decremented value. + * + * @since XT 1.0 + */ +XTFASTCALL +LONG +RtlAtomicDecrement32(IN VOLATILE PLONG Address) +{ + return __sync_sub_and_fetch(Address, 1); +} + +/** + * Performs atomically decrement of the 64-bit value. + * + * @param Address + * Supplies the address of the value to decrement. + * + * @return This routine returns the decremented value. + * + * @since XT 1.0 + */ +XTFASTCALL +LONGLONG +RtlAtomicDecrement64(IN VOLATILE PLONGLONG Address) +{ + return __sync_sub_and_fetch(Address, 1); +} + +/** + * Performs atomically operation on the 8-bit value. + * + * @param Address + * Supplies the address of the value to exchange with. + * + * @param Exchange + * Supplies the value to write to the address. + * + * @return This routine returns the original value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +CHAR +RtlAtomicExchange8(IN VOLATILE PCHAR Address, + IN CHAR Exchange) +{ + return __sync_lock_test_and_set(Address, Exchange); +} + +/** + * Performs atomically operation on the 16-bit value. + * + * @param Address + * Supplies the address of the value to exchange with. + * + * @param Exchange + * Supplies the value to write to the address. + * + * @return This routine returns the original value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +SHORT +RtlAtomicExchange16(IN VOLATILE PSHORT Address, + IN SHORT Exchange) +{ + return __sync_lock_test_and_set(Address, Exchange); +} + +/** + * Performs atomically operation on the 32-bit value. + * + * @param Address + * Supplies the address of the value to exchange with. + * + * @param Exchange + * Supplies the value to write to the address. + * + * @return This routine returns the original value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +LONG +RtlAtomicExchange32(IN VOLATILE PLONG Address, + IN LONG Exchange) +{ + return __sync_lock_test_and_set(Address, Exchange); +} + +/** + * Performs atomically operation on the 64-bit value. + * + * @param Address + * Supplies the address of the value to exchange with. + * + * @param Exchange + * Supplies the value to write to the address. + * + * @return This routine returns the original value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +LONGLONG +RtlAtomicExchange64(IN VOLATILE PLONGLONG Address, + IN LONGLONG Exchange) +{ + return __sync_lock_test_and_set(Address, Exchange); +} + +/** + * Performs atomically addition of the 8-bit value. + * + * @param Address + * Supplies the address of the original value. + * + * @param Value + * Supplies a value, to be add to variable found at specified address. + * + * @return Returns the initial value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +CHAR +RtlAtomicExchangeAdd8(IN VOLATILE PCHAR Address, + IN CHAR Value) +{ + return __sync_fetch_and_add(Address, Value); +} + +/** + * Performs atomically addition of the 16-bit value. + * + * @param Address + * Supplies the address of the original value. + * + * @param Value + * Supplies a value, to be add to variable found at specified address. + * + * @return Returns the initial value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +SHORT +RtlAtomicExchangeAdd16(IN VOLATILE PSHORT Address, + IN SHORT Value) +{ + return __sync_fetch_and_add(Address, Value); +} + +/** + * Performs atomically addition of the 32-bit value. + * + * @param Address + * Supplies the address of the original value. + * + * @param Value + * Supplies a value, to be add to variable found at specified address. + * + * @return Returns the initial value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +LONG +RtlAtomicExchangeAdd32(IN VOLATILE PLONG Address, + IN LONG Value) +{ + return __sync_fetch_and_add(Address, Value); +} + +/** + * Performs atomically addition of the 64-bit value. + * + * @param Address + * Supplies the address of the original value. + * + * @param Value + * Supplies a value, to be add to variable found at specified address. + * + * @return Returns the initial value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +LONGLONG +RtlAtomicExchangeAdd64(IN VOLATILE PLONGLONG Address, + IN LONGLONG Value) +{ + return __sync_fetch_and_add(Address, Value); +} + +/** + * Performs atomically exchange operation. + * + * @param Address + * Supplies the address of the value to exchange with. + * + * @param Exchange + * Supplies a pointer to the value to write to the address. + * + * @return This routine returns the original value at the given address. + * + * @since XT 1.0 + */ +XTFASTCALL +PVOID +RtlAtomicExchangePointer(IN VOLATILE PVOID *Address, + IN PVOID Exchange) +{ + return (PVOID)__sync_lock_test_and_set(Address, Exchange); +} + +/** + * Performs atomically increment of the 8-bit value. + * + * @param Address + * Supplies the address of the value to increment. + * + * @return This routine returns the incremented value. + * + * @since XT 1.0 + */ +XTFASTCALL +CHAR +RtlAtomicIncrement8(IN VOLATILE PCHAR Address) +{ + return __sync_add_and_fetch(Address, 1); +} + +/** + * Performs atomically increment of the 16-bit value. + * + * @param Address + * Supplies the address of the value to increment. + * + * @return This routine returns the incremented value. + * + * @since XT 1.0 + */ +XTFASTCALL +SHORT +RtlAtomicIncrement16(IN VOLATILE PSHORT Address) +{ + return __sync_add_and_fetch(Address, 1); +} + +/** + * Performs atomically increment of the 32-bit value. + * + * @param Address + * Supplies the address of the value to increment. + * + * @return This routine returns the incremented value. + * + * @since XT 1.0 + */ +XTFASTCALL +LONG +RtlAtomicIncrement32(IN VOLATILE PLONG Address) +{ + return __sync_add_and_fetch(Address, 1); +} + +/** + * Performs atomically increment of the 64-bit value. + * + * @param Address + * Supplies the address of the value to increment. + * + * @return This routine returns the incremented value. + * + * @since XT 1.0 + */ +XTFASTCALL +LONGLONG +RtlAtomicIncrement64(IN VOLATILE PLONGLONG Address) +{ + return __sync_add_and_fetch(Address, 1); +}