public void Free(byte *ptr) { var header = (BlockHeader *)(ptr - BlockHeader.SIZE); _blockPool.Push(header->BlockIndex); header->Invalidate(); Interlocked.Increment(ref _freeBlocks); }
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); } }