Thread improvements.

svn path=/trunk/; revision=646
This commit is contained in:
Eric Kohl 1999-09-06 21:32:57 +00:00
parent 4280f4f60d
commit 8c0b595a5e
7 changed files with 237 additions and 27 deletions

View file

@ -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;i<NR_THREADS;i++)
// {
#if 0
printf("Creating %d threads...\n",NR_THREADS*2);
for (i=0;i<NR_THREADS;i++)
{
CreateThread(NULL,
0,
thread_main1,
(LPVOID)i,
thread_main1,
(LPVOID)i,
0,
&id);
#if 0
CreateThread(NULL,
0,
thread_main2,
(LPVOID)i,
thread_main2,
(LPVOID)i,
0,
&id);
}
#endif
printf("Threads created...\n");
// Sleep (5000);
SuspendThread (GetCurrentThread());
printf("All threads created...\n");
/*
* Waiting for threads is not implemented yet.
* If you want to see all threads running, uncomment the
* call to SuspendThread(). The test application will
* freeze after all threads are created.
*/
/* SuspendThread (GetCurrentThread()); */
#else
printf("Creating thread...\n");
hThread = CreateThread(NULL,
0,
thread_main1,
(LPVOID)i,
0,
&id);
printf("Thread created. Waiting for termination...\n");
WaitForSingleObject (hThread,
-1);
CloseHandle (hThread);
printf("Thread terminated...\n");
#endif
return 0;
}

View file

@ -11,3 +11,4 @@
#define ID_EVENT_OBJECT (ID_BASE_OBJECT + 5)
#define ID_TIMER_OBJECT (ID_BASE_OBJECT + 6)
#define ID_PROCESS_OBJECT (ID_BASE_OBJECT + 7)
#define ID_THREAD_OBJECT (ID_BASE_OBJECT + 8)

View file

@ -23,6 +23,19 @@
/* FUNCTIONS *****************************************************************/
static VOID STDCALL
ThreadStartup (LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter)
{
UINT uExitCode;
uExitCode = (lpStartAddress)(lpParameter);
NtTerminateThread(NtCurrentThread(),
uExitCode);
}
HANDLE STDCALL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
@ -55,7 +68,6 @@ HANDLE STDCALL CreateRemoteThread(HANDLE hProcess,
BOOLEAN CreateSuspended = FALSE;
PVOID BaseAddress;
DWORD StackSize;
ULONG BytesWritten;
NTSTATUS Status;
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
@ -94,18 +106,24 @@ HANDLE STDCALL CreateRemoteThread(HANDLE hProcess,
DPRINT("Stack base address: %p\n", BaseAddress);
memset(&ThreadContext,0,sizeof(CONTEXT));
ThreadContext.Eip = (LONG)lpStartAddress;
// ThreadContext.Eip = (LONG)lpStartAddress;
ThreadContext.Eip = (LONG)ThreadStartup;
ThreadContext.SegGs = USER_DS;
ThreadContext.SegFs = USER_DS;
ThreadContext.SegEs = USER_DS;
ThreadContext.SegDs = USER_DS;
ThreadContext.SegCs = USER_CS;
ThreadContext.SegSs = USER_DS;
ThreadContext.Esp = (ULONG)(BaseAddress + StackSize - 8);
ThreadContext.Esp = (ULONG)(BaseAddress + StackSize - 12);
ThreadContext.EFlags = (1<<1) + (1<<9);
/* write lpParameter to highest stack address */
*((PBYTE)(BaseAddress + StackSize - 4)) = lpParameter;
/* initialize call stack */
*((PULONG)(BaseAddress + StackSize - 4)) = (ULONG)lpParameter;
*((PULONG)(BaseAddress + StackSize - 8)) = (ULONG)lpStartAddress;
*((PULONG)(BaseAddress + StackSize - 12)) = 0xdeadbeef;
DPRINT("Esp: %p\n", ThreadContext.Esp);
DPRINT("Eip: %p\n", ThreadContext.Eip);
Status = NtCreateThread(&ThreadHandle,
THREAD_ALL_ACCESS,

View file

@ -132,8 +132,8 @@ RtlCreateUserThread(HANDLE ProcessHandle,
LONG StackZeroBits,
PULONG StackReserved,
PULONG StackCommit,
PVOID StartAddress,
HANDLE DebugPort,
PTHREAD_START_ROUTINE StartAddress,
PVOID Parameter,
PHANDLE ThreadHandle,
PCLIENT_ID ClientId)
{
@ -214,6 +214,9 @@ DPRINT("Checkpoint\n");
ObjectAttributes.SecurityQualityOfService = NULL;
if (*StackCommit < 4096)
*StackCommit = 4096;
BaseAddress = 0;
ZwAllocateVirtualMemory(ProcessHandle,
&BaseAddress,
@ -271,8 +274,8 @@ DPRINT("Checkpoint\n");
NTSTATUS STDCALL
RtlInitializeContext(HANDLE ProcessHandle,
PCONTEXT Context,
HANDLE DebugPort,
PVOID StartAddress,
PVOID Parameter,
PTHREAD_START_ROUTINE StartAddress,
PINITIAL_TEB InitialTeb)
{
NTSTATUS Status;
@ -289,8 +292,16 @@ RtlInitializeContext(HANDLE ProcessHandle,
Context->SegDs = 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;

View file

@ -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
}

View file

@ -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);

View file

@ -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,