public PmemTwoLevelStack(PhysMem _pmem, nuint paddrbase, nuint len, nuint _ssize = 4096, nuint _lsize = 2048 * 1024) { pmem = _pmem; ssize = _ssize; lsize = _lsize; // Calculate start addresses and lengths for the ring buffer structure nuint sbasep = paddrbase; nuint slen = len / _ssize * (nuint)sizeof(nuint); nuint lbasep = sbasep + slen; nuint llen = len / _lsize * (nuint)sizeof(nuint); // Create the ring buffers rbs = new Collections.RingBuffer <nuint>((void *)pmem.vmem.Map(sbasep, slen, 0, 0).vaddr, (int)slen); rbl = new Collections.RingBuffer <nuint>((void *)pmem.vmem.Map(lbasep, llen, 0, 0).vaddr, (int)llen); // Add the pages, use small pages at either end and then large pages in the middle nuint x = llen + lbasep; x = util.align(x, ssize); StartAddr = x; Length = len - (x - paddrbase); // This assumes page sizes are powers of 2 var lmask = lsize - 1; // Small pages at start while ((x & lmask) != 0 & (x + ssize <= paddrbase + len)) { rbs.Enqueue(x); x += ssize; } // Large pages in middle while (x + lsize <= paddrbase + len) { rbl.Enqueue(x); x += lsize; } // Small pages at end while (x + ssize <= paddrbase + len) { rbs.Enqueue(x); x += ssize; } // Debug Formatter.Write("PmemTwoLevelStack: rbs count ", Program.arch.DebugOutput); Formatter.Write((ulong)rbs.Count, Program.arch.DebugOutput); Formatter.Write(", lbs count ", Program.arch.DebugOutput); Formatter.Write((ulong)rbl.Count, Program.arch.DebugOutput); Formatter.WriteLine(Program.arch.DebugOutput); }
public PmemStack(PhysMem _pmem, nuint paddrbase, nuint len, nuint _ssize = 4096) { pmem = _pmem; ssize = _ssize; // Calculate start addresse and length for the ring buffer structure nuint sbasep = paddrbase; nuint slen = len / _ssize * (nuint)sizeof(nuint); // Create the ring buffer rbs = new Collections.RingBuffer <nuint>((void *)pmem.vmem.Map(sbasep, slen, 0, 0).vaddr, (int)slen); // Add the pages nuint x = slen + sbasep; x = util.align(x, ssize); StartAddr = x; Length = len - (x - paddrbase); while (x + ssize <= paddrbase + len) { rbs.Enqueue(x); x += ssize; } }
public override nuint Allocate(nuint len) { if (len > lsize) { return(0); } if (len <= ssize) { // Small alloc if (rbs.Dequeue(out var ret)) { return(ret); } else { // See if we can break up a large block if (rbl.Dequeue(out ret)) { Formatter.Write("PmemTwoLevelStack break large block: rbs count ", Program.arch.DebugOutput); Formatter.Write((ulong)rbs.Count, Program.arch.DebugOutput); Formatter.Write(", lbs count ", Program.arch.DebugOutput); Formatter.Write((ulong)rbl.Count, Program.arch.DebugOutput); // we can - store everything after the first entry back for (nuint x = ret + ssize; x < ret + lsize; x += ssize) { rbs.Enqueue(x); } Formatter.Write(" -> rbs count ", Program.arch.DebugOutput); Formatter.Write((ulong)rbs.Count, Program.arch.DebugOutput); Formatter.Write(", lbs count ", Program.arch.DebugOutput); Formatter.Write((ulong)rbl.Count, Program.arch.DebugOutput); Formatter.WriteLine(Program.arch.DebugOutput); return(ret); } else { // Cannot return(0); } } } else { // Large alloc if (rbl.Dequeue(out var ret)) { return(ret); } else { return(0); } } }
internal bool SendMessage(IPCMessage message) { if (!ready) { return(false); } return(rb.Enqueue((IntPtr)libsupcs.CastOperations.ReinterpretAsPointer(message))); }
public bool Enqueue(T val) { return(rb.Enqueue(libsupcs.CastOperations.ReinterpretAsIntPtr(val))); }