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]