public byte *Malloc(int size, bool counterBased)
        {
            int idx    = _blockPool.Pop();
            var ptr    = &_data[idx * _physicalBlockSize];
            var header = (BlockHeader *)ptr;

            header->BlockIndex     = idx;
            header->PtrSize        = size;
            header->BlocksSize     = _blocksSize;
            header->SegmentIndex   = _segmentIndex;
            header->ReferenceCount = counterBased ? 1 : 0;
            Interlocked.Decrement(ref _freeBlocks);
            return(ptr + BlockHeader.SIZE);
        }
예제 #2
0
        // ****************************************************************************************** //
        // ********** STATISTICS
        public static byte *New(int size, bool counterBased = false, bool overSized = false)
        {
            byte *ptr = null;
            int   q   = SizeToQueue(size + (overSized ? size * 2 : 0));
            int   mem = -1;

            // -------- Reduced contention with minimal instructions count
            lock (_locker) {
                int idx = _pool.FirstOfQueue(q);
                if (idx == -1)
                {
                    idx = _pool.Pop();
                    _pool.Enqueue(idx, q);
                    int segsSize   = 0;
                    int blocksSize = 0;
                    SizeToSegmentProperties(size + (overSized ? size * 2 : 0), out segsSize, out blocksSize);
                    _segments[idx].Build(segsSize, blocksSize, idx, out mem);
                    ptr = _segments[idx].Malloc(size, counterBased);
                }
                else
                {
                    ptr = _segments[idx].Malloc(size, counterBased);
                    if (_segments[idx].FreeBlocks == 0)
                    {
                        _pool.Enqueue(idx, q + 1);
                    }
                }
            }
            // -------- Update statistics
            Interlocked.Add(ref _totalMemory, size);
            Interlocked.Increment(ref _totalBlockCount);
            if (mem != -1)
            {
                Interlocked.Add(ref _totalBufferSpace, mem);
                Interlocked.Increment(ref _totalSegmentCount);
            }
            return(ptr);
        }