- Fix regression in Firefox installer by making KiWaitSatisfyAll a function instead...
authorAlex Ionescu <aionescu@gmail.com>
Tue, 10 Jan 2006 21:36:42 +0000 (21:36 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Tue, 10 Jan 2006 21:36:42 +0000 (21:36 +0000)
- Make KiCheckAleratbility a macro to simplify its code and callers, and also clearly explain what rules it obeys.

svn path=/trunk/; revision=20768

reactos/include/ndk/ketypes.h
reactos/include/ndk/umtypes.h
reactos/include/reactos/debug.h
reactos/ntoskrnl/include/internal/ke.h
reactos/ntoskrnl/ke/kthread.c
reactos/ntoskrnl/ke/wait.c

index 9c3b321..3d1760b 100644 (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
 
 //
index 12859c8..891d4d1 100644 (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
index 21ad784..e10d04d 100644 (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
index 74faed6..92922b1 100644 (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 ********************************************************************/
index beceae6..2ea1091 100644 (file)
 #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
index c182346..e30d85f 100644 (file)
 
 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
-
-/* FUNCTIONS *****************************************************************/
+/*
+ * 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;                                                              \
+    }                                                                       \
+
+/* 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)
+    PKWAIT_BLOCK WaitBlock = FirstBlock;
+    PKTHREAD WaitThread = WaitBlock->Thread;
+
+    /* Loop through all the Wait Blocks, and wake each Object */
+    do
     {
-        /* 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])))
+        /* Make sure it hasn't timed out */
+        if (WaitBlock->WaitKey != STATUS_TIMEOUT)
         {
-            /* 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;
+            /* Wake the Object */
+            KiSatisfyObjectWait((PKMUTANT)WaitBlock->Object, WaitThread);
         }
-        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 */
-    return FALSE;
+        /* 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 */