static ULONG PriorityListMask = 0;
ULONG IdleProcessorMask = 0;
extern BOOLEAN DoneInitYet;
+extern PETHREAD PspReaperList;
/* FUNCTIONS *****************************************************************/
KiInsertIntoThreadList(KPRIORITY Priority,
PKTHREAD Thread)
{
- ASSERT(THREAD_STATE_READY == Thread->State);
+ ASSERT(Ready == Thread->State);
ASSERT(Thread->Priority == Priority);
if (Priority >= MAXIMUM_PRIORITY || Priority < LOW_PRIORITY) {
VOID
KiRemoveFromThreadList(PKTHREAD Thread)
{
- ASSERT(THREAD_STATE_READY == Thread->State);
+ ASSERT(Ready == Thread->State);
RemoveEntryList(&Thread->QueueListEntry);
if (IsListEmpty(&PriorityListHead[(ULONG)Thread->Priority])) {
current = CONTAINING_RECORD(current_entry, KTHREAD, QueueListEntry);
- if (current->State != THREAD_STATE_READY) {
+ if (current->State != Ready) {
DPRINT1("%d/%d\n", ¤t, current->State);
}
- ASSERT(current->State == THREAD_STATE_READY);
+ ASSERT(current->State == Ready);
if (current->Affinity & Affinity) {
CurrentThread->State = (UCHAR)NewThreadStatus;
- if (NewThreadStatus == THREAD_STATE_READY) {
+ if (NewThreadStatus == Ready) {
KiInsertIntoThreadList(CurrentThread->Priority,
CurrentThread);
if (Candidate == CurrentThread) {
- Candidate->State = THREAD_STATE_RUNNING;
+ Candidate->State = Running;
KeReleaseDispatcherDatabaseLockFromDpcLevel();
return;
}
DPRINT("Scheduling %x(%d)\n",Candidate, CurrentPriority);
- Candidate->State = THREAD_STATE_RUNNING;
+ Candidate->State = Running;
OldThread = CurrentThread;
CurrentThread = Candidate;
MmUpdatePageDir(PsGetCurrentProcess(),((PETHREAD)CurrentThread)->ThreadsProcess, sizeof(EPROCESS));
/* Special note for Filip: This will release the Dispatcher DB Lock ;-) -- Alex */
- KiArchContextSwitch(CurrentThread, OldThread);
+ DPRINT("You are : %x, swapping to: %x\n", OldThread, CurrentThread);
+ KiArchContextSwitch(CurrentThread);
+ DPRINT("You are : %x, swapped from: %x\n", OldThread, CurrentThread);
return;
}
}
/* Remove Waits */
WaitBlock = Thread->WaitBlockList;
- while (WaitBlock) {
+ do {
RemoveEntryList (&WaitBlock->WaitListEntry);
WaitBlock = WaitBlock->NextWaitBlock;
- }
+ } while (WaitBlock != Thread->WaitBlockList);
Thread->WaitBlockList = NULL;
/* Dispatch it and return status */
- KiDispatchThreadNoLock (THREAD_STATE_READY);
+ KiDispatchThreadNoLock (Ready);
if (Status != NULL) *Status = STATUS_KERNEL_APC;
} else {
/* Set the Thread Data as Requested */
- DPRINT("Dispatching Thread as blocked\n");
+ DPRINT("Dispatching Thread as blocked: %d\n", Thread->WaitStatus);
Thread->Alertable = Alertable;
Thread->WaitMode = (UCHAR)WaitMode;
Thread->WaitReason = WaitReason;
/* Dispatch it and return status */
- KiDispatchThreadNoLock(THREAD_STATE_BLOCKED);
+ KiDispatchThreadNoLock(Waiting);
+ DPRINT("Dispatching Thread as blocked: %d\n", Thread->WaitStatus);
if (Status != NULL) *Status = Thread->WaitStatus;
}
PNTSTATUS WaitStatus,
KPRIORITY Increment)
{
- if (THREAD_STATE_TERMINATED_1 == Thread->State ||
- THREAD_STATE_TERMINATED_2 == Thread->State) {
+ if (Terminated == Thread->State) {
- DPRINT("Can't unblock thread %d because it's terminating\n",
- Thread->Cid.UniqueThread);
+ DPRINT("Can't unblock thread 0x%x because it's terminating\n",
+ Thread);
- } else if (THREAD_STATE_READY == Thread->State ||
- THREAD_STATE_RUNNING == Thread->State) {
+ } else if (Ready == Thread->State ||
+ Running == Thread->State) {
- DPRINT("Can't unblock thread %d because it's ready or running\n",
- Thread->Cid.UniqueThread);
+ DPRINT("Can't unblock thread 0x%x because it's %s\n",
+ Thread, (Thread->State == Ready ? "ready" : "running"));
} else {
Thread->WaitStatus = *WaitStatus;
}
- Thread->State = THREAD_STATE_READY;
+ Thread->State = Ready;
KiInsertIntoThreadList(Thread->Priority, Thread);
Processor = KeGetCurrentProcessorNumber();
Affinity = Thread->Affinity;
PKTHREAD CurrentThread = KeGetCurrentThread();
/* Non-alertable kernel-mode suspended wait */
- DPRINT1("Waiting...\n");
+ DPRINT("Waiting...\n");
KeWaitForSingleObject(&CurrentThread->SuspendSemaphore,
Suspended,
KernelMode,
FALSE,
NULL);
- DPRINT1("Done Waiting\n");
+ DPRINT("Done Waiting\n");
+}
+
+#ifdef KeGetCurrentThread
+#undef KeGetCurrentThread
+#endif
+/*
+ * @implemented
+ */
+PKTHREAD
+STDCALL
+KeGetCurrentThread(VOID)
+{
+#ifdef CONFIG_SMP
+ ULONG Flags;
+ PKTHREAD Thread;
+ Ke386SaveFlags(Flags);
+ Ke386DisableInterrupts();
+ Thread = KeGetCurrentPrcb()->CurrentThread;
+ Ke386RestoreFlags(Flags);
+ return Thread;
+#else
+ return(KeGetCurrentPrcb()->CurrentThread);
+#endif
+}
+
+VOID
+STDCALL
+KeSetPreviousMode(ULONG Mode)
+{
+ PsGetCurrentThread()->Tcb.PreviousMode = (UCHAR)Mode;
+}
+
+/*
+ * @implemented
+ */
+KPROCESSOR_MODE
+STDCALL
+KeGetPreviousMode(VOID)
+{
+ return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
}
VOID
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
- CurrentEntry = Thread->MutantListHead.Flink;
- while (CurrentEntry != &Thread->MutantListHead) {
+ while (!IsListEmpty(&Thread->MutantListHead)) {
/* Get the Mutant */
+ CurrentEntry = RemoveHeadList(&Thread->MutantListHead);
Mutant = CONTAINING_RECORD(CurrentEntry, KMUTANT, MutantListEntry);
- ASSERT(Mutant->ApcDisable);
+ ASSERT(Mutant->ApcDisable == 0);
/* Uncondtionally abandon it */
DPRINT("Abandonning the Mutant\n");
ULONG PreviousCount;
KIRQL OldIrql;
- DPRINT1("KeResumeThread (Thread %p called). %x, %x\n", Thread, Thread->SuspendCount, Thread->FreezeCount);
+ DPRINT("KeResumeThread (Thread %p called). %x, %x\n", Thread, Thread->SuspendCount, Thread->FreezeCount);
/* Lock the Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
STDCALL
KiInsertQueueApc(PKAPC Apc,
KPRIORITY PriorityBoost);
-
+
+/*
+ * Used by the debugging code to freeze all the process's threads
+ * while the debugger is examining their state.
+ */
+VOID
+STDCALL
+KeFreezeAllThreads(PKPROCESS Process)
+{
+ KIRQL OldIrql;
+ PLIST_ENTRY CurrentEntry;
+ PKTHREAD Current;
+ PKTHREAD CurrentThread = KeGetCurrentThread();
+
+ /* Acquire Lock */
+ OldIrql = KeAcquireDispatcherDatabaseLock();
+
+ /* Loop the Process's Threads */
+ CurrentEntry = Process->ThreadListHead.Flink;
+ while (CurrentEntry != &Process->ThreadListHead)
+ {
+ /* Get the Thread */
+ Current = CONTAINING_RECORD(CurrentEntry, KTHREAD, ThreadListEntry);
+
+ /* Make sure it's not ours */
+ if (Current == CurrentThread) continue;
+
+ /* Make sure it wasn't already frozen, and that it's not suspended */
+ if (!(++Current->FreezeCount) && !(Current->SuspendCount))
+ {
+ /* Insert the APC */
+ if (!KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT))
+ {
+ /* Unsignal the Semaphore, the APC already got inserted */
+ Current->SuspendSemaphore.Header.SignalState--;
+ }
+ }
+
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
+ /* Release the lock */
+ KeReleaseDispatcherDatabaseLock(OldIrql);
+}
+
NTSTATUS
STDCALL
KeSuspendThread(PKTHREAD Thread)
ULONG PreviousCount;
KIRQL OldIrql;
- DPRINT1("KeSuspendThread (Thread %p called). %x, %x\n", Thread, Thread->SuspendCount, Thread->FreezeCount);
+ DPRINT("KeSuspendThread (Thread %p called). %x, %x\n", Thread, Thread->SuspendCount, Thread->FreezeCount);
/* Lock the Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
if (Thread->Alerted[KernelMode] == FALSE) {
/* If it's Blocked, unblock if it we should */
- if (Thread->State == THREAD_STATE_BLOCKED && Thread->Alertable) {
+ if (Thread->State == Waiting && Thread->Alertable) {
DPRINT("Aborting Wait\n");
KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT);
if (PreviousState == FALSE) {
/* If it's Blocked, unblock if it we should */
- if (Thread->State == THREAD_STATE_BLOCKED &&
+ if (Thread->State == Waiting &&
(AlertMode == KernelMode || Thread->WaitMode == AlertMode) &&
Thread->Alertable) {
STDCALL
KeInitializeThread(PKPROCESS Process,
PKTHREAD Thread,
- BOOLEAN First)
-{
- PVOID KernelStack;
- NTSTATUS Status;
- extern unsigned int init_stack_top;
- extern unsigned int init_stack;
- PMEMORY_AREA StackArea;
- ULONG i;
- PHYSICAL_ADDRESS BoundaryAddressMultiple;
-
- /* Initialize the Boundary Address */
- BoundaryAddressMultiple.QuadPart = 0;
-
+ PKSYSTEM_ROUTINE SystemRoutine,
+ PKSTART_ROUTINE StartRoutine,
+ PVOID StartContext,
+ PCONTEXT Context,
+ PVOID Teb,
+ PVOID KernelStack)
+{
/* Initalize the Dispatcher Header */
+ DPRINT("Initializing Dispatcher Header for New Thread: %x in Process: %x\n", Thread, Process);
KeInitializeDispatcherHeader(&Thread->DispatcherHeader,
ThreadObject,
sizeof(KTHREAD),
FALSE);
- InitializeListHead(&Thread->MutantListHead);
- /* If this is isn't the first thread, allocate the Kernel Stack */
- if (!First) {
-
- PFN_TYPE Page[MM_STACK_SIZE / PAGE_SIZE];
- KernelStack = NULL;
-
- MmLockAddressSpace(MmGetKernelAddressSpace());
- Status = MmCreateMemoryArea(NULL,
- MmGetKernelAddressSpace(),
- MEMORY_AREA_KERNEL_STACK,
- &KernelStack,
- MM_STACK_SIZE,
- 0,
- &StackArea,
- FALSE,
- FALSE,
- BoundaryAddressMultiple);
- MmUnlockAddressSpace(MmGetKernelAddressSpace());
-
- /* Check for Success */
- if (!NT_SUCCESS(Status)) {
-
- DPRINT1("Failed to create thread stack\n");
- KEBUGCHECK(0);
- }
-
- /* Mark the Stack */
- for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++) {
-
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page[i]);
-
- /* Check for success */
- if (!NT_SUCCESS(Status)) {
-
- KEBUGCHECK(0);
- }
- }
-
- /* Create a Virtual Mapping for it */
- Status = MmCreateVirtualMapping(NULL,
- KernelStack,
- PAGE_READWRITE,
- Page,
- MM_STACK_SIZE / PAGE_SIZE);
-
- /* Check for success */
- if (!NT_SUCCESS(Status)) {
-
- KEBUGCHECK(0);
- }
-
- /* Set the Kernel Stack */
- Thread->InitialStack = (PCHAR)KernelStack + MM_STACK_SIZE;
- Thread->StackBase = (PCHAR)KernelStack + MM_STACK_SIZE;
- Thread->StackLimit = (ULONG_PTR)KernelStack;
- Thread->KernelStack = (PCHAR)KernelStack + MM_STACK_SIZE;
-
- } else {
-
- /* Use the Initial Stack */
- Thread->InitialStack = (PCHAR)init_stack_top;
- Thread->StackBase = (PCHAR)init_stack_top;
- Thread->StackLimit = (ULONG_PTR)init_stack;
- Thread->KernelStack = (PCHAR)init_stack_top;
- }
-
- /*
- * Establish the pde's for the new stack and the thread structure within the
- * address space of the new process. They are accessed while taskswitching or
- * while handling page faults. At this point it isn't possible to call the
- * page fault handler for the missing pde's.
- */
- MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
- MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
-
- /* Set the Thread to initalized */
- Thread->State = THREAD_STATE_INITIALIZED;
-
- /* The Native API function will initialize the TEB field later */
- Thread->Teb = NULL;
+ DPRINT("Thread Header Created. SystemRoutine: %x, StartRoutine: %x with Context: %x\n",
+ SystemRoutine, StartRoutine, StartContext);
+ DPRINT("UserMode Information. Context: %x, Teb: %x\n", Context, Teb);
+
+ /* Initialize the Mutant List */
+ InitializeListHead(&Thread->MutantListHead);
- /* Initialize stuff to zero */
- Thread->TlsArray = NULL;
- Thread->DebugActive = 0;
- Thread->Alerted[0] = 0;
- Thread->Alerted[1] = 0;
- Thread->Iopl = 0;
+ /* Setup the Service Descriptor Table for Native Calls */
+ Thread->ServiceTable = KeServiceDescriptorTable;
- /* Set up FPU/NPX Stuff */
- Thread->NpxState = NPX_STATE_INVALID;
- Thread->NpxIrql = 0;
-
/* Setup APC Fields */
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->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStateIndex = OriginalApcEnvironment;
- Thread->ApcQueueable = TRUE;
- RtlZeroMemory(&Thread->SavedApcState, sizeof(KAPC_STATE));
KeInitializeSpinLock(&Thread->ApcQueueLock);
- /* Setup Wait Fields */
- Thread->WaitStatus = STATUS_SUCCESS;
- Thread->WaitIrql = PASSIVE_LEVEL;
- Thread->WaitMode = 0;
- Thread->WaitNext = FALSE;
- Thread->WaitListEntry.Flink = NULL;
- Thread->WaitListEntry.Blink = NULL;
- Thread->WaitTime = 0;
- Thread->WaitBlockList = NULL;
- RtlZeroMemory(Thread->WaitBlock, sizeof(KWAIT_BLOCK) * 4);
- RtlZeroMemory(&Thread->Timer, sizeof(KTIMER));
- KeInitializeTimer(&Thread->Timer);
-
- /* Setup scheduler Fields */
- Thread->BasePriority = Process->BasePriority;
- Thread->DecrementCount = 0;
- Thread->PriorityDecrement = 0;
- Thread->Quantum = Process->ThreadQuantum;
- Thread->Saturation = 0;
- Thread->Priority = Process->BasePriority;
- Thread->UserAffinity = Process->Affinity;
- Thread->SystemAffinityActive = 0;
- Thread->Affinity = Process->Affinity;
- Thread->Preempted = 0;
- Thread->ProcessReadyQueue = 0;
- Thread->KernelStackResident = 1;
- Thread->NextProcessor = 0;
- Thread->ContextSwitches = 0;
-
- /* Setup Queue Fields */
- Thread->Queue = NULL;
- Thread->QueueListEntry.Flink = NULL;
- Thread->QueueListEntry.Blink = NULL;
-
- /* Setup Misc Fields */
- Thread->LegoData = 0;
- Thread->PowerState = 0;
- Thread->ServiceTable = KeServiceDescriptorTable;
- Thread->CallbackStack = NULL;
- Thread->Win32Thread = NULL;
- Thread->TrapFrame = NULL;
- Thread->EnableStackSwap = 0;
- Thread->LargeStack = 0;
- Thread->ResourceIndex = 0;
- Thread->PreviousMode = KernelMode;
- Thread->KernelTime = 0;
- Thread->UserTime = 0;
- Thread->AutoAlignment = Process->AutoAlignment;
-
- /* FIXME OPTIMIZATION OF DOOM. DO NOT ENABLE FIXME */
-#if 0
- Thread->WaitBlock[3].Object = (PVOID)&Thread->Timer;
- Thread->WaitBlock[3].Thread = Thread;
- Thread->WaitBlock[3].WaitKey = STATUS_TIMEOUT;
- Thread->WaitBlock[3].WaitType = WaitAny;
- Thread->WaitBlock[3].NextWaitBlock = NULL;
- InsertTailList(&Thread->Timer.Header.WaitListHead,
- &Thread->WaitBlock[3].WaitListEntry);
-#endif
-
/* Initialize the Suspend APC */
KeInitializeApc(&Thread->SuspendApc,
Thread,
NULL);
/* Initialize the Suspend Semaphore */
- KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128);
+ KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128);
+
+ /* FIXME OPTIMIZATION OF DOOM. DO NOT ENABLE FIXME */
+#if 0
+ Thread->WaitBlock[3].Object = (PVOID)&Thread->Timer;
+ Thread->WaitBlock[3].Thread = Thread;
+ Thread->WaitBlock[3].WaitKey = STATUS_TIMEOUT;
+ Thread->WaitBlock[3].WaitType = WaitAny;
+ Thread->WaitBlock[3].NextWaitBlock = NULL;
+ InsertTailList(&Thread->Timer.Header.WaitListHead,
+ &Thread->WaitBlock[3].WaitListEntry);
+#endif
+ KeInitializeTimer(&Thread->Timer);
+
+ /* Set the TEB */
+ Thread->Teb = Teb;
+
+ /* Set the Thread Stacks */
+ Thread->InitialStack = (PCHAR)KernelStack + MM_STACK_SIZE;
+ Thread->StackBase = (PCHAR)KernelStack + MM_STACK_SIZE;
+ Thread->StackLimit = (ULONG_PTR)KernelStack;
+ Thread->KernelStackResident = TRUE;
- /* Insert the Thread into the Process's Thread List */
+ /*
+ * Establish the pde's for the new stack and the thread structure within the
+ * address space of the new process. They are accessed while taskswitching or
+ * while handling page faults. At this point it isn't possible to call the
+ * page fault handler for the missing pde's.
+ */
+ MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
+ MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
+
+ /* Initalize the Thread Context */
+ DPRINT("Initializing the Context for the thread: %x\n", Thread);
+ KiArchInitThreadWithContext(Thread,
+ SystemRoutine,
+ StartRoutine,
+ StartContext,
+ Context);
+
+ /* Setup scheduler Fields based on Parent */
+ DPRINT("Thread context created, setting Scheduler Data\n");
+ Thread->BasePriority = Process->BasePriority;
+ Thread->Quantum = Process->ThreadQuantum;
+ Thread->Affinity = Process->Affinity;
+ Thread->Priority = Process->BasePriority;
+ Thread->UserAffinity = Process->Affinity;
+ Thread->DisableBoost = Process->DisableBoost;
+ Thread->AutoAlignment = Process->AutoAlignment;
+ Thread->Iopl = Process->Iopl;
+
+ /* Set the Thread to initalized */
+ Thread->State = Initialized;
+
+ /*
+ * Insert the Thread into the Process's Thread List
+ * Note, this is the KTHREAD Thread List. It is removed in
+ * ke/kthread.c!KeTerminateThread.
+ */
InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
-
- /* Set up the Suspend Counts */
- Thread->FreezeCount = 0;
- Thread->SuspendCount = 0;
-
- /* Do x86 specific part */
+ DPRINT("Thread initalized\n");
}
+
/*
* @implemented
*/
return Thread->KernelTime;
}
-VOID
-KeFreeStackPage(PVOID Context,
- MEMORY_AREA* MemoryArea,
- PVOID Address,
- PFN_TYPE Page,
- SWAPENTRY SwapEntry,
- BOOLEAN Dirty)
-{
- ASSERT(SwapEntry == 0);
- if (Page) MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
-}
-
-NTSTATUS
-KeReleaseThread(PKTHREAD Thread)
-/*
- * FUNCTION: Releases the resource allocated for a thread by
- * KeInitializeThread
- * NOTE: The thread had better not be running when this is called
- */
-{
- extern unsigned int init_stack;
-
- /* FIXME - lock the process */
- RemoveEntryList(&Thread->ThreadListEntry);
-
- if (Thread->StackLimit != (ULONG_PTR)init_stack)
- {
- MmLockAddressSpace(MmGetKernelAddressSpace());
- MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
- (PVOID)Thread->StackLimit,
- KeFreeStackPage,
- NULL);
- MmUnlockAddressSpace(MmGetKernelAddressSpace());
- }
- Thread->StackLimit = 0;
- Thread->InitialStack = NULL;
- Thread->StackBase = NULL;
- Thread->KernelStack = NULL;
- return(STATUS_SUCCESS);
-}
-
/*
* @implemented
*/
/* We need to dispatch a new thread */
CurrentThread->WaitIrql = OldIrql;
- KiDispatchThreadNoLock(THREAD_STATE_READY);
+ KiDispatchThreadNoLock(Ready);
KeLowerIrql(OldIrql);
}
}
/* We need to dispatch a new thread */
CurrentThread->WaitIrql = OldIrql;
- KiDispatchThreadNoLock(THREAD_STATE_READY);
+ KiDispatchThreadNoLock(Ready);
KeLowerIrql(OldIrql);
}
}
CurrentThread = KeGetCurrentThread();
- if (Thread->State == THREAD_STATE_READY) {
+ if (Thread->State == Ready) {
KiRemoveFromThreadList(Thread);
Thread->BasePriority = Thread->Priority = (CHAR)Priority;
if (CurrentThread->Priority < Priority) {
- KiDispatchThreadNoLock(THREAD_STATE_READY);
+ KiDispatchThreadNoLock(Ready);
KeLowerIrql(OldIrql);
return (OldPriority);
}
- } else if (Thread->State == THREAD_STATE_RUNNING) {
+ } else if (Thread->State == Running) {
Thread->BasePriority = Thread->Priority = (CHAR)Priority;
if (Thread == CurrentThread) {
- KiDispatchThreadNoLock(THREAD_STATE_READY);
+ KiDispatchThreadNoLock(Ready);
KeLowerIrql(OldIrql);
return (OldPriority);
Thread->Affinity = Affinity;
- if (Thread->State == THREAD_STATE_RUNNING) {
+ if (Thread->State == Running) {
ProcessorMask = 1 << KeGetCurrentKPCR()->ProcessorNumber;
if (Thread == KeGetCurrentThread()) {
if (!(Affinity & ProcessorMask)) {
- KiDispatchThreadNoLock(THREAD_STATE_READY);
+ KiDispatchThreadNoLock(Ready);
KeLowerIrql(OldIrql);
return STATUS_SUCCESS;
}
PKTHREAD Thread = KeGetCurrentThread();
/* Lock the Dispatcher Database and the APC Queue */
- DPRINT1("Terminating\n");
+ DPRINT("Terminating\n");
OldIrql = KeAcquireDispatcherDatabaseLock();
+
+ /* Remove the thread from the list */
+ RemoveEntryList(&Thread->ThreadListEntry);
/* Insert into the Reaper List */
- InsertTailList(&PspReaperListHead, &((PETHREAD)Thread)->TerminationPortList);
+ DPRINT("List: %p\n", PspReaperList);
+ ((PETHREAD)Thread)->ReaperLink = PspReaperList;
+ PspReaperList = (PETHREAD)Thread;
+ DPRINT("List: %p\n", PspReaperList);
/* Check if it's active */
if (PspReaping == FALSE) {
/* Activate it. We use the internal function for speed, and use the Hyper Critical Queue */
PspReaping = TRUE;
- DPRINT1("Terminating\n");
+ DPRINT("Terminating\n");
KiInsertQueue(&ExWorkerQueue[HyperCriticalWorkQueue].WorkerQueue,
&PspReaperWorkItem.List,
FALSE);
/* Handle Kernel Queues */
if (Thread->Queue) {
- DPRINT1("Waking Queue\n");
+ DPRINT("Waking Queue\n");
RemoveEntryList(&Thread->QueueListEntry);
KiWakeQueue(Thread->Queue);
}
}
/* Find a new Thread */
- KiDispatchThreadNoLock(THREAD_STATE_TERMINATED_1);
+ KiDispatchThreadNoLock(Terminated);
}
/*