diff --git a/reactos/include/ndk/ketypes.h b/reactos/include/ndk/ketypes.h index 9c3b321c3bc..3d1760bf668 100644 --- a/reactos/include/ndk/ketypes.h +++ b/reactos/include/ndk/ketypes.h @@ -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 // diff --git a/reactos/include/ndk/umtypes.h b/reactos/include/ndk/umtypes.h index 12859c8f344..891d4d18441 100644 --- a/reactos/include/ndk/umtypes.h +++ b/reactos/include/ndk/umtypes.h @@ -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 diff --git a/reactos/include/reactos/debug.h b/reactos/include/reactos/debug.h index 21ad7846d17..e10d04de1bf 100644 --- a/reactos/include/reactos/debug.h +++ b/reactos/include/reactos/debug.h @@ -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 diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 74faed6154b..92922b1dfb5 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -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 ********************************************************************/ diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index beceae6c2f8..2ea10910447 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -14,13 +14,7 @@ #define NDEBUG #include -/* 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 diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index c1823468d2c..e30d85f0eeb 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -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 */