mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Fixed timer code
Fixed NtClose return in case of error Added new APC-like primitive for terminating threads Fixed restriction on size of working set svn path=/trunk/; revision=1603
This commit is contained in:
parent
ae6b859854
commit
076c1c6ac3
24 changed files with 440 additions and 236 deletions
|
@ -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 timer
|
||||
|
||||
# objdir
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define NR_THREADS (0x1)
|
||||
#define NR_THREADS (30)
|
||||
|
||||
|
||||
DWORD WINAPI
|
||||
thread_main1(LPVOID param)
|
||||
{
|
||||
printf("Thread 1 running (Counter %lu)\n", (DWORD)param);
|
||||
|
||||
SleepEx(INFINITE, TRUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ DWORD WINAPI
|
|||
thread_main2(LPVOID param)
|
||||
{
|
||||
printf("Thread 2 running (Counter %lu)\n", (DWORD)param);
|
||||
|
||||
Sleep(INFINITE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,6 @@ int main (void)
|
|||
|
||||
printf("Thread terminated...\n");
|
||||
#endif
|
||||
|
||||
printf("Exiting\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: thread.c,v 1.6 2000/01/31 20:24:27 ekohl Exp $
|
||||
/* $Id: thread.c,v 1.7 2001/02/06 00:11:17 dwelch Exp $
|
||||
*
|
||||
*
|
||||
*
|
||||
|
@ -48,12 +48,13 @@ int main (int argc, char* argv[])
|
|||
|
||||
// The user must supply one argument (the seed). if he/she doesn't
|
||||
// then we show the help.
|
||||
if(argc < 2) {
|
||||
showHelp();
|
||||
return 1;
|
||||
}
|
||||
// if(argc < 2) {
|
||||
// showHelp();
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
nr = atoi(argv[1]);
|
||||
// nr = atoi(argv[1]);
|
||||
nr = 500;
|
||||
printf("Seed %ld\n", nr);
|
||||
|
||||
printf("Creating %d threads...\n",NR_THREADS*2);
|
||||
|
|
|
@ -75,7 +75,12 @@ typedef VOID (*PFLUSH_TO_LSN)(IN PVOID LogHandle, IN LARGE_INTEGER Lsn);
|
|||
|
||||
typedef struct _REACTOS_COMMON_FCB_HEADER
|
||||
{
|
||||
CSHORT NodeTypeCode;
|
||||
CSHORT NodeByteSize;
|
||||
PBCB Bcb;
|
||||
LARGE_INTEGER AllocationSize;
|
||||
LARGE_INTEGER FileSize;
|
||||
LARGE_INTEGER ValidDataLength;
|
||||
} REACTOS_COMMON_FCB_HEADER;
|
||||
|
||||
#endif /* __INCLUDE_DDK_CCTYPES_H */
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#define IMAGE_DOS_SIGNATURE 0x5a4d
|
||||
#define IMAGE_OS2_SIGNATURE 0x454e
|
||||
|
||||
#define IMAGE_OS2_SIGNATURE_LE 0x454c
|
||||
#define IMAGE_VXD_SIGNATURE 0x454c
|
||||
#define IMAGE_NT_SIGNATURE 0x00004550
|
||||
|
|
|
@ -41,4 +41,5 @@ cp apps/dump_shared_data/dump_shared_data.exe $1/reactos/bin
|
|||
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/ptest/ptest.exe $1/reactos/bin/
|
||||
cp apps/timer/timer.exe $1/reactos/bin/
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: proc.c,v 1.36 2000/12/28 20:38:27 ekohl Exp $
|
||||
/* $Id: proc.c,v 1.37 2001/02/06 00:11:18 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -284,25 +284,35 @@ Sleep (
|
|||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
SleepEx (
|
||||
DWORD dwMilliseconds,
|
||||
BOOL bAlertable
|
||||
)
|
||||
DWORD STDCALL
|
||||
SleepEx (DWORD dwMilliseconds,
|
||||
BOOL bAlertable)
|
||||
{
|
||||
TIME Interval;
|
||||
NTSTATUS errCode;
|
||||
TIME Interval;
|
||||
NTSTATUS errCode;
|
||||
|
||||
if (dwMilliseconds != INFINITE)
|
||||
{
|
||||
/*
|
||||
* System time units are 100 nanoseconds (a nanosecond is a billionth of
|
||||
* a second).
|
||||
*/
|
||||
Interval.QuadPart = dwMilliseconds;
|
||||
Interval.QuadPart = -(Interval.QuadPart * 10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Approximately 292000 years hence */
|
||||
Interval.QuadPart = -0x7FFFFFFFFFFFFFFF;
|
||||
}
|
||||
|
||||
Interval.QuadPart = dwMilliseconds * 1000;
|
||||
|
||||
errCode = NtDelayExecution (bAlertable, & Interval);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastErrorByStatus (errCode);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
errCode = NtDelayExecution (bAlertable, &Interval);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastErrorByStatus (errCode);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -102,6 +102,8 @@ PULONG KeGetStackTopThread(struct _ETHREAD* Thread);
|
|||
VOID KeContextToTrapFrame(PCONTEXT Context,
|
||||
PKTRAP_FRAME TrapFrame);
|
||||
VOID KeReleaseDispatcherDatabaseLockAtDpcLevel(BOOLEAN Wait);
|
||||
VOID
|
||||
KiDeliverNormalApc(VOID);
|
||||
|
||||
BOOLEAN STDCALL KeRemoveQueueApc (PKAPC Apc);
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ typedef ULONG SWAPENTRY;
|
|||
#define MEMORY_AREA_SECTION_VIEW_RESERVE (9)
|
||||
#define MEMORY_AREA_CACHE_SEGMENT (10)
|
||||
#define MEMORY_AREA_SHARED_DATA (11)
|
||||
|
||||
#define MEMORY_AREA_WORKING_SET (12)
|
||||
|
||||
#define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
|
||||
((x) / (4*1024*1024))
|
||||
|
@ -119,28 +119,23 @@ typedef struct
|
|||
} Data;
|
||||
} MEMORY_AREA, *PMEMORY_AREA;
|
||||
|
||||
#define WSET_ADDRESSES_IN_PAGE (1020)
|
||||
|
||||
typedef struct _MWORKING_SET
|
||||
{
|
||||
PVOID Address[WSET_ADDRESSES_IN_PAGE];
|
||||
struct _MWORKING_SET* Next;
|
||||
} MWORKING_SET, *PMWORKING_SET;
|
||||
|
||||
typedef struct _MADDRESS_SPACE
|
||||
{
|
||||
LIST_ENTRY MAreaListHead;
|
||||
KMUTEX Lock;
|
||||
ULONG LowestAddress;
|
||||
struct _EPROCESS* Process;
|
||||
ULONG WorkingSetSize;
|
||||
ULONG WorkingSetLruFirst;
|
||||
ULONG WorkingSetLruLast;
|
||||
ULONG WorkingSetPagesAllocated;
|
||||
PUSHORT PageTableRefCountTable;
|
||||
ULONG PageTableRefCountTableSize;
|
||||
LIST_ENTRY MAreaListHead;
|
||||
KMUTEX Lock;
|
||||
ULONG LowestAddress;
|
||||
struct _EPROCESS* Process;
|
||||
PMEMORY_AREA WorkingSetArea;
|
||||
ULONG WorkingSetSize;
|
||||
ULONG WorkingSetLruFirst;
|
||||
ULONG WorkingSetLruLast;
|
||||
ULONG WorkingSetPagesAllocated;
|
||||
ULONG WorkingSetMaximumLength;
|
||||
PUSHORT PageTableRefCountTable;
|
||||
ULONG PageTableRefCountTableSize;
|
||||
} MADDRESS_SPACE, *PMADDRESS_SPACE;
|
||||
|
||||
|
||||
/* FUNCTIONS */
|
||||
|
||||
VOID MmLockAddressSpace(PMADDRESS_SPACE AddressSpace);
|
||||
|
@ -268,11 +263,12 @@ ULONG MmTrimWorkingSet(struct _EPROCESS* Process,
|
|||
ULONG ReduceHint);
|
||||
VOID MmRemovePageFromWorkingSet(struct _EPROCESS* Process,
|
||||
PVOID Address);
|
||||
BOOLEAN MmAddPageToWorkingSet(struct _EPROCESS* Process,
|
||||
PVOID Address);
|
||||
VOID
|
||||
MmAddPageToWorkingSet(struct _EPROCESS* Process, PVOID Address);
|
||||
|
||||
VOID MmInitPagingFile(VOID);
|
||||
VOID MmReserveSwapPages(ULONG Nr);
|
||||
BOOLEAN
|
||||
MmReserveSwapPages(ULONG Nr);
|
||||
VOID MmDereserveSwapPages(ULONG Nr);
|
||||
SWAPENTRY MmAllocSwapPage(VOID);
|
||||
VOID MmFreeSwapPage(SWAPENTRY Entry);
|
||||
|
|
|
@ -33,21 +33,6 @@ VOID PsTerminateCurrentThread(NTSTATUS ExitStatus);
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID KeCallKernelRoutineApc(PKAPC Apc)
|
||||
/*
|
||||
* FUNCTION: Call the kernel routine for an APC
|
||||
*/
|
||||
{
|
||||
DPRINT("KeCallKernelRoutineApc(Apc %x)\n",Apc);
|
||||
|
||||
Apc->KernelRoutine(Apc,
|
||||
&Apc->NormalRoutine,
|
||||
&Apc->NormalContext,
|
||||
&Apc->SystemArgument1,
|
||||
&Apc->SystemArgument2);
|
||||
DPRINT("Finished KeCallKernelRoutineApc()\n");
|
||||
}
|
||||
|
||||
VOID KiRundownThread(VOID)
|
||||
/*
|
||||
* FUNCTION:
|
||||
|
@ -74,7 +59,51 @@ BOOLEAN KiTestAlert(VOID)
|
|||
return(TRUE);
|
||||
}
|
||||
|
||||
BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame)
|
||||
VOID
|
||||
KiDeliverNormalApc(VOID)
|
||||
{
|
||||
PETHREAD Thread = PsGetCurrentThread();
|
||||
PLIST_ENTRY current;
|
||||
PKAPC Apc;
|
||||
KIRQL oldlvl;
|
||||
PKNORMAL_ROUTINE NormalRoutine;
|
||||
PVOID NormalContext;
|
||||
PVOID SystemArgument1;
|
||||
PVOID SystemArgument2;
|
||||
|
||||
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);
|
||||
|
||||
NormalRoutine = Apc->NormalRoutine;
|
||||
NormalContext = Apc->NormalContext;
|
||||
SystemArgument1 = Apc->SystemArgument1;
|
||||
SystemArgument2 = Apc->SystemArgument2;
|
||||
Apc->KernelRoutine(Apc,
|
||||
&NormalRoutine,
|
||||
&NormalContext,
|
||||
&SystemArgument1,
|
||||
&SystemArgument2);
|
||||
NormalRoutine(NormalContext, SystemArgument1, SystemArgument2);
|
||||
|
||||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||
Thread->Tcb.ApcState.KernelApcInProgress--;
|
||||
}
|
||||
}
|
||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
KiDeliverUserApc(PKTRAP_FRAME TrapFrame)
|
||||
/*
|
||||
* FUNCTION: Tests whether there are any pending APCs for the current thread
|
||||
* and if so the APCs will be delivered on exit from kernel mode.
|
||||
|
@ -205,17 +234,26 @@ VOID STDCALL KiDeliverApc(ULONG Unknown1,
|
|||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||
while(!IsListEmpty(&(Thread->Tcb.ApcState.ApcListHead[0])))
|
||||
{
|
||||
DPRINT("Delivering APC\n");
|
||||
current = RemoveTailList(&(Thread->Tcb.ApcState.ApcListHead[0]));
|
||||
Thread->Tcb.ApcState.KernelApcInProgress++;
|
||||
Thread->Tcb.ApcState.KernelApcPending--;
|
||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||
|
||||
Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry);
|
||||
KeCallKernelRoutineApc(Apc);
|
||||
|
||||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||
Thread->Tcb.ApcState.KernelApcInProgress--;
|
||||
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--;
|
||||
}
|
||||
}
|
||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||
}
|
||||
|
@ -267,11 +305,23 @@ KeInsertQueueApc (PKAPC Apc,
|
|||
Apc->Inserted = TRUE;
|
||||
|
||||
if (Apc->ApcMode == KernelMode && TargetThread->KernelApcDisable >= 1 &&
|
||||
TargetThread->WaitIrql < APC_LEVEL)
|
||||
TargetThread->WaitIrql < APC_LEVEL && Apc->NormalRoutine == NULL)
|
||||
{
|
||||
KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb),
|
||||
STATUS_KERNEL_APC);
|
||||
}
|
||||
if (Apc->ApcMode == KernelMode && Apc->NormalRoutine != NULL)
|
||||
{
|
||||
TargetThread->Alerted[1] = 1;
|
||||
if (TargetThread->Alertable == TRUE &&
|
||||
TargetThread->WaitMode == UserMode)
|
||||
{
|
||||
PETHREAD Thread;
|
||||
|
||||
Thread = CONTAINING_RECORD(TargetThread, ETHREAD, Tcb);
|
||||
KeRemoveAllWaitsThread(Thread, STATUS_USER_APC);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For user mode APCs if the thread is already waiting then we wait it
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: irq.c,v 1.4 2001/01/18 15:00:08 dwelch Exp $
|
||||
/* $Id: irq.c,v 1.5 2001/02/06 00:11:19 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -199,6 +199,13 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
|
|||
{
|
||||
PsDispatchThread(THREAD_STATE_RUNNABLE);
|
||||
}
|
||||
if (KeGetCurrentThread() != NULL &&
|
||||
KeGetCurrentThread()->Alerted[1] != 0 &&
|
||||
Trapframe->Cs != KERNEL_CS)
|
||||
{
|
||||
HalEndSystemInterrupt (APC_LEVEL, 0);
|
||||
KiDeliverNormalApc();
|
||||
}
|
||||
}
|
||||
|
||||
HalEndSystemInterrupt (old_level, 0);
|
||||
|
@ -426,8 +433,7 @@ IoConnectInterrupt(PKINTERRUPT* InterruptObject,
|
|||
}
|
||||
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
VOID STDCALL
|
||||
IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
|
||||
/*
|
||||
* FUNCTION: Releases a drivers isr
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: usercall.c,v 1.18 2001/01/19 15:09:01 dwelch Exp $
|
||||
/* $Id: usercall.c,v 1.19 2001/02/06 00:11:19 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -25,10 +25,6 @@
|
|||
#include <ddk/defines.h>
|
||||
#include <internal/ps.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
VOID PsTerminateCurrentThread(NTSTATUS ExitStatus);
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID KiSystemCallHook(ULONG Nr, ...)
|
||||
|
@ -53,32 +49,14 @@ VOID KiSystemCallHook(ULONG Nr, ...)
|
|||
|
||||
ULONG KiAfterSystemCallHook(ULONG NtStatus, PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
PETHREAD EThread;
|
||||
extern KSPIN_LOCK PiThreadListLock;
|
||||
|
||||
assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||
|
||||
/*
|
||||
* Check if the current thread is terminating
|
||||
*/
|
||||
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
|
||||
EThread = PsGetCurrentThread();
|
||||
if (EThread->DeadThread)
|
||||
if (KeGetCurrentThread()->Alerted[1] != 0 && TrapFrame->Cs != KERNEL_CS)
|
||||
{
|
||||
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
|
||||
PsTerminateCurrentThread(EThread->ExitStatus);
|
||||
KiDeliverNormalApc();
|
||||
}
|
||||
else
|
||||
if (KeGetCurrentThread()->Alerted[0] != 0 && TrapFrame->Cs != KERNEL_CS)
|
||||
{
|
||||
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
|
||||
KiDeliverUserApc(TrapFrame);
|
||||
}
|
||||
|
||||
if (KeGetCurrentThread()->Alerted[0] == 0 || TrapFrame->Cs == KERNEL_CS)
|
||||
{
|
||||
return(NtStatus);
|
||||
}
|
||||
KiDeliverUserApc(TrapFrame);
|
||||
return(NtStatus);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,18 @@
|
|||
|
||||
extern VOID
|
||||
PiTimeoutThread(struct _KDPC Dpc, PVOID Context, PVOID Arg1, PVOID Arg2);
|
||||
VOID
|
||||
PiSuspendThreadRundownRoutine(PKAPC Apc);
|
||||
VOID
|
||||
PiSuspendThreadKernelRoutine(PKAPC Apc,
|
||||
PKNORMAL_ROUTINE* NormalRoutine,
|
||||
PVOID* NormalContext,
|
||||
PVOID* SystemArgument1,
|
||||
PVOID* SystemArguemnt2);
|
||||
VOID
|
||||
PiSuspendThreadNormalRoutine(PVOID NormalContext,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2);
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
@ -141,7 +153,14 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
|||
Thread->ApcQueueable = 0;
|
||||
Thread->AutoAlignment = 0;
|
||||
Thread->StackBase = KernelStack;
|
||||
memset(&Thread->SuspendApc, 0, sizeof(KAPC));
|
||||
KeInitializeApc(&Thread->SuspendApc,
|
||||
Thread,
|
||||
0,
|
||||
PiSuspendThreadKernelRoutine,
|
||||
PiSuspendThreadRundownRoutine,
|
||||
PiSuspendThreadNormalRoutine,
|
||||
KernelMode,
|
||||
NULL);
|
||||
KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 255);
|
||||
Thread->ThreadListEntry.Flink = NULL;
|
||||
Thread->ThreadListEntry.Blink = NULL;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: main.c,v 1.76 2001/01/18 16:54:22 ekohl Exp $
|
||||
/* $Id: main.c,v 1.77 2001/02/06 00:11:18 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -475,14 +475,6 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
|
|||
HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
|
||||
KeInit1();
|
||||
KeLowerIrql(DISPATCH_LEVEL);
|
||||
|
||||
{
|
||||
char tmpbuf[80];
|
||||
sprintf(tmpbuf,"system with %d/%d MB memory\n",
|
||||
(unsigned int)(KeLoaderBlock.MemLower)/1024,
|
||||
(unsigned int)(KeLoaderBlock.MemHigher)/1024);
|
||||
HalDisplayString(tmpbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Display version number and copyright/warranty message
|
||||
|
@ -495,6 +487,19 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
|
|||
HalDisplayString("are welcome to change it and/or distribute copies of it "
|
||||
"under certain\n");
|
||||
HalDisplayString("conditions. There is absolutely no warranty for ReactOS.\n");
|
||||
|
||||
/*
|
||||
* Fail at runtime if someone has changed various structures without
|
||||
* updating the offsets used for the assembler code
|
||||
*/
|
||||
assert(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
|
||||
assert(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
|
||||
assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
|
||||
assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
|
||||
assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
|
||||
assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
|
||||
assert(FIELD_OFFSET(KPROCESS, PageTableDirectory) ==
|
||||
KPROCESS_PAGE_TABLE_DIRECTORY);
|
||||
|
||||
last_kernel_address = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: timer.c,v 1.37 2001/02/05 02:31:04 phreak Exp $
|
||||
/* $Id: timer.c,v 1.38 2001/02/06 00:11:18 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -119,8 +119,8 @@ NTSTATUS KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval)
|
|||
|
||||
DPRINT("KeAddThreadTimeout(Thread %x, Interval %x)\n",Thread,Interval);
|
||||
|
||||
KeInitializeTimer(&(Thread->Timer));
|
||||
KeSetTimer( &(Thread->Timer), *Interval, &Thread->TimerDpc );
|
||||
KeInitializeTimer(&Thread->Timer);
|
||||
KeSetTimer(&Thread->Timer, *Interval, &Thread->TimerDpc);
|
||||
|
||||
DPRINT("Thread->Timer.entry.Flink %x\n",
|
||||
Thread->Timer.TimerListEntry.Flink);
|
||||
|
@ -136,10 +136,11 @@ NTSTATUS STDCALL NtDelayExecution(IN ULONG Alertable,
|
|||
LARGE_INTEGER Timeout;
|
||||
|
||||
Timeout = *((PLARGE_INTEGER)Interval);
|
||||
Timeout.QuadPart = -Timeout.QuadPart;
|
||||
DPRINT("NtDelayExecution(Alertable %d, Internal %x) IntervalP %x\n",
|
||||
Alertable, Internal, Timeout);
|
||||
|
||||
DPRINT("Execution delay is %d/%d\n",
|
||||
Timeout.u.Highpart, Timeout.u.LowPart);
|
||||
Status = KeDelayExecutionThread(UserMode, Alertable, &Timeout);
|
||||
return(Status);
|
||||
}
|
||||
|
@ -161,9 +162,9 @@ KeDelayExecutionThread (KPROCESSOR_MODE WaitMode,
|
|||
{
|
||||
PKTHREAD CurrentThread = KeGetCurrentThread();
|
||||
KeAddThreadTimeout(CurrentThread, Interval);
|
||||
return (KeWaitForSingleObject(&(CurrentThread->Timer),
|
||||
return (KeWaitForSingleObject(&CurrentThread->Timer,
|
||||
Executive,
|
||||
KernelMode,
|
||||
UserMode,
|
||||
Alertable,
|
||||
NULL));
|
||||
}
|
||||
|
|
|
@ -280,6 +280,8 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
|
|||
InsertTailList(&FreePageListHead,
|
||||
&MmPageArray[i].ListEntry);
|
||||
}
|
||||
MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages +
|
||||
MmStats.NrReservedPages + MmStats.NrUserPages;
|
||||
return((PVOID)LastKernelAddress);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: page.c,v 1.17 2001/01/08 02:14:06 dwelch Exp $
|
||||
/* $Id: page.c,v 1.18 2001/02/06 00:11:19 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -283,7 +283,7 @@ ULONG MmGetPhysicalAddressForProcess(PEPROCESS Process,
|
|||
|
||||
VOID MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage)
|
||||
/*
|
||||
* FUNCTION: Delete a virtual mapping
|
||||
` * FUNCTION: Delete a virtual mapping
|
||||
*/
|
||||
{
|
||||
PULONG Pte;
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/mm.h>
|
||||
#include <internal/ke.h>
|
||||
#include <internal/i386/segment.h>
|
||||
#include <internal/ps.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
@ -54,7 +57,13 @@ NTSTATUS MmPageFault(ULONG Cs,
|
|||
{
|
||||
Status = MmNotPresentFault(Mode, Cr2);
|
||||
}
|
||||
|
||||
|
||||
if (KeGetCurrentThread() != NULL &&
|
||||
KeGetCurrentThread()->Alerted[1] != 0 &&
|
||||
Cs != KERNEL_CS)
|
||||
{
|
||||
KiDeliverNormalApc();
|
||||
}
|
||||
if (!NT_SUCCESS(Status) && (Mode == KernelMode) &&
|
||||
((*Eip) >= (ULONG)MmSafeCopyFromUserUnsafeStart) &&
|
||||
((*Eip) <= (ULONG)MmSafeCopyFromUserRestart))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: pagefile.c,v 1.9 2001/01/13 18:38:09 dwelch Exp $
|
||||
/* $Id: pagefile.c,v 1.10 2001/02/06 00:11:19 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -38,14 +38,32 @@ typedef struct _PAGINGFILE
|
|||
|
||||
#define MAX_PAGING_FILES (32)
|
||||
|
||||
/* List of paging files, both used and free */
|
||||
static PPAGINGFILE PagingFileList[MAX_PAGING_FILES];
|
||||
/* Lock for examining the list of paging files */
|
||||
static KSPIN_LOCK PagingFileListLock;
|
||||
|
||||
/* Number of pages that are available for swapping */
|
||||
static ULONG MiFreeSwapPages;
|
||||
/* Number of pages that have been allocated for swapping */
|
||||
static ULONG MiUsedSwapPages;
|
||||
/*
|
||||
* Number of pages that have been reserved for swapping but not yet allocated
|
||||
*/
|
||||
static ULONG MiReservedSwapPages;
|
||||
|
||||
/*
|
||||
* Ratio between reserved and available swap pages, e.g. setting this to five
|
||||
* forces one swap page to be available for every five swap pages that are
|
||||
* reserved. Setting this to zero turns off commit checking altogether.
|
||||
*/
|
||||
#define MM_PAGEFILE_COMMIT_RATIO (1)
|
||||
/*
|
||||
* Number of pages that can be used for potentially swapable memory without
|
||||
* pagefile space being reserved. The intention is that is allows smss
|
||||
* to start up and create page files while ordinarily having a commit
|
||||
* ratio of one.
|
||||
*/
|
||||
#define MM_PAGEFILE_COMMIT_GRACE (256)
|
||||
|
||||
#if 0
|
||||
|
@ -53,9 +71,11 @@ static PVOID MmCoreDumpPageFrame;
|
|||
static BYTE MmCoreDumpHeader[PAGESIZE];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Translate between a swap entry and a file and offset pair.
|
||||
*/
|
||||
#define FILE_FROM_ENTRY(i) ((i) >> 24)
|
||||
#define OFFSET_FROM_ENTRY(i) (((i) & 0xffffff) - 1)
|
||||
|
||||
#define ENTRY_FROM_FILE_OFFSET(i, j) (((i) << 24) || ((j) + 1))
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
@ -111,7 +131,8 @@ NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
|
|||
return(Status);
|
||||
}
|
||||
|
||||
VOID MmInitPagingFile(VOID)
|
||||
VOID
|
||||
MmInitPagingFile(VOID)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
|
@ -127,27 +148,38 @@ VOID MmInitPagingFile(VOID)
|
|||
}
|
||||
}
|
||||
|
||||
VOID MmReserveSwapPages(ULONG Nr)
|
||||
BOOLEAN
|
||||
MmReserveSwapPages(ULONG Nr)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
ULONG MiAvailSwapPages;
|
||||
|
||||
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
|
||||
MiAvailSwapPages =
|
||||
(MiFreeSwapPages * MM_PAGEFILE_COMMIT_RATIO) + MM_PAGEFILE_COMMIT_GRACE;
|
||||
if (MM_PAGEFILE_COMMIT_RATIO != 0 && MiAvailSwapPages < MiReservedSwapPages)
|
||||
{
|
||||
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
||||
return(FALSE);
|
||||
}
|
||||
MiReservedSwapPages = MiReservedSwapPages + Nr;
|
||||
// MiFreeSwapPages = MiFreeSwapPages - Nr;
|
||||
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
VOID MmDereserveSwapPages(ULONG Nr)
|
||||
VOID
|
||||
MmDereserveSwapPages(ULONG Nr)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
|
||||
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
|
||||
MiReservedSwapPages = MiReservedSwapPages - Nr;
|
||||
// MiFreeSwapPages = MiFreeSwapPages - Nr;
|
||||
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
||||
}
|
||||
|
||||
ULONG MiAllocPageFromPagingFile(PPAGINGFILE PagingFile)
|
||||
static ULONG
|
||||
MiAllocPageFromPagingFile(PPAGINGFILE PagingFile)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
ULONG i;
|
||||
|
@ -170,7 +202,8 @@ ULONG MiAllocPageFromPagingFile(PPAGINGFILE PagingFile)
|
|||
return(0);
|
||||
}
|
||||
|
||||
VOID MmFreeSwapPage(SWAPENTRY Entry)
|
||||
VOID
|
||||
MmFreeSwapPage(SWAPENTRY Entry)
|
||||
{
|
||||
ULONG i;
|
||||
ULONG off;
|
||||
|
@ -194,7 +227,8 @@ VOID MmFreeSwapPage(SWAPENTRY Entry)
|
|||
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
||||
}
|
||||
|
||||
SWAPENTRY MmAllocSwapPage(VOID)
|
||||
SWAPENTRY
|
||||
MmAllocSwapPage(VOID)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
ULONG i;
|
||||
|
@ -256,10 +290,11 @@ NTSTATUS STDCALL MmDumpToPagingFile(PCONTEXT Context,
|
|||
}
|
||||
#endif
|
||||
|
||||
NTSTATUS STDCALL NtCreatePagingFile(IN PUNICODE_STRING PageFileName,
|
||||
IN ULONG MinimumSize,
|
||||
IN ULONG MaximumSize,
|
||||
OUT PULONG ActualSize)
|
||||
NTSTATUS STDCALL
|
||||
NtCreatePagingFile(IN PUNICODE_STRING PageFileName,
|
||||
IN ULONG MinimumSize,
|
||||
IN ULONG MaximumSize,
|
||||
OUT PULONG ActualSize)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: section.c,v 1.43 2001/01/28 15:17:52 ekohl Exp $
|
||||
/* $Id: section.c,v 1.44 2001/02/06 00:11:19 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -1135,7 +1135,7 @@ MmAllocateSection (IN ULONG Length)
|
|||
Length,
|
||||
0,
|
||||
&marea);
|
||||
if (!NT_SUCCESS(STATUS_SUCCESS))
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: wset.c,v 1.6 2001/01/08 02:14:06 dwelch Exp $
|
||||
/* $Id: wset.c,v 1.7 2001/02/06 00:11:19 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -14,6 +14,7 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <internal/mm.h>
|
||||
#include <internal/ps.h>
|
||||
#include <ntos/minmax.h>
|
||||
|
||||
#include <internal/debug.h>
|
||||
|
||||
|
@ -38,16 +39,55 @@ VOID MmUnlockWorkingSet(PEPROCESS Process)
|
|||
KeReleaseMutex(&Process->WorkingSetLock, FALSE);
|
||||
}
|
||||
|
||||
VOID MmInitializeWorkingSet(PEPROCESS Process,
|
||||
PMADDRESS_SPACE AddressSpace)
|
||||
VOID
|
||||
MmInitializeWorkingSet(PEPROCESS Process, PMADDRESS_SPACE AddressSpace)
|
||||
{
|
||||
AddressSpace->WorkingSetSize = 0;
|
||||
AddressSpace->WorkingSetLruFirst = 0;
|
||||
AddressSpace->WorkingSetLruLast = 0;
|
||||
AddressSpace->WorkingSetPagesAllocated = 1;
|
||||
KeInitializeMutex(&Process->WorkingSetLock, 1);
|
||||
Process->WorkingSetPage = ExAllocatePage();
|
||||
memset(Process->WorkingSetPage, 0, 4096);
|
||||
PVOID BaseAddress;
|
||||
ULONG MaximumLength;
|
||||
PVOID FirstPage;
|
||||
NTSTATUS Status;
|
||||
|
||||
/*
|
||||
* The maximum number of pages in the working set is the maximum
|
||||
* of the size of physical memory and the size of the user address space
|
||||
*/
|
||||
MaximumLength = MmStats.NrTotalPages - MmStats.NrReservedPages;
|
||||
MaximumLength = min(MaximumLength, KERNEL_BASE / PAGESIZE);
|
||||
MaximumLength = PAGE_ROUND_UP(MaximumLength * sizeof(ULONG));
|
||||
|
||||
FirstPage = MmAllocPageMaybeSwap(0);
|
||||
if (FirstPage == NULL)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
BaseAddress = 0;
|
||||
Status = MmCreateMemoryArea(NULL,
|
||||
MmGetKernelAddressSpace(),
|
||||
MEMORY_AREA_WORKING_SET,
|
||||
&BaseAddress,
|
||||
MaximumLength,
|
||||
0,
|
||||
&AddressSpace->WorkingSetArea);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
AddressSpace->WorkingSetSize = 0;
|
||||
AddressSpace->WorkingSetLruFirst = 0;
|
||||
AddressSpace->WorkingSetLruLast = 0;
|
||||
AddressSpace->WorkingSetMaximumLength = MaximumLength;
|
||||
KeInitializeMutex(&Process->WorkingSetLock, 1);
|
||||
Process->WorkingSetPage = BaseAddress;
|
||||
Status = MmCreateVirtualMapping(NULL,
|
||||
Process->WorkingSetPage,
|
||||
PAGE_READWRITE,
|
||||
(ULONG)FirstPage);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
memset(Process->WorkingSetPage, 0, 4096);
|
||||
}
|
||||
|
||||
ULONG MmPageOutPage(PMADDRESS_SPACE AddressSpace,
|
||||
|
@ -87,13 +127,13 @@ ULONG MmTrimWorkingSet(PEPROCESS Process,
|
|||
{
|
||||
ULONG i, j;
|
||||
PMADDRESS_SPACE AddressSpace;
|
||||
PMWORKING_SET WSet;
|
||||
PVOID* WSet;
|
||||
ULONG Count;
|
||||
BOOLEAN Ul;
|
||||
|
||||
MmLockWorkingSet(Process);
|
||||
|
||||
WSet = (PMWORKING_SET)Process->WorkingSetPage;
|
||||
WSet = (PVOID*)Process->WorkingSetPage;
|
||||
AddressSpace = &Process->AddressSpace;
|
||||
|
||||
Count = 0;
|
||||
|
@ -104,7 +144,7 @@ ULONG MmTrimWorkingSet(PEPROCESS Process,
|
|||
PVOID Address;
|
||||
PMEMORY_AREA MArea;
|
||||
|
||||
Address = WSet->Address[j];
|
||||
Address = WSet[j];
|
||||
|
||||
MArea = MmOpenMemoryAreaByAddress(AddressSpace, Address);
|
||||
|
||||
|
@ -124,7 +164,7 @@ ULONG MmTrimWorkingSet(PEPROCESS Process,
|
|||
}
|
||||
else
|
||||
{
|
||||
j = (j + 1) % WSET_ADDRESSES_IN_PAGE;
|
||||
j = (j + 1) % AddressSpace->WorkingSetMaximumLength;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -143,58 +183,93 @@ VOID MmRemovePageFromWorkingSet(PEPROCESS Process,
|
|||
{
|
||||
ULONG i;
|
||||
PMADDRESS_SPACE AddressSpace;
|
||||
PMWORKING_SET WSet;
|
||||
PVOID* WSet;
|
||||
ULONG j;
|
||||
|
||||
WSet = (PMWORKING_SET)Process->WorkingSetPage;
|
||||
WSet = (PVOID*)Process->WorkingSetPage;
|
||||
AddressSpace = &Process->AddressSpace;
|
||||
|
||||
j = AddressSpace->WorkingSetLruFirst;
|
||||
for (i = 0; i < AddressSpace->WorkingSetSize; i++)
|
||||
{
|
||||
if (WSet->Address[j] == Address)
|
||||
if (WSet[j] == Address)
|
||||
{
|
||||
WSet->Address[j] =
|
||||
WSet->Address[AddressSpace->WorkingSetLruLast - 1];
|
||||
WSet[j] = WSet[AddressSpace->WorkingSetLruLast - 1];
|
||||
if (AddressSpace->WorkingSetLruLast != 0)
|
||||
{
|
||||
AddressSpace->WorkingSetLruLast =
|
||||
AddressSpace->WorkingSetLruLast --;
|
||||
AddressSpace->WorkingSetLruLast--;
|
||||
}
|
||||
else
|
||||
{
|
||||
AddressSpace->WorkingSetLruLast = WSET_ADDRESSES_IN_PAGE;
|
||||
AddressSpace->WorkingSetLruLast =
|
||||
AddressSpace->WorkingSetMaximumLength;
|
||||
}
|
||||
return;
|
||||
}
|
||||
j = (j + 1) % WSET_ADDRESSES_IN_PAGE;
|
||||
j = (j + 1) % AddressSpace->WorkingSetMaximumLength;
|
||||
}
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
BOOLEAN MmAddPageToWorkingSet(PEPROCESS Process,
|
||||
PVOID Address)
|
||||
VOID
|
||||
MmAddPageToWorkingSet(PEPROCESS Process,
|
||||
PVOID Address)
|
||||
{
|
||||
PMWORKING_SET WSet;
|
||||
PVOID* WSet;
|
||||
PMADDRESS_SPACE AddressSpace;
|
||||
|
||||
BOOLEAN Present;
|
||||
ULONG Current;
|
||||
PVOID NextAddress;
|
||||
|
||||
AddressSpace = &Process->AddressSpace;
|
||||
|
||||
if (((AddressSpace->WorkingSetLruLast + 1) % WSET_ADDRESSES_IN_PAGE) ==
|
||||
AddressSpace->WorkingSetLruFirst)
|
||||
/*
|
||||
* This can't happen unless there is a bug
|
||||
*/
|
||||
if (AddressSpace->WorkingSetSize == AddressSpace->WorkingSetMaximumLength)
|
||||
{
|
||||
return(FALSE);
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
WSet = (PMWORKING_SET)Process->WorkingSetPage;
|
||||
WSet = (PVOID*)Process->WorkingSetPage;
|
||||
|
||||
WSet->Address[AddressSpace->WorkingSetLruLast] = Address;
|
||||
Current = AddressSpace->WorkingSetLruLast;
|
||||
|
||||
AddressSpace->WorkingSetLruLast =
|
||||
(AddressSpace->WorkingSetLruLast + 1) % WSET_ADDRESSES_IN_PAGE;
|
||||
/*
|
||||
* If we are growing the working set then check to see if we need
|
||||
* to allocate a page
|
||||
*/
|
||||
NextAddress = (PVOID)PAGE_ROUND_DOWN((PVOID)&WSet[Current]);
|
||||
Present = MmIsPagePresent(NULL, NextAddress);
|
||||
if (!Present)
|
||||
{
|
||||
PVOID Page;
|
||||
NTSTATUS Status;
|
||||
|
||||
Page = MmAllocPageMaybeSwap(0);
|
||||
if (Page == 0)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
Status = MmCreateVirtualMapping(NULL,
|
||||
NextAddress,
|
||||
PAGE_READWRITE,
|
||||
(ULONG)Page);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert the page in the working set
|
||||
*/
|
||||
WSet[Current] = Address;
|
||||
|
||||
AddressSpace->WorkingSetLruLast =
|
||||
(Current + 1) % AddressSpace->WorkingSetMaximumLength;
|
||||
AddressSpace->WorkingSetSize++;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: handle.c,v 1.27 2001/02/02 20:46:36 ekohl Exp $
|
||||
/* $Id: handle.c,v 1.28 2001/02/06 00:11:19 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -595,7 +595,7 @@ NTSTATUS STDCALL NtClose(HANDLE Handle)
|
|||
ObjectBody = ObDeleteHandle(PsGetCurrentProcess(), Handle);
|
||||
if (ObjectBody == NULL)
|
||||
{
|
||||
return(STATUS_HANDLES_CLOSED);
|
||||
return(STATUS_INVALID_HANDLE);
|
||||
}
|
||||
|
||||
Header = BODY_TO_HEADER(ObjectBody);
|
||||
|
|
|
@ -139,6 +139,30 @@ VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
|
|||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
VOID
|
||||
PiTerminateThreadRundownRoutine(PKAPC Apc)
|
||||
{
|
||||
ExFreePool(Apc);
|
||||
}
|
||||
|
||||
VOID
|
||||
PiTerminateThreadKernelRoutine(PKAPC Apc,
|
||||
PKNORMAL_ROUTINE* NormalRoutine,
|
||||
PVOID* NormalContext,
|
||||
PVOID* SystemArgument1,
|
||||
PVOID* SystemArguemnt2)
|
||||
{
|
||||
ExFreePool(Apc);
|
||||
}
|
||||
|
||||
VOID
|
||||
PiTerminateThreadNormalRoutine(PVOID NormalContext,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
{
|
||||
PsTerminateCurrentThread(PsGetCurrentThread()->ExitStatus);
|
||||
}
|
||||
|
||||
VOID
|
||||
PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus)
|
||||
/*
|
||||
|
@ -146,22 +170,26 @@ PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus)
|
|||
* NOTES: This function must be called with PiThreadListLock held
|
||||
*/
|
||||
{
|
||||
DPRINT("PsTerminateOtherThread(Thread %x, ExitStatus %x)\n",
|
||||
Thread, ExitStatus);
|
||||
|
||||
/*
|
||||
* We must synchronize the termination of a thread with its execution
|
||||
* so all this routine does is to mark the thread as terminated and
|
||||
* wake it if possible. The thread will then kill itself when it
|
||||
* next exits kernel mode.
|
||||
*/
|
||||
Thread->DeadThread = 1;
|
||||
Thread->ExitStatus = ExitStatus;
|
||||
if (Thread->Tcb.State == THREAD_STATE_FROZEN &&
|
||||
(Thread->Tcb.Alertable || Thread->Tcb.WaitMode == UserMode))
|
||||
{
|
||||
KeRemoveAllWaitsThread(Thread, STATUS_ALERTED);
|
||||
}
|
||||
PKAPC Apc;
|
||||
|
||||
DPRINT("PsTerminateOtherThread(Thread %x, ExitStatus %x)\n",
|
||||
Thread, ExitStatus);
|
||||
|
||||
Thread->DeadThread = 1;
|
||||
Thread->ExitStatus = ExitStatus;
|
||||
Apc = ExAllocatePool(NonPagedPool, sizeof(KAPC));
|
||||
KeInitializeApc(Apc,
|
||||
&Thread->Tcb,
|
||||
0,
|
||||
PiTerminateThreadKernelRoutine,
|
||||
PiTerminateThreadRundownRoutine,
|
||||
PiTerminateThreadNormalRoutine,
|
||||
KernelMode,
|
||||
NULL);
|
||||
KeInsertQueueApc(Apc,
|
||||
NULL,
|
||||
NULL,
|
||||
KernelMode);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: suspend.c,v 1.2 2001/01/21 14:54:30 dwelch Exp $
|
||||
/* $Id: suspend.c,v 1.3 2001/02/06 00:11:20 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -28,7 +28,6 @@
|
|||
VOID
|
||||
PiSuspendThreadRundownRoutine(PKAPC Apc)
|
||||
{
|
||||
ExFreePool(Apc);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -37,13 +36,19 @@ PiSuspendThreadKernelRoutine(PKAPC Apc,
|
|||
PVOID* NormalContext,
|
||||
PVOID* SystemArgument1,
|
||||
PVOID* SystemArguemnt2)
|
||||
{
|
||||
}
|
||||
|
||||
VOID
|
||||
PiSuspendThreadNormalRoutine(PVOID NormalContext,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
{
|
||||
KeWaitForSingleObject(&PsGetCurrentThread()->Tcb.SuspendSemaphore,
|
||||
0,
|
||||
UserMode,
|
||||
TRUE,
|
||||
NULL);
|
||||
ExFreePool(Apc);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -56,45 +61,20 @@ PsResumeThread(PETHREAD Thread, PULONG SuspendCount)
|
|||
NTSTATUS
|
||||
PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount)
|
||||
{
|
||||
PKAPC Apc;
|
||||
NTSTATUS Status;
|
||||
ULONG OldValue;
|
||||
|
||||
/*
|
||||
* If we are suspending ourselves then we can cut out the work in
|
||||
* sending an APC
|
||||
*/
|
||||
if (Thread == PsGetCurrentThread())
|
||||
OldValue = InterlockedIncrement((PULONG)&Thread->Tcb.SuspendCount);
|
||||
if (OldValue == 0)
|
||||
{
|
||||
Status = KeWaitForSingleObject(&Thread->Tcb.SuspendSemaphore,
|
||||
0,
|
||||
UserMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
return(Status);
|
||||
KeInsertQueueApc(&Thread->Tcb.SuspendApc,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
|
||||
Apc = ExAllocatePool(NonPagedPool, sizeof(KAPC));
|
||||
if (Apc == NULL)
|
||||
else
|
||||
{
|
||||
return(STATUS_NO_MEMORY);
|
||||
InterlockedDecrement(&Thread->Tcb.SuspendSemaphore.Header.SignalState);
|
||||
}
|
||||
|
||||
KeInitializeApc(Apc,
|
||||
&Thread->Tcb,
|
||||
0,
|
||||
PiSuspendThreadKernelRoutine,
|
||||
PiSuspendThreadRundownRoutine,
|
||||
NULL,
|
||||
KernelMode,
|
||||
NULL);
|
||||
KeInsertQueueApc(Apc,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue