/// <summary> /// Coalesces/Merges all the adjacent FREE arenas into one arena. /// </summary> internal static MemArena CoalesceAdjacent(MemArena arena) { // Only free arenas can be coalesced. if (!arena.IsFree) { return(arena); } // Check if there is an arena next to this one. MemArena curr = arena; MemArena next = arena.NextArena(); int nHeaderCount = 0;//need to know how many headers are being freed while merging free arenas. if (next != null) { uint freedSpace = 0; // Find the first USED arena below this arena in the view. // Skip/Merge all the free arenas along the way. while (next != null && next.IsFree) { nHeaderCount++; freedSpace += next.TotalLength; curr = next; next = next.NextArena(); } // Fix up links! if (freedSpace > 0) { arena.Capacity += freedSpace; uint nCapacity = arena.Capacity; arena = SetNextArena(arena, GetActualArena(next)); //update only the actual arena arena.Capacity = nCapacity; } } if (arena.HasPrevious) { uint freedSpace = 0; // Find the first USED arena above this arena in the view. // Skip/Merge all the free arenas along the way. MemArena cur = arena; MemArena prev = null; do { prev = cur.PreviousArena(); if (prev == null || !prev.IsFree) { break; } freedSpace += prev.TotalLength; cur = prev; nHeaderCount++; }while (true); // Fix up links! For even if we find previous arena free.. The last from previous is now our Pivot.Its call to adjust its Next then. if (freedSpace > 0) { arena.Capacity += freedSpace; uint nCapacity = arena.Capacity; MemArena tempNext = arena.NextArena(); arena = SetNextArena(cur, GetActualArena(next)); //update only the actual arena arena.Capacity = nCapacity; } } if (nHeaderCount > 0) //update memory freed, while merging arenas. { arena.View.MyFreeSpace += (uint)(nHeaderCount * Header.Size); } return(arena); }