From 956f376f4fd2cee1d5faecb5a2f246724132a5b0 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Fri, 15 Apr 2005 06:24:35 +0000 Subject: [PATCH] Implemented Guarded Mutex, a drop-in replacement for Fast Mutex (the correct one, not the one ROS incorrectly implements) on NT 5.2. Not fully tested yet, so nothing switched to it and probably not usable. Also made KeGetCurrentThread/Irql become inlined, since this should create quite a speed boost. Made KeLeaveCriticalRegion deliver APCs if possible, and made Crit regions macros usable from outside ntoskrnl thanks to a new NT 5.2 API (KiCheckForKernelApcDelivery). Guarded Mutex code based on Filip Navara. svn path=/trunk/; revision=14625 --- reactos/drivers/storage/diskdump/diskdump.c | 1 + reactos/hal/hal/hal.c | 2 +- reactos/hal/halx86/generic/fmutex.c | 2 + reactos/hal/halx86/generic/irql.c | 1 + reactos/include/ddk/kedef.h | 2 +- reactos/include/ddk/kefuncs.h | 44 ++++ reactos/include/ddk/ketypes.h | 15 ++ reactos/ntoskrnl/Makefile | 2 + reactos/ntoskrnl/ex/i386/interlck.c | 38 ++++ reactos/ntoskrnl/include/internal/i386/ke.h | 1 + reactos/ntoskrnl/include/internal/i386/ps.h | 1 + reactos/ntoskrnl/include/internal/ke.h | 46 +++- reactos/ntoskrnl/include/internal/ps.h | 8 +- reactos/ntoskrnl/ke/apc.c | 124 +++++++---- reactos/ntoskrnl/ke/gmutex.c | 222 ++++++++++++++++++-- reactos/ntoskrnl/ntoskrnl.def | 1 + reactos/ntoskrnl/ps/thread.c | 7 +- reactos/w32api/include/ddk/winddk.h | 15 ++ 18 files changed, 473 insertions(+), 59 deletions(-) diff --git a/reactos/drivers/storage/diskdump/diskdump.c b/reactos/drivers/storage/diskdump/diskdump.c index 927af75911f..29c578c764d 100644 --- a/reactos/drivers/storage/diskdump/diskdump.c +++ b/reactos/drivers/storage/diskdump/diskdump.c @@ -41,6 +41,7 @@ #undef VERSION #define VERSION "0.0.1" +#undef KeGetCurrentIrql /* PROTOTYPES ***************************************************************/ NTSTATUS STDCALL diff --git a/reactos/hal/hal/hal.c b/reactos/hal/hal/hal.c index 1eae03265f1..a28d5c9e6b0 100644 --- a/reactos/hal/hal/hal.c +++ b/reactos/hal/hal/hal.c @@ -748,7 +748,7 @@ KeFlushWriteBuffer(VOID) UNIMPLEMENTED; } - +#undef KeGetCurrentIrql KIRQL STDCALL KeGetCurrentIrql(VOID) diff --git a/reactos/hal/halx86/generic/fmutex.c b/reactos/hal/halx86/generic/fmutex.c index b31e6b8f200..fc6f61f9eab 100644 --- a/reactos/hal/halx86/generic/fmutex.c +++ b/reactos/hal/halx86/generic/fmutex.c @@ -18,6 +18,8 @@ /* FUNCTIONS *****************************************************************/ +#undef KeEnterCriticalRegion +#undef KeLeaveCriticalRegion VOID FASTCALL ExAcquireFastMutex (PFAST_MUTEX FastMutex) { diff --git a/reactos/hal/halx86/generic/irql.c b/reactos/hal/halx86/generic/irql.c index b9a3ae159ed..bca26a93b1f 100644 --- a/reactos/hal/halx86/generic/irql.c +++ b/reactos/hal/halx86/generic/irql.c @@ -65,6 +65,7 @@ KiInterruptDispatch2 (ULONG Irq, KIRQL old_level); /* FUNCTIONS ****************************************************************/ +#undef KeGetCurrentIrql KIRQL STDCALL KeGetCurrentIrql (VOID) /* * PURPOSE: Returns the current irq level diff --git a/reactos/include/ddk/kedef.h b/reactos/include/ddk/kedef.h index c1212f8a5d0..36be542f3f9 100644 --- a/reactos/include/ddk/kedef.h +++ b/reactos/include/ddk/kedef.h @@ -56,7 +56,7 @@ typedef enum _KWAIT_REASON WrPageOut, WrRendezvous, Spare2, - Spare3, + WrGuardedMutex, Spare4, Spare5, Spare6, diff --git a/reactos/include/ddk/kefuncs.h b/reactos/include/ddk/kefuncs.h index 2559e460276..dfc26595b0e 100644 --- a/reactos/include/ddk/kefuncs.h +++ b/reactos/include/ddk/kefuncs.h @@ -809,4 +809,48 @@ KeRaiseUserException( IN NTSTATUS ExceptionCode ); +VOID +FASTCALL +KeAcquireGuardedMutex( + PKGUARDED_MUTEX GuardedMutex +); + +VOID +FASTCALL +KeAcquireGuardedMutexUnsafe( + PKGUARDED_MUTEX GuardedMutex +); + +VOID +STDCALL +KeEnterGuardedRegion(VOID); + +VOID +STDCALL +KeLeaveGuardedRegion(VOID); + +VOID +FASTCALL +KeInitializeGuardedMutex( + PKGUARDED_MUTEX GuardedMutex +); + +VOID +FASTCALL +KeReleaseGuardedMutexUnsafe( + PKGUARDED_MUTEX GuardedMutex +); + +VOID +FASTCALL +KeReleaseGuardedMutex( + PKGUARDED_MUTEX GuardedMutex +); + +BOOL +FASTCALL +KeTryToAcquireGuardedMutex( + PKGUARDED_MUTEX GuardedMutex +); + #endif /* __INCLUDE_DDK_KEFUNCS_H */ diff --git a/reactos/include/ddk/ketypes.h b/reactos/include/ddk/ketypes.h index 5b7fa5793e6..952932af281 100644 --- a/reactos/include/ddk/ketypes.h +++ b/reactos/include/ddk/ketypes.h @@ -180,6 +180,21 @@ typedef struct _KMUTEX UCHAR ApcDisable; } KMUTEX, *PKMUTEX, KMUTANT, *PKMUTANT; +typedef struct _KGUARDED_MUTEX +{ + LONG Count; + struct _KTHREAD* Owner; + ULONG Contention; + KGATE Gate; + union { + struct { + SHORT KernelApcDisable; + SHORT SpecialApcDisable; + }; + ULONG CombinedApcDisable; + }; +} KGUARDED_MUTEX, *PKGUARDED_MUTEX; + #include typedef struct _KSEMAPHORE diff --git a/reactos/ntoskrnl/Makefile b/reactos/ntoskrnl/Makefile index 59134f10392..89051b3e123 100644 --- a/reactos/ntoskrnl/Makefile +++ b/reactos/ntoskrnl/Makefile @@ -100,6 +100,8 @@ OBJECTS_KE = \ ke/dpc.o \ ke/device.o \ ke/event.o \ + ke/gate.o \ + ke/gmutex.o \ ke/kqueue.o \ ke/kthread.o \ ke/ipi.o \ diff --git a/reactos/ntoskrnl/ex/i386/interlck.c b/reactos/ntoskrnl/ex/i386/interlck.c index 12a3c2d9887..adf4ed90eba 100644 --- a/reactos/ntoskrnl/ex/i386/interlck.c +++ b/reactos/ntoskrnl/ex/i386/interlck.c @@ -396,6 +396,44 @@ InterlockedExchangeAdd(PLONG Addend, #error Unknown compiler for inline assembler #endif +/********************************************************************** + * FASTCALL: @InterlockedClearBit@8 + * STDCALL: _InterlockedClearBit@8 + */ +#if defined(__GNUC__) +/* + * @implemented + */ +UCHAR +FASTCALL +InterlockedClearBit(PLONG Destination, + LONG Bit); + +__asm__("\n\t.global @InterlockedClearBit@8\n\t" + "@InterlockedClearBit@8:\n\t" + LOCK + "btr %edx,(%ecx)\n\t" + "setc %al\n\t" + "ret $8\n\t"); + +#elif defined(_MSC_VER) +/* + * @implemented + */ +__declspec(naked) +UCHAR +FASTCALL +InterlockedClearBit(PUCHAR Destination, + UCHAR Bit) +{ + __asm LOCK btr [ecx], edx + __asm setc al + __asm ret +} + +#else +#error Unknown compiler for inline assembler +#endif /********************************************************************** * FASTCALL: @InterlockedCompareExchange@12 diff --git a/reactos/ntoskrnl/include/internal/i386/ke.h b/reactos/ntoskrnl/include/internal/i386/ke.h index 5efe824339d..e8bc96b26c1 100644 --- a/reactos/ntoskrnl/include/internal/i386/ke.h +++ b/reactos/ntoskrnl/include/internal/i386/ke.h @@ -205,6 +205,7 @@ NtEarlyInitVdm(VOID); #define LOCK "" #endif +#define KeGetCurrentIrql(X) (((PKPCR)KPCR_BASE)->Irql) #if defined(__GNUC__) #define Ke386DisableInterrupts() __asm__("cli\n\t"); diff --git a/reactos/ntoskrnl/include/internal/i386/ps.h b/reactos/ntoskrnl/include/internal/i386/ps.h index 6eb1c4125fb..6d86116be29 100644 --- a/reactos/ntoskrnl/include/internal/i386/ps.h +++ b/reactos/ntoskrnl/include/internal/i386/ps.h @@ -292,6 +292,7 @@ static inline PKPRCB KeGetCurrentPrcb(VOID) #define KeGetCurrentKPCR(X) ((PKPCR)KPCR_BASE) #define KeGetCurrentPrcb() (((PKPCR)KPCR_BASE)->Prcb) +#define KeGetCurrentThread(X) (((PKPCR)KPCR_BASE)->PrcbData.CurrentThread) #endif diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 305d46f4490..043d3f8cf21 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -49,6 +49,26 @@ struct _KEXCEPTION_FRAME; #define IPI_REQUEST_DPC 2 #define IPI_REQUEST_FREEZE 3 +/* MACROS *************************************************************************/ + +#define KeEnterCriticalRegion(X) \ +{ \ + PKTHREAD _Thread = KeGetCurrentThread(); \ + if (_Thread) _Thread->KernelApcDisable--; \ +} + +#define KeLeaveCriticalRegion(X) \ +{ \ + PKTHREAD _Thread = KeGetCurrentThread(); \ + if((_Thread) && (++_Thread->KernelApcDisable == 0)) \ + { \ + if (!IsListEmpty(&_Thread->ApcState.ApcListHead[KernelMode])) \ + { \ + KiKernelApcDeliveryCheck(); \ + } \ + } \ +} + /* threadsch.c ********************************************************************/ /* Thread Scheduler Functions */ @@ -77,6 +97,28 @@ STDCALL KiUnblockThread(PKTHREAD Thread, PNTSTATUS WaitStatus, KPRIORITY Increment); + +/* gmutex.c ********************************************************************/ + +VOID +FASTCALL +KiAcquireGuardedMutexContented(PKGUARDED_MUTEX GuardedMutex); + +/* gate.c **********************************************************************/ + +VOID +FASTCALL +KeInitializeGate(PKGATE Gate); + +VOID +FASTCALL +KeSignalGateBoostPriority(PKGATE Gate); + +VOID +FASTCALL +KeWaitForGate(PKGATE Gate, + KWAIT_REASON WaitReason, + KPROCESSOR_MODE WaitMode); /* ipi.c ********************************************************************/ @@ -237,7 +279,9 @@ VOID KeContextToTrapFrame(PCONTEXT Context, PKTRAP_FRAME TrapFrame); VOID STDCALL KiDeliverApc(KPROCESSOR_MODE PreviousMode, PVOID Reserved, PKTRAP_FRAME TrapFrame); - +VOID +STDCALL +KiKernelApcDeliveryCheck(VOID); LONG STDCALL KiInsertQueue(IN PKQUEUE Queue, diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index 7cbf16f2260..eee710bd882 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -97,7 +97,13 @@ typedef struct _KTHREAD CHAR Quantum; /* 6B */ KWAIT_BLOCK WaitBlock[4]; /* 6C */ PVOID LegoData; /* CC */ - ULONG KernelApcDisable; /* D0 */ + union { + struct { + USHORT KernelApcDisable; + USHORT SpecialApcDisable; + }; + ULONG CombinedApcDisable; /* D0 */ + }; KAFFINITY UserAffinity; /* D4 */ UCHAR SystemAffinityActive;/* D8 */ UCHAR PowerState; /* D9 */ diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index b2f06266117..f2fa3974989 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -16,6 +16,51 @@ /* FUNCTIONS *****************************************************************/ +/*++ + * KiKernelApcDeliveryCheck + * @implemented NT 5.2 + * + * The KiKernelApcDeliveryCheck routine is called whenever APCs have just + * been re-enabled in Kernel Mode, such as after leaving a Critical or + * Guarded Region. It delivers APCs if the environment is right. + * + * Params: + * None. + * + * Returns: + * None. + * + * Remarks: + * This routine allows KeLeave/EnterCritical/GuardedRegion to be used as a + * macro from inside WIN32K or other Drivers, which will then only have to + * do an Import API call in the case where APCs are enabled again. + * + *--*/ +VOID +STDCALL +KiKernelApcDeliveryCheck(VOID) +{ + /* We should only deliver at passive */ + if (KeGetCurrentIrql() == PASSIVE_LEVEL) + { + /* Raise to APC and Deliver APCs, then lower back to Passive */ + KfRaiseIrql(APC_LEVEL); + KiDeliverApc(KernelMode, 0, 0); + KfLowerIrql(PASSIVE_LEVEL); + } + else + { + /* + * If we're not at passive level it means someone raised IRQL + * to APC level before the a critical or guarded section was entered + * (e.g) by a fast mutex). This implies that the APCs shouldn't + * be delivered now, but after the IRQL is lowered to passive + * level again. + */ + HalRequestSoftwareInterrupt(APC_LEVEL); + } +} + /*++ * KeEnterCriticalRegion * @implemented NT4 @@ -37,6 +82,7 @@ * Callers of KeEnterCriticalRegion must be running at IRQL <= APC_LEVEL. * *--*/ +#undef KeEnterCriticalRegion VOID STDCALL KeEnterCriticalRegion(VOID) @@ -46,6 +92,45 @@ KeEnterCriticalRegion(VOID) if (Thread) Thread->KernelApcDisable--; } +/*++ + * KeLeaveCriticalRegion + * @implemented NT4 + * + * The KeLeaveCriticalRegion routine reenables the delivery of normal + * kernel-mode APCs that were disabled by a call to KeEnterCriticalRegion. + * + * Params: + * None. + * + * Returns: + * None. + * + * Remarks: + * Highest-level drivers can call this routine while running in the context + * of the thread that requested the current I/O operation. + * + * Callers of KeLeaveCriticalRegion must be running at IRQL <= DISPATCH_LEVEL. + * + *--*/ +#undef KeLeaveCriticalRegion +VOID +STDCALL +KeLeaveCriticalRegion (VOID) +{ + PKTHREAD Thread = KeGetCurrentThread(); + + /* Check if Kernel APCs are now enabled */ + if((Thread) && (++Thread->KernelApcDisable == 0)) + { + /* Check if we need to request an APC Delivery */ + if (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) + { + /* Check for the right environment */ + KiKernelApcDeliveryCheck(); + } + } +} + /*++ * KeInitializeApc * @implemented NT4 @@ -325,45 +410,6 @@ KeInsertQueueApc(PKAPC Apc, return Inserted; } -/*++ - * KeLeaveCriticalRegion - * @implemented NT4 - * - * The KeLeaveCriticalRegion routine reenables the delivery of normal - * kernel-mode APCs that were disabled by a call to KeEnterCriticalRegion. - * - * Params: - * None. - * - * Returns: - * None. - * - * Remarks: - * Highest-level drivers can call this routine while running in the context - * of the thread that requested the current I/O operation. - * - * Callers of KeLeaveCriticalRegion must be running at IRQL <= DISPATCH_LEVEL. - * - *--*/ -VOID -STDCALL -KeLeaveCriticalRegion (VOID) -{ - PKTHREAD Thread = KeGetCurrentThread(); - - /* Check if Kernel APCs are now enabled */ - if((Thread) && (++Thread->KernelApcDisable == 0)) { - - /* Check if we need to request an APC Delivery */ - if (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) { - - /* Set APC Pending */ - Thread->ApcState.KernelApcPending = TRUE; - HalRequestSoftwareInterrupt(APC_LEVEL); - } - } -} - /*++ * KeRemoveQueueApc * diff --git a/reactos/ntoskrnl/ke/gmutex.c b/reactos/ntoskrnl/ke/gmutex.c index 35d1d436276..62130cee797 100644 --- a/reactos/ntoskrnl/ke/gmutex.c +++ b/reactos/ntoskrnl/ke/gmutex.c @@ -1,11 +1,11 @@ -/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel + * PROJECT: ReactOS Kernel * FILE: ntoskrnl/ke/gmutex.c - * PURPOSE: Implements guarded mutex (w2k3+/64) + * PURPOSE: Implements Guarded Mutex * - * PROGRAMMERS: No programmer listed. + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) and + * Filip Navara (xnavara@volny.cz) */ /* INCLUDES *****************************************************************/ @@ -13,17 +13,209 @@ #include #include +UCHAR +FASTCALL +InterlockedClearBit(PLONG Destination, + LONG Bit); + +typedef enum _KGUARDED_MUTEX_BITS +{ + GM_LOCK_BIT = 1, + GM_LOCK_WAITER_WOKEN = 2, + GM_LOCK_WAITER_INC = 4 +} KGUARDED_MUTEX_BITS; + /* FUNCTIONS *****************************************************************/ -/* -KeAcquireGuardedMutex -KeAcquireGuardedMutexUnsafe -KeEnterGuardedRegion -KeInitializeGuardedMutex -KeReleaseGuardedMutexUnsafe -KeTryToAcquireGuardedMutex -KeReleaseGuardedMutex -KeLeaveGuardedRegion -*/ +/** + * @name KeEnterGuardedRegion + * + * Enters a guarded region. This causes all (incl. special kernel) APCs + * to be disabled. + */ +VOID +STDCALL +KeEnterGuardedRegion(VOID) +{ + /* Disable Special APCs */ + KeGetCurrentThread()->SpecialApcDisable--; +} + +/** + * @name KeLeaveGuardedRegion + * + * Leaves a guarded region and delivers pending APCs if possible. + */ +VOID +STDCALL +KeLeaveGuardedRegion(VOID) +{ + PKTHREAD Thread = KeGetCurrentThread(); + + /* Boost the enable count and check if Special APCs are enabled */ + if (++Thread->SpecialApcDisable == 0) + { + /* Check if there are Kernel APCs on the list */ + if (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) + { + /* Check for APC Delivery */ + KiKernelApcDeliveryCheck(); + } + } +} + +VOID +FASTCALL +KeInitializeGuardedMutex(PKGUARDED_MUTEX GuardedMutex) +{ + /* Setup the Initial Data */ + GuardedMutex->Count = GM_LOCK_BIT; + GuardedMutex->Owner = NULL; + GuardedMutex->Contention = 0; + + /* Initialize the Wait Gate */ + KeInitializeGate(&GuardedMutex->Gate); +} + +VOID +FASTCALL +KiAcquireGuardedMutexContented(PKGUARDED_MUTEX GuardedMutex) +{ + ULONG BitsToRemove; + ULONG BitsToAdd; + LONG OldValue; + + /* Increase the contention count */ + InterlockedIncrement(&GuardedMutex->Contention); + + /* Start by unlocking the Guarded Mutex */ + BitsToRemove = GM_LOCK_BIT; + BitsToAdd = GM_LOCK_WAITER_INC; + + while (1) + { + /* Get the Count Bits */ + OldValue = (volatile LONG)GuardedMutex->Count; + + /* Check if the Guarded Mutex is locked */ + if (OldValue & GM_LOCK_BIT) + { + /* Unlock it by removing the Lock Bit */ + if (InterlockedCompareExchange(&GuardedMutex->Count, + OldValue &~ BitsToRemove, + OldValue) == OldValue) + { + /* The Guarded Mutex is now unlocked */ + break; + } + } + else + { + /* The Guarded Mutex isn't locked, so simply set the bits */ + if (InterlockedCompareExchange(&GuardedMutex->Count, + OldValue | BitsToAdd, + OldValue) != OldValue) + { + /* The Guarded Mutex value changed behind our back, start over */ + continue; + } + + /* Now we have to wait for it */ + KeWaitForGate(&GuardedMutex->Gate, WrGuardedMutex, KernelMode); + + /* Ok, the wait is done, so set the new bits */ + BitsToRemove = GM_LOCK_BIT | GM_LOCK_WAITER_WOKEN; + BitsToAdd = GM_LOCK_WAITER_WOKEN; + } + } +} + +VOID +FASTCALL +KeAcquireGuardedMutex(PKGUARDED_MUTEX GuardedMutex) +{ + /* Disable Special APCs */ + KeEnterGuardedRegion(); + + /* Do the Unsafe Acquire */ + KeAcquireGuardedMutexUnsafe(GuardedMutex); +} + +VOID +FASTCALL +KeAcquireGuardedMutexUnsafe(PKGUARDED_MUTEX GuardedMutex) +{ + /* Remove the lock */ + if (!InterlockedClearBit(&GuardedMutex->Count, 0)) + { + /* The Guarded Mutex was already locked, enter contented case */ + KiAcquireGuardedMutexContented(GuardedMutex); + } + + /* Set the Owner */ + GuardedMutex->Owner = KeGetCurrentThread(); +} + +VOID +FASTCALL +KeReleaseGuardedMutexUnsafe(PKGUARDED_MUTEX GuardedMutex) +{ + LONG OldValue; + + /* Destroy the Owner */ + GuardedMutex->Owner = NULL; + + /* Add the Lock Bit */ + OldValue = InterlockedExchangeAdd(&GuardedMutex->Count, 1); + + /* Check if it was already locked, but not woken */ + if (OldValue && !(OldValue & GM_LOCK_WAITER_WOKEN)) + { + /* Update the Oldvalue to what it should be now */ + OldValue |= GM_LOCK_BIT; + + /* Remove the Woken bit */ + if (InterlockedCompareExchange(&GuardedMutex->Count, + OldValue &~ GM_LOCK_WAITER_WOKEN, + OldValue) == OldValue) + { + /* Signal the Gate */ + KeSignalGateBoostPriority(&GuardedMutex->Gate); + } + } +} + +VOID +FASTCALL +KeReleaseGuardedMutex(PKGUARDED_MUTEX GuardedMutex) +{ + /* Do the actual release */ + KeReleaseGuardedMutexUnsafe(GuardedMutex); + + /* Re-enable APCs */ + KeLeaveGuardedRegion(); +} + +BOOL +FASTCALL +KeTryToAcquireGuardedMutex(PKGUARDED_MUTEX GuardedMutex) +{ + /* Block APCs */ + KeEnterGuardedRegion(); + + /* Remove the lock */ + if (InterlockedClearBit(&GuardedMutex->Count, 0)) + { + /* Re-enable APCs */ + KeLeaveGuardedRegion(); + + /* Return failure */ + return FALSE; + } + + /* Set the Owner */ + GuardedMutex->Owner = KeGetCurrentThread(); + return TRUE; +} /* EOF */ diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index f7159dee818..dc939e42ecf 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -649,6 +649,7 @@ KeWaitForSingleObject@20 ;KiBugCheckData DATA KiCoprocessorError@0 KiDeliverApc@12 +KiKernelApcDeliveryCheck@0 KiDispatchInterrupt@0 KiEnableTimerWatchdog KiInterruptDispatch2@8 diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 952ff730402..b5583c703d2 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -44,10 +44,15 @@ static GENERIC_MAPPING PiThreadMapping = {STANDARD_RIGHTS_READ | THREAD_GET_CONT /* FUNCTIONS ***************************************************************/ +#ifdef KeGetCurrentThread +#undef KeGetCurrentThread +#endif /* * @implemented */ -PKTHREAD STDCALL KeGetCurrentThread(VOID) +PKTHREAD +STDCALL +KeGetCurrentThread(VOID) { #ifdef CONFIG_SMP ULONG Flags; diff --git a/reactos/w32api/include/ddk/winddk.h b/reactos/w32api/include/ddk/winddk.h index e37c6456f28..5e4af896a4c 100644 --- a/reactos/w32api/include/ddk/winddk.h +++ b/reactos/w32api/include/ddk/winddk.h @@ -929,6 +929,21 @@ typedef struct _FAST_MUTEX { ULONG OldIrql; } FAST_MUTEX, *PFAST_MUTEX; +typedef struct _KGUARDED_MUTEX +{ + LONG Count; + struct _KTHREAD* Owner; + ULONG Contention; + struct _KGATE* Gate; + union { + struct { + SHORT KernelApcDisable; + SHORT SpecialApcDisable; + }; + ULONG CombinedApcDisable; + }; +} KGUARDED_MUTEX, *PKGUARDED_MUTEX, *RESTRICTED_POINTER PRKGUARDED_MUTEX; + typedef struct _KTIMER { DISPATCHER_HEADER Header; ULARGE_INTEGER DueTime;