- 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:
Alex Ionescu 2006-01-10 21:36:42 +00:00
parent 795d686a4a
commit 538917d0fb
6 changed files with 106 additions and 120 deletions

View file

@ -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
//

View file

@ -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

View file

@ -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

View file

@ -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 ********************************************************************/

View file

@ -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

View file

@ -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 */