132 lines
3.9 KiB
C#
132 lines
3.9 KiB
C#
/*******************************************************************/
|
|
/* 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; }
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|