#pragma once // ke_spinlock.h - spinlock for short, non-sleeping critical sections // Uses MSVC interlocked intrinsics. Never hold across a scheduling boundary. #include #include typedef struct SPINLOCK { volatile long Locked; } SPINLOCK; #define SPINLOCK_INIT { 0 } // Issue 1 Fix: Save EFLAGS, disable interrupts, and return old flags. static __forceinline uintptr_t KeAcquireSpinlock(SPINLOCK* sl) { uintptr_t flags = __readeflags(); _disable(); while (_InterlockedCompareExchange(&sl->Locked, 1, 0) != 0) _mm_pause(); return flags; } // Issue 1 Fix: Restore EFLAGS upon release. static __forceinline void KeReleaseSpinlock(SPINLOCK* sl, uintptr_t flags) { _InterlockedExchange(&sl->Locked, 0); __writeeflags(flags); } static __forceinline int KeTryAcquireSpinlock(SPINLOCK* sl, uintptr_t* outFlags) { uintptr_t flags = __readeflags(); _disable(); if (_InterlockedCompareExchange(&sl->Locked, 1, 0) == 0) { *outFlags = flags; return 1; } __writeeflags(flags); return 0; }