Implement PsSetLegoNotifyRoutine and PsRemoveCreateThreadNotifyroutine. Clean up ps/thread.c, move things to their own subsystem, do proper TEB Allocation with MmCreateTeb, remove TEB EPROCESS hack fields. Rename PsFrezeAllThreads to KeFreezeAllThreads and implement a working version. Modified: trunk/reactos/ntoskrnl/ex/init.c Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h Modified: trunk/reactos/ntoskrnl/include/internal/ps.h Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c Modified: trunk/reactos/ntoskrnl/ke/kthread.c Modified: trunk/reactos/ntoskrnl/ke/main.c Modified: trunk/reactos/ntoskrnl/mm/process.c Modified: trunk/reactos/ntoskrnl/ps/kill.c Modified: trunk/reactos/ntoskrnl/ps/notify.c Modified: trunk/reactos/ntoskrnl/ps/psmgr.c Modified: trunk/reactos/ntoskrnl/ps/thread.c _____
Modified: trunk/reactos/ntoskrnl/ex/init.c --- trunk/reactos/ntoskrnl/ex/init.c 2005-04-18 02:12:30 UTC (rev 14662) +++ trunk/reactos/ntoskrnl/ex/init.c 2005-04-18 04:46:06 UTC (rev 14663) @@ -461,7 +461,7 @@
/* Set up the Kernel and Process Manager for this CPU */ KePrepareForApplicationProcessorInit(KeNumberProcessors); - PsPrepareForApplicationProcessorInit(KeNumberProcessors); + KeCreateApplicationProcessorIdleThread(KeNumberProcessors);
/* Allocate a stack for use when booting the processor */ ProcessorStack = Ki386InitialStackArray[((int)KeNumberProcessors)] + MM_STACK_SIZE; _____
Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c --- trunk/reactos/ntoskrnl/ex/sysinfo.c 2005-04-18 02:12:30 UTC (rev 14662) +++ trunk/reactos/ntoskrnl/ex/sysinfo.c 2005-04-18 04:46:06 UTC (rev 14663) @@ -587,8 +587,13 @@
SpiCur = (PSYSTEM_PROCESSES)pCur;
- nThreads = PsEnumThreadsByProcess(pr); - + current_entry = pr->ThreadListHead.Flink; + while (current_entry != &pr->ThreadListHead) + { + nThreads++; + current_entry = current_entry->Flink; + } + // size of the structure for every process curSize = sizeof(SYSTEM_PROCESSES)-sizeof(SYSTEM_THREADS)+sizeof(SYSTEM_THREADS)*n Threads; ovlSize += curSize+inLen; @@ -667,7 +672,7 @@ }
pr = PsGetNextProcess(pr); - + nThreads = 0; if ((pr == syspr) || (pr == NULL)) { SpiCur->NextEntryDelta = 0; _____
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h --- trunk/reactos/ntoskrnl/include/internal/i386/ke.h 2005-04-18 02:12:30 UTC (rev 14662) +++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h 2005-04-18 04:46:06 UTC (rev 14663) @@ -198,6 +198,10 @@
VOID KeFreeGdtSelector(ULONG Entry); VOID NtEarlyInitVdm(VOID); +VOID +KeApplicationProcessorInitDispatcher(VOID); +VOID +KeCreateApplicationProcessorIdleThread(ULONG Id);
#ifdef CONFIG_SMP #define LOCK "lock ; " _____
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h --- trunk/reactos/ntoskrnl/include/internal/ps.h 2005-04-18 02:12:30 UTC (rev 14662) +++ trunk/reactos/ntoskrnl/include/internal/ps.h 2005-04-18 04:46:06 UTC (rev 14663) @@ -437,8 +437,6 @@
*/ MADDRESS_SPACE AddressSpace; LIST_ENTRY ProcessListEntry; - PVOID TebBlock; - PVOID TebLastAllocated; };
#define PROCESS_STATE_TERMINATED (1) _____
Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c --- trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-04-18 02:12:30 UTC (rev 14662) +++ trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-04-18 04:46:06 UTC (rev 14663) @@ -26,6 +26,8 @@
BOOLEAN Ke386Pae = FALSE; BOOLEAN Ke386GlobalPagesEnabled = FALSE; ULONG KiFastSystemCallDisable = 1; +extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS]; +extern ULONG IdleProcessorMask;
/* FUNCTIONS *****************************************************************/
@@ -123,6 +125,42 @@ } }
+VOID +KeApplicationProcessorInitDispatcher(VOID) +{ + KIRQL oldIrql; + oldIrql = KeAcquireDispatcherDatabaseLock(); + IdleProcessorMask |= (1 << KeGetCurrentProcessorNumber()); + KeReleaseDispatcherDatabaseLock(oldIrql); +} + +VOID +INIT_FUNCTION +KeCreateApplicationProcessorIdleThread(ULONG Id) +{ + PETHREAD IdleThread; + PKPRCB Prcb = ((PKPCR)((ULONG_PTR)KPCR_BASE + Id * PAGE_SIZE))->Prcb; + + PsInitializeThread(PsIdleProcess, + &IdleThread, + NULL, + KernelMode, + FALSE); + IdleThread->Tcb.State = THREAD_STATE_RUNNING; + IdleThread->Tcb.FreezeCount = 0; + IdleThread->Tcb.Affinity = 1 << Id; + IdleThread->Tcb.UserAffinity = 1 << Id; + IdleThread->Tcb.Priority = LOW_PRIORITY; + IdleThread->Tcb.BasePriority = LOW_PRIORITY; + Prcb->IdleThread = &IdleThread->Tcb; + Prcb->CurrentThread = &IdleThread->Tcb; + + Ki386InitialStackArray[Id] = (PVOID)IdleThread->Tcb.StackLimit; + + DPRINT("IdleThread for Processor %d has PID %d\n", + Id, IdleThread->Cid.UniqueThread); +} + VOID INIT_FUNCTION KePrepareForApplicationProcessorInit(ULONG Id) { _____
Modified: trunk/reactos/ntoskrnl/ke/kthread.c --- trunk/reactos/ntoskrnl/ke/kthread.c 2005-04-18 02:12:30 UTC (rev 14662) +++ trunk/reactos/ntoskrnl/ke/kthread.c 2005-04-18 04:46:06 UTC (rev 14663) @@ -342,8 +342,48 @@
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 +STDCALL KeRundownThread(VOID) { KIRQL OldIrql; @@ -422,7 +462,51 @@ 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) _____
Modified: trunk/reactos/ntoskrnl/ke/main.c --- trunk/reactos/ntoskrnl/ke/main.c 2005-04-18 02:12:30 UTC (rev 14662) +++ trunk/reactos/ntoskrnl/ke/main.c 2005-04-18 04:46:06 UTC (rev 14663) @@ -109,7 +109,7 @@
} else {
/* Do application processor initialization */ - PsApplicationProcessorInit(); + KeApplicationProcessorInitDispatcher();
/* Lower IRQL and go to Idle Thread */ KeLowerIrql(PASSIVE_LEVEL); _____
Modified: trunk/reactos/ntoskrnl/mm/process.c --- trunk/reactos/ntoskrnl/mm/process.c 2005-04-18 02:12:30 UTC (rev 14662) +++ trunk/reactos/ntoskrnl/mm/process.c 2005-04-18 04:46:06 UTC (rev 14663) @@ -16,6 +16,7 @@
extern ULONG NtMajorVersion; extern ULONG NtMinorVersion; extern ULONG NtOSCSDVersion; + /* FUNCTIONS *****************************************************************/
PVOID @@ -28,25 +29,33 @@ PMEMORY_AREA MemoryArea; PHYSICAL_ADDRESS BoundaryAddressMultiple; BoundaryAddressMultiple.QuadPart = 0; + PVOID AllocatedBase = BaseAddress;
/* Acquire the Lock */ MmLockAddressSpace(ProcessAddressSpace);
- /* Create a Peb or Teb */ - Status = MmCreateMemoryArea(Process, - ProcessAddressSpace, - MEMORY_AREA_PEB_OR_TEB, - &BaseAddress, - PAGE_SIZE, - PAGE_READWRITE, - &MemoryArea, - FALSE, - FALSE, - BoundaryAddressMultiple); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to allocate PEB or TEB\n"); - } + /* + * Create a Peb or Teb. + * Loop until it works, decreasing by PAGE_SIZE each time. The logic here + * is that a PEB allocation should never fail since the address is free, + * while TEB allocation can fail, and we should simply try the address + * below. Is there a nicer way of doing this automagically? (ie: findning) + * a gap region? -- Alex + */ + do { + DPRINT("Trying to allocate: %x\n", AllocatedBase); + Status = MmCreateMemoryArea(Process, + ProcessAddressSpace, + MEMORY_AREA_PEB_OR_TEB, + &AllocatedBase, + PAGE_SIZE, + PAGE_READWRITE, + &MemoryArea, + TRUE, + FALSE, + BoundaryAddressMultiple); + AllocatedBase = AllocatedBase - PAGE_SIZE; + } while (Status != STATUS_SUCCESS);
/* Initialize the Region */
MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead, @@ -60,7 +69,7 @@ /* Unlock Address Space */ DPRINT("Returning\n"); MmUnlockAddressSpace(ProcessAddressSpace); - return BaseAddress; + return AllocatedBase + PAGE_SIZE; }
VOID @@ -77,7 +86,7 @@
VOID STDCALL -MmDeleteKernelStack(PVOID Stack, +MmDeleteKernelStack(PVOID Stack, BOOLEAN GuiStack) { /* Lock the Address Space */ @@ -93,6 +102,54 @@ MmUnlockAddressSpace(MmGetKernelAddressSpace()); }
+VOID +MiFreePebPage(PVOID Context, + MEMORY_AREA* MemoryArea, + PVOID Address, + PFN_TYPE Page, + SWAPENTRY SwapEntry, + BOOLEAN Dirty) +{ + PEPROCESS Process = (PEPROCESS)Context; + + if (Page != 0) + { + SWAPENTRY SavedSwapEntry; + SavedSwapEntry = MmGetSavedSwapEntryPage(Page); + if (SavedSwapEntry != 0) + { + MmFreeSwapPage(SavedSwapEntry); + MmSetSavedSwapEntryPage(Page, 0); + } + MmDeleteRmap(Page, Process, Address); + MmReleasePageMemoryConsumer(MC_USER, Page); + } + else if (SwapEntry != 0) + { + MmFreeSwapPage(SwapEntry); + } +} + +VOID +STDCALL +MmDeleteTeb(PEPROCESS Process, + PTEB Teb) +{ + PMADDRESS_SPACE ProcessAddressSpace = &Process->AddressSpace; + + /* Lock the Address Space */ + MmLockAddressSpace(ProcessAddressSpace); + + /* Delete the Stack */ + MmFreeMemoryAreaByPtr(ProcessAddressSpace, + Teb, + MiFreePebPage, + Process); + + /* Unlock the Address Space */ + MmUnlockAddressSpace(ProcessAddressSpace); +} + PVOID STDCALL MmCreateKernelStack(BOOLEAN GuiStack) @@ -218,11 +275,64 @@ return STATUS_SUCCESS; }
-VOID +PTEB STDCALL -MmCreateTeb(VOID) +MmCreateTeb(PEPROCESS Process, + PCLIENT_ID ClientId, + PINITIAL_TEB InitialTeb) { + PTEB Teb; + BOOLEAN Attached = FALSE;
+ /* Attach to the process */ + DPRINT("MmCreateTeb\n"); + if (Process != PsGetCurrentProcess()) + { + /* Attach to Target */ + KeAttachProcess(&Process->Pcb); + Attached = TRUE; + } + + /* Allocate the TEB */ + Teb = MiCreatePebOrTeb(Process, (PVOID)TEB_BASE); + + /* Initialize the PEB */ + RtlZeroMemory(Teb, sizeof(TEB)); + + /* Set TIB Data */ + Teb->Tib.ExceptionList = (PVOID)0xFFFFFFFF; + Teb->Tib.Version = 1; + Teb->Tib.Self = (PNT_TIB)Teb; + + /* Set TEB Data */ + Teb->Cid = *ClientId; + Teb->RealClientId = *ClientId; + Teb->Peb = Process->Peb; + Teb->CurrentLocale = PsDefaultThreadLocaleId; + + /* Store stack information from InitialTeb */ + if(InitialTeb != NULL) + { + /* fixed-size stack */ + if(InitialTeb->StackBase && InitialTeb->StackLimit) + { + Teb->Tib.StackBase = InitialTeb->StackBase; + Teb->Tib.StackLimit = InitialTeb->StackLimit; + Teb->DeallocationStack = InitialTeb->StackLimit; + } + /* expandable stack */ + else + { + Teb->Tib.StackBase = InitialTeb->StackCommit; + Teb->Tib.StackLimit = InitialTeb->StackCommitMax; + Teb->DeallocationStack = InitialTeb->StackReserved; + } + } + + /* Return TEB Address */ + DPRINT("Allocated: %x\n", Teb); + if (Attached) KeDetachProcess(); + return Teb; }
NTSTATUS _____
Modified: trunk/reactos/ntoskrnl/ps/kill.c --- trunk/reactos/ntoskrnl/ps/kill.c 2005-04-18 02:12:30 UTC (rev 14662) +++ trunk/reactos/ntoskrnl/ps/kill.c 2005-04-18 04:46:06 UTC (rev 14663) @@ -24,6 +24,11 @@
extern LIST_ENTRY PsActiveProcessHead; extern FAST_MUTEX PspActiveProcessMutex;
+VOID +STDCALL +MmDeleteTeb(PEPROCESS Process, + PTEB Teb); + /* FUNCTIONS *****************************************************************/
STDCALL @@ -204,9 +209,8 @@ PETHREAD CurrentThread; BOOLEAN Last; PEPROCESS CurrentProcess; - SIZE_T Length = PAGE_SIZE; - PVOID TebBlock; PTERMINATION_PORT TerminationPort; + PTEB Teb;
DPRINT("PspExitThread(ExitStatus %x), Current: 0x%x\n", ExitStatus, PsGetCurrentThread());
@@ -285,26 +289,10 @@ //CmNotifyRunDown(CurrentThread);
/* Free the TEB */ - if(CurrentThread->Tcb.Teb) { + if((Teb = CurrentThread->Tcb.Teb)) {
- DPRINT("Decommit teb at %p\n", CurrentThread->Tcb.Teb); - TebBlock = MM_ROUND_DOWN(CurrentThread->Tcb.Teb, MM_VIRTMEM_GRANULARITY); - - ZwFreeVirtualMemory(NtCurrentProcess(), - (PVOID *)&CurrentThread->Tcb.Teb, - &Length, - MEM_DECOMMIT); - - DPRINT("teb %p, TebBlock %p\n", CurrentThread->Tcb.Teb, TebBlock); - - if (TebBlock != CurrentProcess->TebBlock || - CurrentProcess->TebBlock == CurrentProcess->TebLastAllocated) { - - MmLockAddressSpace(&CurrentProcess->AddressSpace); - MmReleaseMemoryAreaIfDecommitted(CurrentProcess, &CurrentProcess->AddressSpace, TebBlock); - MmUnlockAddressSpace(&CurrentProcess->AddressSpace); - } - + DPRINT1("Decommit teb at %p\n", Teb); + MmDeleteTeb(CurrentProcess, Teb); CurrentThread->Tcb.Teb = NULL; }
_____
Modified: trunk/reactos/ntoskrnl/ps/notify.c --- trunk/reactos/ntoskrnl/ps/notify.c 2005-04-18 02:12:30 UTC (rev 14662) +++ trunk/reactos/ntoskrnl/ps/notify.c 2005-04-18 04:46:06 UTC (rev 14663) @@ -18,9 +18,9 @@
#define MAX_THREAD_NOTIFY_ROUTINE_COUNT 8 #define TAG_KAPC TAG('k','p','a','p') /* kpap - kernel ps apc */
-static ULONG PiThreadNotifyRoutineCount = 0; +static ULONG PspThreadNotifyRoutineCount = 0; static PCREATE_THREAD_NOTIFY_ROUTINE -PiThreadNotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT]; +PspThreadNotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
static PCREATE_PROCESS_NOTIFY_ROUTINE PspProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT]; @@ -28,6 +28,8 @@ static PLOAD_IMAGE_NOTIFY_ROUTINE PspLoadImageNotifyRoutine[MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT];
+static PVOID PspLegoNotifyRoutine; + /* FUNCTIONS ***************************************************************/
/* @@ -77,6 +79,20 @@ /* * @implemented */ +ULONG +STDCALL +PsSetLegoNotifyRoutine(PVOID LegoNotifyRoutine) +{ + /* Set the System-Wide Lego Routine */ + PspLegoNotifyRoutine = LegoNotifyRoutine; + + /* Return the location to the Lego Data */ + return FIELD_OFFSET(KTHREAD, LegoData); +} + +/* + * @implemented + */ NTSTATUS STDCALL PsRemoveLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine) @@ -124,17 +140,60 @@ return STATUS_INVALID_PARAMETER; }
-VOID STDCALL -PspRunCreateThreadNotifyRoutines ( - PETHREAD CurrentThread, - BOOLEAN Create ) +/* + * @implemented + */ +NTSTATUS +STDCALL +PsRemoveCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine) { ULONG i; + + /* Loop the routines */ + for(i=0;i<MAX_THREAD_NOTIFY_ROUTINE_COUNT;i++) + { + /* Check for a match */ + if ((PVOID)PspThreadNotifyRoutine[i] == (PVOID)NotifyRoutine) + { + /* Remove and return */ + PspThreadNotifyRoutine[i] = NULL; + return(STATUS_SUCCESS); + } + } + + /* Nothing found */ + return STATUS_INVALID_PARAMETER; +} + +/* + * @implemented + */ +NTSTATUS +STDCALL +PsSetCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine) +{ + if (PspThreadNotifyRoutineCount >= MAX_THREAD_NOTIFY_ROUTINE_COUNT) + { + return(STATUS_INSUFFICIENT_RESOURCES); + } + + PspThreadNotifyRoutine[PspThreadNotifyRoutineCount] = NotifyRoutine; + PspThreadNotifyRoutineCount++; + + return(STATUS_SUCCESS); +} + +VOID +STDCALL +PspRunCreateThreadNotifyRoutines(PETHREAD CurrentThread, + BOOLEAN Create) +{ + ULONG i; CLIENT_ID Cid = CurrentThread->Cid;
- for (i = 0; i < PiThreadNotifyRoutineCount; i++) + for (i = 0; i < PspThreadNotifyRoutineCount; i++) { - PiThreadNotifyRoutine[i](Cid.UniqueProcess, Cid.UniqueThread, Create); + PspThreadNotifyRoutine[i](Cid.UniqueProcess, Cid.UniqueThread, Create); } }
@@ -173,22 +232,4 @@ } }
-/* - * @implemented - */ -NTSTATUS STDCALL -PsSetCreateThreadNotifyRoutine ( - IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine ) -{ - if (PiThreadNotifyRoutineCount >= MAX_THREAD_NOTIFY_ROUTINE_COUNT) - { - return(STATUS_INSUFFICIENT_RESOURCES); - } - - PiThreadNotifyRoutine[PiThreadNotifyRoutineCount] = NotifyRoutine; - PiThreadNotifyRoutineCount++; - - return(STATUS_SUCCESS); -} - /* EOF */ _____
Modified: trunk/reactos/ntoskrnl/ps/psmgr.c --- trunk/reactos/ntoskrnl/ps/psmgr.c 2005-04-18 02:12:30 UTC (rev 14662) +++ trunk/reactos/ntoskrnl/ps/psmgr.c 2005-04-18 04:46:06 UTC (rev 14663) @@ -15,15 +15,26 @@
#include <internal/debug.h>
extern LARGE_INTEGER ShortPsLockDelay, PsLockTimeout; +extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
static GENERIC_MAPPING PiProcessMapping = { STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, STANDARD_RIGHTS_WRITE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | - PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION | PROCESS_SET_PORT, + PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION | + PROCESS_SET_PORT, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, PROCESS_ALL_ACCESS};
+static GENERIC_MAPPING PiThreadMapping = { + STANDARD_RIGHTS_READ | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, + STANDARD_RIGHTS_WRITE | THREAD_TERMINATE | THREAD_SUSPEND_RESUME | + THREAD_ALERT | THREAD_SET_INFORMATION | THREAD_SET_CONTEXT, + STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, + THREAD_ALL_ACCESS}; + +BOOLEAN DoneInitYet = FALSE; + VOID INIT_FUNCTION PsInitClientIDManagment(VOID); @@ -50,6 +61,60 @@
VOID INIT_FUNCTION +PsInitThreadManagment(VOID) +/* + * FUNCTION: Initialize thread managment + */ +{ + PETHREAD FirstThread; + ULONG i; + + for (i=0; i < MAXIMUM_PRIORITY; i++) + { + InitializeListHead(&PriorityListHead[i]); + } + + PsThreadType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE)); + + PsThreadType->Tag = TAG('T', 'H', 'R', 'T'); + PsThreadType->TotalObjects = 0; + PsThreadType->TotalHandles = 0; + PsThreadType->PeakObjects = 0; + PsThreadType->PeakHandles = 0; + PsThreadType->PagedPoolCharge = 0; + PsThreadType->NonpagedPoolCharge = sizeof(ETHREAD); + PsThreadType->Mapping = &PiThreadMapping; + PsThreadType->Dump = NULL; + PsThreadType->Open = NULL; + PsThreadType->Close = NULL; + PsThreadType->Delete = PspDeleteThread; + PsThreadType->Parse = NULL; + PsThreadType->Security = NULL; + PsThreadType->QueryName = NULL; + PsThreadType->OkayToClose = NULL; + PsThreadType->Create = NULL; + PsThreadType->DuplicationNotify = NULL; + + RtlInitUnicodeString(&PsThreadType->TypeName, L"Thread"); + + ObpCreateTypeObject(PsThreadType); + + PsInitializeThread(NULL, &FirstThread, NULL, KernelMode, TRUE); + FirstThread->Tcb.State = THREAD_STATE_RUNNING; + FirstThread->Tcb.FreezeCount = 0; + FirstThread->Tcb.UserAffinity = (1 << 0); /* Set the affinity of the first thread to the boot processor */ + FirstThread->Tcb.Affinity = (1 << 0); + KeGetCurrentPrcb()->CurrentThread = (PVOID)FirstThread; + + DPRINT("FirstThread %x\n",FirstThread); + + DoneInitYet = TRUE; + + ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL); +} + +VOID +INIT_FUNCTION PsInitProcessManagment(VOID) { PKPROCESS KProcess; _____
Modified: trunk/reactos/ntoskrnl/ps/thread.c --- trunk/reactos/ntoskrnl/ps/thread.c 2005-04-18 02:12:30 UTC (rev 14662) +++ trunk/reactos/ntoskrnl/ps/thread.c 2005-04-18 04:46:06 UTC (rev 14663) @@ -1,5 +1,4 @@
-/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/ps/thread.c @@ -9,14 +8,6 @@ * Phillip Susi */
-/* - * NOTE: - * - * All of the routines that manipulate the thread queue synchronize on - * a single spinlock - * - */ - /* INCLUDES ****************************************************************/
#include <ntoskrnl.h> @@ -30,49 +21,183 @@
POBJECT_TYPE EXPORTED PsThreadType = NULL;
-extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS]; -extern ULONG IdleProcessorMask; -extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY]; +PTEB +STDCALL +MmCreateTeb(PEPROCESS Process, + PCLIENT_ID ClientId, + PINITIAL_TEB InitialTeb);
+/* FUNCTIONS ***************************************************************/
-BOOLEAN DoneInitYet = FALSE; -static GENERIC_MAPPING PiThreadMapping = {STANDARD_RIGHTS_READ | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, - STANDARD_RIGHTS_WRITE | THREAD_TERMINATE | THREAD_SUSPEND_RESUME | THREAD_ALERT | - THREAD_SET_INFORMATION | THREAD_SET_CONTEXT, - STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, - THREAD_ALL_ACCESS}; +VOID STDCALL +LdrInitApcRundownRoutine ( PKAPC Apc ) +{ + ExFreePool(Apc); +}
-/* FUNCTIONS ***************************************************************/
-#ifdef KeGetCurrentThread -#undef KeGetCurrentThread -#endif -/* - * @implemented - */ -PKTHREAD -STDCALL -KeGetCurrentThread(VOID) +VOID STDCALL +LdrInitApcKernelRoutine ( + PKAPC Apc, + PKNORMAL_ROUTINE* NormalRoutine, + PVOID* NormalContext, + PVOID* SystemArgument1, + PVOID* SystemArgument2) { -#ifdef CONFIG_SMP - ULONG Flags; - PKTHREAD Thread; - Ke386SaveFlags(Flags); - Ke386DisableInterrupts(); - Thread = KeGetCurrentPrcb()->CurrentThread; - Ke386RestoreFlags(Flags); - return Thread; -#else - return(KeGetCurrentPrcb()->CurrentThread); -#endif + ExFreePool(Apc); }
+VOID +PiBeforeBeginThread(CONTEXT c) +{ + KeLowerIrql(PASSIVE_LEVEL); +} + +NTSTATUS +PsInitializeThread ( + PEPROCESS Process, + PETHREAD* ThreadPtr, + POBJECT_ATTRIBUTES ObjectAttributes, + KPROCESSOR_MODE AccessMode, + BOOLEAN First ) +{ + PETHREAD Thread; + NTSTATUS Status; + KIRQL oldIrql; + + PAGED_CODE(); + + if (Process == NULL) + { + Process = PsInitialSystemProcess; + } + + /* + * Create and initialize thread + */ + Status = ObCreateObject(AccessMode, + PsThreadType, + ObjectAttributes, + KernelMode, + NULL, + sizeof(ETHREAD), + 0, + 0, + (PVOID*)&Thread); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + /* + * Reference process + */ + ObReferenceObjectByPointer(Process, + PROCESS_CREATE_THREAD, + PsProcessType, + KernelMode); + + Thread->ThreadsProcess = Process; + Thread->Cid.UniqueThread = NULL; + Thread->Cid.UniqueProcess = (HANDLE)Thread->ThreadsProcess->UniqueProcessId; + + DPRINT("Thread = %x\n",Thread); + + KeInitializeThread(&Process->Pcb, &Thread->Tcb, First); + InitializeListHead(&Thread->ActiveTimerListHead); + KeInitializeSpinLock(&Thread->ActiveTimerListLock); + InitializeListHead(&Thread->IrpList); + Thread->DeadThread = FALSE; + Thread->HasTerminated = FALSE; + Thread->Tcb.Win32Thread = NULL; + DPRINT("Thread->Cid.UniqueThread %d\n",Thread->Cid.UniqueThread); + + + Thread->Tcb.BasePriority = (CHAR)Process->Pcb.BasePriority; + Thread->Tcb.Priority = Thread->Tcb.BasePriority; + + /* + * Local Procedure Call facility (LPC) + */ + KeInitializeSemaphore (& Thread->LpcReplySemaphore, 0, LONG_MAX); + Thread->LpcReplyMessage = NULL; + Thread->LpcReplyMessageId = 0; /* not valid */ + /* Thread->LpcReceiveMessageId = 0; */ + Thread->LpcExitThreadCalled = FALSE; + Thread->LpcReceivedMsgIdValid = FALSE; + + oldIrql = KeAcquireDispatcherDatabaseLock(); + InsertTailList(&Process->ThreadListHead, + &Thread->ThreadListEntry); + KeReleaseDispatcherDatabaseLock(oldIrql); + + *ThreadPtr = Thread; + + return STATUS_SUCCESS; +} + +VOID PsDumpThreads(BOOLEAN IncludeSystem) +{ + PLIST_ENTRY AThread, AProcess; + PEPROCESS Process; + PETHREAD Thread; + ULONG nThreads = 0; + + AProcess = PsActiveProcessHead.Flink; + while(AProcess != &PsActiveProcessHead) + { + Process = CONTAINING_RECORD(AProcess, EPROCESS, ProcessListEntry); + /* FIXME - skip suspended, ... processes? */ + if((Process != PsInitialSystemProcess) || + (Process == PsInitialSystemProcess && IncludeSystem)) + { + AThread = Process->ThreadListHead.Flink; + while(AThread != &Process->ThreadListHead) + { + Thread = CONTAINING_RECORD(AThread, ETHREAD, ThreadListEntry); + + nThreads++; + DbgPrint("Thread->Tcb.State %d Affinity %08x Priority %d PID.TID %d.%d Name %.8s Stack: \n", + Thread->Tcb.State, + Thread->Tcb.Affinity, + Thread->Tcb.Priority, + Thread->ThreadsProcess->UniqueProcessId, + Thread->Cid.UniqueThread, + Thread->ThreadsProcess->ImageFileName); + if(Thread->Tcb.State == THREAD_STATE_READY || + Thread->Tcb.State == THREAD_STATE_SUSPENDED || + Thread->Tcb.State == THREAD_STATE_BLOCKED) + { + ULONG i = 0; + PULONG Esp = (PULONG)Thread->Tcb.KernelStack; + PULONG Ebp = (PULONG)Esp[4]; + DbgPrint("Ebp 0x%.8X\n", Ebp); + while(Ebp != 0 && Ebp >= (PULONG)Thread->Tcb.StackLimit) + { + DbgPrint("%.8X %.8X%s", Ebp[0], Ebp[1], (i % 8) == 7 ? "\n" : " "); + Ebp = (PULONG)Ebp[0]; + i++; + } + if((i % 8) != 0) + { + DbgPrint("\n"); + } + } + AThread = AThread->Flink; + } + } + AProcess = AProcess->Flink; + } +} + /* * @implemented */ -HANDLE STDCALL PsGetCurrentThreadId(VOID) +HANDLE +STDCALL +PsGetCurrentThreadId(VOID) { - return(PsGetCurrentThread()->Cid.UniqueThread); + return(PsGetCurrentThread()->Cid.UniqueThread); }
/* @@ -80,11 +205,9 @@ */ ULONG STDCALL -PsGetThreadFreezeCount( - PETHREAD Thread - ) +PsGetThreadFreezeCount(PETHREAD Thread) { - return Thread->Tcb.FreezeCount; + return Thread->Tcb.FreezeCount; }
/* @@ -92,11 +215,9 @@ */ BOOLEAN STDCALL -PsGetThreadHardErrorsAreDisabled( - PETHREAD Thread - ) +PsGetThreadHardErrorsAreDisabled(PETHREAD Thread) { - return Thread->HardErrorsAreDisabled; + return Thread->HardErrorsAreDisabled; } [truncated at 1000 lines; 895 more skipped]