MCPcopy Create free account
hub / github.com/catboost/catboost / DefragmentMem

Function DefragmentMem

library/cpp/lfalloc/lf_allocX64.h:777–863  ·  view source on GitHub ↗

///////////////////////////////////////////////////////////////////// find free chunks and reset chunk size so they can be reused by different sized allocations do not look at blockFreeList (TFreeListGroup has same size for any allocations)

Source from the content-addressed store, hash-verified

775// find free chunks and reset chunk size so they can be reused by different sized allocations
776// do not look at blockFreeList (TFreeListGroup has same size for any allocations)
777static bool DefragmentMem() {
778 if (!EnableDefrag) {
779 return false;
780 }
781
782 IncrementCounter(CT_DEGRAGMENT_CNT, 1);
783
784 int* nFreeCount = (int*)SystemAlloc(N_CHUNKS * sizeof(int));
785 if (Y_UNLIKELY(!nFreeCount)) {
786 //__debugbreak();
787 NMalloc::AbortFromCorruptedAllocator("debugbreak");
788 }
789 memset(nFreeCount, 0, N_CHUNKS * sizeof(int));
790
791 TFreeListGroup* wholeLists[N_SIZES];
792 for (int nSizeIdx = 0; nSizeIdx < N_SIZES; ++nSizeIdx) {
793 wholeLists[nSizeIdx] = (TFreeListGroup*)globalFreeLists[nSizeIdx].GetWholeList();
794 for (TFreeListGroup* g = wholeLists[nSizeIdx]; g; g = g->Next) {
795 for (auto pData : g->Ptrs) {
796 if (pData) {
797 uintptr_t nChunk = (pData - ALLOC_START) / N_CHUNK_SIZE;
798 ++nFreeCount[nChunk];
799 Y_ASSERT_NOBT(chunkSizeIdx[nChunk] == nSizeIdx);
800 }
801 }
802 }
803 }
804
805 bool bRes = false;
806 for (size_t nChunk = 0; nChunk < N_CHUNKS; ++nChunk) {
807 int fc = nFreeCount[nChunk];
808 nFreeCount[nChunk] = 0;
809 if (chunkSizeIdx[nChunk] <= 0)
810 continue;
811 int nEntries = N_CHUNK_SIZE / nSizeIdxToSize[static_cast<int>(chunkSizeIdx[nChunk])];
812 Y_ASSERT_NOBT(fc <= nEntries); // can not have more free blocks then total count
813 if (fc == nEntries) {
814 bRes = true;
815 nFreeCount[nChunk] = 1;
816 }
817 }
818 if (bRes) {
819 for (auto& wholeList : wholeLists) {
820 TFreeListGroup** ppPtr = &wholeList;
821 while (*ppPtr) {
822 TFreeListGroup* g = *ppPtr;
823 int dst = 0;
824 for (auto pData : g->Ptrs) {
825 if (pData) {
826 uintptr_t nChunk = (pData - ALLOC_START) / N_CHUNK_SIZE;
827 if (nFreeCount[nChunk] == 0)
828 g->Ptrs[dst++] = pData; // block is not freed, keep pointer
829 }
830 }
831 if (dst == 0) {
832 // no valid pointers in group, free it
833 *ppPtr = g->Next;
834 blockFreeList.Free(g);

Callers 1

SlowLFAllocFunction · 0.85

Calls 8

IncrementCounterFunction · 0.85
SystemAllocFunction · 0.85
AddFreeChunkFunction · 0.85
SystemFreeFunction · 0.85
GetWholeListMethod · 0.80
ReturnWholeListMethod · 0.80
FreeMethod · 0.45

Tested by

no test coverage detected