/// <summary> /// Attempts to allocate a fragment range in the remaining lane space. /// </summary> /// <param name="size">The requested length.</param> /// <param name="frag">A data bag.</param> /// <param name="tries">The number of fails before switching to another lane.</param> /// <param name="awaitMS">The awaitMS for each try</param> /// <returns>True if the space was successfully taken.</returns> internal bool Alloc(int size, ref FragmentRange frag, int tries, int awaitMS) { var CAP = LaneCapacity; var r = false; if (Volatile.Read(ref i[OFFSET]) + size <= CAP) { while (isDisposed < 1 && !IsClosed && tries-- > 0 && !r && Monitor.TryEnter(allocGate, awaitMS)) { var offset = i[OFFSET]; if (offset + size <= CAP) { i[OFFSET] += size; frag.Allocation = ++i[ALLOCS]; frag.Length = size; frag.Offset = offset; frag.LaneCycle = i[LCYCLE]; lastAllocTick = DateTime.Now.Ticks; r = true; } Monitor.Exit(allocGate); } } return(r); }
public MappedFragment AllocMappedFragment(int size, int tries, int awaitMS) { var fr = new FragmentRange(); return(Alloc(size, ref fr, tries, awaitMS) ? new MappedFragment(fr.Offset, fr.Length, mmva, this, () => resetOne(fr.LaneCycle)) : null); }
public HeapFragment AllocHeapFragment(int size, int tries, int awaitMS) { var fr = new FragmentRange(); if (Alloc(size, ref fr, tries, awaitMS)) { var mem = new Memory <byte>(lane, fr.Offset, fr.Length); var frag = new HeapFragment(mem, this, () => resetOne(fr.LaneCycle)); return(frag); } else { return(null); } }
public MarshalLaneFragment AllocMarshalFragment(int size, int tries, int awaitMS) { var fr = new FragmentRange(); if (Alloc(size, ref fr, tries, awaitMS)) { var frag = new MarshalLaneFragment( fr.Offset, fr.Length, lanePtr, this, () => resetOne(fr.LaneCycle)); return(frag); } else { return(null); } }