Worked around compiler bug in NtDelayExecution
authorDavid Welch <welch@cwcom.net>
Sat, 18 Dec 1999 17:48:23 +0000 (17:48 +0000)
committerDavid Welch <welch@cwcom.net>
Sat, 18 Dec 1999 17:48:23 +0000 (17:48 +0000)
Added some page free checking
Reorganised thread code a bit

svn path=/trunk/; revision=892

12 files changed:
reactos/apps/tests/thread/thread.c
reactos/include/ddk/pstypes.h
reactos/include/ddk/zw.h
reactos/include/internal/ps.h
reactos/include/kernel32/kernel32.h
reactos/ntoskrnl/ke/i386/usercall.c
reactos/ntoskrnl/ke/main.c
reactos/ntoskrnl/ke/timer.c
reactos/ntoskrnl/mm/freelist.c
reactos/ntoskrnl/mm/i386/page.c
reactos/ntoskrnl/ps/kill.c
reactos/ntoskrnl/ps/thread.c

index 2b03be5..e9aa2c6 100644 (file)
@@ -14,6 +14,7 @@ DWORD WINAPI thread_main1(LPVOID param)
    s = s % 10;
    printf("s %d\n", s);
    Sleep(s);
+   printf("Thread %d finished\n", (DWORD)param);
    return 0;
 }
 
index dc3a53d..05afb2a 100644 (file)
@@ -174,7 +174,7 @@ typedef struct _KTHREAD
    PVOID             KernelStack;
    UCHAR             DebugActive;
    UCHAR             State;
-   USHORT            Alerted;
+   UCHAR             Alerted[2];
    UCHAR             Iopl;
    UCHAR             NpxState;
    UCHAR             Saturation;
@@ -199,9 +199,9 @@ typedef struct _KTHREAD
    KAFFINITY         UserAffinity;
    UCHAR             SystemAffinityActive;
    UCHAR             Pad;
-   PKQUEUE           Queue;     
+   PKQUEUE           Queue;    
+   KSPIN_LOCK        ApcQueueLock;
    KTIMER            Timer;
-   KDPC              TimerDpc;                 // Added by Phillip Susi for internal KeAddThreadTimeout() impl.
    LIST_ENTRY        QueueListEntry;
    KAFFINITY         Affinity;
    UCHAR             Preempted;
@@ -234,7 +234,7 @@ typedef struct _KTHREAD
 
    /* Provisionally added by David Welch */
    hal_thread_state                   Context;
-
+   KDPC              TimerDpc;                 // Added by Phillip Susi for internal KeAddThreadTimeout() impl.
 } KTHREAD, *PKTHREAD;
 
 // According to documentation the stack should have a commited [ 1 page ] and
index 7146e08..eeb8208 100644 (file)
@@ -1,5 +1,5 @@
 
-/* $Id: zw.h,v 1.23 1999/12/10 17:04:33 dwelch Exp $
+/* $Id: zw.h,v 1.24 1999/12/18 17:48:21 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -1201,12 +1201,7 @@ NtCurrentTeb(VOID
  *        Interval  = Specifies the interval to wait.      
  * RETURNS: Status
  */
-NTSTATUS
-STDCALL
-NtDelayExecution(
-       IN BOOLEAN Alertable,
-       IN TIME* Interval
-       );
+NTSTATUS STDCALL NtDelayExecution(IN ULONG Alertable, IN TIME* Interval);
 
 NTSTATUS
 STDCALL
index 603525c..affca54 100644 (file)
@@ -31,6 +31,7 @@ ULONG PsFreezeThread(PETHREAD Thread, PNTSTATUS WaitStatus,
 VOID PiInitApcManagement(VOID);
 VOID PiDeleteThread(PVOID ObjectBody);
 VOID PiCloseThread(PVOID ObjectBody, ULONG HandleCount);
+VOID PsReapThreads(VOID);
 NTSTATUS PsInitializeThread(HANDLE ProcessHandle,
                            PETHREAD* ThreadPtr,
                            PHANDLE ThreadHandle,
index dd1ffd0..3c3cabf 100644 (file)
@@ -10,6 +10,8 @@
 #define CHECKPOINT do { dprintf("(KERNEL32:%s:%d) Checkpoint\n",__FILE__,__LINE__); } while(0);
 #endif
 
+#define DPRINT1(args...) do { dprintf("(KERNEL32:%s:%d) ",__FILE__,__LINE__); dprintf(args);  } while(0);
+
 void dprintf(char* fmt, ...);
 void aprintf(char* fmt, ...);
 
index dd060aa..b80161f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: usercall.c,v 1.3 1999/12/02 20:53:53 dwelch Exp $
+/* $Id: usercall.c,v 1.4 1999/12/18 17:48:22 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -99,11 +99,24 @@ void PsBeginThreadWithContextInternal(void);
      "popl %ebp\n\t"
      "iret\n\t");
 
-VOID KiSystemCallHook(ULONG Nr)
+VOID KiSystemCallHook(ULONG Nr, ...)
 {
-//   DbgPrint("KiSystemCallHook(Nr %d) %x ", Nr, PsGetCurrentProcess());
-//   DbgPrint("SystemCall %x\n", _SystemServiceTable[Nr].Function);
+#ifdef TRACE_SYSTEM_CALLS
+   va_list ap;
+   ULONG i;
+   
+   va_start(ap, Nr);
+   
+   DbgPrint("%x/%d ", _SystemServiceTable[Nr].Function,Nr);
+   DbgPrint("%x (", _SystemServiceTable[Nr].ParametersSize);
+   for (i = 0; i < _SystemServiceTable[Nr].ParametersSize / 4; i++)
+     {
+       DbgPrint("%x, ", va_arg(ap, ULONG));
+     }
+   DbgPrint(")\n");
    assert_irql(PASSIVE_LEVEL);
+   va_end(ap);
+#endif
 }
 
 ULONG KiAfterSystemCallHook(ULONG NtStatus, PCONTEXT Context)
@@ -210,62 +223,3 @@ void interrupt_handler2e(void);
           
            "iret\n\t");
 
-
-void old_interrupt_handler2e(void);
-   __asm__("\n\t.global _old_interrupt_handler2e\n\t"
-           "_old_interrupt_handler2e:\n\t"
-           
-           /*  Save the users context  */
-           "pushl %ds\n\t"
-           "pushl %es\n\t"
-           "pushl %esi\n\t"
-           "pushl %edi\n\t"
-           "pushl %ebp\n\t"
-           "pushl %ebx\n\t"
-           
-           /*  Set ES to kernel segment  */
-           "movw  $"STR(KERNEL_DS)",%bx\n\t"
-           "movw %bx,%es\n\t"
-           
-           /*  Allocate new Kernel stack frame  */
-           "movl %esp,%ebp\n\t"
-           
-           /*  Users's current stack frame pointer is source  */
-           "movl %edx,%esi\n\t"
-
-           /* FIXME: determine system service table to use  */
-           /* FIXME: chech to see if SS is valid/inrange  */
-           
-           /*  Allocate room for argument list from kernel stack  */
-           "movl %es:__SystemServiceTable(,%eax,8),%ecx\n\t"
-           "subl %ecx,%esp\n\t"
-           
-           /*  Copy the arguments from the user stack to the kernel stack  */
-           "movl %esp,%edi\n\t"
-           "rep\n\tmovsb\n\t"
-           
-           /*  DS is now also kernel segment  */
-           "movw %bx,%ds\n\t"
-           
-          /* Call system call hook */
-          "pushl %eax\n\t"
-          "call _KiSystemCallHook\n\t"
-          "popl %eax\n\t"
-          
-           /*  Make the system service call  */
-           "movl %ds:__SystemServiceTable+4(,%eax,8),%eax\n\t"
-           "call *%eax\n\t"
-           
-           /*  Deallocate the kernel stack frame  */
-           "movl %ebp,%esp\n\t"
-           
-           /*  Restore the user context  */
-           "popl %ebx\n\t"
-           "popl %ebp\n\t"
-           "popl %edi\n\t"
-           "popl %esi\n\t"
-           "popl %es\n\t"
-           "popl %ds\n\t"
-           "iret\n\t");
-
-
index e730e4a..df5cdf5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.32 1999/12/13 22:04:36 dwelch Exp $
+/* $Id: main.c,v 1.33 1999/12/18 17:48:22 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -26,7 +26,7 @@
 #include <internal/mmhal.h>
 #include <internal/i386/segment.h>
 
-//#define NDEBUG
+#define NDEBUG
 #include <internal/debug.h>
 
 /* FUNCTIONS ****************************************************************/
index 2382ec2..9978b47 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: timer.c,v 1.24 1999/12/13 22:04:36 dwelch Exp $
+/* $Id: timer.c,v 1.25 1999/12/18 17:48:22 dwelch Exp $
  *
  * COPYRIGHT:      See COPYING in the top level directory
  * PROJECT:        ReactOS kernel
@@ -129,13 +129,18 @@ NTSTATUS KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval)
 }
 
 
-NTSTATUS STDCALL NtDelayExecution(IN BOOLEAN Alertable,
+NTSTATUS STDCALL NtDelayExecution(IN ULONG Alertable,
                                  IN TIME* Interval)
 {
    NTSTATUS Status;
+   PLARGE_INTEGER IntervalP;
    
-   Status = KeDelayExecutionThread(UserMode, Alertable, 
-                                  (PLARGE_INTEGER)Internal);
+   IntervalP = (PLARGE_INTEGER)Interval;
+   
+   DPRINT1("NtDelayExecution(Alertable %d, Internal %x) IntervalP %x\n",
+         Alertable, Internal, IntervalP);
+   
+   Status = KeDelayExecutionThread(UserMode, Alertable, IntervalP);
    return(Status);
 }
 
index 9422ecd..ae4ddce 100644 (file)
@@ -168,7 +168,11 @@ VOID MmFreePage(PVOID PhysicalAddress, ULONG Nr)
    
    DPRINT("MmFreePage(PhysicalAddress %x, Nr %x)\n", PhysicalAddress, Nr);
    
-   assert(((ULONG)PhysicalAddress) <= 0x400000);
+   if (((ULONG)PhysicalAddress) > 0x400000)
+     {
+       DbgPrint("MmFreePage() failed with %x\n", PhysicalAddress);
+       KeBugCheck(0);
+     }
    
    MiNrFreePages = MiNrFreePages + Nr;
    MiNrUsedPages = MiNrUsedPages - Nr;
@@ -218,7 +222,11 @@ PVOID MmAllocPage(VOID)
    MiNrUsedPages = MiNrUsedPages + 1;
    MiNrFreePages = MiNrFreePages - 1;
    
-   assert(offset <= 0x400000);
+   if (offset > 0x400000)
+     {
+       DbgPrint("Failed in MmAllocPage() with offset %x\n", offset);
+       KeBugCheck(0);
+     }
    
    DPRINT("MmAllocPage() = %x\n",offset);
    return((PVOID)offset);
index d0a11a0..f1e6ef0 100644 (file)
@@ -23,6 +23,8 @@
 
 /* GLOBALS *****************************************************************/
 
+extern ULONG MiNrFreePages;
+
 #define PA_BIT_PRESENT   (0)
 #define PA_BIT_READWRITE (1)
 #define PA_BIT_USER      (2)
@@ -168,9 +170,17 @@ VOID MmDeletePageEntry(PEPROCESS Process, PVOID Address, BOOL FreePage)
          }     
        return;
      }
-   page_tlb = ADDR_TO_PTE(Address);
+   page_tlb = ADDR_TO_PTE(Address);   
    if (FreePage && PAGE_MASK(*page_tlb) != 0)
      {
+       if (PAGE_MASK(*page_tlb) >= 0x400000)
+         {
+            DbgPrint("MmDeletePageEntry(Address %x) Physical %x Free %d, "
+                      "Entry %x\n",
+                     Address, PAGE_MASK(*page_tlb), MiNrFreePages,
+                     *page_tlb);
+            KeBugCheck(0);
+         }
         MmFreePage((PVOID)PAGE_MASK(*page_tlb),1);
      }
    *page_tlb = 0;
@@ -219,11 +229,19 @@ VOID MmSetPage(PEPROCESS Process,
    PEPROCESS CurrentProcess = PsGetCurrentProcess();
    ULONG Attributes = 0;
    
-   DPRINT("MmSetPage(Process %x, Address %x, flProtect %x, "
-         "PhysicalAddress %x)\n",Process,Address,flProtect,
-         PhysicalAddress);
+   if (PAGE_ROUND_DOWN(Address) == 0x77631000)
+     {
+       DPRINT1("MmSetPage(Process %x, Address %x, flProtect %x, "
+               "PhysicalAddress %x)\n",Process,Address,flProtect,
+               PhysicalAddress);
+     }
    
-   assert(((ULONG)PhysicalAddress)<0x400000);
+    if (((ULONG)PhysicalAddress) >= 0x400000)
+     {
+       DbgPrint("MmSetPage(Process %x, Address %x, PhysicalAddress %x)\n",
+                Process, Address, PhysicalAddress);
+       KeBugCheck(0);
+     }
    
    Attributes = ProtectToPTE(flProtect);
    
index 8ae130a..129705d 100644 (file)
 extern ULONG PiNrThreads;
 extern ULONG PiNrRunnableThreads;
 extern KSPIN_LOCK PiThreadListLock;
+extern LIST_ENTRY PiThreadListHead;
 
 /* FUNCTIONS *****************************************************************/
 
+VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus)
+{
+   KIRQL oldlvl;
+   PLIST_ENTRY current_entry;
+   PETHREAD current;
+
+   KeAcquireSpinLock(&PiThreadListLock, &oldlvl);
+
+   current_entry = PiThreadListHead.Flink;
+   while (current_entry != &PiThreadListHead)
+     {
+       current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.QueueListEntry);
+       if (current->ThreadsProcess == Process &&
+           current != PsGetCurrentThread())
+         {
+            KeReleaseSpinLock(&PiThreadListLock, oldlvl);
+            PsTerminateOtherThread(current, ExitStatus);
+            KeAcquireSpinLock(&PiThreadListLock, &oldlvl);
+            current_entry = PiThreadListHead.Flink;
+         }
+       current_entry = current_entry->Flink;
+     }
+
+   KeReleaseSpinLock(&PiThreadListLock, oldlvl);
+}
+
+VOID PsReapThreads(VOID)
+{
+   PLIST_ENTRY current_entry;
+   PETHREAD current;
+   KIRQL oldIrql;
+   
+//   DPRINT1("PsReapThreads()\n");
+   
+   KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
+   
+   current_entry = PiThreadListHead.Flink;
+   
+   while (current_entry != &PiThreadListHead)
+     {
+       current = CONTAINING_RECORD(current_entry, ETHREAD, 
+                                   Tcb.ThreadListEntry);
+       
+       current_entry = current_entry->Flink;
+       
+       if (current->Tcb.State == THREAD_STATE_TERMINATED_1)
+         {
+            PEPROCESS Process = current->ThreadsProcess; 
+            NTSTATUS Status = current->ExitStatus;
+            
+            ObReferenceObjectByPointer(Process, 
+                                       0, 
+                                       PsProcessType, 
+                                       KernelMode );
+            DPRINT("Reaping thread %x\n", current);
+            current->Tcb.State = THREAD_STATE_TERMINATED_2;
+            RemoveEntryList(&current->Tcb.ProcessThreadListEntry);
+            KeReleaseSpinLock(&PiThreadListLock, oldIrql);
+            ObDereferenceObject(current);
+            KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
+            if(IsListEmpty( &Process->Pcb.ThreadListHead))
+              {
+                 /* 
+                  * TODO: Optimize this so it doesnt jerk the IRQL around so 
+                  * much :)
+                  */
+                 DPRINT("Last thread terminated, terminating process\n");
+                 KeReleaseSpinLock(&PiThreadListLock, oldIrql);
+                 PiTerminateProcess(Process, Status);
+                 KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
+              }
+            ObDereferenceObject(Process);
+            current_entry = PiThreadListHead.Flink;
+         }
+     }
+   KeReleaseSpinLock(&PiThreadListLock, oldIrql);
+}
+
 VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
 /*
  * FUNCTION: Terminates the current thread
@@ -35,7 +114,6 @@ VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
    KIRQL oldIrql;
    PETHREAD CurrentThread;
    
-   
    CurrentThread = PsGetCurrentThread();
    
    DPRINT("terminating %x\n",CurrentThread);
@@ -65,15 +143,13 @@ VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus)
    KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
    if (Thread->Tcb.State == THREAD_STATE_RUNNABLE)
      {
-       PiNrRunnableThreads--;
        RemoveEntryList(&Thread->Tcb.QueueListEntry);
      }
-   RemoveEntryList(&Thread->Tcb.ThreadListEntry);
    Thread->Tcb.State = THREAD_STATE_TERMINATED_2;
    Thread->Tcb.DispatcherHeader.SignalState = TRUE;
    KeDispatcherObjectWake(&Thread->Tcb.DispatcherHeader);
-   ObDereferenceObject(Thread);
    KeReleaseSpinLock(&PiThreadListLock, oldIrql);
+   ObDereferenceObject(Thread);
 }
 
 NTSTATUS STDCALL PiTerminateProcess(PEPROCESS Process,
index 265721a..c9b20c7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: thread.c,v 1.43 1999/12/18 07:33:53 phreak Exp $
+/* $Id: thread.c,v 1.44 1999/12/18 17:48:23 dwelch Exp $
  *
  * COPYRIGHT:              See COPYING in the top level directory
  * PROJECT:                ReactOS kernel
@@ -71,32 +71,6 @@ HANDLE PsGetCurrentThreadId(VOID)
    return(CurrentThread->Cid.UniqueThread);
 }
 
-VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus)
-{
-   KIRQL oldlvl;
-   PLIST_ENTRY current_entry;
-   PETHREAD current;
-
-   KeAcquireSpinLock(&PiThreadListLock, &oldlvl);
-
-   current_entry = PiThreadListHead.Flink;
-   while (current_entry != &PiThreadListHead)
-     {
-       current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.QueueListEntry);
-       if (current->ThreadsProcess == Process &&
-           current != PsGetCurrentThread())
-         {
-            KeReleaseSpinLock(&PiThreadListLock, oldlvl);
-            PsTerminateOtherThread(current, ExitStatus);
-            KeAcquireSpinLock(&PiThreadListLock, &oldlvl);
-            current_entry = PiThreadListHead.Flink;
-         }
-       current_entry = current_entry->Flink;
-     }
-
-   KeReleaseSpinLock(&PiThreadListLock, oldlvl);
-}
-
 static VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)
 {
 //   DPRINT("PsInsertIntoThreadList(Priority %x, Thread %x)\n",Priority,
@@ -129,63 +103,17 @@ VOID PsDumpThreads(VOID)
             DbgPrint("Too many threads on list\n");
             return;
          }
-       DPRINT1("current %x current->Tcb.State %d eip %x ",
+       DbgPrint("current %x current->Tcb.State %d eip %x ",
                current, current->Tcb.State,
                current->Tcb.Context.eip);
 //     KeDumpStackFrames(0, 16);
-       DPRINT1("PID %d ", current->ThreadsProcess->UniqueProcessId);
-       DPRINT1("\n");
+       DbgPrint("PID %d ", current->ThreadsProcess->UniqueProcessId);
+       DbgPrint("\n");
        
        current_entry = current_entry->Flink;
      }
 }
 
-VOID PsReapThreads(VOID)
-{
-   PLIST_ENTRY current_entry;
-   PETHREAD current;
-   KIRQL oldIrql;
-   
-//   DPRINT1("PsReapThreads()\n");
-   
-   KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
-   
-   current_entry = PiThreadListHead.Flink;
-   
-   while (current_entry != &PiThreadListHead)
-     {
-       current = CONTAINING_RECORD(current_entry, ETHREAD, 
-                                   Tcb.ThreadListEntry);
-       
-       current_entry = current_entry->Flink;
-       
-       if (current->Tcb.State == THREAD_STATE_TERMINATED_1)
-         {
-         PEPROCESS Process = current->ThreadsProcess; 
-         NTSTATUS Status = current->ExitStatus;
-
-         ObReferenceObjectByPointer( Process, 0, PsProcessType, KernelMode );
-            DPRINT("Reaping thread %x\n", current);
-            current->Tcb.State = THREAD_STATE_TERMINATED_2;
-         RemoveEntryList( &current->Tcb.ProcessThreadListEntry );
-         KeReleaseSpinLock(&PiThreadListLock, oldIrql);
-            ObDereferenceObject(current);
-            KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
-         if( IsListEmpty( &Process->Pcb.ThreadListHead ) )
-         {
-             //TODO: Optimize this so it doesnt jerk the IRQL around so much :)
-             DPRINT( "Last thread terminated, terminating process\n" );
-             KeReleaseSpinLock(&PiThreadListLock, oldIrql);
-             PiTerminateProcess( Process, Status );
-             KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
-         }
-         ObDereferenceObject( Process );
-            current_entry = PiThreadListHead.Flink;
-         }
-     }
-   KeReleaseSpinLock(&PiThreadListLock, oldIrql);
-}
-
 static PETHREAD PsScanThreadList (KPRIORITY Priority)
 {
    PLIST_ENTRY current_entry;
@@ -282,14 +210,15 @@ ULONG PsUnfreezeThread(PETHREAD Thread, PNTSTATUS WaitStatus)
    Thread->Tcb.FreezeCount--;
    r = Thread->Tcb.FreezeCount;
    
+   if (WaitStatus != NULL)
+     {
+       Thread->Tcb.WaitStatus = *WaitStatus;
+     }
+   
    if (r <= 0)
      {
        DPRINT("Resuming thread\n");
        Thread->Tcb.State = THREAD_STATE_RUNNABLE;
-       if (WaitStatus != NULL)
-         {
-            Thread->Tcb.WaitStatus = *WaitStatus;
-         }
        PsInsertIntoThreadList(Thread->Tcb.Priority, Thread);
      }