diff --git a/reactos/Makefile b/reactos/Makefile index 398e18c024d..d2b0a37d4b3 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -41,7 +41,7 @@ FS_DRIVERS = vfat # FS_DRIVERS = minix ext2 template KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS) -APPS = args hello shell test cat bench apc shm lpc +APPS = args hello shell test cat bench apc shm lpc thread # APPS = cmd all: buildno $(COMPONENTS) $(DLLS) $(SUBSYS) $(LOADERS) $(KERNEL_SERVICES) $(APPS) diff --git a/reactos/apps/tests/thread/makefile b/reactos/apps/tests/thread/makefile new file mode 100644 index 00000000000..d2d18d38f54 --- /dev/null +++ b/reactos/apps/tests/thread/makefile @@ -0,0 +1,41 @@ +# +# +# +PROGS = thread + +all: $(PROGS:%=%.exe) + +.phony: all + +clean: $(PROGS:%=%_clean) + +$(PROGS:%=%_clean): %_clean: + - $(RM) $*.o + - $(RM) $*.exe + - $(RM) $*.sym + +.phony: clean + +floppy: # $(PROGS:%=$(FLOPPY_DIR)/apps/%.exe) + +$(PROGS:%=$(FLOPPY_DIR)/apps/%.exe): $(FLOPPY_DIR)/apps/%.exe: %.exe +ifeq ($(DOSCLI),yes) + $(CP) $*.exe $(FLOPPY_DIR)\apps\$*.exe +else + $(CP) $*.exe $(FLOPPY_DIR)/apps/$*.exe +endif + +dist: $(PROGS:%=../../$(DIST_DIR)/apps/%.exe) + +$(PROGS:%=../../$(DIST_DIR)/apps/%.exe): ../../$(DIST_DIR)/apps/%.exe: %.exe +ifeq ($(DOSCLI),yes) + $(CP) $*.exe ..\..\$(DIST_DIR)\apps\$*.exe +else + $(CP) $*.exe ../../$(DIST_DIR)/apps/$*.exe +endif + +thread.exe: thread.c + $(CC) $(CFLAGS) thread.c -lkernel32 -o thread.exe + $(NM) --numeric-sort thread.exe > thread.sym + +include ../../rules.mak diff --git a/reactos/apps/tests/thread/thread.c b/reactos/apps/tests/thread/thread.c new file mode 100644 index 00000000000..2b03be5a85f --- /dev/null +++ b/reactos/apps/tests/thread/thread.c @@ -0,0 +1,45 @@ +#include +#include + +#define NR_THREADS (10) + +ULONG nr; + +DWORD WINAPI thread_main1(LPVOID param) +{ + ULONG s; + + printf("Thread %d running\n", (DWORD)param); + s = nr = ((nr * 1103515245) + 12345) & 0x7fffffff; + s = s % 10; + printf("s %d\n", s); + Sleep(s); + return 0; +} + +int main (int argc, char* argv[]) +{ + HANDLE hThread; + DWORD i=0; + DWORD id; + ULONG nr; + + nr = atoi(argv[1]); + printf("Seed %d\n", nr); + + printf("Creating %d threads...\n",NR_THREADS*2); + for (i=0;i #include -//#define NDEBUG +#define NDEBUG #include diff --git a/reactos/lib/ntdll/ldr/utils.c b/reactos/lib/ntdll/ldr/utils.c index 27d64e92299..0d2d9e5547d 100644 --- a/reactos/lib/ntdll/ldr/utils.c +++ b/reactos/lib/ntdll/ldr/utils.c @@ -1,4 +1,4 @@ -/* $Id: utils.c,v 1.19 1999/12/11 21:14:47 dwelch Exp $ +/* $Id: utils.c,v 1.20 1999/12/13 22:04:34 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -698,7 +698,7 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders, PDLL Module; NTSTATUS Status; - DPRINT1("LdrFixupImports(NTHeaders %x, ImageBase %x)\n", NTHeaders, + DPRINT("LdrFixupImports(NTHeaders %x, ImageBase %x)\n", NTHeaders, ImageBase); /* @@ -708,7 +708,7 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders, ImageBase + NTHeaders->OptionalHeader .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] .VirtualAddress); - DPRINT1("ImportModuleDirectory %x\n", ImportModuleDirectory); + DPRINT("ImportModuleDirectory %x\n", ImportModuleDirectory); while (ImportModuleDirectory->dwRVAModuleName) { @@ -717,7 +717,7 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders, DWORD pName; PWORD pHint; - DPRINT1("ImportModule->Directory->dwRVAModuleName %s\n", + DPRINT("ImportModule->Directory->dwRVAModuleName %s\n", (PCHAR)(ImageBase + ImportModuleDirectory->dwRVAModuleName)); Status = LdrLoadDll(&Module, diff --git a/reactos/ntoskrnl/hal/x86/irql.c b/reactos/ntoskrnl/hal/x86/irql.c index bce36232a18..7b3f9102b38 100644 --- a/reactos/ntoskrnl/hal/x86/irql.c +++ b/reactos/ntoskrnl/hal/x86/irql.c @@ -47,8 +47,6 @@ static unsigned int HiSetCurrentPICMask(unsigned int mask) return mask; } -extern VOID KeApcProlog2(); - static VOID HiSwitchIrql(KIRQL oldIrql) /* * FUNCTION: Switches to the current irql @@ -85,28 +83,37 @@ static VOID HiSwitchIrql(KIRQL oldIrql) __asm__("sti\n\t"); return; } - HiSetCurrentPICMask(0); - if(CurrentIrql == APC_LEVEL) - { - if (DpcQueueSize > 0 ) - { - KeSetCurrentIrql(DISPATCH_LEVEL); - __asm__("sti\n\t"); - KeDrainDpcQueue(); - __asm__("cli\n\t"); - KeSetCurrentIrql(PASSIVE_LEVEL); - } - __asm__("sti\n\t"); - return; - } - if( CurrentIrql == PASSIVE_LEVEL && CurrentThread && CurrentThread->ApcState.KernelApcPending ) - { - KeSetCurrentIrql( APC_LEVEL ); - KeApcProlog2(); - KeSetCurrentIrql( PASSIVE_LEVEL ); - } - - __asm__("sti\n\t"); + + HiSetCurrentPICMask(0); + if (CurrentIrql == APC_LEVEL) + { + if (DpcQueueSize > 0 ) + { + KeSetCurrentIrql(DISPATCH_LEVEL); + __asm__("sti\n\t"); + KeDrainDpcQueue(); + __asm__("cli\n\t"); + KeSetCurrentIrql(PASSIVE_LEVEL); + } + __asm__("sti\n\t"); + return; + } + + if (CurrentIrql == PASSIVE_LEVEL && + CurrentThread != NULL && + CurrentThread->ApcState.KernelApcPending) + { + KeSetCurrentIrql(APC_LEVEL); + __asm__("sti\n\t"); + KeCallApcsThread(); + __asm__("cli\n\t"); + KeSetCurrentIrql(PASSIVE_LEVEL); + __asm__("sti\n\t"); + } + else + { + __asm__("sti\n\t"); + } } VOID KeSetCurrentIrql(KIRQL newlvl) diff --git a/reactos/ntoskrnl/hal/x86/spinlock.c b/reactos/ntoskrnl/hal/x86/spinlock.c index 72ab20671d2..995a187ac72 100644 --- a/reactos/ntoskrnl/hal/x86/spinlock.c +++ b/reactos/ntoskrnl/hal/x86/spinlock.c @@ -67,13 +67,9 @@ VOID KeAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock) * SpinLock = Spinlock to acquire */ { - if (SpinLock->Lock == 1) - { - DbgPrint("May be acquiring locked spinlock\n"); - } while (InterlockedExchange(&SpinLock->Lock, 1) == 1) { - DbgPrint("Spinning on spinlock\n"); + DbgPrint("Spinning on spinlock %x\n", SpinLock); KeBugCheck(0); } } diff --git a/reactos/ntoskrnl/io/irp.c b/reactos/ntoskrnl/io/irp.c index f58e67239ce..87c088751fe 100644 --- a/reactos/ntoskrnl/io/irp.c +++ b/reactos/ntoskrnl/io/irp.c @@ -253,7 +253,7 @@ VOID IopCompleteRequest(struct _KAPC* Apc, "(*SystemArgument1) %x\n", Apc, SystemArgument1, *SystemArgument1); IoSecondStageCompletion((PIRP)(*SystemArgument1), - SystemArgument2); + (KPRIORITY)(*SystemArgument2)); } VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost) @@ -270,8 +270,8 @@ VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost) NTSTATUS Status; PKTHREAD Thread; - DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n", - Irp,PriorityBoost); + DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n", + Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread()); for (i=0;iStackCount;i++) { @@ -307,14 +307,16 @@ VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost) (PVOID) Irp->Overlay.AsynchronousParameters.UserApcContext); KeInsertQueueApc(&Irp->Tail.Apc, - Irp, - PriorityBoost, + (PVOID)Irp, + (PVOID)(ULONG)PriorityBoost, KernelMode); + DPRINT("Finished dispatching APC\n"); } else { DPRINT("Calling completion routine directly\n"); IoSecondStageCompletion(Irp,PriorityBoost); + DPRINT("Finished completition routine\n"); } } diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 61a1902bc42..ad41ffd106f 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -16,19 +16,32 @@ #include #include #include +#include #define NDEBUG #include -extern VOID KeApcProlog(VOID); +/* GLOBALS *******************************************************************/ + static KSPIN_LOCK PiApcLock; -/* PROTOTYPES ****************************************************************/ - -VOID KeApcProlog3(PKAPC Apc); - /* FUNCTIONS *****************************************************************/ +VOID KeCallKernelRoutineApc(PKAPC Apc) +/* + * FUNCTION: Call the kernel routine for an APC + */ +{ + DPRINT("KeCallKernelRoutineApc(Apc %x)\n",Apc); + + Apc->KernelRoutine(Apc, + &Apc->NormalRoutine, + &Apc->NormalContext, + &Apc->SystemArgument1, + &Apc->SystemArgument2); + DPRINT("Finished KeCallKernelRoutineApc()\n"); +} + BOOLEAN KiTestAlert(PKTHREAD Thread, PCONTEXT UserContext) /* @@ -77,81 +90,41 @@ BOOLEAN KiTestAlert(PKTHREAD Thread, * Now call for the kernel routine for the APC, which will free * the APC data structure */ - KeApcProlog3(Apc); + KeCallKernelRoutineApc(Apc); } UserContext->Esp = (ULONG)Esp; InitializeListHead(&Thread->ApcState.ApcListHead[1]); return(TRUE); } -VOID KeApcProlog2() +VOID KeCallApcsThread(VOID) { PETHREAD Thread = PsGetCurrentThread(); PLIST_ENTRY current; PKAPC Apc; KIRQL oldlvl; - DPRINT( "KeApcProlog2()\n" ); - KeLowerIrql( APC_LEVEL ); - KeAcquireSpinLock( &PiApcLock, &oldlvl ); - while( !IsListEmpty( &(Thread->Tcb.ApcState.ApcListHead[0]) ) ) + DPRINT("KeCallApcsThread()\n"); + KeAcquireSpinLock(&PiApcLock, &oldlvl); + while(!IsListEmpty(&(Thread->Tcb.ApcState.ApcListHead[0]))) { - DPRINT( "Delivering APC\n" ); - current = RemoveTailList( &(Thread->Tcb.ApcState.ApcListHead[0]) ); - KeReleaseSpinLock( &PiApcLock, oldlvl ); - Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry); - KeApcProlog3(Apc); - KeAcquireSpinLock( &PiApcLock, &oldlvl ); + DPRINT("Delivering APC\n"); + current = RemoveTailList(&(Thread->Tcb.ApcState.ApcListHead[0])); + Thread->Tcb.ApcState.KernelApcInProgress++; + Thread->Tcb.ApcState.KernelApcPending--; + KeReleaseSpinLock(&PiApcLock, oldlvl); + + Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry); + KeCallKernelRoutineApc(Apc); + + KeAcquireSpinLock(&PiApcLock, &oldlvl); + DPRINT("Called kernel routine for APC\n"); +// PsFreezeThread(Thread, NULL, FALSE, KernelMode); + DPRINT("Done frozen thread\n"); + Thread->Tcb.ApcState.KernelApcInProgress--; } - KeReleaseSpinLock( &PiApcLock, oldlvl ); - Thread->Tcb.WaitStatus = STATUS_ALERTED; - KeLowerIrql( PASSIVE_LEVEL ); -} - -VOID KeApcProlog3(PKAPC Apc) -/* - * FUNCTION: This is called from the prolog proper (in assembly) to deliver - * a kernel APC - */ -{ - PKTHREAD Thread = KeGetCurrentThread(); - DPRINT("KeApcProlog3(Apc %x)\n",Apc); - InterlockedIncrement( &(Thread->ApcState.KernelApcInProgress) ); - InterlockedDecrement( &(Thread->ApcState.KernelApcPending) ); - - Apc->KernelRoutine(Apc, - &Apc->NormalRoutine, - &Apc->NormalContext, - &Apc->SystemArgument1, - &Apc->SystemArgument2); - InterlockedDecrement( &(Thread->ApcState.KernelApcInProgress) ); -} - -VOID KeDeliverKernelApc( PKTHREAD TargetThread ) -/* - * FUNCTION: Simulates an interrupt on the target thread which will transfer - * control to a kernel mode routine - * Must be called while holding the PiApcLock - */ -{ - PULONG Stack; - - DPRINT( "KeDeliverKernelApc( TargetThread %x)\n", TargetThread ); - if (TargetThread == KeGetCurrentThread()) - { - KeApcProlog2(); - return; - } - - TargetThread->Context.esp = TargetThread->Context.esp - 12; - Stack = (PULONG)TargetThread->Context.esp; - Stack[0] = TargetThread->Context.eip; - Stack[1] = TargetThread->Context.cs; - Stack[2] = TargetThread->Context.eflags; - TargetThread->Context.eip = (ULONG)KeApcProlog; - - PsResumeThread(CONTAINING_RECORD(TargetThread,ETHREAD,Tcb), - NULL); + KeReleaseSpinLock(&PiApcLock, oldlvl); +// Thread->Tcb.WaitStatus = STATUS_KERNEL_APC; } VOID KeInsertQueueApc(PKAPC Apc, @@ -173,7 +146,7 @@ VOID KeInsertQueueApc(PKAPC Apc, "SystemArgument2 %x, Mode %d)\n",Apc,SystemArgument1, SystemArgument2,Mode); - KeAcquireSpinLock( &PiApcLock, &oldlvl ); + KeAcquireSpinLock(&PiApcLock, &oldlvl); Apc->SystemArgument1 = SystemArgument1; Apc->SystemArgument2 = SystemArgument2; @@ -200,25 +173,12 @@ VOID KeInsertQueueApc(PKAPC Apc, } Apc->Inserted = TRUE; - DPRINT("TargetThread->KernelApcDisable %d\n", - TargetThread->KernelApcDisable); - DPRINT("Apc->KernelRoutine %x\n", Apc->KernelRoutine); - DPRINT( "TargetThread->Altertable = %x, TargetThread->WaitIrql = %d\n", TargetThread->Alertable, TargetThread->WaitIrql ); - if (Apc->ApcMode == KernelMode && TargetThread->KernelApcDisable >= 1 ) - if( TargetThread != PsGetCurrentThread() ) - { - PsSuspendThread( CONTAINING_RECORD( TargetThread, ETHREAD, Tcb ), NULL, TRUE, KernelMode ); - KeReleaseSpinLock( &PiApcLock, oldlvl ); - if( TargetThread->WaitIrql < APC_LEVEL ) - KeDeliverKernelApc( TargetThread ); - } - else { - if( TargetThread->WaitIrql < APC_LEVEL ) - KeDeliverKernelApc( TargetThread ); - } - else + if (Apc->ApcMode == KernelMode && TargetThread->KernelApcDisable >= 1 && + TargetThread->WaitIrql < APC_LEVEL) { - DPRINT("Queuing APC for later delivery\n"); + KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb), + STATUS_KERNEL_APC); + KeReleaseSpinLock(&PiApcLock, oldlvl); } if (Apc->ApcMode == UserMode && TargetThread->Alertable == TRUE && TargetThread->WaitMode == UserMode) @@ -228,8 +188,9 @@ VOID KeInsertQueueApc(PKAPC Apc, DPRINT("Resuming thread for user APC\n"); Status = STATUS_USER_APC; - PsResumeThread((PETHREAD)TargetThread, - &Status); + KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb), + STATUS_USER_APC); + KeReleaseSpinLock(&PiApcLock, oldlvl); } } @@ -332,8 +293,8 @@ NTSTATUS STDCALL NtTestAlert(VOID) return(STATUS_SUCCESS); } -VOID PiInitApcManagement() +VOID PiInitApcManagement(VOID) { - KeInitializeSpinLock( &PiApcLock ); + KeInitializeSpinLock(&PiApcLock); } diff --git a/reactos/ntoskrnl/ke/bug.c b/reactos/ntoskrnl/ke/bug.c index 8c89f9734f7..754debdeba7 100644 --- a/reactos/ntoskrnl/ke/bug.c +++ b/reactos/ntoskrnl/ke/bug.c @@ -19,6 +19,7 @@ /* GLOBALS ******************************************************************/ static LIST_ENTRY BugcheckCallbackListHead = {NULL,NULL}; +static ULONG InBugCheck; VOID PsDumpThreads(VOID); @@ -32,6 +33,7 @@ BOOLEAN KeDeregisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord) VOID KeInitializeBugCheck(VOID) { InitializeListHead(&BugcheckCallbackListHead); + InBugCheck = 0; } VOID KeInitializeCallbackRecord(PKBUGCHECK_CALLBACK_RECORD CallbackRecord) @@ -72,7 +74,7 @@ VOID KeBugCheckEx(ULONG BugCheckCode, BugCheckParameter1,BugCheckParameter2,BugCheckParameter3, BugCheckParameter4); PsDumpThreads(); - KeDumpStackFrames(0,64); + KeDumpStackFrames(&((&BugCheckCode)[-1]),64); for(;;) __asm__("hlt\n\t"); //PJS: use HLT instruction, rather than busy wait @@ -87,6 +89,19 @@ VOID KeBugCheck(ULONG BugCheckCode) * RETURNS: Doesn't */ { - KeBugCheckEx(BugCheckCode,0,0,0,0); + __asm__("cli\n\t"); + DbgPrint("Bug detected (code %x)\n", BugCheckCode); + if (InBugCheck == 1) + { + DbgPrint("Recursive bug check halting now\n"); + for(;;); + } + InBugCheck = 1; + PsDumpThreads(); + KeDumpStackFrames(&((&BugCheckCode)[-1]), 80); + for(;;) + { + __asm__("hlt\n\t"); + } } diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 688471a9d16..2394ad27768 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -242,7 +242,7 @@ asmlinkage void exception_handler(unsigned int edi, } DbgPrint("CS:EIP %x:%x\n",cs&0xffff,eip); DbgPrint("CS:EIP %x:", cs&0xffff); - print_address(eip); + print_address((PVOID)eip); DbgPrint("\n"); __asm__("movl %%cr2,%0\n\t" : "=d" (cr2)); @@ -302,7 +302,7 @@ asmlinkage void exception_handler(unsigned int edi, stack[i] <= ((ULONG)&init_stack_top))) { // DbgPrint(" %.8x", stack[i]); - print_address(stack[i]); + print_address((PVOID)stack[i]); DbgPrint(" "); } } @@ -328,6 +328,7 @@ asmlinkage void exception_handler(unsigned int edi, DbgPrint("\n"); DbgPrint("Killing current task\n"); +// for(;;); KeLowerIrql(PASSIVE_LEVEL); if ((cs&0xffff) == USER_CS) { @@ -338,12 +339,13 @@ asmlinkage void exception_handler(unsigned int edi, for(;;); } -VOID KeDumpStackFrames(ULONG DummyArg, ULONG NrFrames) +VOID KeDumpStackFrames(PVOID _Stack, ULONG NrFrames) { - PULONG Stack = &((&DummyArg)[-1]); + PULONG Stack = (PULONG)_Stack; ULONG i; Stack = (PVOID)(((ULONG)Stack) & (~0x3)); + DbgPrint("Stack: %x\n", Stack); DbgPrint("Frames:\n"); for (i=0; i KERNEL_BASE) { // DbgPrint("%.8x ",Stack[i]); - print_address(Stack[i]); + print_address((PVOID)Stack[i]); DbgPrint(" "); } if (Stack[i] == 0xceafbeef) diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index 2426de7c320..e730e4a4736 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.31 1999/11/24 11:51:50 dwelch Exp $ +/* $Id: main.c,v 1.32 1999/12/13 22:04:36 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -26,7 +26,7 @@ #include #include -#define NDEBUG +//#define NDEBUG #include /* FUNCTIONS ****************************************************************/ @@ -128,70 +128,6 @@ unsigned int old_idt[256][2]; //extern unsigned int idt[]; unsigned int old_idt_valid = 1; -ERESOURCE TestResource; - -NTSTATUS thread_main(PVOID param) -{ - ULONG Id; - - Id = (ULONG)param; - - DbgPrint("THREAD(%d) Resource %x\n",Id,&TestResource); - - DbgPrint("THREAD(%d) Acquiring resource for shared access\n", Id); - - ExAcquireResourceExclusiveLite(&TestResource, TRUE); - - DbgPrint("THREAD(%d) Acquired resource for shared access\n", Id); - - return(STATUS_SUCCESS); -} - -VOID resource_test(VOID) -{ - HANDLE thread1_handle; - CLIENT_ID thread1_cid; - HANDLE thread2_handle; - CLIENT_ID thread2_cid; - ULONG i; - - ExInitializeResourceLite(&TestResource); - - DbgPrint("Resource %x\n", &TestResource); - - ExAcquireResourceExclusiveLite(&TestResource, TRUE); - - DbgPrint("Acquired resource for exclusive access\n"); - - PsCreateSystemThread(&thread1_handle, - THREAD_ALL_ACCESS, - NULL, - NULL, - &thread1_cid, - thread_main, - (PVOID)1); - PsCreateSystemThread(&thread2_handle, - THREAD_ALL_ACCESS, - NULL, - NULL, - &thread2_cid, - thread_main, - (PVOID)2); - - DbgPrint("KeGetCurrentIrql() %d\n", KeGetCurrentIrql()); - - for (i=0; i<10000000; i++) - { - __asm__("nop\n\t"); - } - - ExReleaseResourceLite(&TestResource); - - DbgPrint("Released resource\n"); - - for(;;); -} - asmlinkage void _main(boot_param* _bp) /* * FUNCTION: Called by the boot loader to start the kernel @@ -271,7 +207,7 @@ asmlinkage void _main(boot_param* _bp) /* * Initalize services loaded at boot time */ - DPRINT("%d files loaded\n",bp.nr_files); + DPRINT1("%d files loaded\n",bp.nr_files); /* Pass 1: load registry chunks passed in */ start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]); @@ -279,7 +215,7 @@ asmlinkage void _main(boot_param* _bp) { if (!strcmp ((PCHAR) start, "REGEDIT4")) { - DPRINT("process registry chunk at %08lx\n", start); + DPRINT1("process registry chunk at %08lx\n", start); CmImportHive((PCHAR) start); } start = start + bp.module_length[i]; @@ -292,7 +228,7 @@ asmlinkage void _main(boot_param* _bp) { if (strcmp ((PCHAR) start, "REGEDIT4")) { - DPRINT("process module at %08lx\n", start); + DPRINT1("process module at %08lx\n", start); LdrProcessDriver((PVOID)start); } start = start + bp.module_length[i]; @@ -301,13 +237,15 @@ asmlinkage void _main(boot_param* _bp) /* * Load Auto configured drivers */ + CHECKPOINT; LdrLoadAutoConfigDrivers(); /* * Launch initial process */ - LdrLoadInitialProcess(); - + CHECKPOINT; + LdrLoadInitialProcess(); + /* * Enter idle loop */ diff --git a/reactos/ntoskrnl/ke/timer.c b/reactos/ntoskrnl/ke/timer.c index 1e335bdb884..2382ec2335a 100644 --- a/reactos/ntoskrnl/ke/timer.c +++ b/reactos/ntoskrnl/ke/timer.c @@ -1,4 +1,4 @@ -/* $Id: timer.c,v 1.23 1999/12/11 17:25:26 phreak Exp $ +/* $Id: timer.c,v 1.24 1999/12/13 22:04:36 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -132,8 +132,11 @@ NTSTATUS KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval) NTSTATUS STDCALL NtDelayExecution(IN BOOLEAN Alertable, IN TIME* Interval) { - UNIMPLEMENTED; - return(STATUS_UNSUCCESSFUL); + NTSTATUS Status; + + Status = KeDelayExecutionThread(UserMode, Alertable, + (PLARGE_INTEGER)Internal); + return(Status); } @@ -396,7 +399,7 @@ VOID KeExpireTimers(VOID) // DPRINT("current_entry->Flink %x\n",current_entry->Flink); // DPRINT("current_entry->Flink->Flink %x\n",current_entry->Flink->Flink); - KeRaiseIrql( HIGH_LEVEL, &oldlvl ); + KeRaiseIrql(HIGH_LEVEL, &oldlvl); KeAcquireSpinLockAtDpcLevel(&TimerListLock); while (current_entry!=(&TimerListHead)) @@ -411,7 +414,7 @@ VOID KeExpireTimers(VOID) } } - KeReleaseSpinLock( &TimerListLock, oldlvl ); + KeReleaseSpinLock(&TimerListLock, oldlvl); // DPRINT("Finished KeExpireTimers()\n"); } @@ -429,7 +432,7 @@ VOID KiTimerInterrupt(VOID) extern unsigned int EiFreeNonPagedPool; extern unsigned int EiUsedNonPagedPool; extern ULONG PiNrThreads; - extern ULONG MiNrFreePages; +// extern ULONG MiNrFreePages; if (TimerInitDone == FALSE) { @@ -462,7 +465,8 @@ VOID KiTimerInterrupt(VOID) // sprintf(str,"%.8u %.8u",(unsigned int)EiNrUsedBlocks, // (unsigned int)EiFreeNonPagedPool); // sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,EiUsedNonPagedPool); - sprintf(str,"%.8u %.8u",(unsigned int)PiNrRunnableThreads,(unsigned int)PiNrThreads); + sprintf(str,"%.8u %.8u",(unsigned int)PiNrRunnableThreads, + (unsigned int)PiNrThreads); // sprintf(str,"%.8u %.8u", (unsigned int)PiNrRunnableThreads, // (unsigned int)MiNrFreePages); for (i=0;i<17;i++) diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 24ed409c521..4e1f4d3f22b 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -18,6 +18,7 @@ #include #include +#include #define NDEBUG #include @@ -120,6 +121,32 @@ static BOOLEAN KiIsObjectSignalled(DISPATCHER_HEADER* hdr) return(TRUE); } +VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus) +{ + PKWAIT_BLOCK WaitBlock; + BOOLEAN WasWaiting = FALSE; + + KeAcquireDispatcherDatabaseLock(FALSE); + + WaitBlock = (PKWAIT_BLOCK)Thread->Tcb.WaitBlockList; + if (WaitBlock != NULL) + { + WasWaiting = TRUE; + } + while (WaitBlock != NULL) + { + RemoveEntryList(&WaitBlock->WaitListEntry); + WaitBlock = WaitBlock->NextWaitBlock; + } + Thread->Tcb.WaitBlockList = NULL; + + if (WasWaiting) + { + PsUnfreezeThread(Thread, &WaitStatus); + } + + KeReleaseDispatcherDatabaseLock(FALSE); +} static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) { @@ -136,21 +163,21 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) while (!IsListEmpty(&(hdr->WaitListHead))) { - NTSTATUS Status = STATUS_WAIT_0; - current_entry = RemoveHeadList(&hdr->WaitListHead); - current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK, - WaitListEntry); + NTSTATUS Status = STATUS_WAIT_0; + current_entry = RemoveHeadList(&hdr->WaitListHead); + current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK, + WaitListEntry); DPRINT("Waking %x\n",current->Thread); if (current->WaitType == WaitAny) { DPRINT("WaitAny: Remove all wait blocks.\n"); - //count the number of the wait block that is waking us, and set that as the wake status - for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; ++Status, PrevBlock = PrevBlock->NextWaitBlock ) - if( PrevBlock == current ) - break; - if( PrevBlock == 0 ) - DbgPrint( "WaitOne: Wait Block not in list! Wait result will be corrupt\n" ); + //count the number of the wait block that is waking us, and set that as the wake status + for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; ++Status, PrevBlock = PrevBlock->NextWaitBlock ) + if( PrevBlock == current ) + break; + if( PrevBlock == 0 ) + DbgPrint( "WaitOne: Wait Block not in list! Wait result will be corrupt\n" ); current->Thread->WaitBlockList = NULL; } else @@ -188,8 +215,8 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) KiSideEffectsBeforeWake(hdr); - PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), - &Status); + PsUnfreezeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), + &Status); }; return(TRUE); } @@ -261,8 +288,8 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) KiSideEffectsBeforeWake(hdr); - PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), - &Status); + PsUnfreezeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), + &Status); return(TRUE); } @@ -356,43 +383,53 @@ NTSTATUS KeWaitForSingleObject(PVOID Object, return(STATUS_USER_APC); } - KeAcquireDispatcherDatabaseLock(FALSE); - - DPRINT("hdr->SignalState %d\n", hdr->SignalState); - - if (KiIsObjectSignalled(hdr)) - { - KeReleaseDispatcherDatabaseLock(FALSE); - return(STATUS_WAIT_0); - } - if (Timeout != NULL) { - KeAddThreadTimeout(CurrentThread,Timeout); + KeAddThreadTimeout(CurrentThread,Timeout); } - - /* Append wait block to the KTHREAD wait block list */ - CurrentThread->WaitBlockList = &blk; - - blk.Object = Object; - blk.Thread = CurrentThread; - blk.WaitKey = 0; - blk.WaitType = WaitAny; - blk.NextWaitBlock = NULL; - DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x blk.WaitListEntry = %x\n", - hdr->WaitListHead.Flink,hdr->WaitListHead.Blink, blk.WaitListEntry ); - InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry)); - KeReleaseDispatcherDatabaseLock(FALSE); - DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__, - KeGetCurrentIrql()); - PsSuspendThread(PsGetCurrentThread(), - &Status, - (UCHAR)Alertable, - WaitMode); + + do + { + KeAcquireDispatcherDatabaseLock(FALSE); + + DPRINT("hdr->SignalState %d\n", hdr->SignalState); + + if (KiIsObjectSignalled(hdr)) + { + KeReleaseDispatcherDatabaseLock(FALSE); + if (Timeout != NULL) + { + KeCancelTimer(&KeGetCurrentThread()->Timer); + } + return(STATUS_WAIT_0); + } + + /* Append wait block to the KTHREAD wait block list */ + CurrentThread->WaitBlockList = &blk; + + blk.Object = Object; + blk.Thread = CurrentThread; + blk.WaitKey = 0; + blk.WaitType = WaitAny; + blk.NextWaitBlock = NULL; + DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x blk.WaitListEntry = %x\n", + hdr->WaitListHead.Flink,hdr->WaitListHead.Blink, blk.WaitListEntry ); + InsertTailList(&hdr->WaitListHead, &blk.WaitListEntry); + KeReleaseDispatcherDatabaseLock(FALSE); + DPRINT("Waiting for %x with irql %d\n", Object, KeGetCurrentIrql()); + PsFreezeThread(PsGetCurrentThread(), + &Status, + (UCHAR)Alertable, + WaitMode); + DPRINT("Woke from wait\n"); + + } while (Status == STATUS_KERNEL_APC); if (Timeout != NULL) + { KeCancelTimer(&KeGetCurrentThread()->Timer); - + } + DPRINT("Returning from KeWaitForSingleObject()\n"); return Status; } @@ -505,7 +542,7 @@ NTSTATUS KeWaitForMultipleObjects(ULONG Count, DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__, KeGetCurrentIrql()); - PsSuspendThread(PsGetCurrentThread(), + PsFreezeThread(PsGetCurrentThread(), &Status, Alertable, WaitMode); diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 7ed8dc195d2..4feaf2aac9b 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -1,4 +1,4 @@ -/* $Id: loader.c,v 1.39 1999/12/04 04:59:38 bpalmer Exp $ +/* $Id: loader.c,v 1.40 1999/12/13 22:04:37 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -467,7 +467,7 @@ LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING pModuleName) unsigned int DriverSize, Idx, Idx2; ULONG RelocDelta, NumRelocs; DWORD CurrentSize, TotalRelocs; - PVOID DriverBase, CurrentBase; + PVOID DriverBase; PULONG PEMagic; PIMAGE_DOS_HEADER PEDosHeader; PIMAGE_FILE_HEADER PEFileHeader; diff --git a/reactos/ntoskrnl/makefile_rex b/reactos/ntoskrnl/makefile_rex index 64c9e9d127d..6fa3f1c7e05 100644 --- a/reactos/ntoskrnl/makefile_rex +++ b/reactos/ntoskrnl/makefile_rex @@ -1,4 +1,4 @@ -# $Id: makefile_rex,v 1.39 1999/12/10 17:04:35 dwelch Exp $ +# $Id: makefile_rex,v 1.40 1999/12/13 22:04:35 dwelch Exp $ # # ReactOS Operating System # @@ -26,7 +26,7 @@ RTL_OBJECTS = rtl/vsprintf.o rtl/lookas.o rtl/unicode.o rtl/time.o \ KE_OBJECTS = ke/main.o ke/timer.o ke/error.o ke/catch.o \ ke/dpc.o ke/wait.o ke/kqueue.o ke/dispatch.o \ ke/sem.o ke/critical.o ke/event.o ke/apc.o ke/bug.o \ - ke/mutex.o ke/kernel.o ke/ldt.o ke/apchelp.o \ + ke/mutex.o ke/kernel.o ke/ldt.o \ ke/process.o ke/gdt.o ke/idt.o ke/udelay.o KE_I386_OBJECTS = ke/i386/thread.o ke/i386/usercall.o ke/i386/exp.o @@ -48,7 +48,7 @@ IO_OBJECTS = io/iomgr.o io/create.o io/irp.o io/device.o io/rw.o \ OB_OBJECTS = ob/object.o ob/handle.o ob/namespc.o ob/ntobj.o ob/dirobj.o PS_OBJECTS = ps/psmgr.o ps/thread.o ps/process.o ps/idle.o ps/kill.o \ - ps/tinfo.o + ps/tinfo.o ps/create.o EX_OBJECTS = ex/work.o ex/fmutex.o ex/resource.o ex/time.o ex/interlck.o \ ex/callback.o ex/napi.o ex/power.o ex/sysinfo.o ex/locale.o \ @@ -226,6 +226,6 @@ ke/main.o: ke/main.c ../include/reactos/buildno.h #WITH_DEBUGGING = yes WIN32_LEAN_AND_MEAN = yes -#WARNINGS_ARE_ERRORS = yes +WARNINGS_ARE_ERRORS = yes include ../rules.mak diff --git a/reactos/ntoskrnl/mm/i386/memsafe.s b/reactos/ntoskrnl/mm/i386/memsafe.s index c1b38c7989a..6407dae74d0 100644 --- a/reactos/ntoskrnl/mm/i386/memsafe.s +++ b/reactos/ntoskrnl/mm/i386/memsafe.s @@ -71,4 +71,4 @@ _MmSafeCopyToUser: ret -_MemSafeCopyToUserEnd: +_MmSafeCopyToUserEnd: diff --git a/reactos/ntoskrnl/mm/pagefile.c b/reactos/ntoskrnl/mm/pagefile.c index 2c96adc47c2..e1e1ee56559 100644 --- a/reactos/ntoskrnl/mm/pagefile.c +++ b/reactos/ntoskrnl/mm/pagefile.c @@ -240,7 +240,7 @@ NTSTATUS STDCALL NtCreatePagingFile(IN PUNICODE_STRING PageFileName, break; } } - MiFreeSwapPages = MiFreeSwapPages + ActualSize; + MiFreeSwapPages = MiFreeSwapPages + MinimumSize; KeReleaseSpinLock(&PagingFileListLock, oldIrql); return(STATUS_SUCCESS); diff --git a/reactos/ntoskrnl/mm/virtual.c b/reactos/ntoskrnl/mm/virtual.c index 219d9594bd9..ce8c8492342 100644 --- a/reactos/ntoskrnl/mm/virtual.c +++ b/reactos/ntoskrnl/mm/virtual.c @@ -57,7 +57,7 @@ NTSTATUS MmReleaseMmInfo(PEPROCESS Process) PLIST_ENTRY CurrentEntry; PMEMORY_AREA Current; - DbgPrint("MmReleaseMmInfo(Process %x)\n",Process); + DPRINT("MmReleaseMmInfo(Process %x)\n",Process); while (!IsListEmpty(&Process->Pcb.MemoryAreaList)) { diff --git a/reactos/ntoskrnl/nt/port.c b/reactos/ntoskrnl/nt/port.c index 44971b11bf0..191cb7d38a4 100644 --- a/reactos/ntoskrnl/nt/port.c +++ b/reactos/ntoskrnl/nt/port.c @@ -1,4 +1,4 @@ -/* $Id: port.c,v 1.13 1999/12/10 17:04:36 dwelch Exp $ +/* $Id: port.c,v 1.14 1999/12/13 22:04:39 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -351,7 +351,7 @@ NTSTATUS STDCALL NtAcceptConnectPort (PHANDLE ServerPortHandle, { NTSTATUS Status; PEPORT NamedPort; - PEPORT OurPort; + PEPORT OurPort = NULL; PQUEUEDMESSAGE ConnectionRequest; KIRQL oldIrql; diff --git a/reactos/ntoskrnl/ps/create.c b/reactos/ntoskrnl/ps/create.c new file mode 100644 index 00000000000..2cb7916fb97 --- /dev/null +++ b/reactos/ntoskrnl/ps/create.c @@ -0,0 +1,392 @@ +/* $Id: create.c,v 1.1 1999/12/13 22:04:41 dwelch Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ps/thread.c + * PURPOSE: Thread managment + * PROGRAMMER: David Welch (welch@mcmail.com) + * REVISION HISTORY: + * 23/06/98: Created + * 12/10/99: Phillip Susi: Thread priorities, and APC work + */ + +/* + * NOTE: + * + * All of the routines that manipulate the thread queue synchronize on + * a single spinlock + * + */ + +/* INCLUDES ****************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +/* GLOBAL *******************************************************************/ + +static ULONG PiNextThreadUniqueId = 0; + +extern KSPIN_LOCK PiThreadListLock; +extern ULONG PiNrThreads; + +extern LIST_ENTRY PiThreadListHead; + +/* FUNCTIONS ***************************************************************/ + +static VOID PiTimeoutThread( struct _KDPC *dpc, PVOID Context, PVOID arg1, PVOID arg2 ) +{ + // wake up the thread, and tell it it timed out + NTSTATUS Status = STATUS_TIMEOUT; + PsUnfreezeThread( (ETHREAD *)Context, &Status ); +} + +VOID PiBeforeBeginThread(VOID) +{ + DPRINT("PiBeforeBeginThread()\n"); + //KeReleaseSpinLock(&PiThreadListLock, PASSIVE_LEVEL); + KeLowerIrql(PASSIVE_LEVEL); + DPRINT("KeGetCurrentIrql() %d\n", KeGetCurrentIrql()); +} + +VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext) +{ + NTSTATUS Ret; + +// KeReleaseSpinLock(&PiThreadListLock,PASSIVE_LEVEL); + KeLowerIrql(PASSIVE_LEVEL); + Ret = StartRoutine(StartContext); + PsTerminateSystemThread(Ret); + KeBugCheck(0); +} + +VOID PiDeleteThread(PVOID ObjectBody) +{ + KIRQL oldIrql; + DPRINT("PiDeleteThread(ObjectBody %x)\n",ObjectBody); + + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); + ObDereferenceObject(((PETHREAD)ObjectBody)->ThreadsProcess); + ((PETHREAD)ObjectBody)->ThreadsProcess = NULL; + PiNrThreads--; + RemoveEntryList(&((PETHREAD)ObjectBody)->Tcb.ThreadListEntry); + HalReleaseTask((PETHREAD)ObjectBody); + KeReleaseSpinLock(&PiThreadListLock, oldIrql); +} + +VOID PiCloseThread(PVOID ObjectBody, ULONG HandleCount) +{ + DPRINT("PiCloseThread(ObjectBody %x)\n", ObjectBody); + DPRINT("ObGetReferenceCount(ObjectBody) %d " + "ObGetHandleCount(ObjectBody) %d\n", + ObGetReferenceCount(ObjectBody), + ObGetHandleCount(ObjectBody)); +} + +NTSTATUS PsInitializeThread(HANDLE ProcessHandle, + PETHREAD * ThreadPtr, + PHANDLE ThreadHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ThreadAttributes) +{ + PETHREAD Thread; + NTSTATUS Status; + KIRQL oldIrql; + PEPROCESS Process; + + /* + * Reference process + */ + if (ProcessHandle != NULL) + { + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_CREATE_THREAD, + PsProcessType, + UserMode, + (PVOID*)&Process, + NULL); + if (Status != STATUS_SUCCESS) + { + DPRINT("Failed at %s:%d\n",__FILE__,__LINE__); + return(Status); + } + } + else + { + Process = SystemProcess; + ObReferenceObjectByPointer(Process, + PROCESS_CREATE_THREAD, + PsProcessType, + UserMode); + } + + /* + * Create and initialize thread + */ + Thread = ObCreateObject(ThreadHandle, + DesiredAccess, + ThreadAttributes, + PsThreadType); + DPRINT("Thread = %x\n",Thread); + + PiNrThreads++; + + Thread->Tcb.State = THREAD_STATE_SUSPENDED; + Thread->Tcb.SuspendCount = 0; + Thread->Tcb.FreezeCount = 1; + InitializeListHead(&Thread->Tcb.ApcState.ApcListHead[0]); + InitializeListHead(&Thread->Tcb.ApcState.ApcListHead[1]); + Thread->Tcb.KernelApcDisable = 1; + Thread->Tcb.WaitIrql = PASSIVE_LEVEL; + Thread->ThreadsProcess = Process; + KeInitializeDpc( &Thread->Tcb.TimerDpc, PiTimeoutThread, Thread ); + + KeInitializeDispatcherHeader(&Thread->Tcb.DispatcherHeader, + InternalThreadType, + sizeof(ETHREAD), + FALSE); + + InitializeListHead(&Thread->IrpList); + Thread->Cid.UniqueThread = (HANDLE)InterlockedIncrement( + &PiNextThreadUniqueId); + Thread->Cid.UniqueProcess = (HANDLE)Thread->ThreadsProcess->UniqueProcessId; + DPRINT("Thread->Cid.UniqueThread %d\n",Thread->Cid.UniqueThread); + + *ThreadPtr = Thread; + + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); + InsertTailList(&PiThreadListHead, &Thread->Tcb.ThreadListEntry); + KeReleaseSpinLock(&PiThreadListLock, oldIrql); + + Thread->Tcb.BasePriority = Thread->ThreadsProcess->Pcb.BasePriority; + Thread->Tcb.Priority = Thread->Tcb.BasePriority; + + return(STATUS_SUCCESS); +} + + +static NTSTATUS PsCreateTeb (HANDLE ProcessHandle, + PNT_TEB *TebPtr, + PETHREAD Thread, + PINITIAL_TEB InitialTeb) +{ + MEMORY_BASIC_INFORMATION Info; + NTSTATUS Status; + ULONG ByteCount; + ULONG RegionSize; + ULONG TebSize; + PVOID TebBase; + NT_TEB Teb; + + TebBase = (PVOID)0x7FFDE000; + TebSize = PAGESIZE; + + while (TRUE) + { + /* The TEB must reside in user space */ + Status = NtAllocateVirtualMemory(ProcessHandle, + &TebBase, + 0, + &TebSize, + MEM_COMMIT, + PAGE_READWRITE); + if (NT_SUCCESS(Status)) + { + DPRINT ("TEB allocated at %x\n", TebBase); + break; + } + else + { + DPRINT ("TEB allocation failed! Status %x\n",Status); + } + + TebBase = Info.BaseAddress - TebSize; + } + + DPRINT ("TebBase %p TebSize %lu\n", TebBase, TebSize); + + /* set all pointers to and from the TEB */ + Teb.Tib.Self = TebBase; + if (Thread->ThreadsProcess) + { + Teb.Peb = Thread->ThreadsProcess->Peb; /* No PEB yet!! */ + } + + /* store stack information from InitialTeb */ + if (InitialTeb != NULL) + { + Teb.Tib.StackBase = InitialTeb->StackBase; + Teb.Tib.StackLimit = InitialTeb->StackLimit; + + /* + * I don't know if this is really stored in a WNT-TEB, + * but it's needed to free the thread stack. (Eric Kohl) + */ + Teb.StackCommit = InitialTeb->StackCommit; + Teb.StackCommitMax = InitialTeb->StackCommitMax; + Teb.StackReserved = InitialTeb->StackReserved; + } + + + /* more initialization */ + Teb.Cid.UniqueThread = Thread->Cid.UniqueThread; + Teb.Cid.UniqueProcess = Thread->Cid.UniqueProcess; + + /* write TEB data into teb page */ + Status = NtWriteVirtualMemory(ProcessHandle, + TebBase, + &Teb, + sizeof(NT_TEB), + &ByteCount); + + if (!NT_SUCCESS(Status)) + { + /* free TEB */ + DPRINT ("Writing TEB failed!\n"); + + RegionSize = 0; + NtFreeVirtualMemory(ProcessHandle, + TebBase, + &RegionSize, + MEM_RELEASE); + + return Status; + } + + /* FIXME: fs:[0] = TEB */ + + if (TebPtr != NULL) + { +// *TebPtr = (PNT_TEB)TebBase; + } + + DPRINT ("TEB allocated at %p\n", TebBase); + + return Status; +} + + +NTSTATUS STDCALL NtCreateThread (PHANDLE ThreadHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + HANDLE ProcessHandle, + PCLIENT_ID Client, + PCONTEXT ThreadContext, + PINITIAL_TEB InitialTeb, + BOOLEAN CreateSuspended) +{ + PETHREAD Thread; + PNT_TEB TebBase; + NTSTATUS Status; + + DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n", + ThreadHandle,ThreadContext); + + Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle, + DesiredAccess,ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + Status = HalInitTaskWithContext(Thread,ThreadContext); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + Status = PsCreateTeb (ProcessHandle, + &TebBase, + Thread, + InitialTeb); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + /* Attention: TebBase is in user memory space */ +// Thread->Tcb.Teb = TebBase; + + Thread->StartAddress=NULL; + + if (Client!=NULL) + { + *Client=Thread->Cid; + } + + if (!CreateSuspended) + { + DPRINT("Not creating suspended\n"); + PsUnfreezeThread(Thread, NULL); + } + DPRINT("Thread %x\n", Thread); + DPRINT("ObGetReferenceCount(Thread) %d ObGetHandleCount(Thread) %x\n", + ObGetReferenceCount(Thread), ObGetHandleCount(Thread)); + DPRINT("Finished PsCreateThread()\n"); + return(STATUS_SUCCESS); +} + + +NTSTATUS PsCreateSystemThread(PHANDLE ThreadHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + HANDLE ProcessHandle, + PCLIENT_ID ClientId, + PKSTART_ROUTINE StartRoutine, + PVOID StartContext) +/* + * FUNCTION: Creates a thread which executes in kernel mode + * ARGUMENTS: + * ThreadHandle (OUT) = Caller supplied storage for the returned thread + * handle + * DesiredAccess = Requested access to the thread + * ObjectAttributes = Object attributes (optional) + * ProcessHandle = Handle of process thread will run in + * NULL to use system process + * ClientId (OUT) = Caller supplied storage for the returned client id + * of the thread (optional) + * StartRoutine = Entry point for the thread + * StartContext = Argument supplied to the thread when it begins + * execution + * RETURNS: Success or failure status + */ +{ + PETHREAD Thread; + NTSTATUS Status; + + DPRINT("PsCreateSystemThread(ThreadHandle %x, ProcessHandle %x)\n", + ThreadHandle,ProcessHandle); + + Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle, + DesiredAccess,ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + Thread->StartAddress=StartRoutine; + Status = HalInitTask(Thread,StartRoutine,StartContext); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + if (ClientId!=NULL) + { + *ClientId=Thread->Cid; + } + + PsUnfreezeThread(Thread, NULL); + + return(STATUS_SUCCESS); +} + diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index 2bc95ffe186..cd07204d2b0 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -16,7 +16,7 @@ #include #include -//#define NDEBUG +#define NDEBUG #include /* GLOBALS *******************************************************************/ @@ -32,17 +32,17 @@ VOID PsTerminateCurrentThread(NTSTATUS ExitStatus) * FUNCTION: Terminates the current thread */ { - KIRQL oldlvl; + KIRQL oldIrql; PETHREAD CurrentThread; PiNrRunnableThreads--; CurrentThread = PsGetCurrentThread(); - CurrentThread->ExitStatus = ExitStatus; - DPRINT("terminating %x\n",CurrentThread); - KeRaiseIrql(DISPATCH_LEVEL,&oldlvl); + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); + + CurrentThread->ExitStatus = ExitStatus; DPRINT("ObGetReferenceCount(CurrentThread) %d\n", ObGetReferenceCount(CurrentThread)); @@ -52,7 +52,7 @@ VOID PsTerminateCurrentThread(NTSTATUS ExitStatus) CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE; KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader); - PsDispatchThread(THREAD_STATE_TERMINATED_1); + PsDispatchThreadNoLock(THREAD_STATE_TERMINATED_1); KeBugCheck(0); } @@ -69,6 +69,7 @@ VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus) PiNrRunnableThreads--; RemoveEntryList(&Thread->Tcb.QueueListEntry); } + RemoveEntryList(&Thread->Tcb.ThreadListEntry); Thread->Tcb.State = THREAD_STATE_TERMINATED_2; Thread->Tcb.DispatcherHeader.SignalState = TRUE; KeDispatcherObjectWake(&Thread->Tcb.DispatcherHeader); diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index e12ad921273..d7db66eb1f2 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.39 1999/12/12 03:56:53 phreak Exp $ +/* $Id: thread.c,v 1.40 1999/12/13 22:04:41 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -46,7 +46,7 @@ KSPIN_LOCK PiThreadListLock; /* * PURPOSE: List of threads associated with each priority level */ -static LIST_ENTRY PiThreadListHead = { &PiThreadListHead, &PiThreadListHead }; +LIST_ENTRY PiThreadListHead; static LIST_ENTRY PriorityListHead[NR_THREAD_PRIORITY_LEVELS]; static BOOLEAN DoneInitYet = FALSE; ULONG PiNrThreads = 0; @@ -54,8 +54,6 @@ ULONG PiNrRunnableThreads = 0; static PETHREAD CurrentThread = NULL; -static ULONG PiNextThreadUniqueId = 0; - /* FUNCTIONS ***************************************************************/ PKTHREAD KeGetCurrentThread(VOID) @@ -88,7 +86,10 @@ VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus) if (current->ThreadsProcess == Process && current != PsGetCurrentThread()) { + KeReleaseSpinLock(&PiThreadListLock, oldlvl); PsTerminateOtherThread(current, ExitStatus); + KeAcquireSpinLock(&PiThreadListLock, &oldlvl); + current_entry = PiThreadListHead.Flink; } current_entry = current_entry->Flink; } @@ -104,31 +105,30 @@ static VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread) InsertTailList(&PriorityListHead[THREAD_PRIORITY_MAX+Priority], &Thread->Tcb.QueueListEntry); -} - -VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext) -{ - NTSTATUS Ret; - -// KeReleaseSpinLock(&PiThreadListLock,PASSIVE_LEVEL); - KeLowerIrql(PASSIVE_LEVEL); - Ret = StartRoutine(StartContext); - PsTerminateSystemThread(Ret); - KeBugCheck(0); + PiNrRunnableThreads++; } VOID PsDumpThreads(VOID) { PLIST_ENTRY current_entry; PETHREAD current; + ULONG t; + +// return; current_entry = PiThreadListHead.Flink; - + t = 0; + while (current_entry != &PiThreadListHead) { current = CONTAINING_RECORD(current_entry, ETHREAD, Tcb.ThreadListEntry); - + t++; + if (t >= PiNrThreads) + { + DbgPrint("Too many threads on list\n"); + return; + } DPRINT1("current %x current->Tcb.State %d eip %x ", current, current->Tcb.State, current->Tcb.Context.eip); @@ -148,6 +148,8 @@ VOID PsReapThreads(VOID) // DPRINT1("PsReapThreads()\n"); + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); + current_entry = PiThreadListHead.Flink; while (current_entry != &PiThreadListHead) @@ -159,11 +161,16 @@ VOID PsReapThreads(VOID) if (current->Tcb.State == THREAD_STATE_TERMINATED_1) { + RemoveEntryList(¤t->Tcb.ThreadListEntry); DPRINT("Reaping thread %x\n", current); current->Tcb.State = THREAD_STATE_TERMINATED_2; + KeReleaseSpinLock(&PiThreadListLock, oldIrql); ObDereferenceObject(current); + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); + current_entry = PiThreadListHead.Flink; } } + KeReleaseSpinLock(&PiThreadListLock, oldIrql); } static PETHREAD PsScanThreadList (KPRIORITY Priority) @@ -189,16 +196,11 @@ static PETHREAD PsScanThreadList (KPRIORITY Priority) } -static VOID PsDispatchThreadNoLock (ULONG NewThreadStatus) +VOID PsDispatchThreadNoLock (ULONG NewThreadStatus) { KPRIORITY CurrentPriority; PETHREAD Candidate; - if (!DoneInitYet) - { - return; - } - CurrentThread->Tcb.State = NewThreadStatus; if (CurrentThread->Tcb.State == THREAD_STATE_RUNNABLE) { @@ -213,6 +215,8 @@ static VOID PsDispatchThreadNoLock (ULONG NewThreadStatus) Candidate = PsScanThreadList(CurrentPriority); if (Candidate == CurrentThread) { + PiNrRunnableThreads--; + KeReleaseSpinLockFromDpcLevel(&PiThreadListLock); return; } if (Candidate != NULL) @@ -223,12 +227,10 @@ static VOID PsDispatchThreadNoLock (ULONG NewThreadStatus) CurrentThread = Candidate; + PiNrRunnableThreads--; KeReleaseSpinLockFromDpcLevel( &PiThreadListLock ); - HalTaskSwitch(&CurrentThread->Tcb); - KeAcquireSpinLockAtDpcLevel( &PiThreadListLock ); - DPRINT( "Woken up, grabbed lock\n" ); + HalTaskSwitch(&CurrentThread->Tcb); PsReapThreads(); - DPRINT( "Reaped\n" ); return; } } @@ -236,200 +238,98 @@ static VOID PsDispatchThreadNoLock (ULONG NewThreadStatus) KeBugCheck(0); } -VOID PiBeforeBeginThread(VOID) -{ - DPRINT("PiBeforeBeginThread()\n"); - //KeReleaseSpinLock(&PiThreadListLock, PASSIVE_LEVEL); - KeLowerIrql(PASSIVE_LEVEL); - DPRINT("KeGetCurrentIrql() %d\n", KeGetCurrentIrql()); -} - VOID PsDispatchThread(ULONG NewThreadStatus) { KIRQL oldIrql; - KeAcquireSpinLock(&PiThreadListLock, &oldIrql); + if (!DoneInitYet) + { + return; + } + + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); CurrentThread->Tcb.WaitIrql = oldIrql; // save wait Irql PsDispatchThreadNoLock(NewThreadStatus); - KeReleaseSpinLock(&PiThreadListLock, oldIrql); KeLowerIrql(oldIrql); // DPRINT("oldIrql %d\n",oldIrql); } -static VOID PiTimeoutThread( struct _KDPC *dpc, PVOID Context, PVOID arg1, PVOID arg2 ) -{ - // wake up the thread, and tell it it timed out - NTSTATUS Status = STATUS_TIMEOUT; - PsResumeThread( (ETHREAD *)Context, &Status ); -} +/* + * Suspend and resume may only be called to suspend the current thread, except by apc.c + */ -NTSTATUS PsInitializeThread(HANDLE ProcessHandle, - PETHREAD * ThreadPtr, - PHANDLE ThreadHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ThreadAttributes) -{ - PETHREAD Thread; - NTSTATUS Status; - - PiNrThreads++; - - Thread = ObCreateObject(ThreadHandle, - DesiredAccess, - ThreadAttributes, - PsThreadType); - DPRINT("Thread = %x\n",Thread); - Thread->Tcb.State = THREAD_STATE_SUSPENDED; - Thread->Tcb.SuspendCount = 1; - InitializeListHead(&Thread->Tcb.ApcState.ApcListHead[0]); - InitializeListHead(&Thread->Tcb.ApcState.ApcListHead[1]); - Thread->Tcb.KernelApcDisable = 1; - Thread->Tcb.WaitIrql = PASSIVE_LEVEL; - KeInitializeDpc( &Thread->Tcb.TimerDpc, PiTimeoutThread, Thread ); - - KeInitializeDispatcherHeader(&Thread->Tcb.DispatcherHeader, - InternalThreadType, - sizeof(ETHREAD), - FALSE); - - if (ProcessHandle != NULL) - { - Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_CREATE_THREAD, - PsProcessType, - UserMode, - (PVOID*)&Thread->ThreadsProcess, - NULL); - if (Status != STATUS_SUCCESS) - { - DPRINT("Failed at %s:%d\n",__FILE__,__LINE__); - ObDereferenceObject( Thread ); - PiNrThreads--; - return(Status); - } - } - else - { - Thread->ThreadsProcess = SystemProcess; - ObReferenceObjectByPointer(Thread->ThreadsProcess, - PROCESS_CREATE_THREAD, - PsProcessType, - UserMode); - } - InitializeListHead(&Thread->IrpList); - Thread->Cid.UniqueThread = (HANDLE)InterlockedIncrement( - &PiNextThreadUniqueId); - Thread->Cid.UniqueProcess = (HANDLE)Thread->ThreadsProcess->UniqueProcessId; - DPRINT("Thread->Cid.UniqueThread %d\n",Thread->Cid.UniqueThread); - - *ThreadPtr = Thread; - - InsertTailList(&PiThreadListHead, &Thread->Tcb.ThreadListEntry); - - Thread->Tcb.BasePriority = Thread->ThreadsProcess->Pcb.BasePriority; - Thread->Tcb.Priority = Thread->Tcb.BasePriority; - - return(STATUS_SUCCESS); -} - - -// Suspend and resume may only be called to suspend the current thread, except by apc.c - -ULONG PsResumeThread(PETHREAD Thread, - PNTSTATUS WaitStatus) +ULONG PsUnfreezeThread(PETHREAD Thread, PNTSTATUS WaitStatus) { KIRQL oldIrql; ULONG r; - - DPRINT("PsResumeThread(Thread %x) CurrentThread %x \n",Thread, - PsGetCurrentThread()); - DPRINT("Thread->Tcb.SuspendCount %d\n",Thread->Tcb.SuspendCount); + + DPRINT("PsUnfreezeThread(Thread %x, WaitStatus %x)\n", Thread, WaitStatus); + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); - DPRINT("Thread->Tcb.SuspendCount %d\n",Thread->Tcb.SuspendCount); - r = Thread->Tcb.SuspendCount; - if ( Thread->Tcb.SuspendCount == TRUE ) + + Thread->Tcb.FreezeCount--; + r = Thread->Tcb.FreezeCount; + + if (r <= 0) { -// DPRINT("Marking thread %x as runnable\n",Thread); - Thread->Tcb.SuspendCount = FALSE; + DPRINT("Resuming thread\n"); Thread->Tcb.State = THREAD_STATE_RUNNABLE; if (WaitStatus != NULL) { Thread->Tcb.WaitStatus = *WaitStatus; } PsInsertIntoThreadList(Thread->Tcb.Priority, Thread); - PiNrRunnableThreads++; } - DPRINT("About release ThreadListLock = %x\n", &PiThreadListLock); + KeReleaseSpinLock(&PiThreadListLock, oldIrql); - DPRINT("Finished PsResumeThread()\n"); - return r; + return(r); } - -ULONG PsSuspendThread(PETHREAD Thread, - PNTSTATUS WaitStatus, - UCHAR Alertable, - ULONG WaitMode) +ULONG PsFreezeThread(PETHREAD Thread, PNTSTATUS Status, UCHAR Alertable, + ULONG WaitMode) { KIRQL oldIrql; ULONG r; - DPRINT("PsSuspendThread(Thread %x)\n",Thread); - DPRINT("Thread->Tcb.BasePriority %d\n", Thread->Tcb.BasePriority); - DPRINT("Thread->Tcb.SuspendCount %d\n",Thread->Tcb.SuspendCount); KeAcquireSpinLock(&PiThreadListLock, &oldIrql); - r = Thread->Tcb.SuspendCount; - if ( Thread->Tcb.SuspendCount == FALSE ) - { - Thread->Tcb.SuspendCount = TRUE; - if (Thread != PsGetCurrentThread()) - { - if (Thread->Tcb.State == THREAD_STATE_RUNNABLE) - RemoveEntryList(&Thread->Tcb.QueueListEntry); - Thread->Tcb.State = THREAD_STATE_SUSPENDED; - Thread->Tcb.Alertable = Alertable; - Thread->Tcb.WaitMode = WaitMode; - PiNrRunnableThreads--; - } - else - { - DPRINT("Suspending current thread\n"); - Thread->Tcb.Alertable = Alertable; - Thread->Tcb.WaitMode = WaitMode; - PiNrRunnableThreads--; - Thread->Tcb.WaitIrql = oldIrql; // save wait IRQL - PsDispatchThreadNoLock(THREAD_STATE_SUSPENDED); - if (WaitStatus != NULL) - { - *WaitStatus = PsGetCurrentThread()->Tcb.WaitStatus; - } - } - } - DPRINT("About to release ThreadListLock = %x\n", &PiThreadListLock); - KeReleaseSpinLock(&PiThreadListLock, oldIrql); - DPRINT("PsSuspendThread() finished\n"); - return r; -} - - -VOID PiDeleteThread(PVOID ObjectBody) -{ - DPRINT("PiDeleteThread(ObjectBody %x)\n",ObjectBody); - ObDereferenceObject(((PETHREAD)ObjectBody)->ThreadsProcess); - ((PETHREAD)ObjectBody)->ThreadsProcess = NULL; - PiNrThreads--; - RemoveEntryList(&((PETHREAD)ObjectBody)->Tcb.ThreadListEntry); - HalReleaseTask((PETHREAD)ObjectBody); -} - -VOID PiCloseThread(PVOID ObjectBody, ULONG HandleCount) -{ - DPRINT("PiCloseThread(ObjectBody %x)\n", ObjectBody); - DPRINT("ObGetReferenceCount(ObjectBody) %d " - "ObGetHandleCount(ObjectBody) %d\n", - ObGetReferenceCount(ObjectBody), - ObGetHandleCount(ObjectBody)); + Thread->Tcb.FreezeCount++; + r = Thread->Tcb.FreezeCount; + + DPRINT("r %d\n", r); + + if (r == 0) + { + DPRINT("Not suspending thread\n"); + KeReleaseSpinLock(&PiThreadListLock, oldIrql); + return(r); + } + + Thread->Tcb.Alertable = Alertable; + Thread->Tcb.WaitMode = WaitMode; + + if (PsGetCurrentThread() != Thread) + { + DPRINT("Suspending other\n"); + if (Thread->Tcb.State == THREAD_STATE_RUNNABLE) + { + RemoveEntryList(&Thread->Tcb.QueueListEntry); + } + Thread->Tcb.State = THREAD_STATE_FROZEN; + KeReleaseSpinLock(&PiThreadListLock, oldIrql); + } + else + { + DPRINT("Suspending self\n"); + Thread->Tcb.WaitIrql = oldIrql; + PsDispatchThreadNoLock(THREAD_STATE_FROZEN); + if (Status != NULL) + { + *Status = Thread->Tcb.WaitStatus; + } + KeLowerIrql(oldIrql); + } + return(r); } VOID PsInitThreadManagment(VOID) @@ -474,8 +374,9 @@ VOID PsInitThreadManagment(VOID) THREAD_ALL_ACCESS,NULL); HalInitFirstTask(FirstThread); FirstThread->Tcb.State = THREAD_STATE_RUNNING; - FirstThread->Tcb.SuspendCount = 0; - + FirstThread->Tcb.FreezeCount = 0; + ZwClose(FirstThreadHandle); + DPRINT("FirstThread %x\n",FirstThread); CurrentThread = FirstThread; @@ -484,226 +385,10 @@ VOID PsInitThreadManagment(VOID) } -static NTSTATUS -PsCreateTeb (HANDLE ProcessHandle, - PNT_TEB *TebPtr, - PETHREAD Thread, - PINITIAL_TEB InitialTeb) -{ - MEMORY_BASIC_INFORMATION Info; - NTSTATUS Status; - ULONG ByteCount; - ULONG RegionSize; - ULONG TebSize; - PVOID TebBase; - NT_TEB Teb; - - TebBase = (PVOID)0x7FFDE000; - TebSize = PAGESIZE; - - while (TRUE) - { - /* The TEB must reside in user space */ - Status = NtAllocateVirtualMemory(ProcessHandle, - &TebBase, - 0, - &TebSize, - MEM_COMMIT, - PAGE_READWRITE); - if (NT_SUCCESS(Status)) - { - DPRINT ("TEB allocated at %x\n", TebBase); - break; - } - else - { - DPRINT ("TEB allocation failed! Status %x\n",Status); - } - - TebBase = Info.BaseAddress - TebSize; - } - - DPRINT ("TebBase %p TebSize %lu\n", TebBase, TebSize); - - /* set all pointers to and from the TEB */ - Teb.Tib.Self = TebBase; - if (Thread->ThreadsProcess) - { - Teb.Peb = Thread->ThreadsProcess->Peb; /* No PEB yet!! */ - } - - /* store stack information from InitialTeb */ - if (InitialTeb != NULL) - { - Teb.Tib.StackBase = InitialTeb->StackBase; - Teb.Tib.StackLimit = InitialTeb->StackLimit; - - /* - * I don't know if this is really stored in a WNT-TEB, - * but it's needed to free the thread stack. (Eric Kohl) - */ - Teb.StackCommit = InitialTeb->StackCommit; - Teb.StackCommitMax = InitialTeb->StackCommitMax; - Teb.StackReserved = InitialTeb->StackReserved; - } - - - /* more initialization */ - Teb.Cid.UniqueThread = Thread->Cid.UniqueThread; - Teb.Cid.UniqueProcess = Thread->Cid.UniqueProcess; - - /* write TEB data into teb page */ - Status = NtWriteVirtualMemory(ProcessHandle, - TebBase, - &Teb, - sizeof(NT_TEB), - &ByteCount); - - if (!NT_SUCCESS(Status)) - { - /* free TEB */ - DPRINT ("Writing TEB failed!\n"); - - RegionSize = 0; - NtFreeVirtualMemory(ProcessHandle, - TebBase, - &RegionSize, - MEM_RELEASE); - - return Status; - } - - /* FIXME: fs:[0] = TEB */ - - if (TebPtr != NULL) - { -// *TebPtr = (PNT_TEB)TebBase; - } - - DPRINT ("TEB allocated at %p\n", TebBase); - - return Status; -} - - -NTSTATUS STDCALL NtCreateThread (PHANDLE ThreadHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, - HANDLE ProcessHandle, - PCLIENT_ID Client, - PCONTEXT ThreadContext, - PINITIAL_TEB InitialTeb, - BOOLEAN CreateSuspended) -{ - PETHREAD Thread; - PNT_TEB TebBase; - NTSTATUS Status; - - DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n", - ThreadHandle,ThreadContext); - - Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle, - DesiredAccess,ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - Status = HalInitTaskWithContext(Thread,ThreadContext); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - Status = PsCreateTeb (ProcessHandle, - &TebBase, - Thread, - InitialTeb); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - /* Attention: TebBase is in user memory space */ -// Thread->Tcb.Teb = TebBase; - - Thread->StartAddress=NULL; - - if (Client!=NULL) - { - *Client=Thread->Cid; - } - - if (!CreateSuspended) - { - DPRINT("Not creating suspended\n"); - PsResumeThread(Thread, NULL); - } - DPRINT("Thread %x\n", Thread); - DPRINT("ObGetReferenceCount(Thread) %d ObGetHandleCount(Thread) %x\n", - ObGetReferenceCount(Thread), ObGetHandleCount(Thread)); - DPRINT("Finished PsCreateThread()\n"); - return(STATUS_SUCCESS); -} - - -NTSTATUS PsCreateSystemThread(PHANDLE ThreadHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, - HANDLE ProcessHandle, - PCLIENT_ID ClientId, - PKSTART_ROUTINE StartRoutine, - PVOID StartContext) /* - * FUNCTION: Creates a thread which executes in kernel mode - * ARGUMENTS: - * ThreadHandle (OUT) = Caller supplied storage for the returned thread - * handle - * DesiredAccess = Requested access to the thread - * ObjectAttributes = Object attributes (optional) - * ProcessHandle = Handle of process thread will run in - * NULL to use system process - * ClientId (OUT) = Caller supplied storage for the returned client id - * of the thread (optional) - * StartRoutine = Entry point for the thread - * StartContext = Argument supplied to the thread when it begins - * execution - * RETURNS: Success or failure status + * Sets thread's base priority relative to the process' base priority + * Should only be passed in THREAD_PRIORITY_ constants in pstypes.h */ -{ - PETHREAD Thread; - NTSTATUS Status; - - DPRINT("PsCreateSystemThread(ThreadHandle %x, ProcessHandle %x)\n", - ThreadHandle,ProcessHandle); - - Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle, - DesiredAccess,ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - Thread->StartAddress=StartRoutine; - Status = HalInitTask(Thread,StartRoutine,StartContext); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - if (ClientId!=NULL) - { - *ClientId=Thread->Cid; - } - - PsResumeThread(Thread, NULL); - - return(STATUS_SUCCESS); -} - - -// Sets thread's base priority relative to the process' base priority -// Should only be passed in THREAD_PRIORITY_ constants in pstypes.h LONG KeSetBasePriorityThread(PKTHREAD Thread, LONG Increment) { Thread->BasePriority = ((PETHREAD)Thread)->ThreadsProcess->Pcb.BasePriority + Increment; @@ -758,7 +443,7 @@ NTSTATUS STDCALL NtAlertThread (IN HANDLE ThreadHandle) } ThreadStatus = STATUS_ALERTED; - (VOID)PsResumeThread(Thread, &ThreadStatus); + (VOID)PsUnfreezeThread(Thread, &ThreadStatus); ObDereferenceObject(Thread); return(STATUS_SUCCESS); @@ -794,24 +479,8 @@ NTSTATUS STDCALL NtResumeThread (IN HANDLE ThreadHandle, * RETURNS: Status */ { - PETHREAD Thread; - NTSTATUS Status; - - Status = ObReferenceObjectByHandle(ThreadHandle, - THREAD_SUSPEND_RESUME, - PsThreadType, - UserMode, - (PVOID*)&Thread, - NULL); - if (Status != STATUS_SUCCESS) - { - return(Status); - } - - (*SuspendCount) = PsResumeThread(Thread, NULL); - - ObDereferenceObject(Thread); - return(STATUS_SUCCESS); + UNIMPLEMENTED; + return(STATUS_UNSUCCESSFUL); } @@ -838,27 +507,8 @@ NTSTATUS STDCALL NtSuspendThread (IN HANDLE ThreadHandle, * RETURNS: Status */ { - PETHREAD Thread; - NTSTATUS Status; - - Status = ObReferenceObjectByHandle(ThreadHandle, - THREAD_SUSPEND_RESUME, - PsThreadType, - UserMode, - (PVOID*)&Thread, - NULL); - if (Status != STATUS_SUCCESS) - { - return(Status); - } - - (*PreviousSuspendCount) = PsSuspendThread(Thread, - NULL, - FALSE, - UserMode); - - ObDereferenceObject(Thread); - return(STATUS_SUCCESS); + UNIMPLEMENTED; + return(STATUS_UNSUCCESSFUL); }