@@ -244,6 +244,175 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
244
244
}
245
245
}
246
246
247
+ PFN_NUMBER
248
+ NTAPI
249
+ MiRemovePageByColor (IN PFN_NUMBER PageIndex ,
250
+ IN ULONG Color )
251
+ {
252
+ PMMPFN Pfn1 ;
253
+ PMMPFNLIST ListHead ;
254
+ MMLISTS ListName ;
255
+ PFN_NUMBER OldFlink , OldBlink ;
256
+ ULONG OldColor , OldCache ;
257
+ #if 0
258
+ PMMCOLOR_TABLES ColorTable ;
259
+ #endif
260
+ /* Make sure PFN lock is held */
261
+ ASSERT (KeGetCurrentIrql () == DISPATCH_LEVEL );
262
+ ASSERT (Color < MmSecondaryColors );
263
+
264
+ /* Get the PFN entry */
265
+ Pfn1 = MiGetPfnEntry (PageIndex );
266
+ ASSERT (Pfn1 -> u3 .e1 .RemovalRequested == 0 );
267
+ ASSERT (Pfn1 -> u3 .e1 .Rom == 0 );
268
+
269
+ /* Capture data for later */
270
+ OldColor = Pfn1 -> u3 .e1 .PageColor ;
271
+ OldCache = Pfn1 -> u3 .e1 .CacheAttribute ;
272
+
273
+ /* Could be either on free or zero list */
274
+ ListHead = MmPageLocationList [Pfn1 -> u3 .e1 .PageLocation ];
275
+ ListName = ListHead -> ListName ;
276
+ ASSERT (ListName <= FreePageList );
277
+
278
+ /* Remove a page */
279
+ ListHead -> Total -- ;
280
+
281
+ /* Get the forward and back pointers */
282
+ OldFlink = Pfn1 -> u1 .Flink ;
283
+ OldBlink = Pfn1 -> u2 .Blink ;
284
+
285
+ /* Check if the next entry is the list head */
286
+ if (OldFlink != LIST_HEAD )
287
+ {
288
+ /* It is not, so set the backlink of the actual entry, to our backlink */
289
+ MiGetPfnEntry (OldFlink )-> u2 .Blink = OldBlink ;
290
+ }
291
+ else
292
+ {
293
+ /* Set the list head's backlink instead */
294
+ ListHead -> Blink = OldFlink ;
295
+ }
296
+
297
+ /* Check if the back entry is the list head */
298
+ if (OldBlink != LIST_HEAD )
299
+ {
300
+ /* It is not, so set the backlink of the actual entry, to our backlink */
301
+ MiGetPfnEntry (OldBlink )-> u1 .Flink = OldFlink ;
302
+ }
303
+ else
304
+ {
305
+ /* Set the list head's backlink instead */
306
+ ListHead -> Flink = OldFlink ;
307
+ }
308
+
309
+ /* We are not on a list anymore */
310
+ Pfn1 -> u1 .Flink = Pfn1 -> u2 .Blink = 0 ;
311
+
312
+ /* Zero flags but restore color and cache */
313
+ Pfn1 -> u3 .e2 .ShortFlags = 0 ;
314
+ Pfn1 -> u3 .e1 .PageColor = OldColor ;
315
+ Pfn1 -> u3 .e1 .CacheAttribute = OldCache ;
316
+ #if 0 // When switching to ARM3
317
+ /* Get the first page on the color list */
318
+ ColorTable = & MmFreePagesByColor [ListName ][Color ];
319
+ ASSERT (ColorTable -> Count >= 1 );
320
+
321
+ /* Set the forward link to whoever we were pointing to */
322
+ ColorTable -> Flink = Pfn1 -> OriginalPte .u .Long ;
323
+ if (ColorTable -> Flink == LIST_HEAD )
324
+ {
325
+ /* This is the beginning of the list, so set the sentinel value */
326
+ ColorTable -> Blink = LIST_HEAD ;
327
+ }
328
+ else
329
+ {
330
+ /* The list is empty, so we are the first page */
331
+ MiGetPfnEntry (ColorTable -> Flink )-> u4 .PteFrame = -1 ;
332
+ }
333
+
334
+ /* One more page */
335
+ ColorTable -> Total ++ ;
336
+ #endif
337
+ /* See if we hit any thresholds */
338
+ if (MmAvailablePages == MmHighMemoryThreshold )
339
+ {
340
+ /* Clear the high memory event */
341
+ KeClearEvent (MiHighMemoryEvent );
342
+ }
343
+ else if (MmAvailablePages == MmLowMemoryThreshold )
344
+ {
345
+ /* Signal the low memory event */
346
+ KeSetEvent (MiLowMemoryEvent , 0 , FALSE);
347
+ }
348
+
349
+ /* One less page */
350
+ if (-- MmAvailablePages < MmMinimumFreePages )
351
+ {
352
+ /* FIXME: Should wake up the MPW and working set manager, if we had one */
353
+ }
354
+
355
+ /* Return the page */
356
+ return PageIndex ;
357
+ }
358
+
359
+ PFN_NUMBER
360
+ NTAPI
361
+ MiRemoveAnyPage (IN ULONG Color )
362
+ {
363
+ PFN_NUMBER PageIndex ;
364
+ PMMPFN Pfn1 ;
365
+
366
+ /* Make sure PFN lock is held and we have pages */
367
+ ASSERT (KeGetCurrentIrql () == DISPATCH_LEVEL );
368
+ ASSERT (MmAvailablePages != 0 );
369
+ ASSERT (Color < MmSecondaryColors );
370
+
371
+ /* Check the colored free list */
372
+ #if 0 // Enable when using ARM3 database */
373
+ PageIndex = MmFreePagesByColor [FreePageList ][Color ].Flink ;
374
+ if (PageIndex == LIST_HEAD )
375
+ {
376
+ /* Check the colored zero list */
377
+ PageIndex = MmFreePagesByColor [ZeroedPageList ][Color ].Flink ;
378
+ if (PageIndex == LIST_HEAD )
379
+ {
380
+ #endif
381
+ /* Check the free list */
382
+ PageIndex = MmFreePageListHead .Flink ;
383
+ Color = PageIndex & MmSecondaryColorMask ;
384
+ if (PageIndex == LIST_HEAD )
385
+ {
386
+ /* Check the zero list */
387
+ ASSERT (MmFreePageListHead .Total == 0 );
388
+ PageIndex = MmZeroedPageListHead .Flink ;
389
+ Color = PageIndex & MmSecondaryColorMask ;
390
+ ASSERT (PageIndex != LIST_HEAD );
391
+ if (PageIndex == LIST_HEAD )
392
+ {
393
+ /* FIXME: Should check the standby list */
394
+ ASSERT (MmZeroedPageListHead .Total == 0 );
395
+ }
396
+ }
397
+ #if 0 // Enable when using ARM3 database */
398
+ }
399
+ }
400
+ #endif
401
+
402
+ /* Remove the page from its list */
403
+ PageIndex = MiRemovePageByColor (PageIndex , Color );
404
+
405
+ /* Sanity checks */
406
+ Pfn1 = MiGetPfnEntry (PageIndex );
407
+ ASSERT ((Pfn1 -> u3 .e1 .PageLocation == FreePageList ) ||
408
+ (Pfn1 -> u3 .e1 .PageLocation == ZeroedPageList ));
409
+ ASSERT (Pfn1 -> u3 .e2 .ReferenceCount == 0 );
410
+ ASSERT (Pfn1 -> u2 .ShareCount == 0 );
411
+
412
+ /* Return the page */
413
+ return PageIndex ;
414
+ }
415
+
247
416
PMMPFN
248
417
NTAPI
249
418
MiRemoveHeadList (IN PMMPFNLIST ListHead )
@@ -285,10 +454,12 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
285
454
{
286
455
PMMPFNLIST ListHead ;
287
456
PFN_NUMBER LastPage ;
288
- PMMPFN Pfn1 , Blink ;
457
+ PMMPFN Pfn1 ;
458
+ #if 0
289
459
ULONG Color ;
290
- PMMCOLOR_TABLES ColorHead ;
291
-
460
+ PMMPFN Blink ;
461
+ PMMCOLOR_TABLES ColorTable ;
462
+ #endif
292
463
/* Make sure the page index is valid */
293
464
ASSERT ((PageFrameIndex != 0 ) &&
294
465
(PageFrameIndex <= MmHighestPhysicalPage ) &&
@@ -351,33 +522,35 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
351
522
KeSetEvent (MiHighMemoryEvent , 0 , FALSE);
352
523
}
353
524
525
+ #if 0 // When using ARM3 PFN
354
526
/* Get the page color */
355
527
Color = PageFrameIndex & MmSecondaryColorMask ;
356
528
357
529
/* Get the first page on the color list */
358
- ColorHead = & MmFreePagesByColor [FreePageList ][Color ];
359
- if (ColorHead -> Flink == LIST_HEAD )
530
+ ColorTable = & MmFreePagesByColor [FreePageList ][Color ];
531
+ if (ColorTable -> Flink == LIST_HEAD )
360
532
{
361
533
/* The list is empty, so we are the first page */
362
534
Pfn1 -> u4 .PteFrame = -1 ;
363
- ColorHead -> Flink = PageFrameIndex ;
535
+ ColorTable -> Flink = PageFrameIndex ;
364
536
}
365
537
else
366
538
{
367
539
/* Get the previous page */
368
- Blink = (PMMPFN )ColorHead -> Blink ;
540
+ Blink = (PMMPFN )ColorTable -> Blink ;
369
541
370
542
/* Make it link to us */
371
543
Pfn1 -> u4 .PteFrame = MI_PFNENTRY_TO_PFN (Blink );
372
544
Blink -> OriginalPte .u .Long = PageFrameIndex ;
373
545
}
374
546
375
547
/* Now initialize our own list pointers */
376
- ColorHead -> Blink = Pfn1 ;
548
+ ColorTable -> Blink = Pfn1 ;
377
549
Pfn1 -> OriginalPte .u .Long = LIST_HEAD ;
378
550
379
551
/* And increase the count in the colored list */
380
- ColorHead -> Count ++ ;
552
+ ColorTable -> Count ++ ;
553
+ #endif
381
554
382
555
/* FIXME: Notify zero page thread if enough pages are on the free list now */
383
556
}
0 commit comments