Example #1
0
        private void UnlikelyEnsureSingleChunk(out byte *ptr, out int size)
        {
            // we are using multiple segments, but the current one can fit all
            // the required memory
            if (_head.Allocation.SizeInBytes - _head.Used > SizeInBytes)
            {
                CopyTo(_head.Address + _head.Used);
                // we need to fit in the beginning of the chunk, so we must move it backward.
                UnmanagedMemory.Move(_head.Address, _head.Address + _head.Used, SizeInBytes);

                ptr        = _head.Address;
                size       = SizeInBytes;
                _head.Used = SizeInBytes;
                // Ensure we are thought of as a single chunk
                _head.Previous = null;
                return;
            }

            var totalSize = SizeInBytes;

            // We might need to allocate, but we don't want to allocate the usual power of 2 * 3
            // because we know _exactly_ what we need
            using (_context.AvoidOverAllocation())
            {
                // If we are here, then we have multiple chunks, we can't
                // allow a growth of the last chunk, since we'll by copying over it
                // so we force a whole new chunk
                AllocateNextSegment(totalSize, false);
            }

            // Go back in time to before we had the last chunk
            var realHead = _head;

            _head = realHead.Previous;

            // Copy all of the data structure into the new chunk's memory
            CopyTo(realHead.Address);
            realHead.Used = totalSize;
            realHead.AccumulatedSizeInBytes = totalSize;

            // Back to the future!
            _head = realHead;

            // Ensure we are thought of as a single chunk
            _head.Previous = null;

            ptr  = _head.Address;
            size = _head.Used;
        }