mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:03:00 +00:00
- Fix regression in Firefox installer by making KiWaitSatisfyAll a function instead of a macro.
- Make KiCheckAleratbility a macro to simplify its code and callers, and also clearly explain what rules it obeys. svn path=/trunk/; revision=20768
This commit is contained in:
parent
795d686a4a
commit
538917d0fb
6 changed files with 106 additions and 120 deletions
|
@ -40,6 +40,16 @@ Author:
|
||||||
//
|
//
|
||||||
#define SSDT_MAX_ENTRIES 4
|
#define SSDT_MAX_ENTRIES 4
|
||||||
|
|
||||||
|
//
|
||||||
|
// Maximum number of times a thread can be suspended
|
||||||
|
//
|
||||||
|
#define MAXIMUM_SUSPEND_COUNT 0x7F
|
||||||
|
|
||||||
|
//
|
||||||
|
// Dispatcher Priority increments
|
||||||
|
//
|
||||||
|
#define THREAD_ALERT_INCREMENT 2
|
||||||
|
|
||||||
#ifdef NTOS_MODE_USER
|
#ifdef NTOS_MODE_USER
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -34,16 +34,16 @@ Author:
|
||||||
//
|
//
|
||||||
#ifndef _MANAGED
|
#ifndef _MANAGED
|
||||||
#if defined(_M_IX86)
|
#if defined(_M_IX86)
|
||||||
#define FASTCALL _fastcall
|
#define FASTCALL _fastcall
|
||||||
#else
|
#else
|
||||||
#define FASTCALL
|
#define FASTCALL
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define FASTCALL NTAPI
|
#define FASTCALL NTAPI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(_M_CEE_PURE)
|
#if !defined(_M_CEE_PURE)
|
||||||
#define NTAPI_INLINE NTAPI
|
#define NTAPI_INLINE NTAPI
|
||||||
#else
|
#else
|
||||||
#define NTAPI_INLINE
|
#define NTAPI_INLINE
|
||||||
#endif
|
#endif
|
||||||
|
@ -66,23 +66,30 @@ Author:
|
||||||
//
|
//
|
||||||
// Native API Return Value Macros
|
// Native API Return Value Macros
|
||||||
//
|
//
|
||||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||||
#define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1)
|
#define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1)
|
||||||
#define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2)
|
#define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2)
|
||||||
#define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3)
|
#define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Limits
|
// Limits
|
||||||
//
|
//
|
||||||
#define MINCHAR 0x80
|
#define MINCHAR 0x80
|
||||||
#define MAXCHAR 0x7f
|
#define MAXCHAR 0x7f
|
||||||
#define MINSHORT 0x8000
|
#define MINSHORT 0x8000
|
||||||
#define MAXSHORT 0x7fff
|
#define MAXSHORT 0x7fff
|
||||||
#define MINLONG 0x80000000
|
#define MINLONG 0x80000000
|
||||||
#define MAXLONG 0x7fffffff
|
#define MAXLONG 0x7fffffff
|
||||||
#define MAXUCHAR 0xff
|
#define MAXUCHAR 0xff
|
||||||
#define MAXUSHORT 0xffff
|
#define MAXUSHORT 0xffff
|
||||||
#define MAXULONG 0xffffffff
|
#define MAXULONG 0xffffffff
|
||||||
|
|
||||||
|
//
|
||||||
|
// CSR Macros
|
||||||
|
//
|
||||||
|
#define CSR_MAKE_OPCODE(s,m) ((s) << 16) | (m)
|
||||||
|
#define CSR_API_ID_FROM_OPCODE(n) ((ULONG)((USHORT)(n)))
|
||||||
|
#define CSR_SERVER_ID_FROM_OPCODE(n) (ULONG)((n) >> 16)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Basic Types that aren't defined in User-Mode Headers
|
// Basic Types that aren't defined in User-Mode Headers
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Define DbgPrint/RtlAssert unless the NDK is used */
|
/* Define DbgPrint/RtlAssert unless the NDK is used */
|
||||||
#if !defined(_NTNDK_) && (!defined(_NTDDK_) || !defined(__NTDDK_H))
|
#if !defined(_RTLFUNCS_H) && (!defined(_NTDDK_) || !defined(__NTDDK_H))
|
||||||
|
|
||||||
/* Make sure we have basic types (some people include us *before* SDK... */
|
/* Make sure we have basic types (some people include us *before* SDK... */
|
||||||
#if defined(_NTDEF_) || (defined _WINDEF_) || (defined _WINDEF_H)
|
#if defined(_NTDEF_) || (defined _WINDEF_) || (defined _WINDEF_H)
|
||||||
|
@ -100,17 +100,8 @@ RtlAssert(
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* On non-debug builds, we never show these */
|
/* On non-debug builds, we never show these */
|
||||||
#ifdef _MSC_VER
|
#define DPRINT1(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
|
||||||
static __inline void DPRINT1 ( const char* fmt, ... )
|
#define DPRINT(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
|
||||||
{
|
|
||||||
}
|
|
||||||
static __inline void DPRINT ( const char* fmt, ... )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define DPRINT1(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
|
|
||||||
#define DPRINT(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CHECKPOINT1
|
#define CHECKPOINT1
|
||||||
#define CHECKPOINT
|
#define CHECKPOINT
|
||||||
|
|
|
@ -169,27 +169,6 @@ extern ULONG_PTR KERNEL_BASE;
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The following macro satisfies multiple objects in a wait state */
|
|
||||||
#define KiSatisifyMultipleObjectWaits(FirstBlock) \
|
|
||||||
{ \
|
|
||||||
PKWAIT_BLOCK WaitBlock = FirstBlock; \
|
|
||||||
PKTHREAD WaitThread = WaitBlock->Thread; \
|
|
||||||
\
|
|
||||||
/* Loop through all the Wait Blocks, and wake each Object */ \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
/* Make sure it hasn't timed out */ \
|
|
||||||
if (WaitBlock->WaitKey != STATUS_TIMEOUT) \
|
|
||||||
{ \
|
|
||||||
/* Wake the Object */ \
|
|
||||||
KiSatisfyObjectWait((PKMUTANT)WaitBlock->Object, WaitThread); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
/* Move to the next block */ \
|
|
||||||
WaitBlock = WaitBlock->NextWaitBlock; \
|
|
||||||
} while (WaitBlock != FirstBlock); \
|
|
||||||
}
|
|
||||||
|
|
||||||
extern KSPIN_LOCK DispatcherDatabaseLock;
|
extern KSPIN_LOCK DispatcherDatabaseLock;
|
||||||
|
|
||||||
#define KeEnterCriticalRegion() \
|
#define KeEnterCriticalRegion() \
|
||||||
|
@ -215,6 +194,12 @@ extern KSPIN_LOCK DispatcherDatabaseLock;
|
||||||
DbgPrint("KeBugCheckWithTf at %s:%i\n",__FILE__,__LINE__), \
|
DbgPrint("KeBugCheckWithTf at %s:%i\n",__FILE__,__LINE__), \
|
||||||
KeBugCheckWithTf(a,b,c,d,e,f)
|
KeBugCheckWithTf(a,b,c,d,e,f)
|
||||||
|
|
||||||
|
/* Tells us if the Timer or Event is a Syncronization or Notification Object */
|
||||||
|
#define TIMER_OR_EVENT_TYPE 0x7L
|
||||||
|
|
||||||
|
/* One of the Reserved Wait Blocks, this one is for the Thread's Timer */
|
||||||
|
#define TIMER_WAIT_BLOCK 0x3L
|
||||||
|
|
||||||
/* INTERNAL KERNEL FUNCTIONS ************************************************/
|
/* INTERNAL KERNEL FUNCTIONS ************************************************/
|
||||||
|
|
||||||
/* threadsch.c ********************************************************************/
|
/* threadsch.c ********************************************************************/
|
||||||
|
|
|
@ -14,13 +14,7 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
/* FIXME: NDK */
|
|
||||||
#define MAXIMUM_SUSPEND_COUNT 0x7F
|
|
||||||
#define THREAD_ALERT_INCREMENT 2
|
|
||||||
|
|
||||||
extern EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue];
|
extern EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue];
|
||||||
#define TIMER_WAIT_BLOCK 0x3L
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PURPOSE: List of threads associated with each priority level
|
* PURPOSE: List of threads associated with each priority level
|
||||||
|
|
|
@ -18,71 +18,70 @@
|
||||||
|
|
||||||
KSPIN_LOCK DispatcherDatabaseLock;
|
KSPIN_LOCK DispatcherDatabaseLock;
|
||||||
|
|
||||||
/* Tells us if the Timer or Event is a Syncronization or Notification Object */
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
#define TIMER_OR_EVENT_TYPE 0x7L
|
|
||||||
|
|
||||||
/* One of the Reserved Wait Blocks, this one is for the Thread's Timer */
|
/*
|
||||||
#define TIMER_WAIT_BLOCK 0x3L
|
* Rules for checking alertability:
|
||||||
|
* - For Alertable waits ONLY:
|
||||||
|
* * We don't wait and return STATUS_ALERTED if the thread is alerted
|
||||||
|
* in EITHER the specified wait mode OR in Kernel Mode.
|
||||||
|
* - For BOTH Alertable AND Non-Alertable waits:
|
||||||
|
* * We don't want and return STATUS_USER_APC if the User Mode APC list
|
||||||
|
* is not empty AND the wait mode is User Mode.
|
||||||
|
*/
|
||||||
|
#define KiCheckAlertability() \
|
||||||
|
if (Alertable) \
|
||||||
|
{ \
|
||||||
|
if (CurrentThread->Alerted[(int)WaitMode]) \
|
||||||
|
{ \
|
||||||
|
CurrentThread->Alerted[(int)WaitMode] = FALSE; \
|
||||||
|
WaitStatus = STATUS_ALERTED; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
else if ((WaitMode != KernelMode) && \
|
||||||
|
(!IsListEmpty(&CurrentThread->ApcState.ApcListHead[UserMode])))\
|
||||||
|
{ \
|
||||||
|
CurrentThread->ApcState.UserApcPending = TRUE; \
|
||||||
|
WaitStatus = STATUS_USER_APC; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
else if (CurrentThread->Alerted[KernelMode]) \
|
||||||
|
{ \
|
||||||
|
CurrentThread->Alerted[KernelMode] = FALSE; \
|
||||||
|
WaitStatus = STATUS_ALERTED; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else if ((WaitMode != KernelMode) && \
|
||||||
|
(CurrentThread->ApcState.UserApcPending)) \
|
||||||
|
{ \
|
||||||
|
WaitStatus = STATUS_USER_APC; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
BOOLEAN
|
VOID
|
||||||
__inline
|
|
||||||
FASTCALL
|
FASTCALL
|
||||||
KiCheckAlertability(BOOLEAN Alertable,
|
KiWaitSatisfyAll(PKWAIT_BLOCK FirstBlock)
|
||||||
PKTHREAD Thread,
|
|
||||||
KPROCESSOR_MODE WaitMode,
|
|
||||||
PNTSTATUS Status)
|
|
||||||
{
|
{
|
||||||
/*
|
PKWAIT_BLOCK WaitBlock = FirstBlock;
|
||||||
* At this point, we have to do a wait, so make sure we can make
|
PKTHREAD WaitThread = WaitBlock->Thread;
|
||||||
* the thread Alertable if requested.
|
|
||||||
*/
|
|
||||||
if (Alertable)
|
|
||||||
{
|
|
||||||
/* If the Thread is Alerted, set the Wait Status accordingly */
|
|
||||||
if (Thread->Alerted[(int)WaitMode])
|
|
||||||
{
|
|
||||||
Thread->Alerted[(int)WaitMode] = FALSE;
|
|
||||||
DPRINT("Thread was Alerted in the specified Mode\n");
|
|
||||||
*Status = STATUS_ALERTED;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else if ((WaitMode != KernelMode) &&
|
|
||||||
(!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
|
|
||||||
{
|
|
||||||
/* If there are User APCs Pending, then we can't really be alertable */
|
|
||||||
DPRINT("APCs are Pending\n");
|
|
||||||
Thread->ApcState.UserApcPending = TRUE;
|
|
||||||
*Status = STATUS_USER_APC;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else if (Thread->Alerted[KernelMode])
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The thread is not alerted in the mode given, but it is alerted
|
|
||||||
* in kernel-mode.
|
|
||||||
*/
|
|
||||||
Thread->Alerted[KernelMode] = FALSE;
|
|
||||||
DPRINT("Thread was Alerted in Kernel-Mode\n");
|
|
||||||
*Status = STATUS_ALERTED;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((WaitMode != KernelMode) &&
|
|
||||||
(Thread->ApcState.UserApcPending))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If there are User APCs Pending and we are waiting in usermode,
|
|
||||||
* then we must notify the caller
|
|
||||||
*/
|
|
||||||
DPRINT("APCs are Pending\n");
|
|
||||||
*Status = STATUS_USER_APC;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stay in the loop */
|
/* Loop through all the Wait Blocks, and wake each Object */
|
||||||
return FALSE;
|
do
|
||||||
|
{
|
||||||
|
/* Make sure it hasn't timed out */
|
||||||
|
if (WaitBlock->WaitKey != STATUS_TIMEOUT)
|
||||||
|
{
|
||||||
|
/* Wake the Object */
|
||||||
|
KiSatisfyObjectWait((PKMUTANT)WaitBlock->Object, WaitThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to the next block */
|
||||||
|
WaitBlock = WaitBlock->NextWaitBlock;
|
||||||
|
}
|
||||||
|
while (WaitBlock != FirstBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -137,8 +136,8 @@ KeDelayExecutionThread(KPROCESSOR_MODE WaitMode,
|
||||||
goto SkipWait;
|
goto SkipWait;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Chceck if we can do an alertable wait, if requested */
|
/* Check if we can do an alertable wait, if requested */
|
||||||
if (KiCheckAlertability(Alertable, CurrentThread, WaitMode, &WaitStatus)) break;
|
KiCheckAlertability();
|
||||||
|
|
||||||
/* Set status */
|
/* Set status */
|
||||||
CurrentThread->WaitStatus = STATUS_WAIT_0;
|
CurrentThread->WaitStatus = STATUS_WAIT_0;
|
||||||
|
@ -311,7 +310,7 @@ KeWaitForSingleObject(PVOID Object,
|
||||||
WaitBlock->NextWaitBlock = WaitBlock;
|
WaitBlock->NextWaitBlock = WaitBlock;
|
||||||
|
|
||||||
/* Make sure we can satisfy the Alertable request */
|
/* Make sure we can satisfy the Alertable request */
|
||||||
if (KiCheckAlertability(Alertable, CurrentThread, WaitMode, &WaitStatus)) break;
|
KiCheckAlertability();
|
||||||
|
|
||||||
/* Enable the Timeout Timer if there was any specified */
|
/* Enable the Timeout Timer if there was any specified */
|
||||||
if (Timeout)
|
if (Timeout)
|
||||||
|
@ -574,13 +573,13 @@ KeWaitForMultipleObjects(ULONG Count,
|
||||||
WaitBlock = CurrentThread->WaitBlockList;
|
WaitBlock = CurrentThread->WaitBlockList;
|
||||||
|
|
||||||
/* Satisfy their Waits and return to the caller */
|
/* Satisfy their Waits and return to the caller */
|
||||||
KiSatisifyMultipleObjectWaits(WaitBlock);
|
KiWaitSatisfyAll(WaitBlock);
|
||||||
WaitStatus = CurrentThread->WaitStatus;
|
WaitStatus = CurrentThread->WaitStatus;
|
||||||
goto DontWait;
|
goto DontWait;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure we can satisfy the Alertable request */
|
/* Make sure we can satisfy the Alertable request */
|
||||||
if (KiCheckAlertability(Alertable, CurrentThread, WaitMode, &WaitStatus)) break;
|
KiCheckAlertability();
|
||||||
|
|
||||||
/* Enable the Timeout Timer if there was any specified */
|
/* Enable the Timeout Timer if there was any specified */
|
||||||
if (Timeout)
|
if (Timeout)
|
||||||
|
@ -754,7 +753,7 @@ KiWaitTest(PVOID ObjectPointer,
|
||||||
/* All the objects are signaled, we can satisfy */
|
/* All the objects are signaled, we can satisfy */
|
||||||
DPRINT("Satisfiying a Wait All\n");
|
DPRINT("Satisfiying a Wait All\n");
|
||||||
WaitEntry = WaitEntry->Blink;
|
WaitEntry = WaitEntry->Blink;
|
||||||
KiSatisifyMultipleObjectWaits(CurrentWaitBlock);
|
KiWaitSatisfyAll(CurrentWaitBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All waits satisfied, unwait the thread */
|
/* All waits satisfied, unwait the thread */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue