- Fix KiDispatchException to unmask KI_EXCEPTION_INTERNAL when setting the exception...
[reactos.git] / reactos / ntoskrnl / mm / mpw.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/mm/mpw.c
6 * PURPOSE: Writes data that has been modified in memory but not on
7 * the disk
8 *
9 * PROGRAMMERS: David Welch (welch@cwcom.net)
10 */
11
12 /* INCLUDES ****************************************************************/
13
14 #include <ntoskrnl.h>
15 #define NDEBUG
16 #include <internal/debug.h>
17
18 /* GLOBALS *******************************************************************/
19
20 static HANDLE MpwThreadHandle;
21 static CLIENT_ID MpwThreadId;
22 static KEVENT MpwThreadEvent;
23 static volatile BOOLEAN MpwThreadShouldTerminate;
24
25 /* FUNCTIONS *****************************************************************/
26
27 NTSTATUS STDCALL
28 MmWriteDirtyPages(ULONG Target, PULONG Actual)
29 {
30 PFN_TYPE Page;
31 PFN_TYPE NextPage;
32 NTSTATUS Status;
33
34 Page = MmGetLRUFirstUserPage();
35 while (Page != 0 && Target > 0)
36 {
37 /*
38 * FIXME: While the current page is write back it is possible
39 * that the next page is freed and not longer a user page.
40 */
41 NextPage = MmGetLRUNextUserPage(Page);
42 if (MmIsDirtyPageRmap(Page))
43 {
44 Status = MmWritePagePhysicalAddress(Page);
45 if (NT_SUCCESS(Status))
46 {
47 Target--;
48 }
49 }
50 Page = NextPage;
51 }
52 *Actual = Target;
53 return(STATUS_SUCCESS);
54 }
55
56 NTSTATUS STDCALL
57 MmMpwThreadMain(PVOID Ignored)
58 {
59 NTSTATUS Status;
60 ULONG PagesWritten;
61 LARGE_INTEGER Timeout;
62
63 Timeout.QuadPart = -50000000;
64
65 for(;;)
66 {
67 Status = KeWaitForSingleObject(&MpwThreadEvent,
68 0,
69 KernelMode,
70 FALSE,
71 &Timeout);
72 if (!NT_SUCCESS(Status))
73 {
74 DbgPrint("MpwThread: Wait failed\n");
75 KEBUGCHECK(0);
76 return(STATUS_UNSUCCESSFUL);
77 }
78 if (MpwThreadShouldTerminate)
79 {
80 DbgPrint("MpwThread: Terminating\n");
81 return(STATUS_SUCCESS);
82 }
83
84 PagesWritten = 0;
85 #if 0
86 /*
87 * FIXME: MmWriteDirtyPages doesn't work correctly.
88 */
89 MmWriteDirtyPages(128, &PagesWritten);
90 #endif
91
92 CcRosFlushDirtyPages(128, &PagesWritten);
93 }
94 }
95
96 NTSTATUS
97 NTAPI
98 MmInitMpwThread(VOID)
99 {
100 KPRIORITY Priority;
101 NTSTATUS Status;
102
103 MpwThreadShouldTerminate = FALSE;
104 KeInitializeEvent(&MpwThreadEvent, SynchronizationEvent, FALSE);
105
106 Status = PsCreateSystemThread(&MpwThreadHandle,
107 THREAD_ALL_ACCESS,
108 NULL,
109 NULL,
110 &MpwThreadId,
111 (PKSTART_ROUTINE) MmMpwThreadMain,
112 NULL);
113 if (!NT_SUCCESS(Status))
114 {
115 return(Status);
116 }
117
118 Priority = 1;
119 NtSetInformationThread(MpwThreadHandle,
120 ThreadPriority,
121 &Priority,
122 sizeof(Priority));
123
124 return(STATUS_SUCCESS);
125 }
126
127 NTSTATUS
128 NTAPI
129 MmInitBsmThread(VOID)
130 {
131 NTSTATUS Status;
132 OBJECT_ATTRIBUTES ObjectAttributes;
133 HANDLE ThreadHandle;
134
135 /* Create the thread */
136 InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
137 Status = PsCreateSystemThread(&ThreadHandle,
138 THREAD_ALL_ACCESS,
139 &ObjectAttributes,
140 NULL,
141 NULL,
142 KeBalanceSetManager,
143 NULL);
144
145 /* Close the handle and return status */
146 ZwClose(ThreadHandle);
147 return Status;
148 }