Alex Ionescu <ionucu(a)videotron.ca>
- Removed ke/alert.c and moved its functions where they belong.
- Commented and organized KeInitializeThread.
- Began switch to true KOBJECT enumeration used in NT.
- Implemented KeAlertResumeThread and NtAlertResumeThread.
- Harmonized Formatting in ke/kthread.c
Modified: trunk/reactos/drivers/storage/floppy/floppy.c
Modified: trunk/reactos/include/ddk/ketypes.h
Modified: trunk/reactos/ntoskrnl/Makefile
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
Deleted: trunk/reactos/ntoskrnl/ke/alert.c
Modified: trunk/reactos/ntoskrnl/ke/apc.c
Modified: trunk/reactos/ntoskrnl/ke/dpc.c
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
Modified: trunk/reactos/ntoskrnl/ke/wait.c
Modified: trunk/reactos/ntoskrnl/ps/thread.c
_____
Modified: trunk/reactos/drivers/storage/floppy/floppy.c
--- trunk/reactos/drivers/storage/floppy/floppy.c 2005-03-12
19:22:30 UTC (rev 13973)
+++ trunk/reactos/drivers/storage/floppy/floppy.c 2005-03-12
19:23:04 UTC (rev 13974)
@@ -58,7 +58,7 @@
/* Queue thread management */
static KEVENT QueueThreadTerminate;
-static PVOID ThreadObject;
+static PVOID QueueThreadObject;
static VOID NTAPI MotorStopDpcFunc(PKDPC UnusedDpc,
@@ -378,8 +378,8 @@
KdPrint(("floppy: unloading\n"));
KeSetEvent(&QueueThreadTerminate, 0, FALSE);
- KeWaitForSingleObject(ThreadObject, Executive, KernelMode, FALSE, 0);
- ObDereferenceObject(ThreadObject);
+ KeWaitForSingleObject(QueueThreadObject, Executive, KernelMode,
FALSE, 0);
+ ObDereferenceObject(QueueThreadObject);
for(i = 0; i < gNumberOfControllers; i++)
{
@@ -1152,7 +1152,7 @@
return STATUS_INSUFFICIENT_RESOURCES;
}
- if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, NULL,
KernelMode, &ThreadObject, NULL) != STATUS_SUCCESS)
+ if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, NULL,
KernelMode, &QueueThreadObject, NULL) != STATUS_SUCCESS)
{
KdPrint(("floppy: Unable to reference returned thread handle;
failing init\n"));
return STATUS_UNSUCCESSFUL;
_____
Modified: trunk/reactos/include/ddk/ketypes.h
--- trunk/reactos/include/ddk/ketypes.h 2005-03-12 19:22:30 UTC (rev
13973)
+++ trunk/reactos/include/ddk/ketypes.h 2005-03-12 19:23:04 UTC (rev
13974)
@@ -36,23 +36,34 @@
struct _DISPATCHER_HEADER;
-typedef enum _KERNEL_OBJECTS {
- KNotificationEvent = 0,
- KSynchronizationEvent = 1,
- KMutant = 2,
- KProcess = 3,
- KQueue = 4,
- KSemaphore = 5,
- KThread = 6,
- KNotificationTimer = 8,
- KSynchronizationTimer = 9,
- KApc = 18,
- KDpc = 19,
- KDeviceQueue = 20,
- KEventPair = 21,
- KInterrupt = 22,
- KProfile = 23
-} KERNEL_OBJECTS;
+typedef enum _KOBJECTS {
+ EventNotificationObject = 0,
+ EventSynchronizationObject = 1,
+ MutantObject = 2,
+ ProcessObject = 3,
+ QueueObject = 4,
+ SemaphoreObject = 5,
+ ThreadObject = 6,
+ GateObject = 7,
+ TimerNotificationObject = 8,
+ TimerSynchronizationObject = 9,
+ Spare2Object = 10,
+ Spare3Object = 11,
+ Spare4Object = 12,
+ Spare5Object = 13,
+ Spare6Object = 14,
+ Spare7Object = 15,
+ Spare8Object = 16,
+ Spare9Object = 17,
+ ApcObject = 18,
+ DpcObject = 19,
+ DeviceQueueObject = 20,
+ EventPairObject = 21,
+ InterruptObject = 22,
+ ProfileObject = 23,
+ ThreadedDpcObject = 24,
+ MaximumKernelObject = 25
+} KOBJECTS;
#include <pshpack1.h>
_____
Modified: trunk/reactos/ntoskrnl/Makefile
--- trunk/reactos/ntoskrnl/Makefile 2005-03-12 19:22:30 UTC (rev
13973)
+++ trunk/reactos/ntoskrnl/Makefile 2005-03-12 19:23:04 UTC (rev
13974)
@@ -113,8 +113,7 @@
ke/sem.o \
ke/spinlock.o \
ke/timer.o \
- ke/wait.o \
- ke/alert.o
+ ke/wait.o
# Memory Manager (Mm)
OBJECTS_MM = \
_____
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
--- trunk/reactos/ntoskrnl/include/internal/ps.h 2005-03-12
19:22:30 UTC (rev 13973)
+++ trunk/reactos/ntoskrnl/include/internal/ps.h 2005-03-12
19:23:04 UTC (rev 13974)
@@ -498,7 +498,7 @@
#define PROCESS_PRIO_RT 18
-VOID
+VOID STDCALL
KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First);
NTSTATUS KeReleaseThread(PKTHREAD Thread);
_____
Deleted: trunk/reactos/ntoskrnl/ke/alert.c
--- trunk/reactos/ntoskrnl/ke/alert.c 2005-03-12 19:22:30 UTC (rev
13973)
+++ trunk/reactos/ntoskrnl/ke/alert.c 2005-03-12 19:23:04 UTC (rev
13974)
@@ -1,150 +0,0 @@
-/* $Id:$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/ke/alert.c
- * PURPOSE: Alerts
- *
- * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net)
- */
-
-/* INCLUDES
*****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* GLOBALS
*******************************************************************/
-
-
-/* FUNCTIONS
*****************************************************************/
-
-
-BOOLEAN
-STDCALL
-KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
-/*
- * FUNCTION: Tests whether there are any pending APCs for the current
thread
- * and if so the APCs will be delivered on exit from kernel mode
- */
-{
- KIRQL OldIrql;
- PKTHREAD Thread = KeGetCurrentThread();
- BOOLEAN OldState;
-
- ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
-
- OldIrql = KeAcquireDispatcherDatabaseLock();
- KiAcquireSpinLock(&Thread->ApcQueueLock);
-
- OldState = Thread->Alerted[AlertMode];
-
- /* If the Thread is Alerted, Clear it */
- if (OldState) {
- Thread->Alerted[AlertMode] = FALSE;
- } else if ((AlertMode == UserMode) &&
(!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) {
- /* If the mode is User and the Queue isn't empty, set Pending */
- Thread->ApcState.UserApcPending = TRUE;
- }
-
- KiReleaseSpinLock(&Thread->ApcQueueLock);
- KeReleaseDispatcherDatabaseLock(OldIrql);
- return OldState;
-}
-
-
-VOID
-KeAlertThread(PKTHREAD Thread, KPROCESSOR_MODE AlertMode)
-{
- KIRQL oldIrql;
-
-
- oldIrql = KeAcquireDispatcherDatabaseLock();
-
-
- /* Return if thread is already alerted. */
- if (Thread->Alerted[AlertMode] == FALSE)
- {
- if (Thread->State == THREAD_STATE_BLOCKED &&
- (AlertMode == KernelMode || Thread->WaitMode == AlertMode) &&
- Thread->Alertable)
- {
- KiAbortWaitThread(Thread, STATUS_ALERTED);
- }
- else
- {
- Thread->Alerted[AlertMode] = TRUE;
- }
- }
-
- KeReleaseDispatcherDatabaseLock(oldIrql);
-
-}
-
-
-/*
- *
- * NOT EXPORTED
- */
-NTSTATUS STDCALL
-NtAlertResumeThread(IN HANDLE ThreadHandle,
- OUT PULONG SuspendCount)
-{
- UNIMPLEMENTED;
- return(STATUS_NOT_IMPLEMENTED);
-
-}
-
-/*
- * @implemented
- *
- * EXPORTED
- */
-NTSTATUS STDCALL
-NtAlertThread (IN HANDLE ThreadHandle)
-{
- KPROCESSOR_MODE PreviousMode;
- PETHREAD Thread;
- NTSTATUS Status;
-
- PreviousMode = ExGetPreviousMode();
-
- Status = ObReferenceObjectByHandle(ThreadHandle,
- THREAD_SUSPEND_RESUME,
- PsThreadType,
- PreviousMode,
- (PVOID*)&Thread,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-
- /* do an alert depending on the processor mode. If some kmode code
wants to
- enforce a umode alert it should call KeAlertThread() directly. If
kmode
- code wants to do a kmode alert it's sufficient to call it with Zw
or just
- use KeAlertThread() directly */
-
- KeAlertThread(&Thread->Tcb, PreviousMode);
-
- ObDereferenceObject(Thread);
- return(STATUS_SUCCESS);
-}
-
-
-/*
- * NOT EXPORTED
- */
-NTSTATUS
-STDCALL
-NtTestAlert(VOID)
-{
- KPROCESSOR_MODE PreviousMode;
-
- PreviousMode = ExGetPreviousMode();
-
- /* Check and Alert Thread if needed */
-
- return KeTestAlertThread(PreviousMode) ? STATUS_ALERTED :
STATUS_SUCCESS;
-}
-
_____
Modified: trunk/reactos/ntoskrnl/ke/apc.c
--- trunk/reactos/ntoskrnl/ke/apc.c 2005-03-12 19:22:30 UTC (rev
13973)
+++ trunk/reactos/ntoskrnl/ke/apc.c 2005-03-12 19:23:04 UTC (rev
13974)
@@ -58,7 +58,7 @@
/* Set up the basic APC Structure Data */
RtlZeroMemory(Apc, sizeof(KAPC));
- Apc->Type = KApc;
+ Apc->Type = ApcObject;
Apc->Size = sizeof(KAPC);
/* Set the Environment */
_____
Modified: trunk/reactos/ntoskrnl/ke/dpc.c
--- trunk/reactos/ntoskrnl/ke/dpc.c 2005-03-12 19:22:30 UTC (rev
13973)
+++ trunk/reactos/ntoskrnl/ke/dpc.c 2005-03-12 19:23:04 UTC (rev
13974)
@@ -88,7 +88,7 @@
*/
{
DPRINT("DPC Initializing: %x with Routine: %x\n", Dpc,
DeferredRoutine);
- Dpc->Type = KDpc;
+ Dpc->Type = DpcObject;
Dpc->Number= 0;
Dpc->Importance= MediumImportance;
Dpc->DeferredRoutine = DeferredRoutine;
_____
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
--- trunk/reactos/ntoskrnl/ke/kthread.c 2005-03-12 19:22:30 UTC (rev
13973)
+++ trunk/reactos/ntoskrnl/ke/kthread.c 2005-03-12 19:23:04 UTC (rev
13974)
@@ -1,11 +1,11 @@
-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Microkernel thread support
*
- * PROGRAMMERS: David Welch (welch(a)cwcom.net)
+ * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net) - Commented,
reorganized some stuff, fixed/implemented some functions.
+ * David Welch (welch(a)cwcom.net)
*/
/* INCLUDES
*****************************************************************/
@@ -16,19 +16,93 @@
/* FUNCTIONS
*****************************************************************/
-VOID
-KiServiceCheck (VOID)
+ULONG
+STDCALL
+KeAlertResumeThread(IN PKTHREAD Thread)
{
- PETHREAD Thread;
+ ULONG PreviousCount;
+ KIRQL OldIrql;
- Thread = PsGetCurrentThread();
+ ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+
+ /* Lock the Dispatcher Database and the APC Queue */
+ OldIrql = KeAcquireDispatcherDatabaseLock();
+ KiAcquireSpinLock(&Thread->ApcQueueLock);
- if (Thread->Tcb.ServiceTable != KeServiceDescriptorTableShadow)
- {
- PsInitWin32Thread (Thread);
+ /* Return if Thread is already alerted. */
+ if (Thread->Alerted[KernelMode] == FALSE) {
+
+ /* If it's Blocked, unblock if it we should */
+ if (Thread->State == THREAD_STATE_BLOCKED &&
Thread->Alertable) {
+
+ DPRINT("Aborting Wait\n");
+ KiAbortWaitThread(Thread, STATUS_ALERTED);
+
+ } else {
+
+ /* If not, simply Alert it */
+ Thread->Alerted[KernelMode] = TRUE;
+ }
+ }
+
+ /* Save the old Suspend Count */
+ PreviousCount = Thread->SuspendCount;
+
+ /* If the thread is suspended, decrease one of the suspend counts
*/
+ if (PreviousCount) {
+
+ /* Decrease count. If we are now zero, unwait it completely */
+ if (--Thread->SuspendCount) {
+
+ /* Signal and satisfy */
+ Thread->SuspendSemaphore.Header.SignalState++;
+ KiDispatcherObjectWake(&Thread->SuspendSemaphore.Header,
IO_NO_INCREMENT);
+ }
+ }
- Thread->Tcb.ServiceTable = KeServiceDescriptorTableShadow;
+ /* Release Locks and return the Old State */
+ KiReleaseSpinLock(&Thread->ApcQueueLock);
+ KeReleaseDispatcherDatabaseLock(OldIrql);
+ return PreviousCount;
+}
+
+BOOLEAN
+STDCALL
+KeAlertThread(PKTHREAD Thread,
+ KPROCESSOR_MODE AlertMode)
+{
+ KIRQL OldIrql;
+ BOOLEAN PreviousState;
+
+ /* Acquire the Dispatcher Database Lock */
+ OldIrql = KeAcquireDispatcherDatabaseLock();
+
+ /* Save the Previous State */
+ PreviousState = Thread->Alerted[AlertMode];
+
+ /* Return if Thread is already alerted. */
+ if (PreviousState == FALSE) {
+
+ /* If it's Blocked, unblock if it we should */
+ if (Thread->State == THREAD_STATE_BLOCKED &&
+ (AlertMode == KernelMode || Thread->WaitMode == AlertMode)
&&
+ Thread->Alertable) {
+
+ DPRINT("Aborting Wait\n");
+ KiAbortWaitThread(Thread, STATUS_ALERTED);
+
+ } else {
+
+ /* If not, simply Alert it */
+ Thread->Alerted[AlertMode] = TRUE;
+ }
}
+
+ /* Release the Dispatcher Lock */
+ KeReleaseDispatcherDatabaseLock(OldIrql);
+
+ /* Return the old state */
+ return PreviousState;
}
/*
@@ -36,28 +110,231 @@
*/
VOID
STDCALL
-KeCapturePersistentThreadState(
- IN PVOID CurrentThread,
- IN ULONG Setting1,
- IN ULONG Setting2,
- IN ULONG Setting3,
- IN ULONG Setting4,
- IN ULONG Setting5,
- IN PVOID ThreadState
-)
+KeCapturePersistentThreadState(IN PVOID CurrentThread,
+ IN ULONG Setting1,
+ IN ULONG Setting2,
+ IN ULONG Setting3,
+ IN ULONG Setting4,
+ IN ULONG Setting5,
+ IN PVOID ThreadState)
{
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
}
+/*
+ * FUNCTION: Initialize the microkernel state of the thread
+ */
VOID
-KeFreeStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
- PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
+STDCALL
+KeInitializeThread(PKPROCESS Process,
+ PKTHREAD Thread,
+ BOOLEAN First)
{
- ASSERT(SwapEntry == 0);
- if (Page != 0)
- {
- MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
+ 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;
+
+ /* Initalize the Dispatcher Header */
+ 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;
+
+ /* Initialize stuff to zero */
+ Thread->TlsArray = NULL;
+ Thread->DebugActive = 0;
+ Thread->Alerted[0] = 0;
+ Thread->Alerted[1] = 0;
+ Thread->Iopl = 0;
+
+ /* 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,
+ OriginalApcEnvironment,
+ PiSuspendThreadKernelRoutine,
+ PiSuspendThreadRundownRoutine,
+ PiSuspendThreadNormalRoutine,
+ KernelMode,
+ NULL);
+
+ /* Initialize the Suspend Semaphore */
+ KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128);
+
+ /* Insert the Thread into the Process's Thread List */
+ InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
+
+ /* Set up the Suspend Counts */
+ Thread->FreezeCount = 0;
+ Thread->SuspendCount = 0;
+
+ /* Do x86 specific part */
}
/*
@@ -65,11 +342,9 @@
*/
KPRIORITY
STDCALL
-KeQueryPriorityThread (
- IN PKTHREAD Thread
- )
+KeQueryPriorityThread (IN PKTHREAD Thread)
{
- return Thread->Priority;
+ return Thread->Priority;
}
/*
@@ -77,19 +352,29 @@
*/
ULONG
STDCALL
-KeQueryRuntimeThread(
- IN PKTHREAD Thread,
- OUT PULONG UserTime
- )
+KeQueryRuntimeThread(IN PKTHREAD Thread,
+ OUT PULONG UserTime)
{
- /* Return the User Time */
- *UserTime = Thread->UserTime;
-
- /* Return the Kernel Time */
- return Thread->KernelTime;
+ /* Return the User Time */
+ *UserTime = Thread->UserTime;
+
+ /* Return the Kernel Time */
+ return Thread->KernelTime;
}
-NTSTATUS
+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
@@ -123,195 +408,26 @@
*/
BOOLEAN
STDCALL
-KeSetKernelStackSwapEnable(
- IN BOOLEAN Enable
- )
+KeSetKernelStackSwapEnable(IN BOOLEAN Enable)
{
- PKTHREAD Thread;
- BOOLEAN PreviousState;
-
- Thread = KeGetCurrentThread();
-
- /* Save Old State */
- PreviousState = Thread->EnableStackSwap;
-
- /* Set New State */
- Thread->EnableStackSwap = Enable;
+ PKTHREAD Thread = KeGetCurrentThread();
+ BOOLEAN PreviousState;
+ KIRQL OldIrql;
+
+ /* Lock the Dispatcher Database */
+ OldIrql = KeAcquireDispatcherDatabaseLock();
- /* Return Old State */
- return PreviousState;
-}
+ /* Save Old State */
+ PreviousState = Thread->EnableStackSwap;
-VOID
-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;
- PHYSICAL_ADDRESS BoundaryAddressMultiple;
-
- BoundaryAddressMultiple.QuadPart = 0;
-
- KeInitializeDispatcherHeader(&Thread->DispatcherHeader,
- InternalThreadType,
- sizeof(ETHREAD),
- FALSE);
- InitializeListHead(&Thread->MutantListHead);
- 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());
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create thread stack\n");
- KEBUGCHECK(0);
- }
- for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++)
- {
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE,
&Page[i]);
- if (!NT_SUCCESS(Status))
- {
- KEBUGCHECK(0);
- }
- }
- Status = MmCreateVirtualMapping(NULL,
- KernelStack,
- PAGE_READWRITE,
- Page,
- MM_STACK_SIZE / PAGE_SIZE);
- if (!NT_SUCCESS(Status))
- {
- KEBUGCHECK(0);
- }
- 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
- {
- Thread->InitialStack = (PCHAR)init_stack_top;
- Thread->StackBase = (PCHAR)init_stack_top;
- Thread->StackLimit = (ULONG_PTR)init_stack;
- Thread->KernelStack = (PCHAR)init_stack_top;
- }
+ /* Set New State */
+ Thread->EnableStackSwap = Enable;
- /*
- * 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));
-
- /*
- * The Native API function will initialize the TEB field later
- */
- Thread->Teb = NULL;
- Thread->TlsArray = NULL;
- Thread->DebugActive = 0;
- Thread->State = THREAD_STATE_INITIALIZED;
- Thread->Alerted[0] = 0;
- Thread->Alerted[1] = 0;
- Thread->Iopl = 0;
- Thread->NpxState = NPX_STATE_INVALID;
-
- Thread->Saturation = 0;
- Thread->Priority = Process->BasePriority;
- 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 = PASSIVE_LEVEL;
- Thread->WaitMode = 0;
- Thread->WaitNext = FALSE;
- Thread->WaitBlockList = NULL;
- Thread->WaitListEntry.Flink = NULL;
- Thread->WaitListEntry.Blink = NULL;
- Thread->WaitTime = 0;
- Thread->BasePriority = Process->BasePriority;
- Thread->DecrementCount = 0;
- Thread->PriorityDecrement = 0;
- Thread->Quantum = Process->ThreadQuantum;
- RtlZeroMemory(Thread->WaitBlock, sizeof(KWAIT_BLOCK)*4);
- Thread->LegoData = 0;
- Thread->UserAffinity = Process->Affinity;
- Thread->SystemAffinityActive = 0;
- Thread->PowerState = 0;
- Thread->NpxIrql = 0;
- Thread->ServiceTable = KeServiceDescriptorTable;
- Thread->Queue = NULL;
- KeInitializeSpinLock(&Thread->ApcQueueLock);
- RtlZeroMemory(&Thread->Timer, sizeof(KTIMER));
- KeInitializeTimer(&Thread->Timer);
- 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 = NULL;
- Thread->TrapFrame = NULL;
- Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
- Thread->ApcStatePointer[AttachedApcEnvironment] =
&Thread->SavedApcState;
- Thread->EnableStackSwap = 0;
- Thread->LargeStack = 0;
- Thread->ResourceIndex = 0;
- Thread->PreviousMode = KernelMode;
- Thread->KernelTime = 0;
- Thread->UserTime = 0;
- RtlZeroMemory(&Thread->SavedApcState, sizeof(KAPC_STATE));
-
- Thread->ApcStateIndex = OriginalApcEnvironment;
- Thread->ApcQueueable = TRUE;
- Thread->AutoAlignment = Process->AutoAlignment;
-
- KeInitializeApc(&Thread->SuspendApc,
- Thread,
- OriginalApcEnvironment,
- PiSuspendThreadKernelRoutine,
- PiSuspendThreadRundownRoutine,
- PiSuspendThreadNormalRoutine,
- KernelMode,
- NULL);
- KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128);
-
- InsertTailList(&Process->ThreadListHead,
- &Thread->ThreadListEntry);
- Thread->FreezeCount = 0;
- Thread->SuspendCount = 0;
-
- /*
- * Do x86 specific part
- */
+ /* No, Release Lock */
+ KeReleaseDispatcherDatabaseLock(OldIrql);
+
+ /* Return Old State */
+ return PreviousState;
}
/*
@@ -321,33 +437,33 @@
STDCALL
KeRevertToUserAffinityThread(VOID)
{
-#ifdef CONFIG_SMP
- PKTHREAD CurrentThread;
- KIRQL oldIrql;
+ PKTHREAD CurrentThread = KeGetCurrentThread();
+ KIRQL OldIrql;
- oldIrql = KeAcquireDispatcherDatabaseLock();
+ ASSERT(CurrentThread->SystemAffinityActive != FALSE);
+
+ /* Lock the Dispatcher Database */
+ OldIrql = KeAcquireDispatcherDatabaseLock();
- CurrentThread = KeGetCurrentThread();
+ /* Return to User Affinity */
+ CurrentThread->Affinity = CurrentThread->UserAffinity;
- ASSERT(CurrentThread->SystemAffinityActive != FALSE);
-
- /* Return to User Affinity */
- CurrentThread->Affinity = CurrentThread->UserAffinity;
-
- /* Disable System Affinity */
- CurrentThread->SystemAffinityActive = FALSE;
-
- if (CurrentThread->Affinity & (1 <<
KeGetCurrentProcessorNumber()))
- {
- KeReleaseDispatcherDatabaseLock(oldIrql);
- }
- else
- {
- CurrentThread->WaitIrql = oldIrql;
- PsDispatchThreadNoLock(THREAD_STATE_READY);
- KeLowerIrql(oldIrql);
- }
-#endif
+ /* Disable System Affinity */
+ CurrentThread->SystemAffinityActive = FALSE;
+
+ /* Check if we need to Dispatch a New thread */
+ if (CurrentThread->Affinity & (1 << KeGetCurrentProcessorNumber()))
{
+
+ /* No, just release */
+ KeReleaseDispatcherDatabaseLock(OldIrql);
+
+ } else {
+
+ /* We need to dispatch a new thread */
+ CurrentThread->WaitIrql = OldIrql;
+ PsDispatchThreadNoLock(THREAD_STATE_READY);
+ KeLowerIrql(OldIrql);
+ }
}
/*
@@ -355,20 +471,26 @@
*/
CCHAR
STDCALL
-KeSetIdealProcessorThread (
- IN PKTHREAD Thread,
- IN CCHAR Processor)
+KeSetIdealProcessorThread(IN PKTHREAD Thread,
+ IN CCHAR Processor)
{
[truncated at 1000 lines; 369 more skipped]