mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
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:
parent
8abc09ec0d
commit
cc5dc64c30
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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, ...);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
||||
|
|
|
@ -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 ****************************************************************/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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(¤t->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,
|
||||
|
|
|
@ -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( ¤t->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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue