mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 18:24:24 +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
|
@ -40,6 +40,16 @@ Author:
|
|||
//
|
||||
#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
|
||||
|
||||
//
|
||||
|
|
|
@ -34,16 +34,16 @@ Author:
|
|||
//
|
||||
#ifndef _MANAGED
|
||||
#if defined(_M_IX86)
|
||||
#define FASTCALL _fastcall
|
||||
#define FASTCALL _fastcall
|
||||
#else
|
||||
#define FASTCALL
|
||||
#endif
|
||||
#else
|
||||
#define FASTCALL NTAPI
|
||||
#define FASTCALL NTAPI
|
||||
#endif
|
||||
|
||||
#if !defined(_M_CEE_PURE)
|
||||
#define NTAPI_INLINE NTAPI
|
||||
#define NTAPI_INLINE NTAPI
|
||||
#else
|
||||
#define NTAPI_INLINE
|
||||
#endif
|
||||
|
@ -66,23 +66,30 @@ Author:
|
|||
//
|
||||
// Native API Return Value Macros
|
||||
//
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1)
|
||||
#define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2)
|
||||
#define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3)
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1)
|
||||
#define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2)
|
||||
#define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3)
|
||||
|
||||
//
|
||||
// Limits
|
||||
//
|
||||
#define MINCHAR 0x80
|
||||
#define MAXCHAR 0x7f
|
||||
#define MINSHORT 0x8000
|
||||
#define MAXSHORT 0x7fff
|
||||
#define MINLONG 0x80000000
|
||||
#define MAXLONG 0x7fffffff
|
||||
#define MAXUCHAR 0xff
|
||||
#define MAXUSHORT 0xffff
|
||||
#define MAXULONG 0xffffffff
|
||||
#define MINCHAR 0x80
|
||||
#define MAXCHAR 0x7f
|
||||
#define MINSHORT 0x8000
|
||||
#define MAXSHORT 0x7fff
|
||||
#define MINLONG 0x80000000
|
||||
#define MAXLONG 0x7fffffff
|
||||
#define MAXUCHAR 0xff
|
||||
#define MAXUSHORT 0xffff
|
||||
#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
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#endif
|
||||
|
||||
/* 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... */
|
||||
#if defined(_NTDEF_) || (defined _WINDEF_) || (defined _WINDEF_H)
|
||||
|
@ -100,17 +100,8 @@ RtlAssert(
|
|||
#else
|
||||
|
||||
/* On non-debug builds, we never show these */
|
||||
#ifdef _MSC_VER
|
||||
static __inline void DPRINT1 ( const char* fmt, ... )
|
||||
{
|
||||
}
|
||||
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 DPRINT1(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
|
||||
#define DPRINT(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
|
||||
|
||||
#define CHECKPOINT1
|
||||
#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;
|
||||
|
||||
#define KeEnterCriticalRegion() \
|
||||
|
@ -215,6 +194,12 @@ extern KSPIN_LOCK DispatcherDatabaseLock;
|
|||
DbgPrint("KeBugCheckWithTf at %s:%i\n",__FILE__,__LINE__), \
|
||||
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 ************************************************/
|
||||
|
||||
/* threadsch.c ********************************************************************/
|
||||
|
|
|
@ -14,13 +14,7 @@
|
|||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FIXME: NDK */
|
||||
#define MAXIMUM_SUSPEND_COUNT 0x7F
|
||||
#define THREAD_ALERT_INCREMENT 2
|
||||
|
||||
extern EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue];
|
||||
#define TIMER_WAIT_BLOCK 0x3L
|
||||
|
||||
|
||||
/*
|
||||
* PURPOSE: List of threads associated with each priority level
|
||||
|
|
|
@ -18,71 +18,70 @@
|
|||
|
||||
KSPIN_LOCK DispatcherDatabaseLock;
|
||||
|
||||
/* Tells us if the Timer or Event is a Syncronization or Notification Object */
|
||||
#define TIMER_OR_EVENT_TYPE 0x7L
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
/* 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
|
||||
__inline
|
||||
VOID
|
||||
FASTCALL
|
||||
KiCheckAlertability(BOOLEAN Alertable,
|
||||
PKTHREAD Thread,
|
||||
KPROCESSOR_MODE WaitMode,
|
||||
PNTSTATUS Status)
|
||||
KiWaitSatisfyAll(PKWAIT_BLOCK FirstBlock)
|
||||
{
|
||||
/*
|
||||
* At this point, we have to do a wait, so make sure we can make
|
||||
* 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;
|
||||
}
|
||||
PKWAIT_BLOCK WaitBlock = FirstBlock;
|
||||
PKTHREAD WaitThread = WaitBlock->Thread;
|
||||
|
||||
/* Stay in the loop */
|
||||
return FALSE;
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -137,8 +136,8 @@ KeDelayExecutionThread(KPROCESSOR_MODE WaitMode,
|
|||
goto SkipWait;
|
||||
}
|
||||
|
||||
/* Chceck if we can do an alertable wait, if requested */
|
||||
if (KiCheckAlertability(Alertable, CurrentThread, WaitMode, &WaitStatus)) break;
|
||||
/* Check if we can do an alertable wait, if requested */
|
||||
KiCheckAlertability();
|
||||
|
||||
/* Set status */
|
||||
CurrentThread->WaitStatus = STATUS_WAIT_0;
|
||||
|
@ -311,7 +310,7 @@ KeWaitForSingleObject(PVOID Object,
|
|||
WaitBlock->NextWaitBlock = WaitBlock;
|
||||
|
||||
/* 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 */
|
||||
if (Timeout)
|
||||
|
@ -574,13 +573,13 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
WaitBlock = CurrentThread->WaitBlockList;
|
||||
|
||||
/* Satisfy their Waits and return to the caller */
|
||||
KiSatisifyMultipleObjectWaits(WaitBlock);
|
||||
KiWaitSatisfyAll(WaitBlock);
|
||||
WaitStatus = CurrentThread->WaitStatus;
|
||||
goto DontWait;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
if (Timeout)
|
||||
|
@ -754,7 +753,7 @@ KiWaitTest(PVOID ObjectPointer,
|
|||
/* All the objects are signaled, we can satisfy */
|
||||
DPRINT("Satisfiying a Wait All\n");
|
||||
WaitEntry = WaitEntry->Blink;
|
||||
KiSatisifyMultipleObjectWaits(CurrentWaitBlock);
|
||||
KiWaitSatisfyAll(CurrentWaitBlock);
|
||||
}
|
||||
|
||||
/* All waits satisfied, unwait the thread */
|
||||
|
|
Loading…
Reference in a new issue