Esempio n. 1
0
        /// <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);
        }