| 1587 | } |
| 1588 | |
| 1589 | static Y_FORCE_INLINE void LFFree(void* p) { |
| 1590 | #if defined(LFALLOC_DBG) |
| 1591 | if (p == nullptr) |
| 1592 | return; |
| 1593 | p = GetOrigAllocHeader(p); |
| 1594 | #endif |
| 1595 | |
| 1596 | uintptr_t chkOffset = ((char*)p - ALLOC_START) - 1ll; |
| 1597 | if (chkOffset >= N_MAX_WORKSET_SIZE) { |
| 1598 | if (p == nullptr) |
| 1599 | return; |
| 1600 | #if defined(LFALLOC_DBG) |
| 1601 | TrackDeallocation(p, N_SIZES); |
| 1602 | #endif |
| 1603 | LargeBlockFree(p, CT_LARGE_FREE); |
| 1604 | return; |
| 1605 | } |
| 1606 | |
| 1607 | uintptr_t chunk = ((char*)p - ALLOC_START) / N_CHUNK_SIZE; |
| 1608 | ptrdiff_t nSizeIdx = chunkSizeIdx[chunk]; |
| 1609 | if (nSizeIdx <= 0) { |
| 1610 | #if defined(LFALLOC_DBG) |
| 1611 | TrackDeallocation(p, N_SIZES); |
| 1612 | #endif |
| 1613 | LargeBlockFree(p, CT_LARGE_FREE); |
| 1614 | return; |
| 1615 | } |
| 1616 | |
| 1617 | #if defined(LFALLOC_DBG) |
| 1618 | TrackDeallocation(p, nSizeIdx); |
| 1619 | #endif |
| 1620 | |
| 1621 | #ifdef DBG_FILL_MEMORY |
| 1622 | memset(p, 0xfe, nSizeIdxToSize[nSizeIdx]); |
| 1623 | #endif |
| 1624 | |
| 1625 | IncrementCounter(CT_SMALL_FREE, nSizeIdxToSize[nSizeIdx]); |
| 1626 | |
| 1627 | // try to store info to per thread buf |
| 1628 | TThreadAllocInfo* thr = pThreadInfo; |
| 1629 | if (thr) { |
| 1630 | int& freePtrIdx = thr->FreePtrIndex[nSizeIdx]; |
| 1631 | if (freePtrIdx > borderSizes[nSizeIdx]) { |
| 1632 | thr->FreePtrs[nSizeIdx][--freePtrIdx] = (char*)p; |
| 1633 | return; |
| 1634 | } |
| 1635 | |
| 1636 | // move several pointers to global free list |
| 1637 | int freeCount = FL_GROUP_SIZE; |
| 1638 | if (freeCount > THREAD_BUF - freePtrIdx) |
| 1639 | freeCount = THREAD_BUF - freePtrIdx; |
| 1640 | char** freePtrs = thr->FreePtrs[nSizeIdx]; |
| 1641 | PutBlocksToGlobalFreeList(nSizeIdx, freePtrs + freePtrIdx, freeCount); |
| 1642 | freePtrIdx += freeCount; |
| 1643 | |
| 1644 | freePtrs[--freePtrIdx] = (char*)p; |
| 1645 | |
| 1646 | } else { |
no test coverage detected