diff --git a/reactos/.gdbinit b/reactos/.gdbinit index 206c454f8d7..a498949ad79 100644 --- a/reactos/.gdbinit +++ b/reactos/.gdbinit @@ -1,5 +1,5 @@ file ntoskrnl/ntoskrnl.nostrip.exe #add-symbol-file lib/ntdll/ntdll.dll 0x77f61000 -#add-symbol-file apps/apc/apc.exe 0x401000 +#add-symbol-file apps/exp/exp.exe 0x401000 #add-symbol-file subsys/csrss/csrss.exe 0x401000 -break exp.c:154 +break exp.c:254 diff --git a/reactos/ChangeLog b/reactos/ChangeLog index d185fc9d734..c8b5b7b554d 100644 --- a/reactos/ChangeLog +++ b/reactos/ChangeLog @@ -1,3 +1,8 @@ +2001-03-17 David Welch + + * ntoskrnl/ke/catch.c (KiDispatchException): Implementation of + exception handling, user-mode only. + 2001-03-16 David Welch * include/ddk/zw.h: Corrected declarations of NtCreateProfile, diff --git a/reactos/Makefile b/reactos/Makefile index d3e3daf42bf..fdead50d904 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -56,7 +56,7 @@ NET_DEVICE_DRIVERS = ne2000 SYS_APPS = shell winlogon services APPS = args hello test cat bench apc shm lpc thread event file gditest \ - pteb consume dump_shared_data vmtest regtest + pteb consume dump_shared_data vmtest regtest exp # objdir diff --git a/reactos/include/ddk/zw.h b/reactos/include/ddk/zw.h index fa836adcca5..8be6dc63909 100644 --- a/reactos/include/ddk/zw.h +++ b/reactos/include/ddk/zw.h @@ -1,5 +1,5 @@ -/* $Id: zw.h,v 1.42 2001/03/16 18:11:20 dwelch Exp $ +/* $Id: zw.h,v 1.43 2001/03/18 19:35:11 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -3620,7 +3620,7 @@ STDCALL NtRaiseException( IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, - IN BOOL IsDebugger OPTIONAL + IN BOOLEAN SearchFrames ); NTSTATUS @@ -3628,7 +3628,7 @@ STDCALL ZwRaiseException( IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, - IN BOOL IsDebugger OPTIONAL + IN BOOLEAN SearchFrames ); /* diff --git a/reactos/include/napi/dbg.h b/reactos/include/napi/dbg.h index 88fe37daef0..e2a51a6a1d7 100644 --- a/reactos/include/napi/dbg.h +++ b/reactos/include/napi/dbg.h @@ -1,6 +1,8 @@ #ifndef __INCLUDE_NAPI_DBG_H #define __INCLUDE_NAPI_DBG_H +#include + #define DBG_EVENT_EXCEPTION (1) #define DBG_EVENT_CREATE_THREAD (2) #define DBG_EVENT_CREATE_PROCESS (3) @@ -19,7 +21,7 @@ typedef struct _LPC_DBG_MESSAGE struct { EXCEPTION_RECORD ExceptionRecord; - ULONG FirstChange; + ULONG FirstChance; } Exception; struct { diff --git a/reactos/install.sh b/reactos/install.sh index 48c765fcf35..fb8d96b335f 100644 --- a/reactos/install.sh +++ b/reactos/install.sh @@ -42,4 +42,5 @@ cp apps/vmtest/vmtest.exe $1/reactos/bin cp apps/uitest/uitest.exe $1/reactos/bin/ cp apps/gditest/gditest.exe $1/reactos/bin/ cp apps/ptest/ptest.exe $1/reactos/bin/ -cp apps/timer/timer.exe $1/reactos/bin/ \ No newline at end of file +cp apps/timer/timer.exe $1/reactos/bin/ +cp apps/exp/exp.exe $1/reactos/bin \ No newline at end of file diff --git a/reactos/lib/ntdll/rtl/exception.c b/reactos/lib/ntdll/rtl/exception.c index 615630ec22b..45180c7800f 100644 --- a/reactos/lib/ntdll/rtl/exception.c +++ b/reactos/lib/ntdll/rtl/exception.c @@ -1,4 +1,4 @@ -/* $Id: exception.c,v 1.4 2001/03/17 11:11:11 dwelch Exp $ +/* $Id: exception.c,v 1.5 2001/03/18 19:35:12 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -24,7 +24,7 @@ ULONG RtlDispatchException(PEXCEPTION_RECORD ExceptionRecord, PCONTEXT Context) { - return(0); + } VOID STDCALL diff --git a/reactos/ntoskrnl/Makefile b/reactos/ntoskrnl/Makefile index 8d2199b537d..f207172ce32 100644 --- a/reactos/ntoskrnl/Makefile +++ b/reactos/ntoskrnl/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.24 2001/03/16 23:04:59 dwelch Exp $ +# $Id: Makefile,v 1.25 2001/03/18 19:35:12 dwelch Exp $ # # ReactOS Operating System # @@ -238,7 +238,8 @@ OBJECTS_CM = \ OBJECTS_DBG = \ dbg/dbgctrl.o \ dbg/errinfo.o \ - dbg/print.o + dbg/print.o \ + dbg/user.o # Loader OBJECTS_LDR = \ diff --git a/reactos/ntoskrnl/include/internal/dbg.h b/reactos/ntoskrnl/include/internal/dbg.h index 3d0706b6df8..59df3057f74 100644 --- a/reactos/ntoskrnl/include/internal/dbg.h +++ b/reactos/ntoskrnl/include/internal/dbg.h @@ -1,11 +1,17 @@ #ifndef __INCLUDE_INTERNAL_DBG_H #define __INCLUDE_INTERNAL_DBG_H +#include #include #include NTSTATUS STDCALL LpcSendDebugMessagePort(PEPORT Port, - PLPC_DBG_MESSAGE Message); + PLPC_DBG_MESSAGE Message, + PLPC_DBG_MESSAGE Reply); +VOID +DbgkCreateThread(PVOID StartAddress); +ULONG +DbgkForwardException(EXCEPTION_RECORD Er, ULONG FirstChance); #endif /* __INCLUDE_INTERNAL_DBG_H */ diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index d103a492e2a..bea5c1b8fd6 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -91,8 +91,6 @@ VOID KeExpireTimers( PKDPC Apc, PVOID Arg1, PVOID Arg2, PVOID Arg3 ); -NTSTATUS KeAddThreadTimeout(struct _KTHREAD* Thread, - PLARGE_INTEGER Interval); VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, ULONG Type, ULONG Size, ULONG SignalState); @@ -129,5 +127,12 @@ VOID NtEarlyInitVdm(VOID); VOID KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Eip); - +VOID +KiDispatchException(PEXCEPTION_RECORD Er, + PCONTEXT Context, + PKTRAP_FRAME Tf, + KPROCESSOR_MODE PreviousMode, + BOOLEAN SearchFrames); +VOID KeTrapFrameToContext(PKTRAP_FRAME TrapFrame, + PCONTEXT Context); #endif diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index db762a1e099..a12e5d33a86 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -95,7 +95,7 @@ KiDeliverNormalApc(VOID) Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry); if (Apc->NormalRoutine != NULL) { - (void)RemoveTailList(&Thread->Tcb.ApcState.ApcListHead[0]); + (VOID)RemoveTailList(&Thread->Tcb.ApcState.ApcListHead[0]); Thread->Tcb.ApcState.KernelApcInProgress++; Thread->Tcb.ApcState.KernelApcPending--; @@ -243,35 +243,39 @@ VOID STDCALL KiDeliverApc(ULONG Unknown1, */ { PETHREAD Thread = PsGetCurrentThread(); - PLIST_ENTRY current; + PLIST_ENTRY current_entry; PKAPC Apc; KIRQL oldlvl; DPRINT("KiDeliverApc()\n"); KeAcquireSpinLock(&PiApcLock, &oldlvl); - while(!IsListEmpty(&(Thread->Tcb.ApcState.ApcListHead[0]))) - { - current = Thread->Tcb.ApcState.ApcListHead[0].Blink; - Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry); - if (Apc->NormalRoutine == NULL) - { - (void)RemoveTailList(&Thread->Tcb.ApcState.ApcListHead[0]); - Thread->Tcb.ApcState.KernelApcInProgress++; - Thread->Tcb.ApcState.KernelApcPending--; - - KeReleaseSpinLock(&PiApcLock, oldlvl); - - Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry); - Apc->KernelRoutine(Apc, - &Apc->NormalRoutine, - &Apc->NormalContext, - &Apc->SystemArgument1, - &Apc->SystemArgument2); - - KeAcquireSpinLock(&PiApcLock, &oldlvl); - Thread->Tcb.ApcState.KernelApcInProgress--; - } - } + current_entry = Thread->Tcb.ApcState.ApcListHead[0].Flink; + while(current_entry != &Thread->Tcb.ApcState.ApcListHead[0]) + { + Apc = CONTAINING_RECORD(current_entry, KAPC, ApcListEntry); + if (Apc->NormalRoutine == NULL) + { + current_entry = current_entry->Flink; + RemoveEntryList(&Apc->ApcListEntry); + Thread->Tcb.ApcState.KernelApcInProgress++; + Thread->Tcb.ApcState.KernelApcPending--; + + KeReleaseSpinLock(&PiApcLock, oldlvl); + + Apc->KernelRoutine(Apc, + &Apc->NormalRoutine, + &Apc->NormalContext, + &Apc->SystemArgument1, + &Apc->SystemArgument2); + + KeAcquireSpinLock(&PiApcLock, &oldlvl); + Thread->Tcb.ApcState.KernelApcInProgress--; + } + else + { + current_entry = current_entry->Flink; + } + } KeReleaseSpinLock(&PiApcLock, oldlvl); } @@ -320,13 +324,28 @@ KeInsertQueueApc (PKAPC Apc, TargetThread->ApcState.UserApcPending++; } Apc->Inserted = TRUE; - + + /* + * If this is a kernel-mode APC and it is waiting at PASSIVE_LEVEL and + * not inside a critical section then wake it up. Otherwise it will + * execute the APC as soon as it returns to PASSIVE_LEVEL. + * FIXME: Check for sending an APC to the current thread. + * FIXME: If the thread is running on another processor then send an + * IPI. + * FIXME: Check if the thread is terminating. + */ if (Apc->ApcMode == KernelMode && TargetThread->KernelApcDisable >= 1 && TargetThread->WaitIrql < APC_LEVEL && Apc->NormalRoutine == NULL) { KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb), STATUS_KERNEL_APC); } + + /* + * If this is a 'funny' user-mode APC then mark the thread as + * alerted so it will execute the APC on exit from kernel mode. If it + * is waiting alertably then wake it up so it can return to user mode. + */ if (Apc->ApcMode == KernelMode && Apc->NormalRoutine != NULL) { TargetThread->Alerted[1] = 1; @@ -341,12 +360,9 @@ KeInsertQueueApc (PKAPC Apc, } /* - * For user mode APCs if the thread is already waiting then we wait it - * up and increment UserApcPending so it will deliver the APC on exit - * from kernel mode. If the thread isn't waiting then before it - * enters an alertable, user mode wait then it will check for - * user mode APCs and if there are any pending then return immediately - * and they will be delivered on exit from kernel mode + * If the thread is waiting alertably then wake it up and it will + * return to to user-mode executing the APC in the process. Otherwise the + * thread will execute the APC next time it enters an alertable wait. */ if (Apc->ApcMode == UserMode && TargetThread->Alertable == TRUE && TargetThread->WaitMode == UserMode) @@ -429,6 +445,7 @@ KeInitializeApc (PKAPC Apc, "KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %d, " "Context %x)\n",Apc,Thread,StateIndex,KernelRoutine,RundownRoutine, NormalRoutine,Mode,Context); + memset(Apc, 0, sizeof(KAPC)); Apc->Thread = Thread; Apc->ApcListEntry.Flink = NULL; diff --git a/reactos/ntoskrnl/ke/catch.c b/reactos/ntoskrnl/ke/catch.c index cc75a05b343..0adfe991692 100644 --- a/reactos/ntoskrnl/ke/catch.c +++ b/reactos/ntoskrnl/ke/catch.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: catch.c,v 1.12 2001/03/17 11:11:11 dwelch Exp $ +/* $Id: catch.c,v 1.13 2001/03/18 19:35:12 dwelch Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/catch.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -36,26 +37,31 @@ VOID KiDispatchException(PEXCEPTION_RECORD Er, - ULONG Reserved, + PCONTEXT Context, PKTRAP_FRAME Tf, KPROCESSOR_MODE PreviousMode, BOOLEAN SearchFrames) { - CONTEXT Context; + CONTEXT TContext; - Context.ContextFlags = CONTEXT_FULL; - if (PreviousMode == UserMode) - { - Context.ContextFlags = Context.ContextFlags | CONTEXT_DEBUGGER; - } - /* PCR->KeExceptionDispatchCount++; */ - // KeContextFromKframes(Tf, Reserved, &Context); + if (Context != NULL) + { + TContext.ContextFlags = CONTEXT_FULL; + if (PreviousMode == UserMode) + { + TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER; + } + + KeTrapFrameToContext(Tf, &TContext); + + Context = &TContext; + } if (Er->ExceptionCode == STATUS_BREAKPOINT) { - Context.Eip--; + Context->Eip--; } if (PreviousMode == UserMode) @@ -86,7 +92,7 @@ KiDispatchException(PEXCEPTION_RECORD Er, /* Pointer to CONTEXT structure */ Stack[2] = (ULONG)&Stack[CDest]; memcpy(&Stack[3], Er, sizeof(EXCEPTION_RECORD)); - memcpy(&Stack[CDest], &Context, sizeof(CONTEXT)); + memcpy(&Stack[CDest], Context, sizeof(CONTEXT)); Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher(); return; @@ -94,13 +100,18 @@ KiDispatchException(PEXCEPTION_RECORD Er, /* FIXME: Forward the exception to the debugger */ - /* FIXME: Forward the exception to the debugger */ + /* FIXME: Forward the exception to the process exception port */ + /* Terminate the offending thread */ ZwTerminateThread(NtCurrentThread(), Er->ExceptionCode); + /* If that fails then bugcheck */ + KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED); + } + else + { KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED); } - } VOID STDCALL @@ -116,7 +127,7 @@ ExRaiseDatatypeMisalignment (VOID) } VOID STDCALL -ExRaiseStatus (IN NTSTATUS Status) +ExRaiseStatus (IN NTSTATUS Status) { DbgPrint("ExRaiseStatus(%x)\n",Status); for(;;); @@ -125,11 +136,16 @@ ExRaiseStatus (IN NTSTATUS Status) NTSTATUS STDCALL -NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord, - IN PCONTEXT Context, - IN BOOL IsDebugger OPTIONAL) +NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context, + IN BOOLEAN SearchFrames) { - UNIMPLEMENTED; + KiDispatchException(ExceptionRecord, + Context, + PsGetCurrentThread()->Tcb.TrapFrame, + ExGetPreviousMode(), + SearchFrames); + return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 38d5fda5f74..6732cfa6d1b 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -48,24 +48,24 @@ extern void interrupt_handler2e(void); extern void interrupt_handler2d(void); -extern void exception_handler0(void); -extern void exception_handler1(void); -extern void exception_handler2(void); -extern void exception_handler3(void); -extern void exception_handler4(void); -extern void exception_handler5(void); -extern void exception_handler6(void); -extern void exception_handler7(void); -extern void exception_handler8(void); -extern void exception_handler9(void); -extern void exception_handler10(void); -extern void exception_handler11(void); -extern void exception_handler12(void); -extern void exception_handler13(void); -extern void exception_handler14(void); -extern void exception_handler15(void); -extern void exception_handler16(void); -extern void exception_handler_unknown(void); +extern VOID KiTrap0(VOID); +extern VOID KiTrap1(VOID); +extern VOID KiTrap2(VOID); +extern VOID KiTrap3(VOID); +extern VOID KiTrap4(VOID); +extern VOID KiTrap5(VOID); +extern VOID KiTrap6(VOID); +extern VOID KiTrap7(VOID); +extern VOID KiTrap8(VOID); +extern VOID KiTrap9(VOID); +extern VOID KiTrap10(VOID); +extern VOID KiTrap11(VOID); +extern VOID KiTrap12(VOID); +extern VOID KiTrap13(VOID); +extern VOID KiTrap14(VOID); +extern VOID KiTrap15(VOID); +extern VOID KiTrap16(VOID); +extern VOID KiTrapUnknown(VOID); extern ULONG init_stack; extern ULONG init_stack_top; @@ -105,7 +105,59 @@ print_address(PVOID address) } ULONG -exception_handler(struct trap_frame* tf) +KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2) +{ + EXCEPTION_RECORD Er; + + if (ExceptionNr == 0) + { + Er.ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO; + } + else if (ExceptionNr == 1) + { + Er.ExceptionCode = STATUS_SINGLE_STEP; + } + else if (ExceptionNr == 3) + { + Er.ExceptionCode = STATUS_BREAKPOINT; + } + else if (ExceptionNr == 4) + { + Er.ExceptionCode = STATUS_INTEGER_OVERFLOW; + } + else if (ExceptionNr == 5) + { + Er.ExceptionCode = STATUS_ARRAY_BOUNDS_EXCEEDED; + } + else if (ExceptionNr == 6) + { + Er.ExceptionCode = STATUS_ILLEGAL_INSTRUCTION; + } + else + { + Er.ExceptionCode = STATUS_ACCESS_VIOLATION; + } + Er.ExceptionFlags = 0; + Er.ExceptionRecord = NULL; + Er.ExceptionAddress = (PVOID)Tf->Eip; + if (ExceptionNr == 14) + { + Er.NumberParameters = 2; + Er.ExceptionInformation[0] = Tf->ErrorCode & 0x1; + Er.ExceptionInformation[1] = (ULONG)Cr2; + } + else + { + Er.NumberParameters = 0; + } + + + KiDispatchException(&Er, 0, Tf, UserMode, TRUE); + return(0); +} + +ULONG +KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr) /* * FUNCTION: Called by the lowlevel execption handlers to print an amusing * message and halt the computer @@ -118,6 +170,7 @@ exception_handler(struct trap_frame* tf) // unsigned int j, sym; PULONG stack; NTSTATUS Status; + ULONG Esp0; static char *TypeStrings[] = { "Divide Error", @@ -139,65 +192,70 @@ exception_handler(struct trap_frame* tf) "Alignment Check", "Machine Check" }; + + /* Use the address of the trap frame as approximation to the ring0 esp */ + Esp0 = (ULONG)Tf; - __asm__("movl %%cr2,%0\n\t" - : "=d" (cr2)); + /* Get CR2 */ + __asm__("movl %%cr2,%0\n\t" : "=d" (cr2)); + /* + * If this was a V86 mode exception then handle it specially + */ +#if 0 if (tf->eflags & (1 << 17)) { return(KeV86Exception(tf, cr2)); } +#endif + /* + * Check for stack underflow + */ if (PsGetCurrentThread() != NULL && - tf->esp < (ULONG)PsGetCurrentThread()->Tcb.StackLimit) + Esp0 < (ULONG)PsGetCurrentThread()->Tcb.StackLimit) { DbgPrint("Stack underflow (tf->esp %x Limit %x)\n", - tf->esp, (ULONG)PsGetCurrentThread()->Tcb.StackLimit); - tf->type = 12; + Esp0, (ULONG)PsGetCurrentThread()->Tcb.StackLimit); + ExceptionNr = 12; } - if (tf->type == 14) + if (ExceptionNr == 14) { __asm__("sti\n\t"); - Status = MmPageFault(tf->cs&0xffff, - &tf->eip, - &tf->eax, + Status = MmPageFault(Tf->Cs&0xffff, + &Tf->Eip, + &Tf->Eax, cr2, - tf->error_code); + Tf->ErrorCode); if (NT_SUCCESS(Status)) { return(0); } } - - /* - * FIXME: Something better - */ - if (tf->type==1) + + if ((Tf->Cs & 0xFFFF) == USER_CS) { - DbgPrint("Trap at CS:EIP %x:%x\n",tf->cs&0xffff,tf->eip); - return(0); + return(KiUserTrapHandler(Tf, ExceptionNr, (PVOID)cr2)); } /* * Print out the CPU registers */ - if (tf->type < 19) + if (ExceptionNr < 19) { - DbgPrint("%s Exception: %d(%x)\n",TypeStrings[tf->type],tf->type, - tf->error_code&0xffff); + DbgPrint("%s Exception: %d(%x)\n",TypeStrings[ExceptionNr], + ExceptionNr, Tf->ErrorCode&0xffff); } else { - DbgPrint("Exception: %d(%x)\n",tf->type,tf->error_code&0xffff); + DbgPrint("Exception: %d(%x)\n", ExceptionNr, Tf->ErrorCode&0xffff); } - DbgPrint("CS:EIP %x:%x ",tf->cs&0xffff,tf->eip); - print_address((PVOID)tf->eip); + DbgPrint("CS:EIP %x:%x ", Tf->Cs&0xffff, Tf->Eip); + print_address((PVOID)Tf->Eip); DbgPrint("\n"); - __asm__("movl %%cr3,%0\n\t" - : "=d" (cr3)); - DbgPrint("cr2 %x cr3 %x ",cr2,cr3); -// for(;;); + __asm__("movl %%cr3,%0\n\t" : "=d" (cr3)); + DbgPrint("cr2 %x cr3 %x ", cr2, cr3); DbgPrint("Proc: %x ",PsGetCurrentProcess()); if (PsGetCurrentProcess() != NULL) { @@ -211,14 +269,14 @@ exception_handler(struct trap_frame* tf) PsGetCurrentThread()->Cid.UniqueThread); } DbgPrint("\n"); - DbgPrint("DS %x ES %x FS %x GS %x\n", tf->ds&0xffff, tf->es&0xffff, - tf->fs&0xffff, tf->gs&0xfff); - DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n", tf->eax, tf->ebx, tf->ecx); - DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n", tf->edx, tf->ebp, tf->esi); - DbgPrint("EDI: %.8x EFLAGS: %.8x ", tf->edi, tf->eflags); - if ((tf->cs&0xffff) == KERNEL_CS) + DbgPrint("DS %x ES %x FS %x GS %x\n", Tf->Ds&0xffff, Tf->Es&0xffff, + Tf->Fs&0xffff, Tf->Gs&0xfff); + DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n", Tf->Eax, Tf->Ebx, Tf->Ecx); + DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n", Tf->Edx, Tf->Ebp, Tf->Esi); + DbgPrint("EDI: %.8x EFLAGS: %.8x ", Tf->Edi, Tf->Eflags); + if ((Tf->Cs&0xffff) == KERNEL_CS) { - DbgPrint("kESP %.8x ", tf->esp); + DbgPrint("kESP %.8x ", Esp0); if (PsGetCurrentThread() != NULL) { DbgPrint("kernel stack base %x\n", @@ -228,12 +286,12 @@ exception_handler(struct trap_frame* tf) } else { - DbgPrint("kernel ESP %.8x\n", tf->esp); + DbgPrint("User ESP %.8x\n", Tf->Esp); } - if ((tf->cs & 0xffff) == KERNEL_CS) + if ((Tf->Cs & 0xffff) == KERNEL_CS) { - DbgPrint("ESP %x\n", tf->esp); - stack = (PULONG) (tf->esp + 24); + DbgPrint("ESP %x\n", Esp0); + stack = (PULONG) (Esp0 + 24); stack = (PULONG)(((ULONG)stack) & (~0x3)); DbgPrint("stack<%p>: ", stack); @@ -261,8 +319,8 @@ exception_handler(struct trap_frame* tf) else { #if 1 - DbgPrint("SS:ESP %x:%x\n", tf->ss0, tf->esp0); - stack=(PULONG)(tf->esp0); + DbgPrint("SS:ESP %x:%x\n", Tf->Ss, Tf->Esp); + stack=(PULONG)(Tf->Esp); DbgPrint("Stack:\n"); for (i=0; i<64; i++) @@ -277,11 +335,11 @@ exception_handler(struct trap_frame* tf) } } - if (MmIsPagePresent(NULL, (PVOID)tf->eip)) + if (MmIsPagePresent(NULL, (PVOID)Tf->Eip)) { unsigned char instrs[512]; - memcpy(instrs, (PVOID)tf->eip, 512); + memcpy(instrs, (PVOID)Tf->Eip, 512); DbgPrint("Instrs: "); @@ -294,13 +352,12 @@ exception_handler(struct trap_frame* tf) } DbgPrint("\n"); - if ((tf->cs&0xffff) == USER_CS && - tf->eip < KERNEL_BASE) + if ((Tf->Cs&0xffff) == USER_CS && + Tf->Eip < KERNEL_BASE) { DbgPrint("Killing current task\n"); - // for(;;); KeLowerIrql(PASSIVE_LEVEL); - if ((tf->cs&0xffff) == USER_CS) + if ((Tf->Cs&0xffff) == USER_CS) { ZwTerminateProcess(NtCurrentProcess(), STATUS_NONCONTINUABLE_EXCEPTION); @@ -366,27 +423,27 @@ void KeInitExceptions(void) DPRINT("KeInitExceptions()\n",0); - set_interrupt_gate(0,(int)exception_handler0); - set_interrupt_gate(1,(int)exception_handler1); - set_interrupt_gate(2,(int)exception_handler2); - set_interrupt_gate(3,(int)exception_handler3); - set_interrupt_gate(4,(int)exception_handler4); - set_interrupt_gate(5,(int)exception_handler5); - set_interrupt_gate(6,(int)exception_handler6); - set_interrupt_gate(7,(int)exception_handler7); - set_interrupt_gate(8,(int)exception_handler8); - set_interrupt_gate(9,(int)exception_handler9); - set_interrupt_gate(10,(int)exception_handler10); - set_interrupt_gate(11,(int)exception_handler11); - set_interrupt_gate(12,(int)exception_handler12); - set_interrupt_gate(13,(int)exception_handler13); - set_interrupt_gate(14,(int)exception_handler14); - set_interrupt_gate(15,(int)exception_handler15); - set_interrupt_gate(16,(int)exception_handler16); + set_interrupt_gate(0, (ULONG)KiTrap0); + set_interrupt_gate(1, (ULONG)KiTrap1); + set_interrupt_gate(2, (ULONG)KiTrap2); + set_interrupt_gate(3, (ULONG)KiTrap3); + set_interrupt_gate(4, (ULONG)KiTrap4); + set_interrupt_gate(5, (ULONG)KiTrap5); + set_interrupt_gate(6, (ULONG)KiTrap6); + set_interrupt_gate(7, (ULONG)KiTrap7); + set_interrupt_gate(8, (ULONG)KiTrap8); + set_interrupt_gate(9, (ULONG)KiTrap9); + set_interrupt_gate(10, (ULONG)KiTrap10); + set_interrupt_gate(11, (ULONG)KiTrap11); + set_interrupt_gate(12, (ULONG)KiTrap12); + set_interrupt_gate(13, (ULONG)KiTrap13); + set_interrupt_gate(14, (ULONG)KiTrap14); + set_interrupt_gate(15, (ULONG)KiTrap15); + set_interrupt_gate(16, (ULONG)KiTrap16); for (i=17;i<256;i++) { - set_interrupt_gate(i,(int)exception_handler_unknown); + set_interrupt_gate(i,(int)KiTrapUnknown); } set_system_call_gate(0x2d,(int)interrupt_handler2d); diff --git a/reactos/ntoskrnl/ke/i386/multiboot.S b/reactos/ntoskrnl/ke/i386/multiboot.S index c341339fde2..c3d54e30d8f 100644 --- a/reactos/ntoskrnl/ke/i386/multiboot.S +++ b/reactos/ntoskrnl/ke/i386/multiboot.S @@ -706,6 +706,10 @@ lowmem_pagetable: .long 0x3f0007,0x3f1007,0x3f2007,0x3f3007,0x3f4007,0x3f5007,0x3f6007,0x3f7007 .long 0x3f8007,0x3f9007,0x3fa007,0x3fb007,0x3fc007,0x3fd007,0x3fe007,0x3ff007 +_init_stack: + .fill 3*4096,1,0 +_init_stack_top: + _gdt_descr: .word (10*8)-1 .long _KiGdt @@ -713,8 +717,4 @@ _gdt_descr: _idt_descr: .word (256*8)-1 .long _KiIdt - -_init_stack: - .fill 4096,1,0 -_init_stack_top: diff --git a/reactos/ntoskrnl/ke/i386/syscall.S b/reactos/ntoskrnl/ke/i386/syscall.S index 362dcf515b0..864298ea77b 100644 --- a/reactos/ntoskrnl/ke/i386/syscall.S +++ b/reactos/ntoskrnl/ke/i386/syscall.S @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: syscall.S,v 1.1 2000/12/10 23:42:00 dwelch Exp $ +/* $Id: syscall.S,v 1.2 2001/03/18 19:35:13 dwelch Exp $ * * FILE: ntoskrnl/hal/x86/syscall.s * PURPOSE: 2E trap handler @@ -96,7 +96,10 @@ L3: movl %ebx, %es movl %ebx, %gs - /* Save the old trap frame pointer (over the EDX register??) */ + /* + * Save the old trap frame pointer over where we would save the EDX + * register. + */ movl KTHREAD_TRAP_FRAME(%esi), %ebx movl %ebx, 0x3C(%esp) diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index f3435cf47be..7b0564c97e3 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: trap.s,v 1.6 2000/12/23 02:37:40 dwelch Exp $ +/* $Id: trap.s,v 1.7 2001/03/18 19:35:13 dwelch Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/i386/trap.s @@ -36,336 +36,283 @@ /* * Epilog for exception handlers */ -_exception_handler_epilog: +_KiTrapEpilog: cmpl $1, %eax /* Check for v86 recovery */ - jne _exception_handler_ret + jne _KiTrapRet jmp _KiV86Complete -_exception_handler_ret: - addl $4, %esp /* Ignore pointer to trap frame */ - popa /* Restore general purpose registers */ - addl $4, %esp /* Ignore trap code */ - popl %ds /* Restore segment registers */ - popl %es - popl %fs +_KiTrapRet: + /* Get a pointer to the current thread */ + movl %fs:0x124, %esi + + /* Restore the old trap frame pointer */ + movl 0x3c(%esp), %ebx + movl %ebx, KTHREAD_TRAP_FRAME(%esi) + + /* Skip debug information and unsaved registers */ + addl $0x30, %esp popl %gs - addl $4, %esp /* Ignore error code */ - iret /* Return from interrupt */ - -.globl _exception_handler0 -_exception_handler0: - pushl $0 - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $0 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog + popl %es + popl %ds + popl %edx + popl %ecx + popl %eax -.globl _exception_handler1 -_exception_handler1: - pushl $0 - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $1 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog + /* Restore the old previous mode */ + popl %ebx + movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi) + /* Restore the old exception handler list */ + popl %ebx + movl %ebx, %fs:KPCR_EXCEPTION_LIST + + popl %fs + popl %edi + popl %esi + popl %ebx + popl %ebp + addl $0x4, %esp /* Ignore error code */ + + iret -.globl _exception_handler2 -_exception_handler2: - pushl $0 - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $2 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler3 -_exception_handler3: - pushl $0 - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $3 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - -.globl _exception_handler4 -_exception_handler4: - pushl $0 - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $4 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler5 -_exception_handler5: - pushl $0 - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $5 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler6 -_exception_handler6: - pushl $0 - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $6 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler7 -_exception_handler7: - pushl $0 - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $7 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler8 -_exception_handler8: - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $8 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler9 -_exception_handler9: - pushl $0 - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $9 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler10 -_exception_handler10: - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $10 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler11 -_exception_handler11: - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $11 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler12 -_exception_handler12: - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $12 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler13 -_exception_handler13: - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $13 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler14 -_exception_handler14: - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $14 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler15 -_exception_handler15: - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $15 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler16 -_exception_handler16: - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $16 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog - -.globl _exception_handler_unknown -_exception_handler_unknown: - pushl $0 - pushl %gs +.globl _KiTrapProlog +_KiTrapProlog: + pushl %edi pushl %fs - pushl %es - pushl %ds - pushl $0xff - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - pushl %esp - call _exception_handler - jmp _exception_handler_epilog + + /* Load the PCR selector into fs */ + movl $PCR_SELECTOR, %ebx + movl %ebx, %fs + + /* Save the old exception list */ + movl %fs:KPCR_EXCEPTION_LIST, %ebx + pushl %ebx + + /* Put the exception handler chain terminator */ + movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST + + /* Get a pointer to the current thread */ + movl %fs:KPCR_CURRENT_THREAD, %edi + + /* The current thread may be NULL early in the boot process */ + cmpl $0, %edi + je .L4 + + /* Save the old previous mode */ + movl $0, %ebx + movb %ss:KTHREAD_PREVIOUS_MODE(%edi), %bl + pushl %ebx + + /* Set the new previous mode based on the saved CS selector */ + movl 0x24(%esp), %ebx + cmpl $KERNEL_CS, %ebx + jne .L1 + movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%edi) + jmp .L3 +.L1: + movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%edi) +.L3: + + /* Save other registers */ + pushl %eax + pushl %ecx + pushl %edx + pushl %ds + pushl %es + pushl %gs + pushl $0 /* DR7 */ + pushl $0 /* DR6 */ + pushl $0 /* DR3 */ + pushl $0 /* DR2 */ + pushl $0 /* DR1 */ + pushl $0 /* DR0 */ + pushl $0 /* XXX: TempESP */ + pushl $0 /* XXX: TempCS */ + pushl $0 /* XXX: DebugPointer */ + pushl $0 /* XXX: DebugArgMark */ + pushl $0 /* XXX: DebugEIP */ + pushl $0 /* XXX: DebugEBP */ + + /* Load the segment registers */ + movl $KERNEL_DS, %ebx + movl %ebx, %ds + movl %ebx, %es + movl %ebx, %gs + + /* Set ES to kernel segment */ + movw $KERNEL_DS,%bx + movw %bx,%es + + /* Call the C exception handler */ + movl %esp, %ebx + pushl %esi + pushl %ebx + call _KiTrapHandler + addl $4, %esp + addl $4, %esp + + /* Return to the caller */ + jmp _KiTrapEpilog + + /* Handle the no-thread case out of line */ +.L4: + pushl $0 + jmp .L3 + +.globl _KiTrap0 +_KiTrap0: + /* No error code */ + pushl $0 + pushl %ebp + pushl %ebx + pushl %esi + movl $0, %esi + jmp _KiTrapProlog + +.globl _KiTrap1 +_KiTrap1: + /* No error code */ + pushl $0 + pushl %ebp + pushl %ebx + pushl %esi + movl $1, %esi + jmp _KiTrapProlog + +.globl _KiTrap2 +_KiTrap2: + pushl $0 + pushl %ebp + pushl %ebx + pushl %esi + movl $2, %esi + jmp _KiTrapProlog + +.globl _KiTrap3 +_KiTrap3: + pushl $0 + pushl %ebp + pushl %ebx + pushl %esi + movl $3, %esi + jmp _KiTrapProlog + +.globl _KiTrap4 +_KiTrap4: + pushl $0 + pushl %ebp + pushl %ebx + pushl %esi + movl $4, %esi + jmp _KiTrapProlog + +.globl _KiTrap5 +_KiTrap5: + pushl $0 + pushl %ebp + pushl %ebx + pushl %esi + movl $5, %esi + jmp _KiTrapProlog + +.globl _KiTrap6 +_KiTrap6: + pushl $0 + pushl %ebp + pushl %ebx + pushl %esi + movl $6, %esi + jmp _KiTrapProlog + +.globl _KiTrap7 +_KiTrap7: + pushl $0 + pushl %ebp + pushl %ebx + pushl %esi + movl $7, %esi + jmp _KiTrapProlog + +.globl _KiTrap8 +_KiTrap8: + pushl %ebp + pushl %ebx + pushl %esi + movl $8, %esi + jmp _KiTrapProlog + +.globl _KiTrap9 +_KiTrap9: + pushl $0 + pushl %ebp + pushl %ebx + pushl %esi + movl $9, %esi + jmp _KiTrapProlog + +.globl _KiTrap10 +_KiTrap10: + pushl %ebp + pushl %ebx + pushl %esi + movl $10, %esi + jmp _KiTrapProlog + +.globl _KiTrap11 +_KiTrap11: + pushl %ebp + pushl %ebx + pushl %esi + movl $11, %esi + jmp _KiTrapProlog + +.globl _KiTrap12 +_KiTrap12: + pushl %ebp + pushl %ebx + pushl %esi + movl $12, %esi + jmp _KiTrapProlog + +.globl _KiTrap13 +_KiTrap13: + pushl %ebp + pushl %ebx + pushl %esi + movl $13, %esi + jmp _KiTrapProlog + +.globl _KiTrap14 +_KiTrap14: + pushl %ebp + pushl %ebx + pushl %esi + movl $14, %esi + jmp _KiTrapProlog + +.globl _KiTrap15 +_KiTrap15: + pushl %ebp + pushl %ebx + pushl %esi + movl $15, %esi + jmp _KiTrapProlog + +.globl _KiTrap16 +_KiTrap16: + pushl %ebp + pushl %ebx + pushl %esi + movl $16, %esi + jmp _KiTrapProlog + +.globl _KiTrapUnknown +_KiTrapUnknown: + pushl $0 + pushl %ebp + pushl %ebx + pushl %esi + movl $255, %esi + jmp _KiTrapProlog /* EOF */ diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index 2cb08f4ae77..baf57ad3890 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -124,6 +124,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First) * FIXME: Think how this might work */ Thread->NpxState = 0; + Thread->Saturation = 0; Thread->Priority = 0; InitializeListHead(&Thread->ApcState.ApcListHead[0]); diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index b6962615e67..ec5c5ccbc73 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: main.c,v 1.80 2001/03/16 18:11:23 dwelch Exp $ +/* $Id: main.c,v 1.81 2001/03/18 19:35:12 dwelch Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/main.c @@ -588,7 +588,29 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock) LdrProcessDriver((PVOID)start, name); } } - + + DbgPrint("About to try MmAllocateContiguousAlignedMemory\n"); + do + { +extern PVOID STDCALL +MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes, + IN PHYSICAL_ADDRESS HighestAcceptableAddress, + IN ULONG Alignment); + PVOID v; + PHYSICAL_ADDRESS p; + p.QuadPart = 16*1024*1024; + v = MmAllocateContiguousAlignedMemory(12*1024, p, + 64*1024); + if (v != NULL) + { + DbgPrint("Worked\n"); + } + else + { + DbgPrint("Failed\n"); + } + } + while (0); /* Create the SystemRoot symbolic link */ DbgPrint("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine); diff --git a/reactos/ntoskrnl/ke/timer.c b/reactos/ntoskrnl/ke/timer.c index ff4de097c4b..fbce048e9f2 100644 --- a/reactos/ntoskrnl/ke/timer.c +++ b/reactos/ntoskrnl/ke/timer.c @@ -1,4 +1,4 @@ -/* $Id: timer.c,v 1.42 2001/03/16 16:05:33 dwelch Exp $ +/* $Id: timer.c,v 1.43 2001/03/18 19:35:13 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -113,22 +113,6 @@ NTSTATUS STDCALL NtQueryPerformanceCounter (IN PLARGE_INTEGER Counter, } -NTSTATUS KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval) -{ - assert(Thread != NULL); - assert(Interval != NULL); - - DPRINT("KeAddThreadTimeout(Thread %x, Interval %x)\n",Thread,Interval); - - KeInitializeTimer(&Thread->Timer); - KeSetTimer(&Thread->Timer, *Interval, &Thread->TimerDpc); - - DPRINT("Thread->Timer.entry.Flink %x\n", - Thread->Timer.TimerListEntry.Flink); - - return STATUS_SUCCESS; -} - NTSTATUS STDCALL NtDelayExecution(IN ULONG Alertable, IN TIME* Interval) @@ -161,9 +145,11 @@ KeDelayExecutionThread (KPROCESSOR_MODE WaitMode, * RETURNS: Status */ { - PKTHREAD CurrentThread = KeGetCurrentThread(); - KeAddThreadTimeout(CurrentThread, Interval); - return (KeWaitForSingleObject(&CurrentThread->Timer, + PKTHREAD Thread = KeGetCurrentThread(); + + KeInitializeTimer(&Thread->Timer); + KeSetTimer(&Thread->Timer, *Interval, NULL); + return (KeWaitForSingleObject(&Thread->Timer, Executive, UserMode, Alertable, @@ -286,7 +272,7 @@ KeCancelTimer (PKTIMER Timer) DPRINT("KeCancelTimer(Timer %x)\n",Timer); - KeRaiseIrql( HIGH_LEVEL, &oldlvl ); + KeRaiseIrql(HIGH_LEVEL, &oldlvl); KeAcquireSpinLockAtDpcLevel( &TimerListLock ); if (Timer->TimerListEntry.Flink == NULL) @@ -367,7 +353,8 @@ KeQueryTickCount (PLARGE_INTEGER TickCount) TickCount->QuadPart = KiTimerTicks; } -static void HandleExpiredTimer(PKTIMER current) +STATIC VOID +HandleExpiredTimer(PKTIMER current) { DPRINT("HandleExpiredTime(current %x)\n",current); if (current->Dpc != NULL) @@ -449,10 +436,6 @@ KiUpdateSystemTime (KIRQL oldIrql, ULONG Eip) KiTimerTicks++; system_time = system_time + CLOCK_INCREMENT; - /* - * Display the tick count in the top left of the screen as a debugging - * aid - */ vidmem[0] = ' '; if (oldIrql < DISPATCH_LEVEL) { diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index aabd42dc367..dd199a9db4e 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -199,65 +199,68 @@ VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus) static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) { - PKWAIT_BLOCK current; - PLIST_ENTRY current_entry; - PKWAIT_BLOCK PrevBlock; - NTSTATUS Status; + PKWAIT_BLOCK current; + PLIST_ENTRY current_entry; + PKWAIT_BLOCK PrevBlock; + NTSTATUS Status; - DPRINT("KeDispatcherObjectWakeAll(hdr %x)\n",hdr); - - if (IsListEmpty(&hdr->WaitListHead)) - { - return(FALSE); - } - - while (!IsListEmpty(&(hdr->WaitListHead))) - { - 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"); - for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; PrevBlock = PrevBlock->NextWaitBlock ) - if( PrevBlock != current ) - RemoveEntryList( &(PrevBlock->WaitListEntry) ); - current->Thread->WaitBlockList = 0; - } - else - { - DPRINT("WaitAll: Remove the current wait block only.\n"); - - PrevBlock = current->Thread->WaitBlockList; - if (PrevBlock == current) - { - DPRINT( "WaitAll: Current block is list head.\n" ); - current->Thread->WaitBlockList = current->NextWaitBlock; - } - else - { - DPRINT( "WaitAll: Current block is not list head.\n" ); - while ( PrevBlock && PrevBlock->NextWaitBlock != current) - { - PrevBlock = PrevBlock->NextWaitBlock; - } - if (PrevBlock) - { - PrevBlock->NextWaitBlock = current->NextWaitBlock; - } - } - } - KiSideEffectsBeforeWake(hdr, current->Thread); - Status = current->WaitKey; - if (current->Thread->WaitBlockList == NULL) - { - PsUnblockThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), - &Status); - } - } - return(TRUE); + DPRINT("KeDispatcherObjectWakeAll(hdr %x)\n",hdr); + + if (IsListEmpty(&hdr->WaitListHead)) + { + return(FALSE); + } + + while (!IsListEmpty(&hdr->WaitListHead)) + { + 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"); + for(PrevBlock = current->Thread->WaitBlockList; PrevBlock; + PrevBlock = PrevBlock->NextWaitBlock) + { + if (PrevBlock != current) + RemoveEntryList(&PrevBlock->WaitListEntry); + } + current->Thread->WaitBlockList = 0; + } + else + { + DPRINT("WaitAll: Remove the current wait block only.\n"); + + PrevBlock = current->Thread->WaitBlockList; + if (PrevBlock == current) + { + DPRINT( "WaitAll: Current block is list head.\n" ); + current->Thread->WaitBlockList = current->NextWaitBlock; + } + else + { + DPRINT( "WaitAll: Current block is not list head.\n" ); + while (PrevBlock && PrevBlock->NextWaitBlock != current) + { + PrevBlock = PrevBlock->NextWaitBlock; + } + if (PrevBlock) + { + PrevBlock->NextWaitBlock = current->NextWaitBlock; + } + } + } + KiSideEffectsBeforeWake(hdr, current->Thread); + Status = current->WaitKey; + if (current->Thread->WaitBlockList == NULL) + { + PsUnblockThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), + &Status); + } + } + return(TRUE); } static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) @@ -342,31 +345,30 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) case InternalSynchronizationEvent: return(KeDispatcherObjectWakeOne(hdr)); - case InternalSynchronizationTimer: return(KeDispatcherObjectWakeOne(hdr)); case InternalSemaphoreType: DPRINT("hdr->SignalState %d\n", hdr->SignalState); if(hdr->SignalState>0) - { - do - { + { + do + { DPRINT("Waking one semaphore waiter\n"); Ret = KeDispatcherObjectWakeOne(hdr); - } while(hdr->SignalState > 0 && Ret) ; - return(Ret); - } + } while(hdr->SignalState > 0 && Ret) ; + return(Ret); + } else return FALSE; - case InternalProcessType: + case InternalProcessType: return(KeDispatcherObjectWakeAll(hdr)); - case InternalThreadType: - return(KeDispatcherObjectWakeAll(hdr)); + case InternalThreadType: + return(KeDispatcherObjectWakeAll(hdr)); - case InternalMutexType: - return(KeDispatcherObjectWakeOne(hdr)); + case InternalMutexType: + return(KeDispatcherObjectWakeOne(hdr)); } DbgPrint("Dispatcher object %x has unknown type %d\n", hdr, hdr->Type); KeBugCheck(0); @@ -398,29 +400,36 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object, NTSTATUS Status; KIRQL WaitIrql; - DPRINT("Entering KeWaitForSingleObject(Object %x) " - "PsGetCurrentThread() %x\n",Object,PsGetCurrentThread()); - CurrentThread = KeGetCurrentThread(); WaitIrql = KeGetCurrentIrql(); + /* + * Set up the timeout + * FIXME: Check for zero timeout + */ if (Timeout != NULL) { - KeAddThreadTimeout(CurrentThread, Timeout); + KeInitializeTimer(&CurrentThread->Timer); + KeSetTimer(&CurrentThread->Timer, *Timeout, NULL); } do { KeAcquireDispatcherDatabaseLock(FALSE); - - DPRINT("hdr->SignalState %d\n", hdr->SignalState); - + + /* + * If we are going to wait alertably and a user apc is pending + * then return + */ if (Alertable && KiTestAlert()) { KeReleaseDispatcherDatabaseLock(FALSE); return(STATUS_USER_APC); } + /* + * If the object is signalled + */ if (KiIsObjectSignalled(hdr, CurrentThread)) { KeReleaseDispatcherDatabaseLock(FALSE); @@ -429,8 +438,25 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object, KeCancelTimer(&KeGetCurrentThread()->Timer); } return(STATUS_WAIT_0); - } + } + + /* + * Check if we have already timed out + */ + if (Timeout != NULL && + KiIsObjectSignalled(&CurrentThread->Timer.Header, CurrentThread)) + { + KeReleaseDispatcherDatabaseLock(FALSE); + if (Timeout != NULL) + { + KeCancelTimer(&KeGetCurrentThread()->Timer); + } + return(STATUS_TIMEOUT); + } + /* + * Set up for a wait + */ CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL; /* Append wait block to the KTHREAD wait block list */ CurrentThread->WaitBlockList = &CurrentThread->WaitBlock[0]; @@ -438,9 +464,24 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object, CurrentThread->WaitBlock[0].Thread = CurrentThread; CurrentThread->WaitBlock[0].WaitKey = 0; CurrentThread->WaitBlock[0].WaitType = WaitAny; - CurrentThread->WaitBlock[0].NextWaitBlock = NULL; InsertTailList(&hdr->WaitListHead, &CurrentThread->WaitBlock[0].WaitListEntry); + if (Timeout != NULL) + { + CurrentThread->WaitBlock[0].NextWaitBlock = + &CurrentThread->WaitBlock[1]; + CurrentThread->WaitBlock[1].Object = (PVOID)&CurrentThread->Timer; + CurrentThread->WaitBlock[1].Thread = CurrentThread; + CurrentThread->WaitBlock[1].WaitKey = 1; + CurrentThread->WaitBlock[1].WaitType = WaitAny; + CurrentThread->WaitBlock[1].NextWaitBlock = NULL; + InsertTailList(&CurrentThread->Timer.Header.WaitListHead, + &CurrentThread->WaitBlock[1].WaitListEntry); + } + else + { + CurrentThread->WaitBlock[0].NextWaitBlock = NULL; + } PsBlockThread(&Status, (UCHAR)Alertable, WaitMode, TRUE, WaitIrql); } while (Status == STATUS_KERNEL_APC); @@ -448,21 +489,25 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object, { KeCancelTimer(&KeGetCurrentThread()->Timer); } - + if (Status == (STATUS_WAIT_0 + 1)) + { + Status = STATUS_TIMEOUT; + } + DPRINT("Returning from KeWaitForSingleObject()\n"); return(Status); } NTSTATUS STDCALL -KeWaitForMultipleObjects (ULONG Count, - PVOID Object[], - WAIT_TYPE WaitType, - KWAIT_REASON WaitReason, - KPROCESSOR_MODE WaitMode, - BOOLEAN Alertable, - PLARGE_INTEGER Timeout, - PKWAIT_BLOCK WaitBlockArray) +KeWaitForMultipleObjects (ULONG Count, + PVOID Object[], + WAIT_TYPE WaitType, + KWAIT_REASON WaitReason, + KPROCESSOR_MODE WaitMode, + BOOLEAN Alertable, + PLARGE_INTEGER Timeout, + PKWAIT_BLOCK WaitBlockArray) { DISPATCHER_HEADER* hdr; PKWAIT_BLOCK blk; @@ -479,87 +524,150 @@ KeWaitForMultipleObjects (ULONG Count, CurrentThread = KeGetCurrentThread(); WaitIrql = KeGetCurrentIrql(); + /* + * Work out where we are going to put the wait blocks + */ if (WaitBlockArray == NULL) { - if (Count > 4) + if (Count > THREAD_WAIT_OBJECTS) { DbgPrint("(%s:%d) Too many objects!\n", __FILE__,__LINE__); - return STATUS_UNSUCCESSFUL; + return(STATUS_UNSUCCESSFUL); } blk = &CurrentThread->WaitBlock[0]; } else { - if (Count > 64) + if (Count > EX_MAXIMUM_WAIT_OBJECTS) { DbgPrint("(%s:%d) Too many objects!\n", __FILE__,__LINE__); - return STATUS_UNSUCCESSFUL; + return(STATUS_UNSUCCESSFUL); } blk = WaitBlockArray; } + + /* + * Set up the timeout if required + */ if (Timeout != NULL) { - KeAddThreadTimeout(CurrentThread,Timeout); + KeInitializeTimer(&CurrentThread->Timer); + KeSetTimer(&CurrentThread->Timer, *Timeout, NULL); } - do { - KeAcquireDispatcherDatabaseLock(FALSE); - - for (i = 0; i < Count; i++) - { - hdr = (DISPATCHER_HEADER *)Object[i]; - - DPRINT("hdr->SignalState %d\n", hdr->SignalState); - - if (KiIsObjectSignalled(hdr, CurrentThread)) - { - CountSignaled++; - - if (WaitType == WaitAny) - { - KeReleaseDispatcherDatabaseLock(FALSE); - DPRINT("One object is already signaled!\n"); + do + { + KeAcquireDispatcherDatabaseLock(FALSE); + + /* + * If we are going to wait alertably and a user apc is pending + * then return + */ + if (Alertable && KiTestAlert()) + { + KeReleaseDispatcherDatabaseLock(FALSE); + return(STATUS_USER_APC); + } + + /* + * Check if the wait is already satisfied + */ + for (i = 0; i < Count; i++) + { + hdr = (DISPATCHER_HEADER *)Object[i]; + + if (KiIsObjectSignalled(hdr, CurrentThread)) + { + CountSignaled++; + + if (WaitType == WaitAny) + { + KeReleaseDispatcherDatabaseLock(FALSE); + DPRINT("One object is already signaled!\n"); return(STATUS_WAIT_0 + i); - } - } - } + } + } + } + + if ((WaitType == WaitAll) && (CountSignaled == Count)) + { + KeReleaseDispatcherDatabaseLock(FALSE); + DPRINT("All objects are already signaled!\n"); + return(STATUS_WAIT_0); + } - if ((WaitType == WaitAll) && (CountSignaled == Count)) - { - KeReleaseDispatcherDatabaseLock(FALSE); - DPRINT("All objects are already signaled!\n"); - return(STATUS_WAIT_0); - } - - /* Append wait block to the KTHREAD wait block list */ - CurrentThread->WaitBlockList = blk; - - for (i = 0; i < Count; i++) - { - hdr = (DISPATCHER_HEADER *)Object[i]; - - DPRINT("hdr->SignalState %d\n", hdr->SignalState); - - blk->Object = Object[i]; - blk->Thread = CurrentThread; - blk->WaitKey = i; - blk->WaitType = WaitType; - if (i == Count - 1) - blk->NextWaitBlock = NULL; - else - blk->NextWaitBlock = blk + 1; - - InsertTailList(&(hdr->WaitListHead),&(blk->WaitListEntry)); - - blk = blk->NextWaitBlock; - } - - PsBlockThread(&Status, Alertable, WaitMode, TRUE, WaitIrql); - } while( Status == STATUS_KERNEL_APC ); + /* + * Check if we have already timed out + */ + if (Timeout != NULL && + KiIsObjectSignalled(&CurrentThread->Timer.Header, CurrentThread)) + { + KeReleaseDispatcherDatabaseLock(FALSE); + if (Timeout != NULL) + { + KeCancelTimer(&KeGetCurrentThread()->Timer); + } + return(STATUS_TIMEOUT); + } + + /* Append wait block to the KTHREAD wait block list */ + CurrentThread->WaitBlockList = blk; + + /* + * Set up the wait + */ + for (i = 0; i < Count; i++) + { + hdr = (DISPATCHER_HEADER *)Object[i]; + + blk->Object = Object[i]; + blk->Thread = CurrentThread; + blk->WaitKey = i; + blk->WaitType = WaitType; + if (i == (Count - 1)) + { + if (Timeout != NULL) + { + blk->NextWaitBlock = &CurrentThread->WaitBlock[3]; + } + else + { + blk->NextWaitBlock = NULL; + } + } + else + { + blk->NextWaitBlock = blk + 1; + } + + InsertTailList(&hdr->WaitListHead, &blk->WaitListEntry); + + blk = blk->NextWaitBlock; + } + if (Timeout != NULL) + { + CurrentThread->WaitBlock[3].Object = (PVOID)&CurrentThread->Timer; + CurrentThread->WaitBlock[3].Thread = CurrentThread; + CurrentThread->WaitBlock[3].WaitKey = Count; + CurrentThread->WaitBlock[3].WaitType = WaitAny; + CurrentThread->WaitBlock[3].NextWaitBlock = NULL; + InsertTailList(&CurrentThread->Timer.Header.WaitListHead, + &CurrentThread->WaitBlock[3].WaitListEntry); + } + + PsBlockThread(&Status, Alertable, WaitMode, TRUE, WaitIrql); + } while(Status == STATUS_KERNEL_APC); + if (Timeout != NULL) - KeCancelTimer(&KeGetCurrentThread()->Timer); + { + KeCancelTimer(&KeGetCurrentThread()->Timer); + } + if (Status == (STATUS_WAIT_63 + 1)) + { + Status = STATUS_TIMEOUT; + } DPRINT("Returning from KeWaitForMultipleObjects()\n"); return(Status); } diff --git a/reactos/ntoskrnl/lpc/send.c b/reactos/ntoskrnl/lpc/send.c index 781217ce22c..60f2d2e1f05 100644 --- a/reactos/ntoskrnl/lpc/send.c +++ b/reactos/ntoskrnl/lpc/send.c @@ -1,4 +1,4 @@ -/* $Id: send.c,v 1.3 2000/10/22 16:36:51 ekohl Exp $ +/* $Id: send.c,v 1.4 2001/03/18 19:35:13 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -32,16 +32,16 @@ * REVISIONS * */ -NTSTATUS STDCALL LpcSendTerminationPort (IN PEPORT Port, - IN TIME CreationTime) +NTSTATUS STDCALL +LpcSendTerminationPort (IN PEPORT Port, + IN TIME CreationTime) { - NTSTATUS Status; - LPC_TERMINATION_MESSAGE Msg; + NTSTATUS Status; + LPC_TERMINATION_MESSAGE Msg; - Msg.CreationTime = CreationTime; - Status = LpcRequestPort (Port, - &Msg.Header); - return(Status); + Msg.CreationTime = CreationTime; + Status = LpcRequestPort (Port, &Msg.Header); + return(Status); } @@ -57,13 +57,45 @@ NTSTATUS STDCALL LpcSendTerminationPort (IN PEPORT Port, * REVISIONS * */ -NTSTATUS STDCALL LpcSendDebugMessagePort (IN PEPORT Port, - IN PLPC_DBG_MESSAGE Message) +NTSTATUS STDCALL +LpcSendDebugMessagePort (IN PEPORT Port, + IN PLPC_DBG_MESSAGE Message, + OUT PLPC_DBG_MESSAGE Reply) { NTSTATUS Status; + KIRQL oldIrql; + PQUEUEDMESSAGE ReplyMessage; - Status = LpcRequestPort(Port, &Message->Header); - return(Status); + Status = EiReplyOrRequestPort(Port, + &Message->Header, + LPC_REQUEST, + Port); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(Port); + return(Status); + } + KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE); + + /* + * Wait for a reply + */ + KeWaitForSingleObject(&Port->Event, + UserRequest, + UserMode, + FALSE, + NULL); + + /* + * Dequeue the reply + */ + KeAcquireSpinLock(&Port->Lock, &oldIrql); + ReplyMessage = EiDequeueMessagePort(Port); + KeReleaseSpinLock(&Port->Lock, oldIrql); + memcpy(Reply, &ReplyMessage->Message, ReplyMessage->Message.MessageSize); + ExFreePool(ReplyMessage); + + return(STATUS_SUCCESS); } @@ -149,9 +181,10 @@ NTSTATUS STDCALL NtRequestPort (IN HANDLE PortHandle, * REVISIONS * */ -NTSTATUS STDCALL NtRequestWaitReplyPort (IN HANDLE PortHandle, - PLPC_MESSAGE LpcRequest, - PLPC_MESSAGE LpcReply) +NTSTATUS STDCALL +NtRequestWaitReplyPort (IN HANDLE PortHandle, + PLPC_MESSAGE LpcRequest, + PLPC_MESSAGE LpcReply) { NTSTATUS Status; PEPORT Port; @@ -177,14 +210,13 @@ NTSTATUS STDCALL NtRequestWaitReplyPort (IN HANDLE PortHandle, LpcRequest, LPC_REQUEST, Port); - KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE); - if (!NT_SUCCESS(Status)) { DbgPrint("Enqueue failed\n"); ObDereferenceObject(Port); return(Status); } + KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE); /* * Wait for a reply diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index bb1df1f6ca1..36d343dd362 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -83,13 +83,13 @@ MmGetContinuousPages(ULONG NumberOfBytes, break; } } - else if (start != -1) + else { start = -1; /* * Fast forward to the base of the next aligned region */ - i = i + (Alignment / PAGESIZE); + i = ROUND_UP((i + 1), (Alignment / PAGESIZE)); } } if (start == -1 || length != NrPages) @@ -176,11 +176,19 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress, } } } - + + /* + * Page zero is reserved + */ + MmPageArray[0].Flags = MM_PHYSICAL_PAGE_BIOS; + MmPageArray[0].ReferenceCount = 0; + InsertTailList(&BiosPageListHead, + &MmPageArray[0].ListEntry); + i = 1; if ((ULONG)FirstPhysKernelAddress < 0xa0000) { - MmStats.NrFreePages += ((ULONG)FirstPhysKernelAddress/PAGESIZE); + MmStats.NrFreePages += (((ULONG)FirstPhysKernelAddress/PAGESIZE) - 1); for (; i<((ULONG)FirstPhysKernelAddress/PAGESIZE); i++) { MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE; @@ -216,7 +224,7 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress, } else { - MmStats.NrFreePages += (0xa0000 / PAGESIZE); + MmStats.NrFreePages += ((0xa0000 / PAGESIZE) - 1); for (; i<(0xa0000 / PAGESIZE); i++) { MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE; diff --git a/reactos/ntoskrnl/ps/create.c b/reactos/ntoskrnl/ps/create.c index dac5e727bc4..bfd95301ad9 100644 --- a/reactos/ntoskrnl/ps/create.c +++ b/reactos/ntoskrnl/ps/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.31 2001/03/16 18:11:24 dwelch Exp $ +/* $Id: create.c,v 1.32 2001/03/18 19:35:13 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -26,6 +26,7 @@ #include #include #include +#include #define NDEBUG #include @@ -577,27 +578,11 @@ NtCreateThread (PHANDLE ThreadHandle, /* * Maybe send a message to the process's debugger */ -#if 0 - if (ParentProcess->DebugPort != NULL) - { - LPC_DBG_MESSAGE Message; - PEPROCESS Process; - - - Message.Header.MessageSize = sizeof(LPC_DBG_MESSAGE); - Message.Header.DataSize = sizeof(LPC_DBG_MESSAGE) - - sizeof(LPC_MESSAGE_HEADER); - Message.EventCode = DBG_EVENT_CREATE_THREAD; - Message.Data.CreateThread.StartAddress = - ; - Message.Data.CreateProcess.Base = ImageBase; - Message.Data.CreateProcess.EntryPoint = NULL; // - - Status = LpcSendDebugMessagePort(ParentProcess->DebugPort, - &Message); - } -#endif + DbgkCreateThread((PVOID)ThreadContext->Eip); + /* + * Start the thread running + */ if (!CreateSuspended) { DPRINT("Not creating suspended\n"); diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index 590b0556515..1fe3b95708d 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -133,6 +133,7 @@ VOID PsTerminateCurrentThread(NTSTATUS ExitStatus) KeAcquireSpinLock(&PiThreadListLock, &oldIrql); CurrentThread->ExitStatus = ExitStatus; + KeCancelTimer(&KeGetCurrentThread()->Timer); KeAcquireDispatcherDatabaseLock(FALSE); CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE; KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader); diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index fc74838b531..b88dc55860d 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.58 2001/03/07 16:48:45 dwelch Exp $ +/* $Id: process.c,v 1.59 2001/03/18 19:35:14 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -532,6 +532,7 @@ NtCreateProcess (OUT PHANDLE ProcessHandle, /* * Maybe send a message to the creator process's debugger */ +#if 0 if (ParentProcess->DebugPort != NULL) { LPC_DBG_MESSAGE Message; @@ -554,6 +555,7 @@ NtCreateProcess (OUT PHANDLE ProcessHandle, Status = LpcSendDebugMessagePort(ParentProcess->DebugPort, &Message); } +#endif ObDereferenceObject(Process); ObDereferenceObject(ParentProcess); diff --git a/reactos/ntoskrnl/ps/suspend.c b/reactos/ntoskrnl/ps/suspend.c index e4ba5f4deb9..ec3ed202f0e 100644 --- a/reactos/ntoskrnl/ps/suspend.c +++ b/reactos/ntoskrnl/ps/suspend.c @@ -1,6 +1,23 @@ -/* $Id: suspend.c,v 1.4 2001/03/16 18:11:24 dwelch Exp $ +/* + * ReactOS kernel + * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id: suspend.c,v 1.5 2001/03/18 19:35:14 dwelch Exp $ * - * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/ps/suspend.c * PURPOSE: Thread managment diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 04720c27e78..b8c8567bdc1 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.71 2001/03/16 18:11:24 dwelch Exp $ +/* $Id: thread.c,v 1.72 2001/03/18 19:35:14 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -73,14 +73,6 @@ HANDLE STDCALL PsGetCurrentThreadId(VOID) VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread) { -// DPRINT("PsInsertIntoThreadList(Priority %x, Thread %x)\n",Priority, -// Thread); -// DPRINT("Offset %x\n", THREAD_PRIORITY_MAX + Priority); - - if (PiThreadListLock.Lock == 0) - { - KeBugCheck(0); - } if (Priority >= MAXIMUM_PRIORITY || Priority < 0) { DPRINT1("Invalid thread priority\n"); @@ -128,11 +120,6 @@ static PETHREAD PsScanThreadList (KPRIORITY Priority) PLIST_ENTRY current_entry; PETHREAD current; -// DPRINT("PsScanThreadList(Priority %d)\n",Priority); - if (PiThreadListLock.Lock == 0) - { - KeBugCheck(0); - } current_entry = RemoveHeadList(&PriorityListHead[Priority]); if (current_entry != &PriorityListHead[Priority]) { @@ -251,6 +238,36 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode, KeLowerIrql(WaitIrql); } +VOID +PsFreezeAllThreads(PEPROCESS Process) + /* + * Used by the debugging code to freeze all the process's threads + * while the debugger is examining their state. + */ +{ + KIRQL oldIrql; + PLIST_ENTRY current_entry; + PETHREAD current; + + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); + + current_entry = Process->ThreadListHead.Flink; + while (current_entry != &Process->ThreadListHead) + { + current = CONTAINING_RECORD(current_entry, ETHREAD, + Tcb.ProcessThreadListEntry); + + /* + * We have to be careful here, we can't just set the freeze the + * thread inside kernel mode since it may be holding a lock. + */ + + current_entry = current_entry->Flink; + } + + KeReleaseSpinLock(&PiThreadListLock, oldIrql); +} + VOID PsInitThreadManagment(VOID) /*