public void Free(byte *ptr)
        {
            var header = (BlockHeader *)(ptr - BlockHeader.SIZE);

            _blockPool.Push(header->BlockIndex);
            header->Invalidate();
            Interlocked.Increment(ref _freeBlocks);
        }
示例#2
0
        public static void Free(byte *ptr, bool counterBased = false)
        {
            var header = ((BlockHeader *)(ptr - BlockHeader.SIZE));

            header->CheckCoherency();
            if (counterBased)
            {
                // -------- Prevent a simultaneous same test on the same pointer
                lock (_freeLocker)
                    if (header->ReferenceCount > 1)
                    {
                        Interlocked.Decrement(ref header->ReferenceCount);
                        return;
                    }
            }
            int mem     = -1;
            int ptrSize = header->PtrSize;

            // -------- Reduced contention with minimal instructions count
            lock (_locker) {
                int idx = (int)header->SegmentIndex;
                _segments[idx].Free(ptr);
                if (_segments[idx].NoAllocatedBlocks)
                {
                    // -------- Todo : Faire en sorte qu'on garde au moins un segment de chaque taille
                    _segments[idx].Dispose(out mem);
                    _pool.Push(idx);
                }
                else
                {
                    var q = _pool.GetEntryQueue(idx);
                    if (q % 2 != 0)
                    {
                        _pool.Enqueue(idx, q - 1);
                    }
                }
            }
            // -------- Update statistics
            Interlocked.Add(ref _totalMemory, -ptrSize);
            Interlocked.Decrement(ref _totalBlockCount);
            if (mem != -1)
            {
                Interlocked.Add(ref _totalBufferSpace, -mem);
                Interlocked.Decrement(ref _totalSegmentCount);
            }
        }