public MemoryNode Allocate(uint size) { size = Align(size); Reserve(size); var firstFreeIdx = _nodes.FindLastIndex(o => !o.IsUsed && o.Size >= size); Debug.Assert(firstFreeIdx != -1); var firstFree = _nodes[firstFreeIdx]; MemoryNode node; if (firstFree.Size == size) { firstFree.AddRef(); node = firstFree; } else { firstFree.Size -= size; var newNode = new MemoryNode(this) { Start = firstFree.Start + firstFree.Size, Size = size }; newNode.AddRef(); _nodes.Insert(firstFreeIdx + 1, newNode); node = newNode; } return(node); }
public MemoryNode Allocate(uint size) { var firstFreeIdx = _nodes.FindLastIndex(o => !o.IsUsed && o.Size >= size); if (firstFreeIdx == -1) throw new InvalidOperationException("KPU ran out of memory."); var firstFree = _nodes[firstFreeIdx]; MemoryNode node; if (firstFree.Size == size) { firstFree.AddRef(); node = firstFree; } else { if (_findFromLast) { firstFree.Size -= size; var newNode = new MemoryNode(this) { Start = firstFree.Start + firstFree.Size, Size = size }; newNode.AddRef(); _nodes.Insert(firstFreeIdx + 1, newNode); node = newNode; } else { var newNode = new MemoryNode(this) { Start = firstFree.Start, Size = size }; newNode.AddRef(); firstFree.Start += size; firstFree.Size -= size; _nodes.Insert(firstFreeIdx, newNode); node = newNode; } _findFromLast = !_findFromLast; } MaxStart = Math.Min(node.Start, MaxStart); return node; }