88 lines
2.5 KiB
Plaintext
88 lines
2.5 KiB
Plaintext
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Microsoft Research Singularity
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
// File: PacketFifo.sg
|
||
|
//
|
||
|
|
||
|
namespace Microsoft.Singularity.Io.Net
|
||
|
{
|
||
|
using System;
|
||
|
using System.Runtime.InteropServices;
|
||
|
using Microsoft.Contracts;
|
||
|
using Microsoft.SingSharp;
|
||
|
using Microsoft.Singularity;
|
||
|
using Microsoft.Singularity.Channels;
|
||
|
|
||
|
public rep struct PacketFifo : ITracked
|
||
|
{
|
||
|
private Packet*[]! in ExHeap packets;
|
||
|
private int head;
|
||
|
private int length;
|
||
|
|
||
|
public PacketFifo(int capacity)
|
||
|
{
|
||
|
this.packets = new [ExHeap] Packet* [capacity];
|
||
|
this.head = 0;
|
||
|
this.length = 0;
|
||
|
}
|
||
|
|
||
|
public int Capacity
|
||
|
{
|
||
|
get { expose (this) { return this.packets.Length; } }
|
||
|
}
|
||
|
|
||
|
public int Count
|
||
|
{
|
||
|
get { expose (this) { return this.length; } }
|
||
|
}
|
||
|
|
||
|
public void Push([Claims] Packet*! in ExHeap p)
|
||
|
requires this.Count < this.Capacity;
|
||
|
{
|
||
|
expose (this) {
|
||
|
int index = this.head;
|
||
|
expose (this.packets[index]) {
|
||
|
assert this.packets[index] == null;
|
||
|
delete this.packets[index];
|
||
|
this.packets[index] = p;
|
||
|
}
|
||
|
this.head = (this.head + 1) % this.Capacity;
|
||
|
this.length++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void Push(PacketFifo*! in ExHeap donor, int count)
|
||
|
requires this.Count + count <= this.Capacity;
|
||
|
{
|
||
|
count = Math.Min(donor->Count, count);
|
||
|
while (count-- > 0) {
|
||
|
this.Push(donor->Pop());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void Push(PacketFifo*! in ExHeap donor)
|
||
|
requires this.Count + donor->Count <= this.Capacity;
|
||
|
{
|
||
|
Push(donor, donor->Count);
|
||
|
}
|
||
|
|
||
|
public Packet*! in ExHeap Pop()
|
||
|
requires this.Count > 0;
|
||
|
{
|
||
|
expose (this) {
|
||
|
Packet*! in ExHeap packet;
|
||
|
int index = (this.Capacity + this.head - this.length) % this.Capacity;
|
||
|
expose (this.packets[index]) {
|
||
|
packet = (!)packets[index];
|
||
|
this.packets[index] = null;
|
||
|
}
|
||
|
this.length--;
|
||
|
return packet;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|