From 52f5bb6bd24b9ee08aa4f707faf84f34f735f2de Mon Sep 17 00:00:00 2001 From: Dibyamartanda Samanta Date: Mon, 15 Jul 2024 10:32:15 +0200 Subject: [PATCH] [NTOSKRNL:KE] Implemented Slim Futex Implemented Exceptionally Fast, yet simple Mutex ,exclusive to Alcyone called Slim Futex. Functions implemented *KeInitializeSlimFutex *KeAcquireSlimFutex *KeReleaseSlimFutex *KeIsSlimFutexHeld *KeIsSlimFutexLocked --- NTOSKRNL/KE/slimfutex.cpp | 145 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 NTOSKRNL/KE/slimfutex.cpp diff --git a/NTOSKRNL/KE/slimfutex.cpp b/NTOSKRNL/KE/slimfutex.cpp new file mode 100644 index 0000000..60cc3f4 --- /dev/null +++ b/NTOSKRNL/KE/slimfutex.cpp @@ -0,0 +1,145 @@ +/* + * PROJECT: Alcyone System Kernel + * LICENSE: BSD Clause 3 + * PURPOSE: Slim Futex + * NT KERNEL: 5.11.9360 + * COPYRIGHT: 2023-2029 Dibymartanda Samanta <> + */ + +#include +#define NTDEBUG + +extern "C" + +typedef struct _KE_SLIM_FUTEX { + volatile LONG Value; +} KE_SLIM_FUTEX, *PKE_SLIM_FUTEX; + +/* IS_HELD_BIT: Indicates if the futex is currently held. + HAS_PARKED_BIT : Indicates if there are any parked (waiting) threads. */ +constexpr ULONG IS_HELD_BIT = 1; +constexpr ULONG HAS_PARKED_BIT = 2; + +NTSTATUS +KeAcquireSlimFutexSlow( + _Inout_ PKE_SLIM_FUTEX Futex +) +{ + NTSTATUS Status; + LARGE_INTEGER Timeout; + Timeout.QuadPart = -50000; // 5ms + + for (;;) { + LONG CurrentValue = Futex->Value; + if (!(CurrentValue & IS_HELD_BIT)) { + if (InterlockedCompareExchange(&Futex->Value, CurrentValue | IS_HELD_BIT, CurrentValue) == CurrentValue) { + return STATUS_SUCCESS; + } + continue; + } + + if (!(CurrentValue & HAS_PARKED_BIT)) { + if (InterlockedCompareExchange(&Futex->Value, CurrentValue | HAS_PARKED_BIT, CurrentValue) != CurrentValue) { + continue; + } + } + + Status = KeWaitForSingleObject(Futex, Executive, KernelMode, FALSE, &Timeout); + if (!NT_SUCCESS(Status) && Status != STATUS_TIMEOUT) { + return Status; + } + } +} + +NTSTATUS +KeReleaseSlimFutexSlow( + _Inout_ PKE_SLIM_FUTEX Futex +) +{ + LONG OldValue; + do { + OldValue = Futex->Value; + LONG NewValue = OldValue & ~IS_HELD_BIT; + if (OldValue & HAS_PARKED_BIT) + NewValue &= ~HAS_PARKED_BIT; + if (InterlockedCompareExchange(&Futex->Value, NewValue, OldValue) == OldValue) { + if (OldValue & HAS_PARKED_BIT) { + KeSetEvent((PRKEVENT)Futex, IO_NO_INCREMENT, FALSE); + } + return STATUS_SUCCESS; + } + } while (TRUE); +} + +/*Exported Function*/ + +/* Initializes PKE_SLIM_FUTEX Pointer*/ +NTSTATUS +KeInitializeSlimFutex( + _Out_ PKE_SLIM_FUTEX Futex +) +{ + Futex->Value = 0; + return STATUS_SUCCESS; +} + +/* Attempts to acquire the slim futex, return STATUS_SUCCESS if succeeds */ +NTSTATUS +KeAcquireSlimFutex( + _Inout_ PKE_SLIM_FUTEX Futex +) +{ + if (InterlockedCompareExchange(&Futex->Value, IS_HELD_BIT, 0) == 0) { + // Futex acquired! + return STATUS_SUCCESS; + } + + return KeAcquireSlimFutexSlow(Futex); +} + +/*TRUE if the futex is successfully acquired, FALSE otherwise*/ + +BOOLEAN +KeTryAcquireSlimFutex( + _Inout_ PKE_SLIM_FUTEX Futex +) +{ + for (;;) { + LONG CurrentValue = Futex->Value; + if (CurrentValue & IS_HELD_BIT) + return FALSE; + if (InterlockedCompareExchange(&Futex->Value, CurrentValue | IS_HELD_BIT, CurrentValue) == CurrentValue) + return TRUE; + } +} + +/* Releases the slim futex*/ +NTSTATUS +KeReleaseSlimFutex( + _Inout_ PKE_SLIM_FUTEX Futex +) +{ + if (InterlockedCompareExchange(&Futex->Value, 0, IS_HELD_BIT) == IS_HELD_BIT) { + // Futex released and nobody was waiting! + return STATUS_SUCCESS; + } + + return KeReleaseSlimFutexSlow(Futex); +} + +/* Return TRUE if provided Slim Futex is held , else false */ +BOOLEAN +KeIsSlimFutexHeld( + _In_ PKE_SLIM_FUTEX Futex +) +{ + return (Futex->Value & IS_HELD_BIT) != 0; +} +/* Return true if Futex Locked, else return False */ +BOOLEAN +KeIsSlimFutexLocked( + _In_ PKE_SLIM_FUTEX Futex +) +{ + return KeIsSlimFutexHeld(Futex); +}