Lock/unlock address space in KeReleasThread.
[reactos.git] / reactos / ntoskrnl / ke / kthread.c
index bb6e4a3..2ba6aa6 100644 (file)
@@ -16,7 +16,8 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/*
+/* $Id: kthread.c,v 1.23 2002/05/07 22:34:17 hbirr Exp $
+ *
  * FILE:            ntoskrnl/ke/kthread.c
  * PURPOSE:         Microkernel thread support
  * PROGRAMMER:      David Welch (welch@cwcom.net)
 /* FUNCTIONS *****************************************************************/
 
 VOID
-KeFreeStackPage(PVOID Context, PVOID Address, ULONG PhysAddr)
+KeFreeStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
+               SWAPENTRY SwapEntry, BOOLEAN Dirty)
 {
+  assert(SwapEntry == 0);
   if (PhysAddr != 0)
     {
       MmDereferencePage((PVOID)PhysAddr);
@@ -52,10 +55,10 @@ KeFreeStackPage(PVOID Context, PVOID Address, ULONG PhysAddr)
 }
 
 NTSTATUS 
-HalReleaseTask(PETHREAD Thread)
+KeReleaseThread(PETHREAD Thread)
 /*
  * FUNCTION: Releases the resource allocated for a thread by
- * HalInitTaskWithContext or HalInitTask
+ * KeInitializeThread
  * NOTE: The thread had better not be running when this is called
  */
 {
@@ -63,11 +66,13 @@ HalReleaseTask(PETHREAD Thread)
 
   if (Thread->Tcb.StackLimit != (ULONG)&init_stack)
     {       
+      MmLockAddressSpace(MmGetKernelAddressSpace());
       MmFreeMemoryArea(MmGetKernelAddressSpace(),
                       (PVOID)Thread->Tcb.StackLimit,
                       MM_STACK_SIZE,
                       KeFreeStackPage,
                       NULL);
+      MmUnlockAddressSpace(MmGetKernelAddressSpace());
     }
   Thread->Tcb.StackLimit = 0;
   Thread->Tcb.InitialStack = NULL;
@@ -82,145 +87,152 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
  * FUNCTION: Initialize the microkernel state of the thread
  */
 {
-   PVOID KernelStack;
-   NTSTATUS Status;
-   extern unsigned int init_stack_top;
-   extern unsigned int init_stack;
-   PMEMORY_AREA StackArea;
-   ULONG i;
-
-   KeInitializeDispatcherHeader(&Thread->DispatcherHeader,
-                                InternalThreadType,
-                                sizeof(ETHREAD),
-                                FALSE);
-   InitializeListHead(&Thread->MutantListHead);
-   if (!First)
-     {
-       KernelStack = NULL;
-       
-          MmLockAddressSpace(MmGetKernelAddressSpace());
-          Status = MmCreateMemoryArea(NULL,
-                                  MmGetKernelAddressSpace(),
-                                  MEMORY_AREA_KERNEL_STACK,
-                                  &KernelStack,
-                                  MM_STACK_SIZE,
-                                  0,
-                                  &StackArea,
-                                  FALSE);
-          MmUnlockAddressSpace(MmGetKernelAddressSpace());
-
-       if (!NT_SUCCESS(Status))
-        {
-          DPRINT1("Failed to create thread stack\n");
-          KeBugCheck(0);
-        }
-       for (i = 0; i < (MM_STACK_SIZE / PAGESIZE); i++)
-        {
-          Status = MmCreateVirtualMapping(NULL,
-                                          KernelStack + (i * PAGESIZE),
-                                          PAGE_EXECUTE_READWRITE,
-                                          (ULONG)MmAllocPage(0));
-        }
-       Thread->InitialStack = KernelStack + MM_STACK_SIZE;
-       Thread->StackBase = KernelStack + MM_STACK_SIZE;
-       Thread->StackLimit = (ULONG)KernelStack;
-       Thread->KernelStack = KernelStack + MM_STACK_SIZE;
-     }
-   else
-     {
-       Thread->InitialStack = (PVOID)&init_stack_top;
-       Thread->StackBase = (PVOID)&init_stack_top;
-       Thread->StackLimit = (ULONG)&init_stack;
-       Thread->KernelStack = (PVOID)&init_stack_top;
-     }
-   
-   /* 
-    * The Native API function will initialize the TEB field later 
-    */
-   Thread->Teb = NULL;
-   Thread->TlsArray = NULL;
-   Thread->DebugActive = 0;
-   Thread->State = THREAD_STATE_BLOCKED;
-   Thread->Alerted[0] = 0;
-   Thread->Alerted[1] = 0;
-   Thread->Iopl = 0;
-   /*
-    * FIXME: Think how this might work
-    */
-   Thread->NpxState = 0;
-
-   Thread->Saturation = 0;
-   Thread->Priority = 0; 
-   InitializeListHead(&Thread->ApcState.ApcListHead[0]);
-   InitializeListHead(&Thread->ApcState.ApcListHead[1]);
-   Thread->ApcState.Process = Process;
-   Thread->ApcState.KernelApcInProgress = 0;
-   Thread->ApcState.KernelApcPending = 0;
-   Thread->ApcState.UserApcPending = 0;
-   Thread->ContextSwitches = 0;
-   Thread->WaitStatus = STATUS_SUCCESS;
-   Thread->WaitIrql = 0;
-   Thread->WaitMode = 0;
-   Thread->WaitNext = 0;
-   Thread->WaitBlockList = NULL;
-   Thread->WaitListEntry.Flink = NULL;
-   Thread->WaitListEntry.Blink = NULL;
-   Thread->WaitTime = 0;
-   Thread->BasePriority = 0; 
-   Thread->DecrementCount = 0;
-   Thread->PriorityDecrement = 0;
-   Thread->Quantum = 0;
-   memset(Thread->WaitBlock, 0, sizeof(KWAIT_BLOCK)*4);
-   Thread->LegoData = 0;
-   /*
-    * FIXME: Why this?
-    */
-   Thread->KernelApcDisable = 1;
-   Thread->UserAffinity = Process->Affinity;
-   Thread->SystemAffinityActive = 0;
-   Thread->Queue = NULL;
-   KeInitializeSpinLock(&Thread->ApcQueueLock);
-   memset(&Thread->Timer, 0, sizeof(KTIMER));
-   Thread->QueueListEntry.Flink = NULL;
-   Thread->QueueListEntry.Blink = NULL;
-   Thread->Affinity = Process->Affinity;
-   Thread->Preempted = 0;
-   Thread->ProcessReadyQueue = 0;
-   Thread->KernelStackResident = 1;
-   Thread->NextProcessor = 0;
-   Thread->CallbackStack = NULL;
-   Thread->Win32Thread = 0;
-   Thread->TrapFrame = NULL;
-   Thread->ApcStatePointer[0] = NULL;
-   Thread->ApcStatePointer[1] = NULL;
-   Thread->EnableStackSwap = 0;
-   Thread->LargeStack = 0;
-   Thread->ResourceIndex = 0;
-   Thread->PreviousMode = KernelMode;
-   Thread->KernelTime = 0;
-   Thread->UserTime = 0;
-   memset(&Thread->SavedApcState, 0, sizeof(KAPC_STATE));
-   Thread->Alertable = 1;
-   Thread->ApcStateIndex = 0;
-   Thread->ApcQueueable = 0;
-   Thread->AutoAlignment = 0;
-   KeInitializeApc(&Thread->SuspendApc,
-                  Thread,
-                  0,
-                  PiSuspendThreadKernelRoutine,
-                  PiSuspendThreadRundownRoutine,
-                  PiSuspendThreadNormalRoutine,
-                  KernelMode,
-                  NULL);
-   KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 255);
-   Thread->ThreadListEntry.Flink = NULL;
-   Thread->ThreadListEntry.Blink = NULL;
-   Thread->FreezeCount = 0;
-   Thread->SuspendCount = 0;
-
-   /*
-    * Initialize ReactOS specific members
-    */
+  PVOID KernelStack;
+  NTSTATUS Status;
+  extern unsigned int init_stack_top;
+  extern unsigned int init_stack;
+  PMEMORY_AREA StackArea;
+  ULONG i;
+  
+  KeInitializeDispatcherHeader(&Thread->DispatcherHeader,
+                              InternalThreadType,
+                              sizeof(ETHREAD),
+                              FALSE);
+  InitializeListHead(&Thread->MutantListHead);
+  if (!First)
+    {
+      KernelStack = NULL;
+      
+      MmLockAddressSpace(MmGetKernelAddressSpace());
+      Status = MmCreateMemoryArea(NULL,
+                                 MmGetKernelAddressSpace(),
+                                 MEMORY_AREA_KERNEL_STACK,
+                                 &KernelStack,
+                                 MM_STACK_SIZE,
+                                 0,
+                                 &StackArea,
+                                 FALSE);
+      MmUnlockAddressSpace(MmGetKernelAddressSpace());
+      
+      if (!NT_SUCCESS(Status))
+       {
+         DPRINT1("Failed to create thread stack\n");
+         KeBugCheck(0);
+       }
+      for (i = 0; i < (MM_STACK_SIZE / PAGESIZE); i++)
+       {
+         PVOID Page;
+         Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
+         if (!NT_SUCCESS(Status))
+           {
+             KeBugCheck(0);
+           }
+         Status = MmCreateVirtualMapping(NULL,
+                                         KernelStack + (i * PAGESIZE),
+                                         PAGE_EXECUTE_READWRITE,
+                                         (ULONG)Page,
+                                         TRUE);
+       }
+      Thread->InitialStack = KernelStack + MM_STACK_SIZE;
+      Thread->StackBase = KernelStack + MM_STACK_SIZE;
+      Thread->StackLimit = (ULONG)KernelStack;
+      Thread->KernelStack = KernelStack + MM_STACK_SIZE;
+    }
+  else
+    {
+      Thread->InitialStack = (PVOID)&init_stack_top;
+      Thread->StackBase = (PVOID)&init_stack_top;
+      Thread->StackLimit = (ULONG)&init_stack;
+      Thread->KernelStack = (PVOID)&init_stack_top;
+    }
+  
+  /* 
+   * The Native API function will initialize the TEB field later 
+   */
+  Thread->Teb = NULL;
+  Thread->TlsArray = NULL;
+  Thread->DebugActive = 0;
+  Thread->State = THREAD_STATE_BLOCKED;
+  Thread->Alerted[0] = 0;
+  Thread->Alerted[1] = 0;
+  Thread->Iopl = 0;
+  /*
+   * FIXME: Think how this might work
+   */
+  Thread->NpxState = 0;
+  
+  Thread->Saturation = 0;
+  Thread->Priority = 0; 
+  InitializeListHead(&Thread->ApcState.ApcListHead[0]);
+  InitializeListHead(&Thread->ApcState.ApcListHead[1]);
+  Thread->ApcState.Process = Process;
+  Thread->ApcState.KernelApcInProgress = 0;
+  Thread->ApcState.KernelApcPending = 0;
+  Thread->ApcState.UserApcPending = 0;
+  Thread->ContextSwitches = 0;
+  Thread->WaitStatus = STATUS_SUCCESS;
+  Thread->WaitIrql = 0;
+  Thread->WaitMode = 0;
+  Thread->WaitNext = 0;
+  Thread->WaitBlockList = NULL;
+  Thread->WaitListEntry.Flink = NULL;
+  Thread->WaitListEntry.Blink = NULL;
+  Thread->WaitTime = 0;
+  Thread->BasePriority = 0; 
+  Thread->DecrementCount = 0;
+  Thread->PriorityDecrement = 0;
+  Thread->Quantum = 0;
+  memset(Thread->WaitBlock, 0, sizeof(KWAIT_BLOCK)*4);
+  Thread->LegoData = 0;
+  /*
+   * FIXME: Why this?
+   */
+  Thread->KernelApcDisable = 1;
+  Thread->UserAffinity = Process->Affinity;
+  Thread->SystemAffinityActive = 0;
+  Thread->Queue = NULL;
+  KeInitializeSpinLock(&Thread->ApcQueueLock);
+  memset(&Thread->Timer, 0, sizeof(KTIMER));
+  Thread->QueueListEntry.Flink = NULL;
+  Thread->QueueListEntry.Blink = NULL;
+  Thread->Affinity = Process->Affinity;
+  Thread->Preempted = 0;
+  Thread->ProcessReadyQueue = 0;
+  Thread->KernelStackResident = 1;
+  Thread->NextProcessor = 0;
+  Thread->CallbackStack = NULL;
+  Thread->Win32Thread = 0;
+  Thread->TrapFrame = NULL;
+  Thread->ApcStatePointer[0] = NULL;
+  Thread->ApcStatePointer[1] = NULL;
+  Thread->EnableStackSwap = 0;
+  Thread->LargeStack = 0;
+  Thread->ResourceIndex = 0;
+  Thread->PreviousMode = KernelMode;
+  Thread->KernelTime = 0;
+  Thread->UserTime = 0;
+  memset(&Thread->SavedApcState, 0, sizeof(KAPC_STATE));
+  Thread->Alertable = 1;
+  Thread->ApcStateIndex = 0;
+  Thread->ApcQueueable = 0;
+  Thread->AutoAlignment = 0;
+  KeInitializeApc(&Thread->SuspendApc,
+                 Thread,
+                 0,
+                 PiSuspendThreadKernelRoutine,
+                 PiSuspendThreadRundownRoutine,
+                 PiSuspendThreadNormalRoutine,
+                 KernelMode,
+                 NULL);
+  KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 255);
+  Thread->ThreadListEntry.Flink = NULL;
+  Thread->ThreadListEntry.Blink = NULL;
+  Thread->FreezeCount = 0;
+  Thread->SuspendCount = 0;
+  
+  /*
+   * Initialize ReactOS specific members
+   */
    Thread->ProcessThreadListEntry.Flink = NULL;
    Thread->ProcessThreadListEntry.Blink = NULL;
    KeInitializeDpc(&Thread->TimerDpc,
@@ -231,6 +243,5 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
    /*
     * Do x86 specific part
     */
-   
 }