From 8c0b595a5e2e9150e7c73dec5d1d639645eb670f Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 6 Sep 1999 21:32:57 +0000 Subject: [PATCH] Thread improvements. svn path=/trunk/; revision=646 --- reactos/apps/tests/bench/bench-thread.c | 57 ++++++--- reactos/include/internal/id.h | 1 + reactos/lib/kernel32/thread/thread.c | 28 ++++- reactos/lib/ntdll/rtl/thread.c | 21 +++- reactos/ntoskrnl/ke/wait.c | 146 +++++++++++++++++++++++- reactos/ntoskrnl/ps/kill.c | 2 + reactos/ntoskrnl/ps/thread.c | 9 +- 7 files changed, 237 insertions(+), 27 deletions(-) diff --git a/reactos/apps/tests/bench/bench-thread.c b/reactos/apps/tests/bench/bench-thread.c index 3164221317c..5bcaa38ccde 100644 --- a/reactos/apps/tests/bench/bench-thread.c +++ b/reactos/apps/tests/bench/bench-thread.c @@ -3,6 +3,7 @@ #define NR_THREADS (0x5) + DWORD WINAPI thread_main1(LPVOID param) { @@ -11,6 +12,7 @@ thread_main1(LPVOID param) return 0; } + DWORD WINAPI thread_main2(LPVOID param) { @@ -19,33 +21,62 @@ thread_main2(LPVOID param) return 0; } + int main (void) { + HANDLE hThread; DWORD i=0; DWORD id; - - printf("Creating %d threads...\n",NR_THREADS); -// for (i=0;iSegDs = USER_DS; Context->SegCs = USER_CS; Context->SegSs = USER_DS; - Context->Esp = InitialTeb->StackBase - InitialTeb->StackCommit; + Context->Esp = (ULONG)InitialTeb->StackBase + + (DWORD)InitialTeb->StackCommit - 8; Context->EFlags = (1<<1)+(1<<9); + + + /* copy Parameter to thread stack */ + *((PULONG)(InitialTeb->StackBase + (DWORD)InitialTeb->StackCommit - 4)) + = (DWORD)Parameter; + + /* #endif */ Status = STATUS_SUCCESS; diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 4f22865cb90..baf06d8faad 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -151,6 +151,9 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) case ID_PROCESS_OBJECT: return(KeDispatcherObjectWakeAll(hdr)); + + case ID_THREAD_OBJECT: + return(KeDispatcherObjectWakeAll(hdr)); } DbgPrint("Dispatcher object %x has unknown type\n",hdr); KeBugCheck(0); @@ -200,6 +203,9 @@ NTSTATUS KeWaitForSingleObject(PVOID Object, case ID_PROCESS_OBJECT: break; + + case ID_THREAD_OBJECT: + break; case NotificationEvent: break; @@ -222,7 +228,7 @@ NTSTATUS KeWaitForSingleObject(PVOID Object, blk.Object=Object; blk.Thread=KeGetCurrentThread(); blk.WaitKey = WaitReason; // Assumed - blk.WaitType = WaitMode; // Assumed + blk.WaitType = WaitAll; blk.NextWaitBlock = NULL; InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry)); // DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n", @@ -249,7 +255,91 @@ NTSTATUS KeWaitForMultipleObjects(ULONG Count, PLARGE_INTEGER Timeout, PKWAIT_BLOCK WaitBlockArray) { +#if 0 + DISPATCHER_HEADER* hdr; + PKWAIT_BLOCK blk; + ULONG Counter; + + DPRINT("Entering KeWaitForSingleObject(Object %x) " + "PsGetCurrentThread() %x\n",Object,PsGetCurrentThread()); + + KeAcquireDispatcherDatabaseLock(FALSE); + + for (Counter = 0; Counter < Count; Counter++) + { + hdr = (DISPATCHER_HEADER *)Object[Counter]; + + DPRINT("hdr->SignalState %d\n", hdr->SignalState); + + if (hdr->SignalState > 0) + { + switch (hdr->Type) + { + case SynchronizationEvent: + hdr->SignalState = FALSE; + break; + + case SemaphoreType: + break; + + case ID_PROCESS_OBJECT: + break; + + case ID_THREAD_OBJECT: + break; + + case NotificationEvent: + break; + + default: + DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n", + __FILE__,__LINE__,hdr); + KeBugCheck(0); + + } + KeReleaseDispatcherDatabaseLock(FALSE); + return(STATUS_SUCCESS); + } + } + + if (Timeout != NULL) + { + KeAddThreadTimeout(KeGetCurrentThread(),Timeout); + } + + for (Counter = 0; Counter < Count; Counter++) + { + hdr = (DISPATCHER_HEADER *)Object[Counter]; + + blk = &WaitBlockArray[Counter]; + + blk->Object=Object[Counter]; + blk->Thread=KeGetCurrentThread(); + blk->WaitKey = WaitReason; // Assumed + blk->WaitType = WaitType; + blk->NextWaitBlock = NULL; + InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry)); +// DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n", +// hdr->WaitListHead.Flink,hdr->WaitListHead.Blink); + } + + KeReleaseDispatcherDatabaseLock(FALSE); + + DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__, + KeGetCurrentIrql()); + + PsSuspendThread(PsGetCurrentThread()); + + if (Timeout != NULL) + { + KeCancelTimer(&KeGetCurrentThread()->Timer); + } + DPRINT("Returning from KeWaitForMultipleObject()\n"); + + return(STATUS_SUCCESS); +#else UNIMPLEMENTED; +#endif } VOID KeInitializeDispatcher(VOID) @@ -267,7 +357,59 @@ NtWaitForMultipleObjects ( IN PLARGE_INTEGER Time ) { - UNIMPLEMENTED; +#if 0 + KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS]; + PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS]; + NTSTATUS Status; + ULONG i, j; + + + DPRINT("NtWaitForMultipleObjects(Count %lu Object[] %x, Alertable %d, Time %x)\n", + Count,Object,Alertable,Time); + + if (Count > MAXIMUM_WAIT_OBJECTS) + return ...; /* WAIT_FAIL */ + + /* reference all objects */ + for (i = 0; i < Count; i++) + { + Status = ObReferenceObjectByHandle(Object[i], + SYNCHRONIZE, + NULL, + UserMode, + &ObjectPtrArray[i], + NULL); + if (Status != STATUS_SUCCESS) + { + /* dereference all referenced objects */ + for (j = 0; j < i; i++) + { + ObDereferenceObject(ObjectPtrArray[j]); + } + + return(Status); + } + } + + Status = KeWaitForMultipleObjects(Count, + ObjectPtrArray, + WaitType, + UserMode, + UserMode, + Alertable, + Time, + WaitBlockArray); + + /* dereference all objects */ + for (i = 0; i < Count; i++) + { + ObDereferenceObject(ObjectPtrArray[i]); + } + + return(Status); +#else + UNIMPLEMENTED; +#endif } diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index 9c92f242467..04fd59d1259 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -44,6 +44,7 @@ VOID PsTerminateCurrentThread(NTSTATUS ExitStatus) CurrentThread->ThreadsProcess = NULL; KeRaiseIrql(DISPATCH_LEVEL,&oldlvl); CurrentThread->Tcb.State = THREAD_STATE_TERMINATED; + KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader); ZwYieldExecution(); for(;;); } @@ -58,6 +59,7 @@ VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus) PiNrThreads--; KeRaiseIrql(DISPATCH_LEVEL, &oldlvl); Thread->Tcb.State = THREAD_STATE_TERMINATED; + KeDispatcherObjectWake(&Thread->Tcb.DispatcherHeader); ObDereferenceObject(Thread->ThreadsProcess); Thread->ThreadsProcess = NULL; KeLowerIrql(oldlvl); diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 41243675d38..dfe949f658f 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.25 1999/08/29 06:59:11 ea Exp $ +/* $Id: thread.c,v 1.26 1999/09/06 21:28:33 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -259,7 +259,12 @@ PsInitializeThread ( InitializeListHead(&Thread->Tcb.ApcState.ApcListHead[0]); InitializeListHead(&Thread->Tcb.ApcState.ApcListHead[1]); Thread->Tcb.KernelApcDisable = 1; - + + KeInitializeDispatcherHeader(&Thread->Tcb.DispatcherHeader, + ID_THREAD_OBJECT, + sizeof(ETHREAD), + FALSE); + if (ProcessHandle != NULL) { Status = ObReferenceObjectByHandle(ProcessHandle,