Worked around compiler bug in NtDelayExecution

Added some page free checking
Reorganised thread code a bit

svn path=/trunk/; revision=892
This commit is contained in:
David Welch 1999-12-18 17:48:23 +00:00
parent 8abc09ec0d
commit cc5dc64c30
12 changed files with 160 additions and 171 deletions

View file

@ -14,6 +14,7 @@ DWORD WINAPI thread_main1(LPVOID param)
s = s % 10;
printf("s %d\n", s);
Sleep(s);
printf("Thread %d finished\n", (DWORD)param);
return 0;
}

View file

@ -174,7 +174,7 @@ typedef struct _KTHREAD
PVOID KernelStack;
UCHAR DebugActive;
UCHAR State;
USHORT Alerted;
UCHAR Alerted[2];
UCHAR Iopl;
UCHAR NpxState;
UCHAR Saturation;
@ -199,9 +199,9 @@ typedef struct _KTHREAD
KAFFINITY UserAffinity;
UCHAR SystemAffinityActive;
UCHAR Pad;
PKQUEUE Queue;
PKQUEUE Queue;
KSPIN_LOCK ApcQueueLock;
KTIMER Timer;
KDPC TimerDpc; // Added by Phillip Susi for internal KeAddThreadTimeout() impl.
LIST_ENTRY QueueListEntry;
KAFFINITY Affinity;
UCHAR Preempted;
@ -234,7 +234,7 @@ typedef struct _KTHREAD
/* Provisionally added by David Welch */
hal_thread_state Context;
KDPC TimerDpc; // Added by Phillip Susi for internal KeAddThreadTimeout() impl.
} KTHREAD, *PKTHREAD;
// According to documentation the stack should have a commited [ 1 page ] and

View file

@ -1,5 +1,5 @@
/* $Id: zw.h,v 1.23 1999/12/10 17:04:33 dwelch Exp $
/* $Id: zw.h,v 1.24 1999/12/18 17:48:21 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -1201,12 +1201,7 @@ NtCurrentTeb(VOID
* Interval = Specifies the interval to wait.
* RETURNS: Status
*/
NTSTATUS
STDCALL
NtDelayExecution(
IN BOOLEAN Alertable,
IN TIME* Interval
);
NTSTATUS STDCALL NtDelayExecution(IN ULONG Alertable, IN TIME* Interval);
NTSTATUS
STDCALL

View file

@ -31,6 +31,7 @@ ULONG PsFreezeThread(PETHREAD Thread, PNTSTATUS WaitStatus,
VOID PiInitApcManagement(VOID);
VOID PiDeleteThread(PVOID ObjectBody);
VOID PiCloseThread(PVOID ObjectBody, ULONG HandleCount);
VOID PsReapThreads(VOID);
NTSTATUS PsInitializeThread(HANDLE ProcessHandle,
PETHREAD* ThreadPtr,
PHANDLE ThreadHandle,

View file

@ -10,6 +10,8 @@
#define CHECKPOINT do { dprintf("(KERNEL32:%s:%d) Checkpoint\n",__FILE__,__LINE__); } while(0);
#endif
#define DPRINT1(args...) do { dprintf("(KERNEL32:%s:%d) ",__FILE__,__LINE__); dprintf(args); } while(0);
void dprintf(char* fmt, ...);
void aprintf(char* fmt, ...);

View file

@ -1,4 +1,4 @@
/* $Id: usercall.c,v 1.3 1999/12/02 20:53:53 dwelch Exp $
/* $Id: usercall.c,v 1.4 1999/12/18 17:48:22 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -99,11 +99,24 @@ void PsBeginThreadWithContextInternal(void);
"popl %ebp\n\t"
"iret\n\t");
VOID KiSystemCallHook(ULONG Nr)
VOID KiSystemCallHook(ULONG Nr, ...)
{
// DbgPrint("KiSystemCallHook(Nr %d) %x ", Nr, PsGetCurrentProcess());
// DbgPrint("SystemCall %x\n", _SystemServiceTable[Nr].Function);
#ifdef TRACE_SYSTEM_CALLS
va_list ap;
ULONG i;
va_start(ap, Nr);
DbgPrint("%x/%d ", _SystemServiceTable[Nr].Function,Nr);
DbgPrint("%x (", _SystemServiceTable[Nr].ParametersSize);
for (i = 0; i < _SystemServiceTable[Nr].ParametersSize / 4; i++)
{
DbgPrint("%x, ", va_arg(ap, ULONG));
}
DbgPrint(")\n");
assert_irql(PASSIVE_LEVEL);
va_end(ap);
#endif
}
ULONG KiAfterSystemCallHook(ULONG NtStatus, PCONTEXT Context)
@ -210,62 +223,3 @@ void interrupt_handler2e(void);
"iret\n\t");
void old_interrupt_handler2e(void);
__asm__("\n\t.global _old_interrupt_handler2e\n\t"
"_old_interrupt_handler2e:\n\t"
/* Save the users context */
"pushl %ds\n\t"
"pushl %es\n\t"
"pushl %esi\n\t"
"pushl %edi\n\t"
"pushl %ebp\n\t"
"pushl %ebx\n\t"
/* Set ES to kernel segment */
"movw $"STR(KERNEL_DS)",%bx\n\t"
"movw %bx,%es\n\t"
/* Allocate new Kernel stack frame */
"movl %esp,%ebp\n\t"
/* Users's current stack frame pointer is source */
"movl %edx,%esi\n\t"
/* FIXME: determine system service table to use */
/* FIXME: chech to see if SS is valid/inrange */
/* Allocate room for argument list from kernel stack */
"movl %es:__SystemServiceTable(,%eax,8),%ecx\n\t"
"subl %ecx,%esp\n\t"
/* Copy the arguments from the user stack to the kernel stack */
"movl %esp,%edi\n\t"
"rep\n\tmovsb\n\t"
/* DS is now also kernel segment */
"movw %bx,%ds\n\t"
/* Call system call hook */
"pushl %eax\n\t"
"call _KiSystemCallHook\n\t"
"popl %eax\n\t"
/* Make the system service call */
"movl %ds:__SystemServiceTable+4(,%eax,8),%eax\n\t"
"call *%eax\n\t"
/* Deallocate the kernel stack frame */
"movl %ebp,%esp\n\t"
/* Restore the user context */
"popl %ebx\n\t"
"popl %ebp\n\t"
"popl %edi\n\t"
"popl %esi\n\t"
"popl %es\n\t"
"popl %ds\n\t"
"iret\n\t");

View file

@ -1,4 +1,4 @@
/* $Id: main.c,v 1.32 1999/12/13 22:04:36 dwelch Exp $
/* $Id: main.c,v 1.33 1999/12/18 17:48:22 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -26,7 +26,7 @@
#include <internal/mmhal.h>
#include <internal/i386/segment.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS ****************************************************************/

View file

@ -1,4 +1,4 @@
/* $Id: timer.c,v 1.24 1999/12/13 22:04:36 dwelch Exp $
/* $Id: timer.c,v 1.25 1999/12/18 17:48:22 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -129,13 +129,18 @@ NTSTATUS KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval)
}
NTSTATUS STDCALL NtDelayExecution(IN BOOLEAN Alertable,
NTSTATUS STDCALL NtDelayExecution(IN ULONG Alertable,
IN TIME* Interval)
{
NTSTATUS Status;
PLARGE_INTEGER IntervalP;
Status = KeDelayExecutionThread(UserMode, Alertable,
(PLARGE_INTEGER)Internal);
IntervalP = (PLARGE_INTEGER)Interval;
DPRINT1("NtDelayExecution(Alertable %d, Internal %x) IntervalP %x\n",
Alertable, Internal, IntervalP);
Status = KeDelayExecutionThread(UserMode, Alertable, IntervalP);
return(Status);
}

View file

@ -168,7 +168,11 @@ VOID MmFreePage(PVOID PhysicalAddress, ULONG Nr)
DPRINT("MmFreePage(PhysicalAddress %x, Nr %x)\n", PhysicalAddress, Nr);
assert(((ULONG)PhysicalAddress) <= 0x400000);
if (((ULONG)PhysicalAddress) > 0x400000)
{
DbgPrint("MmFreePage() failed with %x\n", PhysicalAddress);
KeBugCheck(0);
}
MiNrFreePages = MiNrFreePages + Nr;
MiNrUsedPages = MiNrUsedPages - Nr;
@ -218,7 +222,11 @@ PVOID MmAllocPage(VOID)
MiNrUsedPages = MiNrUsedPages + 1;
MiNrFreePages = MiNrFreePages - 1;
assert(offset <= 0x400000);
if (offset > 0x400000)
{
DbgPrint("Failed in MmAllocPage() with offset %x\n", offset);
KeBugCheck(0);
}
DPRINT("MmAllocPage() = %x\n",offset);
return((PVOID)offset);

View file

@ -23,6 +23,8 @@
/* GLOBALS *****************************************************************/
extern ULONG MiNrFreePages;
#define PA_BIT_PRESENT (0)
#define PA_BIT_READWRITE (1)
#define PA_BIT_USER (2)
@ -168,9 +170,17 @@ VOID MmDeletePageEntry(PEPROCESS Process, PVOID Address, BOOL FreePage)
}
return;
}
page_tlb = ADDR_TO_PTE(Address);
page_tlb = ADDR_TO_PTE(Address);
if (FreePage && PAGE_MASK(*page_tlb) != 0)
{
if (PAGE_MASK(*page_tlb) >= 0x400000)
{
DbgPrint("MmDeletePageEntry(Address %x) Physical %x Free %d, "
"Entry %x\n",
Address, PAGE_MASK(*page_tlb), MiNrFreePages,
*page_tlb);
KeBugCheck(0);
}
MmFreePage((PVOID)PAGE_MASK(*page_tlb),1);
}
*page_tlb = 0;
@ -219,11 +229,19 @@ VOID MmSetPage(PEPROCESS Process,
PEPROCESS CurrentProcess = PsGetCurrentProcess();
ULONG Attributes = 0;
DPRINT("MmSetPage(Process %x, Address %x, flProtect %x, "
"PhysicalAddress %x)\n",Process,Address,flProtect,
PhysicalAddress);
if (PAGE_ROUND_DOWN(Address) == 0x77631000)
{
DPRINT1("MmSetPage(Process %x, Address %x, flProtect %x, "
"PhysicalAddress %x)\n",Process,Address,flProtect,
PhysicalAddress);
}
assert(((ULONG)PhysicalAddress)<0x400000);
if (((ULONG)PhysicalAddress) >= 0x400000)
{
DbgPrint("MmSetPage(Process %x, Address %x, PhysicalAddress %x)\n",
Process, Address, PhysicalAddress);
KeBugCheck(0);
}
Attributes = ProtectToPTE(flProtect);

View file

@ -24,9 +24,88 @@
extern ULONG PiNrThreads;
extern ULONG PiNrRunnableThreads;
extern KSPIN_LOCK PiThreadListLock;
extern LIST_ENTRY PiThreadListHead;
/* FUNCTIONS *****************************************************************/
VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus)
{
KIRQL oldlvl;
PLIST_ENTRY current_entry;
PETHREAD current;
KeAcquireSpinLock(&PiThreadListLock, &oldlvl);
current_entry = PiThreadListHead.Flink;
while (current_entry != &PiThreadListHead)
{
current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.QueueListEntry);
if (current->ThreadsProcess == Process &&
current != PsGetCurrentThread())
{
KeReleaseSpinLock(&PiThreadListLock, oldlvl);
PsTerminateOtherThread(current, ExitStatus);
KeAcquireSpinLock(&PiThreadListLock, &oldlvl);
current_entry = PiThreadListHead.Flink;
}
current_entry = current_entry->Flink;
}
KeReleaseSpinLock(&PiThreadListLock, oldlvl);
}
VOID PsReapThreads(VOID)
{
PLIST_ENTRY current_entry;
PETHREAD current;
KIRQL oldIrql;
// DPRINT1("PsReapThreads()\n");
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
current_entry = PiThreadListHead.Flink;
while (current_entry != &PiThreadListHead)
{
current = CONTAINING_RECORD(current_entry, ETHREAD,
Tcb.ThreadListEntry);
current_entry = current_entry->Flink;
if (current->Tcb.State == THREAD_STATE_TERMINATED_1)
{
PEPROCESS Process = current->ThreadsProcess;
NTSTATUS Status = current->ExitStatus;
ObReferenceObjectByPointer(Process,
0,
PsProcessType,
KernelMode );
DPRINT("Reaping thread %x\n", current);
current->Tcb.State = THREAD_STATE_TERMINATED_2;
RemoveEntryList(&current->Tcb.ProcessThreadListEntry);
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
ObDereferenceObject(current);
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
if(IsListEmpty( &Process->Pcb.ThreadListHead))
{
/*
* TODO: Optimize this so it doesnt jerk the IRQL around so
* much :)
*/
DPRINT("Last thread terminated, terminating process\n");
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
PiTerminateProcess(Process, Status);
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
}
ObDereferenceObject(Process);
current_entry = PiThreadListHead.Flink;
}
}
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
}
VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
/*
* FUNCTION: Terminates the current thread
@ -35,7 +114,6 @@ VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
KIRQL oldIrql;
PETHREAD CurrentThread;
CurrentThread = PsGetCurrentThread();
DPRINT("terminating %x\n",CurrentThread);
@ -65,15 +143,13 @@ VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus)
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
if (Thread->Tcb.State == THREAD_STATE_RUNNABLE)
{
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);
ObDereferenceObject(Thread);
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
ObDereferenceObject(Thread);
}
NTSTATUS STDCALL PiTerminateProcess(PEPROCESS Process,

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.43 1999/12/18 07:33:53 phreak Exp $
/* $Id: thread.c,v 1.44 1999/12/18 17:48:23 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -71,32 +71,6 @@ HANDLE PsGetCurrentThreadId(VOID)
return(CurrentThread->Cid.UniqueThread);
}
VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus)
{
KIRQL oldlvl;
PLIST_ENTRY current_entry;
PETHREAD current;
KeAcquireSpinLock(&PiThreadListLock, &oldlvl);
current_entry = PiThreadListHead.Flink;
while (current_entry != &PiThreadListHead)
{
current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.QueueListEntry);
if (current->ThreadsProcess == Process &&
current != PsGetCurrentThread())
{
KeReleaseSpinLock(&PiThreadListLock, oldlvl);
PsTerminateOtherThread(current, ExitStatus);
KeAcquireSpinLock(&PiThreadListLock, &oldlvl);
current_entry = PiThreadListHead.Flink;
}
current_entry = current_entry->Flink;
}
KeReleaseSpinLock(&PiThreadListLock, oldlvl);
}
static VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)
{
// DPRINT("PsInsertIntoThreadList(Priority %x, Thread %x)\n",Priority,
@ -129,63 +103,17 @@ VOID PsDumpThreads(VOID)
DbgPrint("Too many threads on list\n");
return;
}
DPRINT1("current %x current->Tcb.State %d eip %x ",
DbgPrint("current %x current->Tcb.State %d eip %x ",
current, current->Tcb.State,
current->Tcb.Context.eip);
// KeDumpStackFrames(0, 16);
DPRINT1("PID %d ", current->ThreadsProcess->UniqueProcessId);
DPRINT1("\n");
DbgPrint("PID %d ", current->ThreadsProcess->UniqueProcessId);
DbgPrint("\n");
current_entry = current_entry->Flink;
}
}
VOID PsReapThreads(VOID)
{
PLIST_ENTRY current_entry;
PETHREAD current;
KIRQL oldIrql;
// DPRINT1("PsReapThreads()\n");
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
current_entry = PiThreadListHead.Flink;
while (current_entry != &PiThreadListHead)
{
current = CONTAINING_RECORD(current_entry, ETHREAD,
Tcb.ThreadListEntry);
current_entry = current_entry->Flink;
if (current->Tcb.State == THREAD_STATE_TERMINATED_1)
{
PEPROCESS Process = current->ThreadsProcess;
NTSTATUS Status = current->ExitStatus;
ObReferenceObjectByPointer( Process, 0, PsProcessType, KernelMode );
DPRINT("Reaping thread %x\n", current);
current->Tcb.State = THREAD_STATE_TERMINATED_2;
RemoveEntryList( &current->Tcb.ProcessThreadListEntry );
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
ObDereferenceObject(current);
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
if( IsListEmpty( &Process->Pcb.ThreadListHead ) )
{
//TODO: Optimize this so it doesnt jerk the IRQL around so much :)
DPRINT( "Last thread terminated, terminating process\n" );
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
PiTerminateProcess( Process, Status );
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
}
ObDereferenceObject( Process );
current_entry = PiThreadListHead.Flink;
}
}
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
}
static PETHREAD PsScanThreadList (KPRIORITY Priority)
{
PLIST_ENTRY current_entry;
@ -282,14 +210,15 @@ ULONG PsUnfreezeThread(PETHREAD Thread, PNTSTATUS WaitStatus)
Thread->Tcb.FreezeCount--;
r = Thread->Tcb.FreezeCount;
if (WaitStatus != NULL)
{
Thread->Tcb.WaitStatus = *WaitStatus;
}
if (r <= 0)
{
DPRINT("Resuming thread\n");
Thread->Tcb.State = THREAD_STATE_RUNNABLE;
if (WaitStatus != NULL)
{
Thread->Tcb.WaitStatus = *WaitStatus;
}
PsInsertIntoThreadList(Thread->Tcb.Priority, Thread);
}