Exemple #1
0
        public void Return(AllocatedMemoryData allocation)
        {
            if (_isDisposed ?? true)
            {
                return;
            }


            var address = allocation.Address;

#if DEBUG
            Debug.Assert(address != _ptrCurrent);
            Debug.Assert(allocation.IsReturned == false);
            allocation.IsReturned = true;
#endif

#if MEM_GUARD
#if MEM_GUARD_STACK
            if (allocation.FreedBy == null)
            {
                allocation.FreedBy = Environment.StackTrace;
            }
#endif
            ElectricFencedMemory.Free(address);
#else
            if (address != _ptrCurrent - allocation.SizeInBytes ||
                address < _ptrStart)
            {
                // we have fragmentation, so'll just store the values that we need here
                // in the memory we just freed :-)

                // note that this fragmentation will be healed by the call to ResetArena
                // trying to do this on the fly is too expensive.

                Debug.Assert(Bits.PowerOf2(allocation.SizeInBytes) == allocation.SizeInBytes,
                             "Allocation size must always be a power of two"
                             );
                Debug.Assert(allocation.SizeInBytes >= sizeof(FreeSection));


                var index   = Bits.MostSignificantBit(allocation.SizeInBytes) - 1;
                var section = (FreeSection *)address;
                section->SizeInBytes = allocation.SizeInBytes;
                section->Previous    = _freed[index];
                _freed[index]        = section;
                return;
            }
            // since the returned allocation is at the end of the arena, we can just move
            // the pointer back
            _used       -= allocation.SizeInBytes;
            TotalUsed   -= allocation.SizeInBytes;
            _ptrCurrent -= allocation.SizeInBytes;
#endif
        }
        public void Return(AllocatedMemoryData allocation)
        {
#if MEM_GUARD
#if MEM_GUARD_STACK
            allocation.FreedBy = Environment.StackTrace;
#endif
            ElectricFencedMemory.Free(allocation.Address);
#else
            if (allocation.Address != _ptrCurrent - allocation.SizeInBytes ||
                allocation.Address < _ptrStart)
            {
                if (_fragements == null)
                {
                    _fragements = new SortedList <long, AllocatedMemoryData>();
                }
                // we have fragmentation, let us try to heal it
                _fragements.Add((long)allocation.Address, allocation);
                return;
            }
            // since the returned allocation is at the end of the arena, we can just move
            // the pointer back
            _used       -= allocation.SizeInBytes;
            _ptrCurrent -= allocation.SizeInBytes;

            if (_fragements == null)
            {
                return;
            }

            // let us try to heal fragmentation at this point
            while (_fragements.Count > 0)
            {
                var highest = _fragements.Values[_fragements.Count - 1];
                if (highest.Address != _ptrCurrent - allocation.SizeInBytes)
                {
                    break;
                }
                _fragements.RemoveAt(_fragements.Count - 1);
                if (highest.Address < _ptrStart)
                {
                    // this is from another segment, probably, currently we'll just ignore it,
                    // we might want to track if all the memory from a previous segment has been
                    // released, and then free it, but not for now
                    continue;
                }
                _used       -= highest.SizeInBytes;
                _ptrCurrent -= highest.SizeInBytes;
            }
#endif
        }
Exemple #3
0
        public void Return(AllocatedMemoryData returned)
        {
#if MEM_GUARD
            ElectricFencedMemory.Free(returned.Address);
#else
            if (returned == null)
            {
                throw new ArgumentNullException(nameof(returned));
            }
            var index = GetIndexFromSize(returned.SizeInBytes);
            if (index == -1)
            {
                NativeMemory.Free(returned.Address, returned.SizeInBytes, returned.AllocatingThread);

                return; // strange size, just free it
            }
            _freeSegments[index].Push(returned);
#endif
        }