Update ETHREAD fields and termination port stucture to XP, and do necessary code changes. This makes reaping even faster. It's 2:30am, i hope there's no bugs ;-)

svn path=/trunk/; revision=14175
This commit is contained in:
Alex Ionescu 2005-03-18 07:19:30 +00:00
parent eb54434d27
commit c2c6049107
7 changed files with 68 additions and 36 deletions

View file

@ -52,7 +52,7 @@ typedef struct _EPORT_CONNECT_REPLY_MESSAGE
} EPORT_CONNECT_REPLY_MESSAGE, *PEPORT_CONNECT_REPLY_MESSAGE; } EPORT_CONNECT_REPLY_MESSAGE, *PEPORT_CONNECT_REPLY_MESSAGE;
typedef struct _TERMINATION_PORT { typedef struct _TERMINATION_PORT {
LIST_ENTRY Links; struct _TERMINATION_PORT *Next;
PVOID Port; PVOID Port;
} TERMINATION_PORT, *PTERMINATION_PORT; } TERMINATION_PORT, *PTERMINATION_PORT;

View file

@ -156,6 +156,7 @@ typedef struct
#include <pshpack1.h> #include <pshpack1.h>
/* This needs to be fixed ASAP! */
typedef struct _ETHREAD typedef struct _ETHREAD
{ {
KTHREAD Tcb; KTHREAD Tcb;
@ -169,7 +170,10 @@ typedef struct _ETHREAD
NTSTATUS ExitStatus; NTSTATUS ExitStatus;
PVOID OfsChain; PVOID OfsChain;
LIST_ENTRY PostBlockList; LIST_ENTRY PostBlockList;
LIST_ENTRY TerminationPortList; union {
struct _TERMINATION_PORT *TerminationPort;
struct _ETHREAD* ReaperLink;
};
KSPIN_LOCK ActiveTimerListLock; KSPIN_LOCK ActiveTimerListLock;
LIST_ENTRY ActiveTimerListHead; LIST_ENTRY ActiveTimerListHead;
CLIENT_ID Cid; CLIENT_ID Cid;

View file

@ -25,6 +25,7 @@ LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
static ULONG PriorityListMask = 0; static ULONG PriorityListMask = 0;
ULONG IdleProcessorMask = 0; ULONG IdleProcessorMask = 0;
extern BOOLEAN DoneInitYet; extern BOOLEAN DoneInitYet;
extern PETHREAD PspReaperList;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -331,13 +332,13 @@ KiSuspendThreadNormalRoutine(PVOID NormalContext,
PKTHREAD CurrentThread = KeGetCurrentThread(); PKTHREAD CurrentThread = KeGetCurrentThread();
/* Non-alertable kernel-mode suspended wait */ /* Non-alertable kernel-mode suspended wait */
DPRINT1("Waiting...\n"); DPRINT("Waiting...\n");
KeWaitForSingleObject(&CurrentThread->SuspendSemaphore, KeWaitForSingleObject(&CurrentThread->SuspendSemaphore,
Suspended, Suspended,
KernelMode, KernelMode,
FALSE, FALSE,
NULL); NULL);
DPRINT1("Done Waiting\n"); DPRINT("Done Waiting\n");
} }
VOID VOID
@ -389,7 +390,7 @@ KeResumeThread(PKTHREAD Thread)
ULONG PreviousCount; ULONG PreviousCount;
KIRQL OldIrql; 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 */ /* Lock the Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
@ -428,7 +429,7 @@ KeSuspendThread(PKTHREAD Thread)
ULONG PreviousCount; ULONG PreviousCount;
KIRQL OldIrql; 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 */ /* Lock the Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
@ -802,6 +803,7 @@ KeInitializeThread(PKPROCESS Process,
/* Set up the Suspend Counts */ /* Set up the Suspend Counts */
Thread->FreezeCount = 0; Thread->FreezeCount = 0;
Thread->SuspendCount = 0; Thread->SuspendCount = 0;
((PETHREAD)Thread)->ReaperLink = NULL; /* Union. Will also clear termination port */
/* Do x86 specific part */ /* Do x86 specific part */
} }
@ -1194,18 +1196,21 @@ KeTerminateThread(IN KPRIORITY Increment)
PKTHREAD Thread = KeGetCurrentThread(); PKTHREAD Thread = KeGetCurrentThread();
/* Lock the Dispatcher Database and the APC Queue */ /* Lock the Dispatcher Database and the APC Queue */
DPRINT1("Terminating\n"); DPRINT("Terminating\n");
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
/* Insert into the Reaper List */ /* 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 */ /* Check if it's active */
if (PspReaping == FALSE) { if (PspReaping == FALSE) {
/* Activate it. We use the internal function for speed, and use the Hyper Critical Queue */ /* Activate it. We use the internal function for speed, and use the Hyper Critical Queue */
PspReaping = TRUE; PspReaping = TRUE;
DPRINT1("Terminating\n"); DPRINT("Terminating\n");
KiInsertQueue(&ExWorkerQueue[HyperCriticalWorkQueue].WorkerQueue, KiInsertQueue(&ExWorkerQueue[HyperCriticalWorkQueue].WorkerQueue,
&PspReaperWorkItem.List, &PspReaperWorkItem.List,
FALSE); FALSE);
@ -1214,7 +1219,7 @@ KeTerminateThread(IN KPRIORITY Increment)
/* Handle Kernel Queues */ /* Handle Kernel Queues */
if (Thread->Queue) { if (Thread->Queue) {
DPRINT1("Waking Queue\n"); DPRINT("Waking Queue\n");
RemoveEntryList(&Thread->QueueListEntry); RemoveEntryList(&Thread->QueueListEntry);
KiWakeQueue(Thread->Queue); KiWakeQueue(Thread->Queue);
} }

View file

@ -93,7 +93,6 @@ PsInitializeThread(PEPROCESS Process,
DPRINT("Thread = %x\n",Thread); DPRINT("Thread = %x\n",Thread);
KeInitializeThread(&Process->Pcb, &Thread->Tcb, First); KeInitializeThread(&Process->Pcb, &Thread->Tcb, First);
InitializeListHead(&Thread->TerminationPortList);
InitializeListHead(&Thread->ActiveTimerListHead); InitializeListHead(&Thread->ActiveTimerListHead);
KeInitializeSpinLock(&Thread->ActiveTimerListLock); KeInitializeSpinLock(&Thread->ActiveTimerListLock);
InitializeListHead(&Thread->IrpList); InitializeListHead(&Thread->IrpList);

View file

@ -18,7 +18,7 @@
#define TAG_TERMINATE_APC TAG('T', 'A', 'P', 'C') #define TAG_TERMINATE_APC TAG('T', 'A', 'P', 'C')
LIST_ENTRY PspReaperListHead; PETHREAD PspReaperList = NULL;
WORK_QUEUE_ITEM PspReaperWorkItem; WORK_QUEUE_ITEM PspReaperWorkItem;
BOOLEAN PspReaping = FALSE; BOOLEAN PspReaping = FALSE;
extern LIST_ENTRY PsActiveProcessHead; extern LIST_ENTRY PsActiveProcessHead;
@ -31,30 +31,51 @@ VOID
PspReapRoutine(PVOID Context) PspReapRoutine(PVOID Context)
{ {
KIRQL OldIrql; KIRQL OldIrql;
PETHREAD Thread; PETHREAD Thread, NewThread;
PLIST_ENTRY ListEntry;
/* Acquire lock */ /* Acquire lock */
DPRINT("Evil reaper running!!\n"); DPRINT("Evil reaper running!!\n");
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
/* Loop the reap list */ /* Get the first Thread Entry */
while((ListEntry = RemoveHeadList(&PspReaperListHead)) != &PspReaperListHead) { Thread = PspReaperList;
PspReaperList = NULL;
DPRINT("PspReaperList: %x\n", Thread);
/* Get the Current Thread to Terminate */ /* Check to see if the list is empty */
Thread = CONTAINING_RECORD(ListEntry, ETHREAD, TerminationPortList); do {
/* Unlock the Dispatcher */ /* Unlock the Dispatcher */
KeReleaseDispatcherDatabaseLock(OldIrql); KeReleaseDispatcherDatabaseLock(OldIrql);
/* Remove the Reference */ /* Is there a thread on the list? */
while (Thread) {
/* Get the next Thread */
DPRINT("Thread: %x\n", Thread);
DPRINT("Thread: %x\n", Thread->ReaperLink);
NewThread = Thread->ReaperLink;
/* Remove reference to current thread */
ObDereferenceObject(Thread); ObDereferenceObject(Thread);
/* Reacquire the Lock */ /* Move to next Thread */
OldIrql = KeAcquireDispatcherDatabaseLock(); Thread = NewThread;
} }
/* No more linked threads... Reacquire the Lock */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Now try to get a new thread from the list */
Thread = PspReaperList;
PspReaperList = NULL;
DPRINT("PspReaperList: %x\n", Thread);
/* Loop again if there is a new thread */
} while (Thread);
PspReaping = FALSE; PspReaping = FALSE;
DPRINT("Done reaping\n");
KeReleaseDispatcherDatabaseLock(OldIrql); KeReleaseDispatcherDatabaseLock(OldIrql);
} }
@ -158,7 +179,6 @@ PspExitThread(NTSTATUS ExitStatus)
PEPROCESS CurrentProcess; PEPROCESS CurrentProcess;
SIZE_T Length = PAGE_SIZE; SIZE_T Length = PAGE_SIZE;
PVOID TebBlock; PVOID TebBlock;
PLIST_ENTRY CurrentEntry;
PTERMINATION_PORT TerminationPort; PTERMINATION_PORT TerminationPort;
DPRINT("PsTerminateCurrentThread(ExitStatus %x)\n", ExitStatus); DPRINT("PsTerminateCurrentThread(ExitStatus %x)\n", ExitStatus);
@ -204,19 +224,19 @@ PspExitThread(NTSTATUS ExitStatus)
} }
/* Process the Termination Ports */ /* Process the Termination Ports */
while ((CurrentEntry = RemoveHeadList(&CurrentThread->TerminationPortList)) != TerminationPort = CurrentThread->TerminationPort;
&CurrentThread->TerminationPortList) { DPRINT("TerminationPort: %p\n", TerminationPort);
while (TerminationPort) {
/* Get the Termination Port */
TerminationPort = CONTAINING_RECORD(CurrentEntry,
TERMINATION_PORT,
Links);
/* Send the LPC Message */ /* Send the LPC Message */
LpcSendTerminationPort(TerminationPort->Port, CurrentThread->CreateTime); LpcSendTerminationPort(TerminationPort->Port, CurrentThread->CreateTime);
/* Free the Port */ /* Free the Port */
ExFreePool(TerminationPort); ExFreePool(TerminationPort);
/* Get the next one */
TerminationPort = TerminationPort->Next;
DPRINT("TerminationPort: %p\n", TerminationPort);
} }
/* Rundown Win32 Structures */ /* Rundown Win32 Structures */
@ -508,6 +528,7 @@ NtRegisterThreadTerminatePort(HANDLE PortHandle)
NTSTATUS Status; NTSTATUS Status;
PTERMINATION_PORT TerminationPort; PTERMINATION_PORT TerminationPort;
PVOID TerminationLpcPort; PVOID TerminationLpcPort;
PETHREAD Thread;
PAGED_CODE(); PAGED_CODE();
@ -530,8 +551,12 @@ NtRegisterThreadTerminatePort(HANDLE PortHandle)
TAG('P', 's', 'T', '=')))) { TAG('P', 's', 'T', '=')))) {
/* Associate the Port */ /* Associate the Port */
Thread = PsGetCurrentThread();
TerminationPort->Port = TerminationLpcPort; TerminationPort->Port = TerminationLpcPort;
InsertTailList(&PsGetCurrentThread()->TerminationPortList, &TerminationPort->Links); DPRINT("TerminationPort: %p\n", TerminationPort);
TerminationPort->Next = Thread->TerminationPort;
Thread->TerminationPort = TerminationPort;
DPRINT("TerminationPort: %p\n", Thread->TerminationPort);
/* Return success */ /* Return success */
return(STATUS_SUCCESS); return(STATUS_SUCCESS);

View file

@ -40,7 +40,7 @@ NtResumeThread(IN HANDLE ThreadHandle,
PAGED_CODE(); PAGED_CODE();
DPRINT1("NtResumeThead(ThreadHandle %lx SuspendCount %p)\n", DPRINT("NtResumeThead(ThreadHandle %lx SuspendCount %p)\n",
ThreadHandle, SuspendCount); ThreadHandle, SuspendCount);
/* Get the Thread Object */ /* Get the Thread Object */

View file

@ -473,7 +473,6 @@ PsInitThreadManagment(VOID)
DoneInitYet = TRUE; DoneInitYet = TRUE;
InitializeListHead(&PspReaperListHead);
ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL); ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL);
} }