Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpageop.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: ntoskrnl/mm/pageop.c 00005 * PURPOSE: No purpose listed. 00006 * 00007 * PROGRAMMERS: David Welch (welch@cwcom.net) 00008 */ 00009 00010 /* INCLUDES ****************************************************************/ 00011 00012 #include <ntoskrnl.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 #if defined (ALLOC_PRAGMA) 00017 #pragma alloc_text(INIT, MmInitializePageOp) 00018 #endif 00019 00020 00021 /* GLOBALS *******************************************************************/ 00022 00023 #define PAGEOP_HASH_TABLE_SIZE (32) 00024 00025 static KSPIN_LOCK MmPageOpHashTableLock; 00026 static PMM_PAGEOP MmPageOpHashTable[PAGEOP_HASH_TABLE_SIZE]; 00027 static NPAGED_LOOKASIDE_LIST MmPageOpLookasideList; 00028 00029 /* FUNCTIONS *****************************************************************/ 00030 00031 VOID 00032 NTAPI 00033 MmReleasePageOp(PMM_PAGEOP PageOp) 00034 /* 00035 * FUNCTION: Release a reference to a page operation descriptor 00036 */ 00037 { 00038 KIRQL oldIrql; 00039 PMM_PAGEOP PrevPageOp; 00040 00041 KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); 00042 PageOp->ReferenceCount--; 00043 if (PageOp->ReferenceCount > 0) 00044 { 00045 KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); 00046 return; 00047 } 00048 (void)InterlockedDecrementUL(&PageOp->MArea->PageOpCount); 00049 PrevPageOp = MmPageOpHashTable[PageOp->Hash]; 00050 if (PrevPageOp == PageOp) 00051 { 00052 MmPageOpHashTable[PageOp->Hash] = PageOp->Next; 00053 KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); 00054 ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp); 00055 return; 00056 } 00057 while (PrevPageOp->Next != NULL) 00058 { 00059 if (PrevPageOp->Next == PageOp) 00060 { 00061 PrevPageOp->Next = PageOp->Next; 00062 KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); 00063 ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp); 00064 return; 00065 } 00066 PrevPageOp = PrevPageOp->Next; 00067 } 00068 KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); 00069 KeBugCheck(MEMORY_MANAGEMENT); 00070 } 00071 00072 PMM_PAGEOP 00073 NTAPI 00074 MmCheckForPageOp(PMEMORY_AREA MArea, HANDLE Pid, PVOID Address, 00075 PMM_SECTION_SEGMENT Segment, ULONGLONG Offset) 00076 { 00077 ULONG_PTR Hash; 00078 KIRQL oldIrql; 00079 PMM_PAGEOP PageOp; 00080 00081 /* 00082 * Calcuate the hash value for pageop structure 00083 */ 00084 if (MArea->Type == MEMORY_AREA_SECTION_VIEW) 00085 { 00086 Hash = (((ULONG_PTR)Segment) | (((ULONG_PTR)Offset) / PAGE_SIZE)); 00087 } 00088 else 00089 { 00090 Hash = (((ULONG_PTR)Pid) | (((ULONG_PTR)Address) / PAGE_SIZE)); 00091 } 00092 Hash = Hash % PAGEOP_HASH_TABLE_SIZE; 00093 00094 KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); 00095 00096 /* 00097 * Check for an existing pageop structure 00098 */ 00099 PageOp = MmPageOpHashTable[Hash]; 00100 while (PageOp != NULL) 00101 { 00102 if (MArea->Type == MEMORY_AREA_SECTION_VIEW) 00103 { 00104 if (PageOp->Segment == Segment && 00105 PageOp->Offset == Offset) 00106 { 00107 break; 00108 } 00109 } 00110 else 00111 { 00112 if (PageOp->Pid == Pid && 00113 PageOp->Address == Address) 00114 { 00115 break; 00116 } 00117 } 00118 PageOp = PageOp->Next; 00119 } 00120 00121 /* 00122 * If we found an existing pageop then increment the reference count 00123 * and return it. 00124 */ 00125 if (PageOp != NULL) 00126 { 00127 PageOp->ReferenceCount++; 00128 KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); 00129 return(PageOp); 00130 } 00131 KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); 00132 return(NULL); 00133 } 00134 00135 PMM_PAGEOP 00136 NTAPI 00137 MmGetPageOp(PMEMORY_AREA MArea, HANDLE Pid, PVOID Address, 00138 PMM_SECTION_SEGMENT Segment, ULONGLONG Offset, ULONG OpType, BOOLEAN First) 00139 /* 00140 * FUNCTION: Get a page operation descriptor corresponding to 00141 * the memory area and either the segment, offset pair or the 00142 * pid, address pair. 00143 */ 00144 { 00145 ULONG_PTR Hash; 00146 KIRQL oldIrql; 00147 PMM_PAGEOP PageOp; 00148 00149 Address = (PVOID)PAGE_ROUND_DOWN(Address); 00150 Offset = PAGE_ROUND_DOWN(Offset); 00151 00152 /* Making a page op during marea destruction is illegal */ 00153 ASSERT(!MArea->DeleteInProgress); 00154 00155 /* 00156 * Calcuate the hash value for pageop structure 00157 */ 00158 if (MArea->Type == MEMORY_AREA_SECTION_VIEW) 00159 { 00160 Hash = (((ULONG_PTR)Segment) | (((ULONG_PTR)Offset) / PAGE_SIZE)); 00161 } 00162 else 00163 { 00164 Hash = (((ULONG_PTR)Pid) | (((ULONG_PTR)Address) / PAGE_SIZE)); 00165 } 00166 Hash = Hash % PAGEOP_HASH_TABLE_SIZE; 00167 00168 KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); 00169 00170 /* 00171 * Check for an existing pageop structure 00172 */ 00173 PageOp = MmPageOpHashTable[Hash]; 00174 while (PageOp != NULL) 00175 { 00176 if (MArea->Type == MEMORY_AREA_SECTION_VIEW) 00177 { 00178 if (PageOp->Segment == Segment && 00179 PageOp->Offset == Offset) 00180 { 00181 break; 00182 } 00183 } 00184 else 00185 { 00186 if (PageOp->Pid == Pid && 00187 PageOp->Address == Address) 00188 { 00189 break; 00190 } 00191 } 00192 PageOp = PageOp->Next; 00193 } 00194 00195 /* 00196 * If we found an existing pageop then increment the reference count 00197 * and return it. 00198 */ 00199 if (PageOp != NULL) 00200 { 00201 if (First) 00202 { 00203 PageOp = NULL; 00204 } 00205 else 00206 { 00207 PageOp->ReferenceCount++; 00208 } 00209 KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); 00210 return(PageOp); 00211 } 00212 00213 /* 00214 * Otherwise add a new pageop. 00215 */ 00216 PageOp = ExAllocateFromNPagedLookasideList(&MmPageOpLookasideList); 00217 if (PageOp == NULL) 00218 { 00219 KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); 00220 KeBugCheck(MEMORY_MANAGEMENT); 00221 return(NULL); 00222 } 00223 00224 if (MArea->Type != MEMORY_AREA_SECTION_VIEW) 00225 { 00226 PageOp->Pid = Pid; 00227 PageOp->Address = Address; 00228 } 00229 else 00230 { 00231 PageOp->Segment = Segment; 00232 PageOp->Offset = Offset; 00233 } 00234 PageOp->ReferenceCount = 1; 00235 PageOp->Next = MmPageOpHashTable[Hash]; 00236 PageOp->Hash = (ULONG)Hash; 00237 PageOp->Thread = PsGetCurrentThread(); 00238 PageOp->Abandoned = FALSE; 00239 PageOp->Status = STATUS_PENDING; 00240 PageOp->OpType = OpType; 00241 PageOp->MArea = MArea; 00242 KeInitializeEvent(&PageOp->CompletionEvent, SynchronizationEvent, FALSE); 00243 MmPageOpHashTable[Hash] = PageOp; 00244 (void)InterlockedIncrementUL(&MArea->PageOpCount); 00245 00246 KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); 00247 return(PageOp); 00248 } 00249 00250 VOID 00251 INIT_FUNCTION 00252 NTAPI 00253 MmInitializePageOp(VOID) 00254 { 00255 memset(MmPageOpHashTable, 0, sizeof(MmPageOpHashTable)); 00256 KeInitializeSpinLock(&MmPageOpHashTableLock); 00257 00258 ExInitializeNPagedLookasideList (&MmPageOpLookasideList, 00259 NULL, 00260 NULL, 00261 0, 00262 sizeof(MM_PAGEOP), 00263 TAG_MM_PAGEOP, 00264 50); 00265 } 00266 00267 00268 00269 00270 00271 00272 00273 00274 Generated on Sat May 26 2012 04:36:30 for ReactOS by
1.7.6.1
|