singrdk/base/Kernel/SingSharp.Runtime/VectorQueue.sg

118 lines
3.4 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: VectorQueue.sg
//
// Note: File is part of Sing# runtime files and copied into Singularity tree
// whenever a new version of Sing# is dropped.
//
using Microsoft.SingSharp;
namespace Microsoft.Singularity.Channels {
public class VectorQueue<T> : ITracked where T:unmanaged struct {
private Node! listHead;
private Node! listTail;
public VectorQueue() {
Node node = this.listHead = new Node();
this.listTail = node;
base();
}
private class Node {
unsafe internal T[] in ExHeap data;
internal Node! next;
internal Node! prev;
internal Node() {
this.next = this;
this.prev = this;
}
internal Node([Claims] T[]! in ExHeap arg) {
this.next = this;
this.prev = this;
this.data = arg;
}
internal T[] in ExHeap Unlink() {
this.prev.next = this.next;
this.next.prev = this.prev;
this.next = this;
this.prev = this;
return this.data;
}
internal void LinkAsNext([Claims] T[]! in ExHeap data) {
Node next = new Node(data);
next.next = this.next;
this.next = next;
next.prev = this;
next.next.prev = next;
}
internal void LinkAsPrev([Claims] T[]! in ExHeap data) {
Node prev = new Node(data);
prev.prev = this.prev;
this.prev = prev;
prev.next = this;
prev.prev.next = prev;
}
}
#region ITracked members
void ITracked.Release() {}
void ITracked.Acquire() {}
public void Dispose()
{
Node current = this.listHead.next;
while (current != this.listHead) {
// temporary hack until we fix the upcast in receiver context
unsafe {
T[] in ExHeap data = current.data;
delete data;
}
current = current.next;
}
this.listTail = this.listHead = new Node();
}
void ITracked.Expose() {}
void ITracked.UnExpose() {}
#endregion
public void AddHead([Claims] T[]! in ExHeap data) {
this.listHead.LinkAsNext(data);
}
public void AddTail([Claims] T[]! in ExHeap data) {
this.listTail.LinkAsPrev(data);
}
public bool Empty { get { return this.listHead.next == this.listTail; } }
public T[] in ExHeap ExtractHead() {
if (this.Empty) return null;
Node candidate = this.listHead.next;
return candidate.Unlink();
}
public T[] in ExHeap ExtractTail() {
if (this.Empty) return null;
Node candidate = this.listTail.prev;
return candidate.Unlink();
}
}
}