diff --git a/NTOSKRNL/KE/mutex.cpp b/NTOSKRNL/KE/mutex.cpp new file mode 100644 index 0000000..713ee57 --- /dev/null +++ b/NTOSKRNL/KE/mutex.cpp @@ -0,0 +1,133 @@ +/* + * PROJECT: Alcyone System Kernel + * LICENSE: BSD Clause 3 + * PURPOSE: Mutexes + * NT KERNEL: 5.11.9360 + * COPYRIGHT: 2023-2029 Dibymartanda Samanta <> + */ + + +#include +#define NTDEBUG + +extern "C" +/*Mutex Count : +0 => Can Be aquired, +1 => Is Aquired by a Thread +In Negative Indigates, Number of Threads waiting*/ + +constexpr ULONG MUTEX_READY_TO_BE_AQUIRED = 0; + +/*Internal Function*/ + +typedef struct _FAST_MUTEX +{ + LONG Count; //0x0 + VOID* Owner; //0x4 + ULONG Contention; //0x8 + struct _KEVENT Event; //0xc + ULONG OldIrql; //0x1c +} FAST_MUTEX, *PFAST_MUTEX; //0x20 bytes (sizeof) + +/*Internal Functio*/ +VOID +FASTCALL +KiAcquireFastMutex( + _Inout_ PFAST_MUTEX Mutex + ) +{ + LONG AcquireMarker; + LONG AcquireBit; + LONG OldCount; + + PAGED_CODE(); + + /* Increment contention count */ + InterlockedIncrement(&Mutex->Contention); + + /* Initialize loop variables */ + AcquireMarker = 4; + AcquireBit = 1; + +AcquireLoop: + while(true) + { + /* Read current count */ + OldCount = ReadForWriteAccess(&Mutex->Count); + + /* Check if mutex is free */ + if ((OldCount & 1) == 0) + { + /* Attempt to acquire by incrementing count */ + if (InterlockedCompareExchange(&Mutex->Count, OldCount + AcquireMarker,OldCount) == OldCount) + { + /* Wait for the mutex event */ + KeWaitForSingleObject(&Mutex->Event,WrFastMutex,KernelMode,false,0); + + AcquireMarker = 2; + AcquireBit = 3; + goto AcquireLoop; + } + } + else + { + /* Attempt to mark mutex as owned */ + if (InterlockedCompareExchange(&Mutex->Count, AcquireBit ^ OldCount,OldCount) == OldCount) + { + /* Mutex acquired successfully */ + break; + } + } + } +} + +/* Exported Function */ + +VOID +NTAPI +KeInitializeFastMutex( + _Out_ PFAST_MUTEX Mutex + ) +{ + PAGED_CODE(); + + /* Initialize the mutex structure */ + RtlZeroMemory(Mutex, sizeof(FAST_MUTEX)); + + /* Set initial values */ + Mutex->Owner = nullptr; + Mutex->Contention = 0; + Mutex->Count = 1; + + /* Initialize the Mutex Gate */ + KeInitializeEvent(&Mutex->Event, SynchronizationEvent, FALSE); +} + +BOOLEAN +VECTORCALL +KeTryToAcquireFastMutex( + _Inout_ PFAST_MUTEX Mutex) +{ + KIRQL CurrentIrql = KeGetCurrentIrql(); + BOOLEAN Result = false; + if(_InterlockedBitTestAndReset(&FastMutex->Count, MUTEX_READY_TO_BE_AQUIRED)) + { + FastMutex->Owner = (PVOID)KeGetCurrentThread(); + Mutex->OldIrql = KeRaiseIrql(APC_LEVEL); + Result = TRUE; + } + else + { + /* Failed to acquire the mutex */ + KeLowerIrql(CurrentIrql); + KeYieldProcessor(); + Result = FALSE; + } + +return Result; +} + + + + +