private KMemoryBlock SplitBlock(KMemoryBlock block, uint address, uint size) { Debug.Assert(size > 0); KMemoryBlock newBlock = new KMemoryBlock(this, address, size, false); LinkedListEntry <KMemoryBlock> blockEntry = Blocks.Find(block); Debug.Assert(blockEntry != null); if (address == block.Address) { // Bottom up - put right before free and shift free up block.Address += size; block.Size -= size; Blocks.InsertBefore(newBlock, blockEntry); } else if (address == block.UpperBound - size) { // Top down - put right after and free shift free down block.Size -= size; Blocks.InsertAfter(newBlock, blockEntry); } else { // Middle - need a real split uint originalSize = block.Size; block.Size = newBlock.Address - block.Address; if (block.Size == 0) { // Special case of block replacing block Blocks.InsertAfter(newBlock, blockEntry); // block will be removed below } else { uint freeAddress = newBlock.Address + newBlock.Size; uint freeSize = originalSize - block.Size - newBlock.Size; KMemoryBlock freeBlock = new KMemoryBlock(this, freeAddress, freeSize, true); // Add free space after start block if needed if (freeSize > 0) { LinkedListEntry <KMemoryBlock> blockEntryFree = FreeList.Find(block); Blocks.InsertAfter(freeBlock, blockEntry); FreeList.InsertAfter(freeBlock, blockEntryFree); } // Add after the block (but before the freeBlock if there was one) Blocks.InsertAfter(newBlock, blockEntry); } } Debug.Assert(block.Size >= 0); // Remove old block if dead if (block.Size == 0) { Blocks.Remove(blockEntry); FreeList.Remove(block); } return(newBlock); }