singrdk/base/Kernel/Bartok/GCs/UnmanagedPageList.cs

132 lines
3.9 KiB
C#
Raw Normal View History

2008-03-05 09:52:00 -05:00
/*******************************************************************/
/* WARNING */
/* This file should be identical in the Bartok and Singularity */
/* depots. Master copy resides in Bartok Depot. Changes should be */
/* made to Bartok Depot and propagated to Singularity Depot. */
/*******************************************************************/
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
namespace System.GCs {
using System.Runtime.CompilerServices;
internal unsafe struct UnmanagedPageList {
internal static UnmanagedPageList pageCache;
private UIntPtr head;
private UIntPtr tail;
internal static void ReleaseStandbyPages() {
while (!pageCache.IsEmpty) {
UIntPtr pageAddr = pageCache.RemoveHead();
PageManager.ReleaseUnusedPages(PageTable.Page(pageAddr),
(UIntPtr) 1, false);
}
}
internal bool IsEmpty {
[Inline]
get { return this.head == UIntPtr.Zero; }
}
internal bool IsSingleton {
[Inline]
get { return this.head == this.tail; }
}
internal UIntPtr Head {
get { return this.head; }
}
internal UIntPtr Tail {
get { return this.tail; }
}
internal void AddTail(UIntPtr pageAddr) {
if (this.head == UIntPtr.Zero) {
this.head = pageAddr;
} else {
SetNext(this.tail, pageAddr);
}
this.tail = pageAddr;
}
internal void AddHead(UIntPtr pageAddr) {
SetNext(pageAddr, this.head);
this.head = pageAddr;
if (this.tail == UIntPtr.Zero) {
this.tail = pageAddr;
}
}
internal UIntPtr RemoveHead() {
UIntPtr oldHead = this.head;
UIntPtr newHead = Next(oldHead);
this.head = newHead;
if (newHead == UIntPtr.Zero) {
this.tail = UIntPtr.Zero;
}
SetNext(oldHead, UIntPtr.Zero);
return oldHead;
}
[Inline]
private static UIntPtr Next(UIntPtr pageAddr) {
return *(UIntPtr *) pageAddr;
}
[Inline]
private static void SetNext(UIntPtr pageAddr,
UIntPtr nextPageAddr)
{
*(UIntPtr *) pageAddr = nextPageAddr;
}
internal static UIntPtr* FirstPageAddr(UIntPtr pageAddr) {
return (((UIntPtr *) pageAddr) + 1);
}
internal static UIntPtr* EndPageAddr(UIntPtr pageAddr) {
return (UIntPtr *) (pageAddr + PageTable.PageSize);
}
internal struct Enumerator {
private bool movedToFirst;
private UIntPtr currentPage;
private UIntPtr tailPage;
internal Enumerator(ref UnmanagedPageList pageList) {
this.movedToFirst = false;
this.currentPage = pageList.Head;
this.tailPage = pageList.Tail;
}
internal bool MoveNext() {
if (!this.movedToFirst) {
this.movedToFirst = true;
return (this.currentPage != UIntPtr.Zero);
} else if (currentPage == tailPage) {
return false;
} else {
this.currentPage = Next(this.currentPage);
VTable.Assert(this.currentPage != UIntPtr.Zero);
return true;
}
}
internal UIntPtr Current {
get { return this.currentPage; }
}
}
}
}