diff --git a/reactos/Makefile b/reactos/Makefile index 0dd58f39a28..31245fc3e11 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -41,7 +41,7 @@ FS_DRIVERS = vfat minix KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS) APPS = args hello shell test cat bench apc shm lpc thread event file gditest \ - pteb + pteb consume # objdir @@ -298,4 +298,4 @@ endif # # etags: - find . -name "*.[ch]" -print | etags --language=c - \ No newline at end of file + find . -name "*.[ch]" -print | etags --language=c - diff --git a/reactos/apps/tests/consume/Makefile b/reactos/apps/tests/consume/Makefile new file mode 100644 index 00000000000..215ce75e571 --- /dev/null +++ b/reactos/apps/tests/consume/Makefile @@ -0,0 +1,39 @@ +# +# +# +OBJECTS = consume.o +PROGS = consume.exe +LIBS = +CLEAN_FILES = consume.o consume.exe + +all: consume.exe + +clean: $(CLEAN_FILES:%=%_clean) + +$(CLEAN_FILES:%=%_clean): %_clean: + - $(RM) $* + +.phony: clean $(CLEAN_FILES:%=%_clean) + +floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%) + +$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: % +ifeq ($(DOSCLI),yes) + $(CP) $* $(FLOPPY_DIR)\apps\$* +else + $(CP) $* $(FLOPPY_DIR)/apps/$* +endif + +dist: $(PROGS:%=../../$(DIST_DIR)/apps/%) + +$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: % +ifeq ($(DOSCLI),yes) + $(CP) $* ..\..\$(DIST_DIR)\apps\$* +else + $(CP) $* ../../$(DIST_DIR)/apps/$* +endif + +consume.exe: $(OBJECTS) + $(CC) $(OBJECTS) -o consume.exe + +include ../../rules.mak diff --git a/reactos/apps/tests/consume/consume.c b/reactos/apps/tests/consume/consume.c new file mode 100644 index 00000000000..05123742574 --- /dev/null +++ b/reactos/apps/tests/consume/consume.c @@ -0,0 +1,29 @@ +#include +#include +#include + +ULONG x[(4 * 1024 * 1024) / 4096]; + +int main() +{ + int i; + PUCHAR BaseAddress; + + BaseAddress = VirtualAlloc(NULL, + 4 * 1024 * 1024, + MEM_COMMIT, + PAGE_READONLY); + if (BaseAddress == NULL) + { + printf("Failed to allocate virtual memory"); + return(1); + } + printf("BaseAddress %p\n", BaseAddress); + for (i = 0; i < ((4 * 1024 * 1024) / 4096); i++) + { + printf("%.6x, ", i*4096); + x[i] = BaseAddress[i*4096]; + } + + return(0); +} diff --git a/reactos/install.sh b/reactos/install.sh index 21c8ebc5a8e..cc4de466e76 100644 --- a/reactos/install.sh +++ b/reactos/install.sh @@ -26,3 +26,4 @@ cp apps/thread/thread.exe $1/reactos/bin cp apps/event/event.exe $1/reactos/bin cp apps/file/file.exe $1/reactos/bin cp apps/pteb/pteb.exe $1/reactos/bin +cp apps/consume/consume.exe $1/reactos/bin diff --git a/reactos/lib/kernel32/misc/dllmain.c b/reactos/lib/kernel32/misc/dllmain.c index f1ae41b6fc1..ee5e9a747bd 100644 --- a/reactos/lib/kernel32/misc/dllmain.c +++ b/reactos/lib/kernel32/misc/dllmain.c @@ -1,4 +1,4 @@ -/* $Id: dllmain.c,v 1.11 2000/03/22 18:35:47 dwelch Exp $ +/* $Id: dllmain.c,v 1.12 2000/07/06 14:34:48 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -40,7 +40,17 @@ WINBOOL STDCALL DllMain(HANDLE hInst, case DLL_PROCESS_ATTACH: { NTSTATUS Status; + DPRINT("DLL_PROCESS_ATTACH\n"); + /* + * Connect to the csrss server + */ + Status = CsrClientConnectToServer(); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Failed to connect to csrss.exe: expect trouble\n"); + // ZwTerminateProcess(NtCurrentProcess(), Status); + } break; } case DLL_PROCESS_DETACH: diff --git a/reactos/lib/ntdll/def/ntdll.def b/reactos/lib/ntdll/def/ntdll.def index 77c39a8174b..c3a5a37e612 100644 --- a/reactos/lib/ntdll/def/ntdll.def +++ b/reactos/lib/ntdll/def/ntdll.def @@ -1,4 +1,4 @@ -; $Id: ntdll.def,v 1.56 2000/07/01 17:06:22 ea Exp $ +; $Id: ntdll.def,v 1.57 2000/07/06 14:34:48 dwelch Exp $ ; ; ReactOS Operating System ; @@ -12,7 +12,7 @@ EXPORTS ;CsrCaptureMessageString ;CsrCaptureTimeout CsrClientCallServer@16 -;CsrClientConnectToServer@24 +CsrClientConnectToServer@0 ;CsrFreeCaptureBuffer ;CsrIdentifyAlertableThread ;CrsNewThread diff --git a/reactos/lib/ntdll/def/ntdll.edf b/reactos/lib/ntdll/def/ntdll.edf index 1060ea0bfc4..e560627a2a2 100644 --- a/reactos/lib/ntdll/def/ntdll.edf +++ b/reactos/lib/ntdll/def/ntdll.edf @@ -1,4 +1,4 @@ -; $Id: ntdll.edf,v 1.45 2000/07/01 17:06:22 ea Exp $ +; $Id: ntdll.edf,v 1.46 2000/07/06 14:34:48 dwelch Exp $ ; ; ReactOS Operating System ; @@ -12,7 +12,7 @@ EXPORTS ;CsrCaptureMessageString ;CsrCaptureTimeout CsrClientCallServer=CsrClientCallServer@16 -;CsrClientConnectToServer=CsrClientConnectToServer@24 +CsrClientConnectToServer=CsrClientConnectToServer@0 ;CsrFreeCaptureBuffer ;CsrIdentifyAlertableThread ;CrsNewThread diff --git a/reactos/lib/ntdll/ldr/startup.c b/reactos/lib/ntdll/ldr/startup.c index 6aef5a72d51..ed55f0184d0 100644 --- a/reactos/lib/ntdll/ldr/startup.c +++ b/reactos/lib/ntdll/ldr/startup.c @@ -1,4 +1,4 @@ -/* $Id: startup.c,v 1.25 2000/05/27 12:48:59 dwelch Exp $ +/* $Id: startup.c,v 1.26 2000/07/06 14:34:49 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -120,16 +120,6 @@ VOID LdrStartup(VOID) DbgPrint("Failed to initialize image\n"); ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); } - - /* - * Connect to the csrss server - */ - Status = CsrClientConnectToServer(); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Failed to connect to csrss.exe: expect trouble\n"); -// ZwTerminateProcess(NtCurrentProcess(), Status); - } DbgPrint("Transferring control to image at %x\n",EntryPoint); Status = EntryPoint(Peb); diff --git a/reactos/ntoskrnl/ex/fmutex.c b/reactos/ntoskrnl/ex/fmutex.c index dbec6579c51..13e44a41b81 100644 --- a/reactos/ntoskrnl/ex/fmutex.c +++ b/reactos/ntoskrnl/ex/fmutex.c @@ -1,4 +1,4 @@ -/* $Id: fmutex.c,v 1.6 2000/06/09 20:02:59 ekohl Exp $ +/* $Id: fmutex.c,v 1.7 2000/07/06 14:34:49 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -18,40 +18,30 @@ /* FUNCTIONS *****************************************************************/ -VOID -FASTCALL -EXPORTED -ExAcquireFastMutexUnsafe ( - PFAST_MUTEX FastMutex - ) +VOID FASTCALL EXPORTED ExAcquireFastMutexUnsafe (PFAST_MUTEX FastMutex) { - if (InterlockedDecrement(&(FastMutex->Count))==0) + if (InterlockedDecrement(&FastMutex->Count) == 0) { return; } FastMutex->Contention++; - KeWaitForSingleObject(&(FastMutex->Event), + KeWaitForSingleObject(&FastMutex->Event, Executive, KernelMode, FALSE, NULL); - FastMutex->Owner=KeGetCurrentThread(); + FastMutex->Owner = KeGetCurrentThread(); } -VOID -FASTCALL -EXPORTED -ExReleaseFastMutexUnsafe ( - PFAST_MUTEX FastMutex - ) +VOID FASTCALL EXPORTED ExReleaseFastMutexUnsafe (PFAST_MUTEX FastMutex) { assert(FastMutex->Owner == KeGetCurrentThread()); - FastMutex->Owner=NULL; - if (InterlockedIncrement(&(FastMutex->Count))<=0) + FastMutex->Owner = NULL; + if (InterlockedIncrement(&FastMutex->Count) <= 0) { return; } - KeSetEvent(&(FastMutex->Event),0,FALSE); + KeSetEvent(&FastMutex->Event, 0, FALSE); } /* EOF */ diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 03b99751bee..4ebb63e1aec 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -85,6 +85,9 @@ BOOLEAN KiTestAlert(struct _KTHREAD* Thread, PCONTEXT UserContext); VOID KeCallApcsThread(VOID); VOID KeRemoveAllWaitsThread(struct _ETHREAD* Thread, NTSTATUS WaitStatus); PULONG KeGetStackTopThread(struct _ETHREAD* Thread); +LONG STDCALL KePulseEvent (PKEVENT Event, + KPRIORITY Increment, + BOOLEAN Wait); /* INITIALIZATION FUNCTIONS *************************************************/ diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 4b7ce9147ad..579084f0f0a 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -162,7 +162,7 @@ VOID MmDeletePageEntry(struct _EPROCESS* Process, PVOID Address, BOOL FreePage); -VOID MmBuildMdlFromPages(PMDL Mdl); +VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages); PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset); VOID MiShutdownMemoryManager(VOID); ULONG MmGetPhysicalAddressForProcess(struct _EPROCESS* Process, @@ -210,10 +210,12 @@ BOOLEAN MmIsPageDirty(struct _EPROCESS* Process, PVOID Address); BOOLEAN MmIsPageTablePresent(PVOID PAddress); ULONG MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, MEMORY_AREA* MemoryArea, - PVOID Address); + PVOID Address, + PBOOLEAN Ul); ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, PMEMORY_AREA MemoryArea, - PVOID Address); + PVOID Address, + PBOOLEAN Ul); MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace, PVOID Address, ULONG Length); @@ -246,4 +248,9 @@ NTSTATUS MmInitPagerThread(VOID); VOID MmInitKernelMap(PVOID BaseAddress); unsigned int alloc_pool_region(unsigned int nr_pages); +VOID MmWaitForFreePages(VOID); +PVOID MmMustAllocPage(SWAPENTRY SavedSwapEntry); +PVOID MmAllocPageMaybeSwap(SWAPENTRY SavedSwapEntry); +NTSTATUS MmCreatePageTable(PVOID PAddress); + #endif diff --git a/reactos/ntoskrnl/ke/event.c b/reactos/ntoskrnl/ke/event.c index 094ece93279..598b9c92576 100644 --- a/reactos/ntoskrnl/ke/event.c +++ b/reactos/ntoskrnl/ke/event.c @@ -22,7 +22,7 @@ VOID STDCALL KeClearEvent (PKEVENT Event) { DPRINT("KeClearEvent(Event %x)\n", Event); - Event->Header.SignalState=FALSE; + Event->Header.SignalState = FALSE; } VOID STDCALL KeInitializeEvent (PKEVENT Event, diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 5f24b3cd356..3962f7e0cfd 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -30,103 +30,30 @@ 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 ULONG init_stack; extern ULONG init_stack_top; /* FUNCTIONS ****************************************************************/ -#define EXCEPTION_HANDLER_WITH_ERROR(y) \ - void exception_handler##y (void); \ - void tmp_exception_handler##y (void) { \ - __asm__("\n\t_exception_handler"STR(y)":\n\t" \ - "pushl %gs\n\t" \ - "pushl %fs\n\t" \ - "pushl %es\n\t" \ - "pushl %ds\n\t" \ - "pushl $"STR(y)"\n\t" \ - "pusha\n\t" \ - "movw $"STR(KERNEL_DS)",%ax\n\t" \ - "movw %ax,%ds\n\t" \ - "movw %ax,%es\n\t" \ - "movw %ax,%fs\n\t" \ - "movw %ax,%gs\n\t" \ - "call _exception_handler\n\t" \ - "popa\n\t" \ - "addl $4,%esp\n\t" \ - "popl %ds\n\t" \ - "popl %es\n\t" \ - "popl %fs\n\t" \ - "popl %gs\n\t" \ - "addl $4,%esp\n\t" \ - "iret\n\t"); } - -#define EXCEPTION_HANDLER_WITHOUT_ERROR(y) \ - void exception_handler##y (void); \ - void tmp_exception_handler##y (void) { \ - __asm__("\n\t_exception_handler"STR(y)":\n\t" \ - "pushl $0\n\t" \ - "pushl %gs\n\t" \ - "pushl %fs\n\t" \ - "pushl %es\n\t" \ - "pushl %ds\n\t" \ - "pushl $"STR(y)"\n\t" \ - "pusha\n\t" \ - "movw $"STR(KERNEL_DS)",%ax\n\t" \ - "movw %ax,%ds\n\t" \ - "movw %ax,%es\n\t" \ - "movw %ax,%fs\n\t" \ - "movw %ax,%gs\n\t" \ - "call _exception_handler\n\t" \ - "popa\n\t" \ - "addl $4,%esp\n\t" \ - "popl %ds\n\t" \ - "popl %es\n\t" \ - "popl %fs\n\t" \ - "popl %gs\n\t" \ - "addl $4,%esp\n\t" \ - "iret\n\t"); } - -void exception_handler_unknown(void); -void tmp_exception_handler_unknown(void) -{ - __asm__("\n\t_exception_handler_unknown:\n\t" - "pushl $0\n\t" - "pushl %gs\n\t" - "pushl %fs\n\t" - "pushl %es\n\t" - "pushl %ds\n\t" - "pushl %ds\n\t" - "pushl $0xff\n\t" - "pusha\n\t" - "movw $"STR(KERNEL_DS)",%ax\n\t" - "movw %ax,%ds\n\t" - "movw %ax,%es\n\t" - "movw %ax,%fs\n\t" - "movw %ax,%gs\n\t" - "call _exception_handler\n\t" - "popa\n\t" - "addl $8,%esp\n\t" - "iret\n\t"); -} - -EXCEPTION_HANDLER_WITHOUT_ERROR(0); -EXCEPTION_HANDLER_WITHOUT_ERROR(1); -EXCEPTION_HANDLER_WITHOUT_ERROR(2); -EXCEPTION_HANDLER_WITHOUT_ERROR(3); -EXCEPTION_HANDLER_WITHOUT_ERROR(4); -EXCEPTION_HANDLER_WITHOUT_ERROR(5); -EXCEPTION_HANDLER_WITHOUT_ERROR(6); -EXCEPTION_HANDLER_WITHOUT_ERROR(7); -EXCEPTION_HANDLER_WITH_ERROR(8); -EXCEPTION_HANDLER_WITHOUT_ERROR(9); -EXCEPTION_HANDLER_WITH_ERROR(10); -EXCEPTION_HANDLER_WITH_ERROR(11); -EXCEPTION_HANDLER_WITH_ERROR(12); -EXCEPTION_HANDLER_WITH_ERROR(13); -EXCEPTION_HANDLER_WITH_ERROR(14); -EXCEPTION_HANDLER_WITH_ERROR(15); -EXCEPTION_HANDLER_WITHOUT_ERROR(16); - extern unsigned int stext, etext; static void print_address(PVOID address) diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index efc3739307b..bb303eee008 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -1,4 +1,4 @@ -/* $Id: trap.s,v 1.1 2000/07/04 08:52:41 dwelch Exp $ +/* $Id: trap.s,v 1.2 2000/07/06 14:34:50 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -12,6 +12,10 @@ #include #include +/* + * + */ + .globl _PsBeginThreadWithContextInternal _PsBeginThreadWithContextInternal: @@ -37,6 +41,10 @@ _PsBeginThreadWithContextInternal: popl %ebp iret +/* + * + */ + .globl _interrupt_handler2e _interrupt_handler2e: @@ -195,4 +203,430 @@ done: iret +/* + * + */ + +.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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + 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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.globl _exception_handler9 +_exception_handler9: + 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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.globl _exception_handler11 +_exception_handler11: + 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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.globl _exception_handler12 +_exception_handler12: + 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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.globl _exception_handler13 +_exception_handler13: + 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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.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 + call _exception_handler + popa + addl $4,%esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4,%esp + iret + +.globl _exception_handler_unknown +_exception_handler_unknown: + pushl $0 + pushl %gs + pushl %fs + pushl %es + pushl %ds + pushl %ds + pushl $0xff + pusha + movw $KERNEL_DS,%ax + movw %ax,%ds + movw %ax,%es + movw %ax,%fs + movw %ax,%gs + call _exception_handler + popa + addl $8,%esp + iret + + /* EOF */ diff --git a/reactos/ntoskrnl/ke/mutex.c b/reactos/ntoskrnl/ke/mutex.c index c62c0c9c04e..ff7aea79e91 100644 --- a/reactos/ntoskrnl/ke/mutex.c +++ b/reactos/ntoskrnl/ke/mutex.c @@ -1,4 +1,4 @@ -/* $Id: mutex.c,v 1.6 2000/06/29 23:35:38 dwelch Exp $ +/* $Id: mutex.c,v 1.7 2000/07/06 14:34:50 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -19,39 +19,27 @@ /* FUNCTIONS *****************************************************************/ -VOID -STDCALL -KeInitializeMutex ( - PKMUTEX Mutex, - ULONG Level - ) +VOID STDCALL KeInitializeMutex (PKMUTEX Mutex, + ULONG Level) { KeInitializeDispatcherHeader(&Mutex->Header, InternalMutexType, sizeof(KMUTEX) / sizeof(ULONG), - TRUE); + 1); } -LONG -STDCALL -KeReadStateMutex ( - PKMUTEX Mutex - ) +LONG STDCALL KeReadStateMutex (PKMUTEX Mutex) { return(Mutex->Header.SignalState); } -LONG -STDCALL -KeReleaseMutex ( - PKMUTEX Mutex, - BOOLEAN Wait - ) +LONG STDCALL KeReleaseMutex (PKMUTEX Mutex, + BOOLEAN Wait) { KeAcquireDispatcherDatabaseLock(Wait); - Mutex->Header.SignalState--; - assert(Mutex->Header.SignalState >= 0); - if (Mutex->Header.SignalState == 0) + Mutex->Header.SignalState++; + assert(Mutex->Header.SignalState <= 1); + if (Mutex->Header.SignalState == 1) { KeDispatcherObjectWake(&Mutex->Header); } @@ -59,15 +47,11 @@ KeReleaseMutex ( return(0); } -NTSTATUS -STDCALL -KeWaitForMutexObject ( - PKMUTEX Mutex, - KWAIT_REASON WaitReason, - KPROCESSOR_MODE WaitMode, - BOOLEAN Alertable, - PLARGE_INTEGER Timeout - ) +NTSTATUS STDCALL KeWaitForMutexObject (PKMUTEX Mutex, + KWAIT_REASON WaitReason, + KPROCESSOR_MODE WaitMode, + BOOLEAN Alertable, + PLARGE_INTEGER Timeout) { return(KeWaitForSingleObject(Mutex,WaitReason,WaitMode,Alertable,Timeout)); } diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 0139b2d827c..aad3393f3d6 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -83,7 +83,7 @@ VOID KiSideEffectsBeforeWake(DISPATCHER_HEADER* hdr, switch (hdr->Type) { case InternalSynchronizationEvent: - hdr->SignalState = FALSE; + hdr->SignalState = 0; break; case InternalSemaphoreType: @@ -113,7 +113,7 @@ VOID KiSideEffectsBeforeWake(DISPATCHER_HEADER* hdr, Mutex = CONTAINING_RECORD(hdr, KMUTEX, Header); - hdr->SignalState++; + hdr->SignalState--; Mutex->OwnerThread = Thread; } break; @@ -137,9 +137,9 @@ static BOOLEAN KiIsObjectSignalled(DISPATCHER_HEADER* hdr, KMUTEX, Header); - if ((hdr->SignalState <= 0 && - Mutex->OwnerThread == Thread) || - hdr->SignalState > 0) + assert(hdr->SignalState <= 1); + if ((hdr->SignalState < 1 && Mutex->OwnerThread == Thread) || + hdr->SignalState == 1) { KiSideEffectsBeforeWake(hdr, Thread); @@ -365,15 +365,11 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) } -NTSTATUS -STDCALL -KeWaitForSingleObject ( - PVOID Object, - KWAIT_REASON WaitReason, - KPROCESSOR_MODE WaitMode, - BOOLEAN Alertable, - PLARGE_INTEGER Timeout - ) +NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object, + KWAIT_REASON WaitReason, + KPROCESSOR_MODE WaitMode, + BOOLEAN Alertable, + PLARGE_INTEGER Timeout) /* * FUNCTION: Puts the current thread into a wait state until the * given dispatcher object is set to signalled diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index 8d6b893232e..dce327e5d3d 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -236,6 +236,11 @@ VOID MmReferencePage(PVOID PhysicalAddress) DPRINT("MmReferencePage(PhysicalAddress %x)\n", PhysicalAddress); + if (((ULONG)PhysicalAddress) == 0) + { + KeBugCheck(0); + } + KeAcquireSpinLock(&PageListLock, &oldIrql); MmPageArray[Start].ReferenceCount++; KeReleaseSpinLock(&PageListLock, oldIrql); @@ -247,6 +252,11 @@ VOID MmDereferencePage(PVOID PhysicalAddress) KIRQL oldIrql; DPRINT("MmDereferencePage(PhysicalAddress %x)\n", PhysicalAddress); + + if (((ULONG)PhysicalAddress) == 0) + { + KeBugCheck(0); + } if (((ULONG)PhysicalAddress) > 0x400000) { @@ -283,8 +293,8 @@ PVOID MmAllocPage(SWAPENTRY SavedSwapEntry) DPRINT("ListEntry %x\n",ListEntry); if (ListEntry == NULL) { - DbgPrint("MmAllocPage(): Out of memory\n"); - KeBugCheck(0); + DPRINT("MmAllocPage(): Out of memory\n"); + return(NULL); } PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry); DPRINT("PageDescriptor %x\n",PageDescriptor); @@ -313,6 +323,33 @@ PVOID MmAllocPage(SWAPENTRY SavedSwapEntry) return((PVOID)offset); } +PVOID MmMustAllocPage(SWAPENTRY SavedSwapEntry) +{ + PVOID Page; + + Page = MmAllocPage(SavedSwapEntry); + if (Page == NULL) + { + KeBugCheck(0); + return(NULL); + } + + return(Page); +} + +PVOID MmAllocPageMaybeSwap(SWAPENTRY SavedSwapEntry) +{ + PVOID Page; + + Page = MmAllocPage(SavedSwapEntry); + while (Page == NULL) + { + MmWaitForFreePages(); + Page = MmAllocPage(SavedSwapEntry); + }; + return(Page); +} + NTSTATUS MmWaitForPage(PVOID PhysicalAddress) { NTSTATUS Status; diff --git a/reactos/ntoskrnl/mm/i386/page.c b/reactos/ntoskrnl/mm/i386/page.c index 85cc13d130d..8dc3769d0d5 100644 --- a/reactos/ntoskrnl/mm/i386/page.c +++ b/reactos/ntoskrnl/mm/i386/page.c @@ -1,4 +1,4 @@ -/* $Id: page.c,v 1.10 2000/07/04 08:52:46 dwelch Exp $ +/* $Id: page.c,v 1.11 2000/07/06 14:34:51 dwelch Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -140,6 +140,46 @@ ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address) return(Entry); } +ULONG MmGetPageEntry1(PVOID PAddress) +/* + * FUNCTION: Get a pointer to the page table entry for a virtual address + */ +{ + PULONG page_tlb; + PULONG page_dir; + ULONG Address = (ULONG)PAddress; + + DPRINT("MmGetPageEntry(Address %x)\n", Address); + + page_dir = ADDR_TO_PDE(Address); + DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir); + if ((*page_dir) == 0) + { + return(0); + } + page_tlb = ADDR_TO_PTE(Address); + DPRINT("page_tlb %x\n",page_tlb); + return(*page_tlb); +} + +ULONG MmGetPageEntryForProcess1(PEPROCESS Process, PVOID Address) +{ + ULONG Entry; + PEPROCESS CurrentProcess = PsGetCurrentProcess(); + + if (Process != NULL && Process != CurrentProcess) + { + KeAttachProcess(Process); + } + Entry = MmGetPageEntry1(Address); + if (Process != NULL && Process != CurrentProcess) + { + KeDetachProcess(); + } + return(Entry); +} + + ULONG MmGetPhysicalAddressForProcess(PEPROCESS Process, PVOID Address) { @@ -202,6 +242,30 @@ BOOLEAN MmIsPageTablePresent(PVOID PAddress) return((*page_dir) == 0); } +NTSTATUS MmCreatePageTable(PVOID PAddress) +{ + PULONG page_dir; + ULONG Address = (ULONG)PAddress; + ULONG npage; + + DPRINT("MmGetPageEntry(Address %x)\n", Address); + + page_dir = ADDR_TO_PDE(Address); + DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir); + if ((*page_dir) == 0) + { + npage = (ULONG)MmAllocPage(0); + if (npage == 0) + { + return(STATUS_UNSUCCESSFUL); + } + (*page_dir) = npage | 0x7; + memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE); + FLUSH_TLB; + } + return(STATUS_SUCCESS); +} + PULONG MmGetPageEntry(PVOID PAddress) /* * FUNCTION: Get a pointer to the page table entry for a virtual address @@ -210,6 +274,7 @@ PULONG MmGetPageEntry(PVOID PAddress) PULONG page_tlb; PULONG page_dir; ULONG Address = (ULONG)PAddress; + ULONG npage; DPRINT("MmGetPageEntry(Address %x)\n", Address); @@ -217,7 +282,12 @@ PULONG MmGetPageEntry(PVOID PAddress) DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir); if ((*page_dir) == 0) { - (*page_dir) = ((ULONG)MmAllocPage(0)) | 0x7; + npage = (ULONG)MmAllocPage(0); + if (npage == 0) + { + KeBugCheck(0); + } + (*page_dir) = npage | 0x7; memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE); FLUSH_TLB; } @@ -233,7 +303,7 @@ BOOLEAN MmIsPageDirty(PEPROCESS Process, PVOID Address) BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address) { - return((MmGetPageEntryForProcess(Process, Address)) & PA_PRESENT); + return((MmGetPageEntryForProcess1(Process, Address)) & PA_PRESENT); } diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index 667cd84c67a..79cb17f636c 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -294,7 +294,10 @@ NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace, { PhysicalAddr = MmGetPhysicalAddress(MemoryArea->BaseAddress + (i*PAGESIZE)); - MmDereferencePage((PVOID)(ULONG)(PhysicalAddr.u.LowPart)); + if (PhysicalAddr.u.LowPart != 0) + { + MmDereferencePage((PVOID)(ULONG)(PhysicalAddr.u.LowPart)); + } } } for (i=0; i<=(MemoryArea->Length/PAGESIZE); i++) diff --git a/reactos/ntoskrnl/mm/mdl.c b/reactos/ntoskrnl/mm/mdl.c index 7469dc015d1..992a4cf2d0e 100644 --- a/reactos/ntoskrnl/mm/mdl.c +++ b/reactos/ntoskrnl/mm/mdl.c @@ -1,4 +1,4 @@ -/* $Id: mdl.c,v 1.21 2000/07/04 08:52:42 dwelch Exp $ +/* $Id: mdl.c,v 1.22 2000/07/06 14:34:51 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -109,7 +109,7 @@ VOID STDCALL MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl) } -VOID MmBuildMdlFromPages(PMDL Mdl) +VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages) { ULONG i; PULONG mdl_pages; @@ -118,19 +118,15 @@ VOID MmBuildMdlFromPages(PMDL Mdl) for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGESIZE);i++) { - mdl_pages[i] = (ULONG)MmAllocPage(0); + mdl_pages[i] = Pages[i]; DPRINT("mdl_pages[i] %x\n",mdl_pages[i]); } } -VOID -STDCALL -MmProbeAndLockPages ( - PMDL Mdl, - KPROCESSOR_MODE AccessMode, - LOCK_OPERATION Operation - ) +VOID STDCALL MmProbeAndLockPages (PMDL Mdl, + KPROCESSOR_MODE AccessMode, + LOCK_OPERATION Operation) /* * FUNCTION: Probes the specified pages, makes them resident and locks them * ARGUMENTS: diff --git a/reactos/ntoskrnl/mm/pager.c b/reactos/ntoskrnl/mm/pager.c index 1a35d95db9a..12b5145deaa 100644 --- a/reactos/ntoskrnl/mm/pager.c +++ b/reactos/ntoskrnl/mm/pager.c @@ -1,4 +1,4 @@ -/* $Id: pager.c,v 1.2 2000/07/04 08:52:45 dwelch Exp $ +/* $Id: pager.c,v 1.3 2000/07/06 14:34:51 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -29,17 +30,42 @@ static KEVENT PagerThreadEvent; static PEPROCESS LastProcess; static volatile BOOLEAN PagerThreadShouldTerminate; static volatile ULONG PageCount; +static volatile ULONG WaiterCount; +static KEVENT FreedMemEvent; /* FUNCTIONS *****************************************************************/ -VOID MmTryPageOutFromProcess(PEPROCESS Process) +VOID MmWaitForFreePages(VOID) { + InterlockedIncrement((PULONG)&PageCount); + KeClearEvent(&FreedMemEvent); + KeSetEvent(&PagerThreadEvent, + IO_NO_INCREMENT, + FALSE); + InterlockedIncrement((PULONG)&WaiterCount); + KeWaitForSingleObject(&FreedMemEvent, + 0, + KernelMode, + FALSE, + NULL); + InterlockedDecrement((PULONG)&WaiterCount); +} + +static VOID MmTryPageOutFromProcess(PEPROCESS Process) +{ + ULONG P; + MmLockAddressSpace(&Process->AddressSpace); - PageCount = PageCount - MmTrimWorkingSet(Process, PageCount); + P = MmTrimWorkingSet(Process, PageCount); + if (P > 0) + { + InterlockedExchangeAdd((PULONG)&PageCount, -P); + KeSetEvent(&FreedMemEvent, IO_NO_INCREMENT, FALSE); + } MmUnlockAddressSpace(&Process->AddressSpace); } -NTSTATUS MmPagerThreadMain(PVOID Ignored) +static NTSTATUS MmPagerThreadMain(PVOID Ignored) { NTSTATUS Status; @@ -54,22 +80,26 @@ NTSTATUS MmPagerThreadMain(PVOID Ignored) { DbgPrint("PagerThread: Wait failed\n"); KeBugCheck(0); - } + } if (PagerThreadShouldTerminate) { DbgPrint("PagerThread: Terminating\n"); return(STATUS_SUCCESS); } - while (PageCount > 0) + while (WaiterCount > 0) { - KeAttachProcess(LastProcess); - MmTryPageOutFromProcess(LastProcess); - KeDetachProcess(); - if (PageCount != 0) + while (PageCount > 0) { - LastProcess = PsGetNextProcess(LastProcess); + KeAttachProcess(LastProcess); + MmTryPageOutFromProcess(LastProcess); + KeDetachProcess(); + if (PageCount != 0) + { + LastProcess = PsGetNextProcess(LastProcess); + } } + KeSetEvent(&FreedMemEvent, IO_NO_INCREMENT, FALSE); } } } @@ -79,11 +109,15 @@ NTSTATUS MmInitPagerThread(VOID) NTSTATUS Status; PageCount = 0; + WaiterCount = 0; LastProcess = PsInitialSystemProcess; PagerThreadShouldTerminate = FALSE; KeInitializeEvent(&PagerThreadEvent, SynchronizationEvent, FALSE); + KeInitializeEvent(&FreedMemEvent, + NotificationEvent, + FALSE); Status = PsCreateSystemThread(&PagerThreadHandle, THREAD_ALL_ACCESS, diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index bff9616910e..b48fe43c475 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -1,4 +1,4 @@ -/* $Id: section.c,v 1.35 2000/07/04 08:52:45 dwelch Exp $ +/* $Id: section.c,v 1.36 2000/07/06 14:34:51 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -122,9 +122,9 @@ NTSTATUS MmUnalignedLoadPageForSection(PMADDRESS_SPACE AddressSpace, MmLockSection(Section); + Page = MmAllocPageMaybeSwap(0); Mdl = MmCreateMdl(NULL, NULL, PAGESIZE); - MmBuildMdlFromPages(Mdl); - Page = MmGetMdlPageAddress(Mdl, 0); + MmBuildMdlFromPages(Mdl, (PULONG)&Page); MmUnlockSection(Section); MmUnlockAddressSpace(AddressSpace); DPRINT("Reading file offset %x\n", Offset.QuadPart); @@ -200,9 +200,11 @@ NTSTATUS MmOldNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, if (Entry == 0) { + Page = MmAllocPageMaybeSwap(0); + + Mdl = MmCreateMdl(NULL, NULL, PAGESIZE); - MmBuildMdlFromPages(Mdl); - Page = MmGetMdlPageAddress(Mdl, 0); + MmBuildMdlFromPages(Mdl, (PULONG)&Page); MmUnlockSection(Section); MmUnlockAddressSpace(AddressSpace); DPRINT("Reading file offset %x\n", Offset.QuadPart); @@ -248,6 +250,103 @@ NTSTATUS MmOldNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, return(STATUS_SUCCESS); } +NTSTATUS MmWaitForPendingOperationSection(PMADDRESS_SPACE AddressSpace, + PMEMORY_AREA MemoryArea, + PVOID Address, + PSECTION_OBJECT Section, + LARGE_INTEGER Offset, + ULONG Entry) +{ + PVOID Page; + NTSTATUS Status; + + /* + * If a page-in on that section offset is pending that wait for + * it to finish. + */ + + do + { + /* + * Release all our locks and wait for the pending operation + * to complete + */ + MmUnlockSection(Section); + MmUnlockAddressSpace(AddressSpace); + /* + * FIXME: What if the event is set and cleared after we + * unlock the section but before we wait. + */ + Status = MmWaitForPage((PVOID)(Entry & (~SPE_PAGEIN_PENDING))); + if (!NT_SUCCESS(Status)) + { + /* + * FIXME: What do we do in this case? Maybe the thread + * has terminated. + */ + + DbgPrint("Failed to wait for page\n"); + KeBugCheck(0); + return(STATUS_UNSUCCESSFUL); + } + + /* + * Relock the address space and section + */ + MmLockAddressSpace(AddressSpace); + MmLockSection(Section); + + /* + * Get the entry for the section offset. If the entry is still + * pending that means another thread is already trying the + * page-in again so we have to wait again. + */ + Entry = MmGetPageEntrySection(Section, + Offset.u.LowPart); + } while (Entry & SPE_PAGEIN_PENDING); + + /* + * Setting the entry to null means the read failing. + * FIXME: We should retry it (unless that filesystem has gone + * entirely e.g. the network died). + */ + if (Entry == 0) + { + DbgPrint("Entry set to null while we slept\n"); + KeBugCheck(0); + } + + /* + * Maybe the thread did the page-in took the fault on the + * same address-space/address as we did. If so we can just + * return success. + */ + if (MmIsPagePresent(NULL, Address)) + { + MmUnlockSection(Section); + return(STATUS_SUCCESS); + } + + /* + * Get a reference to the page containing the data for the page. + */ + Page = (PVOID)Entry; + MmReferencePage(Page); + + /* + * When we reach here, we have the address space and section locked + * and have a reference to a page containing valid data for the + * section offset. Set the page and return success. + */ + MmSetPage(NULL, + Address, + MemoryArea->Attributes, + (ULONG)Page); + MmUnlockSection(Section); + + return(STATUS_SUCCESS); +} + NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MEMORY_AREA* MemoryArea, PVOID Address) @@ -317,12 +416,48 @@ NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, * locked the section) then we need to load the page. */ + /* + * + */ + Page = MmAllocPage(0); + while (Page == NULL) + { + MmUnlockSection(Section); + MmUnlockAddressSpace(AddressSpace); + MmWaitForFreePages(); + MmLockAddressSpace(AddressSpace); + MmLockSection(Section); + Entry1 = MmGetPageEntrySection(Section, Offset.u.LowPart); + if (Entry1 & SPE_PAGEIN_PENDING) + { + return(MmWaitForPendingOperationSection(AddressSpace, + MemoryArea, + Address, + Section, + Offset, + Entry1)); + } + else if (Entry1 != 0) + { + Page = (PVOID)Entry; + MmReferencePage(Page); + + MmSetPage(NULL, + Address, + MemoryArea->Attributes, + (ULONG)Page); + MmUnlockSection(Section); + + return(STATUS_SUCCESS); + } + Page = MmAllocPage(0); + } + /* * Create an mdl to hold the page we are going to read data into. */ Mdl = MmCreateMdl(NULL, NULL, PAGESIZE); - MmBuildMdlFromPages(Mdl); - Page = MmGetMdlPageAddress(Mdl, 0); + MmBuildMdlFromPages(Mdl, (PULONG)&Page); /* * Clear the wait state (Since we are holding the only reference to @@ -390,80 +525,24 @@ NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, * may be waiting know that valid data is now in-memory. */ MmSetWaitPage(Page); + + MmSetPage(NULL, + Address, + MemoryArea->Attributes, + (ULONG)Page); + MmUnlockSection(Section); + + return(STATUS_SUCCESS); + } else if (Entry & SPE_PAGEIN_PENDING) { - /* - * If a page-in on that section offset is pending that wait for - * it to finish. - */ - - do - { - /* - * Release all our locks and wait for the pending operation - * to complete - */ - MmUnlockSection(Section); - MmUnlockAddressSpace(AddressSpace); - /* - * FIXME: What if the event is set and cleared after we - * unlock the section but before we wait. - */ - Status = MmWaitForPage((PVOID)(Entry & (~SPE_PAGEIN_PENDING))); - if (!NT_SUCCESS(Status)) - { - /* - * FIXME: What do we do in this case? Maybe the thread - * has terminated. - */ - - DbgPrint("Failed to wait for page\n"); - KeBugCheck(0); - } - - /* - * Relock the address space and section - */ - MmLockAddressSpace(AddressSpace); - MmLockSection(Section); - - /* - * Get the entry for the section offset. If the entry is still - * pending that means another thread is already trying the - * page-in again so we have to wait again. - */ - Entry = MmGetPageEntrySection(Section, - Offset.u.LowPart); - } while (Entry & SPE_PAGEIN_PENDING); - - /* - * Setting the entry to null means the read failing. - * FIXME: We should retry it (unless that filesystem has gone - * entirely e.g. the network died). - */ - if (Entry == 0) - { - DbgPrint("Entry set to null while we slept\n"); - KeBugCheck(0); - } - - /* - * Maybe the thread did the page-in took the fault on the - * same address-space/address as we did. If so we can just - * return success. - */ - if (MmIsPagePresent(NULL, Address)) - { - MmUnlockSection(Section); - return(STATUS_SUCCESS); - } - - /* - * Get a reference to the page containing the data for the page. - */ - Page = (PVOID)Entry; - MmReferencePage(Page); + return(MmWaitForPendingOperationSection(AddressSpace, + MemoryArea, + Address, + Section, + Offset, + Entry)); } else { @@ -474,27 +553,23 @@ NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, Page = (PVOID)Entry; MmReferencePage(Page); + + MmSetPage(NULL, + Address, + MemoryArea->Attributes, + (ULONG)Page); + MmUnlockSection(Section); + + return(STATUS_SUCCESS); } - - /* - * When we reach here, we have the address space and section locked - * and have a reference to a page containing valid data for the - * section offset. Set the page and return success. - */ - - MmSetPage(NULL, - Address, - MemoryArea->Attributes, - (ULONG)Page); - MmUnlockSection(Section); - - return(STATUS_SUCCESS); } ULONG MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, MEMORY_AREA* MemoryArea, - PVOID Address) + PVOID Address, + PBOOLEAN Ul) { + (*Ul) = FALSE; return(0); } diff --git a/reactos/ntoskrnl/mm/virtual.c b/reactos/ntoskrnl/mm/virtual.c index 085e0b01e8c..8f4cf736967 100644 --- a/reactos/ntoskrnl/mm/virtual.c +++ b/reactos/ntoskrnl/mm/virtual.c @@ -1,4 +1,4 @@ -/* $Id: virtual.c,v 1.30 2000/07/04 08:52:45 dwelch Exp $ +/* $Id: virtual.c,v 1.31 2000/07/06 14:34:51 dwelch Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -29,7 +29,8 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, PMEMORY_AREA MemoryArea, - PVOID Address) + PVOID Address, + PBOOLEAN Ul) { PHYSICAL_ADDRESS PhysicalAddress; @@ -39,30 +40,71 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, { PhysicalAddress = MmGetPhysicalAddress(Address); - MmDereferencePage((PVOID)PhysicalAddress.u.LowPart); + MmRemovePageFromWorkingSet(AddressSpace->Process, + Address); MmSetPage(PsGetCurrentProcess(), Address, 0, 0); + MmDereferencePage((PVOID)PhysicalAddress.u.LowPart); + *Ul = TRUE; return(1); } + *Ul = FALSE; return(0); } NTSTATUS MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, MEMORY_AREA* MemoryArea, PVOID Address) +/* + * FUNCTION: Move data into memory to satisfy a page not present fault + * ARGUMENTS: + * AddressSpace = Address space within which the fault occurred + * MemoryArea = The memory area within which the fault occurred + * Address = The absolute address of fault + * RETURNS: Status + * NOTES: This function is called with the address space lock held. + */ { + PVOID Page; + NTSTATUS Status; + if (MmIsPagePresent(NULL, Address)) - { - + { return(STATUS_SUCCESS); } + Page = MmAllocPage(0); + while (Page == NULL) + { + MmUnlockAddressSpace(AddressSpace); + MmWaitForFreePages(); + MmLockAddressSpace(AddressSpace); + if (MmIsPagePresent(NULL, Address)) + { + return(STATUS_SUCCESS); + } + Page = MmAllocPage(0); + } + Status = MmCreatePageTable(Address); + while (!NT_SUCCESS(Status)) + { + MmUnlockAddressSpace(AddressSpace); + MmWaitForFreePages(); + MmLockAddressSpace(AddressSpace); + if (MmIsPagePresent(NULL, Address)) + { + MmDereferencePage(Page); + return(STATUS_SUCCESS); + } + Status = MmCreatePageTable(Address); + } + MmAddPageToWorkingSet(PsGetCurrentProcess(), Address); MmSetPage(PsGetCurrentProcess(), Address, MemoryArea->Attributes, - (ULONG)MmAllocPage(0)); + (ULONG)Page); return(STATUS_SUCCESS); } @@ -239,6 +281,7 @@ NTSTATUS STDCALL NtFreeVirtualMemory(IN HANDLE ProcessHandle, NTSTATUS Status; PEPROCESS Process; PMADDRESS_SPACE AddressSpace; + ULONG i; DPRINT("NtFreeVirtualMemory(ProcessHandle %x, *BaseAddress %x, " "*RegionSize %x, FreeType %x)\n",ProcessHandle,*BaseAddress, @@ -283,10 +326,26 @@ NTSTATUS STDCALL NtFreeVirtualMemory(IN HANDLE ProcessHandle, { MmDereserveSwapPages(PAGE_ROUND_UP(MemoryArea->Length)); } + + for (i=0; i<=(MemoryArea->Length/PAGESIZE); i++) + { + LARGE_INTEGER PhysicalAddr; + + PhysicalAddr = MmGetPhysicalAddress(MemoryArea->BaseAddress + + (i*PAGESIZE)); + if (PhysicalAddr.u.LowPart != 0) + { + MmRemovePageFromWorkingSet(AddressSpace->Process, + MemoryArea->BaseAddress + + (i*PAGESIZE)); + MmDereferencePage((PVOID)(ULONG)(PhysicalAddr.u.LowPart)); + } + } + MmFreeMemoryArea(&Process->AddressSpace, BaseAddress, 0, - TRUE); + FALSE); MmUnlockAddressSpace(AddressSpace); ObDereferenceObject(Process); return(STATUS_SUCCESS); diff --git a/reactos/ntoskrnl/mm/wset.c b/reactos/ntoskrnl/mm/wset.c index 0dbc3635952..d8541f98231 100644 --- a/reactos/ntoskrnl/mm/wset.c +++ b/reactos/ntoskrnl/mm/wset.c @@ -1,4 +1,4 @@ -/* $Id: wset.c,v 1.1 2000/07/04 08:52:45 dwelch Exp $ +/* $Id: wset.c,v 1.2 2000/07/06 14:34:51 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -42,15 +42,49 @@ VOID MmInitializeWorkingSet(PEPROCESS Process, AddressSpace->WorkingSetPagesAllocated = 1; KeInitializeMutex(&Process->WorkingSetLock, 1); Process->WorkingSetPage = ExAllocatePage(); + memset(Process->WorkingSetPage, 0, 4096); +} + +ULONG MmPageOutPage(PMADDRESS_SPACE AddressSpace, + PMEMORY_AREA MArea, + PVOID Address, + PBOOLEAN Ul) +{ + ULONG Count; + + switch(MArea->Type) + { + case MEMORY_AREA_SYSTEM: + *Ul = FALSE; + return(0); + + case MEMORY_AREA_SECTION_VIEW_COMMIT: + Count = MmPageOutSectionView(AddressSpace, + MArea, + Address, + Ul); + return(Count); + + case MEMORY_AREA_COMMIT: + Count = MmPageOutVirtualMemory(AddressSpace, + MArea, + Address, + Ul); + return(Count); + + } + *Ul = FALSE; + return(0); } ULONG MmTrimWorkingSet(PEPROCESS Process, ULONG ReduceHint) { - ULONG i; + ULONG i, j; PMADDRESS_SPACE AddressSpace; PMWORKING_SET WSet; ULONG Count; + BOOLEAN Ul; MmLockWorkingSet(Process); @@ -58,41 +92,37 @@ ULONG MmTrimWorkingSet(PEPROCESS Process, AddressSpace = &Process->AddressSpace; Count = 0; + j = AddressSpace->WorkingSetLruFirst; - for (i = 0; i < AddressSpace->WorkingSetSize; i++) + for (i = 0; i < AddressSpace->WorkingSetSize; ) { PVOID Address; PMEMORY_AREA MArea; - Address = WSet->Address[AddressSpace->WorkingSetLruFirst]; - + Address = WSet->Address[j]; + MArea = MmOpenMemoryAreaByAddress(AddressSpace, Address); - switch(MArea->Type) + if (MArea == NULL) { - case MEMORY_AREA_SYSTEM: - break; - - case MEMORY_AREA_SECTION_VIEW_COMMIT: - Count = Count + MmPageOutSectionView(AddressSpace, - MArea, - Address); - break; - - case MEMORY_AREA_COMMIT: - Count = Count + MmPageOutVirtualMemory(AddressSpace, - MArea, - Address); - break; - - default: - break; + KeBugCheck(0); } - - AddressSpace->WorkingSetLruFirst = - ((AddressSpace->WorkingSetLruFirst) + 1) % 1020; + Count = Count + MmPageOutPage(AddressSpace, MArea, Address, &Ul); + if (Ul) + { + MmLockWorkingSet(Process); + + j = AddressSpace->WorkingSetLruFirst; + i = 0; + } + else + { + j = (j + 1) % 1020; + i++; + } + if (Count == ReduceHint) { MmUnlockWorkingSet(Process); @@ -119,7 +149,8 @@ VOID MmRemovePageFromWorkingSet(PEPROCESS Process, { if (WSet->Address[j] == Address) { - WSet->Address[j] = WSet->Address[AddressSpace->WorkingSetLruLast]; + WSet->Address[j] = + WSet->Address[AddressSpace->WorkingSetLruLast - 1]; if (AddressSpace->WorkingSetLruLast != 0) { AddressSpace->WorkingSetLruLast = diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index b8737886b3d..ff5e044c130 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.49 2000/07/04 11:11:04 dwelch Exp $ +/* $Id: process.c,v 1.50 2000/07/06 14:34:52 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -55,9 +55,18 @@ PEPROCESS PsGetNextProcess(PEPROCESS OldProcess) } KeAcquireSpinLock(&PsProcessListLock, &oldIrql); - NextProcess = CONTAINING_RECORD(OldProcess->ProcessListEntry.Flink, - EPROCESS, - ProcessListEntry); + if (OldProcess->ProcessListEntry.Flink == &PsProcessListHead) + { + NextProcess = CONTAINING_RECORD(PsProcessListHead.Flink, + EPROCESS, + ProcessListEntry); + } + else + { + NextProcess = CONTAINING_RECORD(OldProcess->ProcessListEntry.Flink, + EPROCESS, + ProcessListEntry); + } KeReleaseSpinLock(&PsProcessListLock, oldIrql); Status = ObReferenceObjectByPointer(NextProcess, PROCESS_ALL_ACCESS, diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 4683a266559..d20cd2db8ec 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.51 2000/07/04 11:11:04 dwelch Exp $ +/* $Id: thread.c,v 1.52 2000/07/06 14:34:52 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -149,7 +149,7 @@ VOID PsDumpThreads(VOID) current = CONTAINING_RECORD(current_entry, ETHREAD, Tcb.ThreadListEntry); t++; - if (t >= PiNrThreads) + if (t > PiNrThreads) { DbgPrint("Too many threads on list\n"); return; @@ -157,7 +157,8 @@ VOID PsDumpThreads(VOID) DbgPrint("current %x current->Tcb.State %d eip %x ", current, current->Tcb.State, current->Tcb.Context.eip); -// KeDumpStackFrames(0, 16); + KeDumpStackFrames((PVOID)current->Tcb.Context.esp0, + 16); DbgPrint("PID %d ", current->ThreadsProcess->UniqueProcessId); DbgPrint("\n"); diff --git a/reactos/subsys/csrss/api/conio.c b/reactos/subsys/csrss/api/conio.c index b66234365a7..e2b391484ea 100644 --- a/reactos/subsys/csrss/api/conio.c +++ b/reactos/subsys/csrss/api/conio.c @@ -1,4 +1,4 @@ -/* $Id: conio.c,v 1.7 2000/05/26 05:40:20 phreak Exp $ +/* $Id: conio.c,v 1.8 2000/07/06 14:34:52 dwelch Exp $ * * reactos/subsys/csrss/api/conio.c * @@ -486,8 +486,10 @@ VOID Console_Api( DWORD Ignored ) NTSTATUS Status; while( 1 ) { - KeyEventRecord = RtlAllocateHeap( CsrssApiHeap, 0, sizeof( ConsoleInput ) ); - if( KeyEventRecord == 0 ) + KeyEventRecord = RtlAllocateHeap(CsrssApiHeap, + 0, + sizeof(ConsoleInput)); + if ( KeyEventRecord == 0 ) { DbgPrint( "CSR: Memory allocation failure!" ); continue;