Skip to content

Commit 0705ef4

Browse files
committed
Added some debugging code to track possible issues with large allocations being treated as small allocations
1 parent 38c49a1 commit 0705ef4

2 files changed

Lines changed: 70 additions & 8 deletions

File tree

include/vsg/core/IntrusiveAllocator.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@ namespace vsg
6464
size_t totalMemorySize() const override;
6565
void setBlockSize(AllocatorAffinity allocatorAffinity, size_t blockSize) override;
6666

67+
size_t num_zero_allocations = 0;
68+
size_t num_nullptr_deallocations = 0;
69+
size_t num_small_allocations = 0;
70+
size_t num_large_allocations = 0;
71+
size_t num_small_deallocations = 0;
72+
size_t num_large_deallocations = 0;
73+
size_t num_poor_large_deallocation_checks = 0;
74+
size_t num_no_deallocations = 0;
75+
size_t num_erroneous_large_deallocations = 0;
76+
6777
protected:
6878
struct VSG_DECLSPEC MemoryBlock
6979
{

src/vsg/core/IntrusiveAllocator.cpp

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ void IntrusiveAllocator::MemoryBlock::SlotTester::report(std::ostream& out)
270270
}
271271
}
272272

273-
bool IntrusiveAllocator::MemoryBlock::deallocate(void* ptr, std::size_t /*size*/)
273+
bool IntrusiveAllocator::MemoryBlock::deallocate(void* ptr, std::size_t in_size)
274274
{
275275
if (within(ptr))
276276
{
@@ -524,9 +524,9 @@ bool IntrusiveAllocator::MemoryBlock::deallocate(void* ptr, std::size_t /*size*/
524524
return true;
525525
}
526526

527-
#if DEBUG_ALLOCATOR
528-
std::cout << "IntrusiveAllocator::MemoryBlock::deallocate((" << ptr << ", " << size << ") OUTWITH block : " << this << std::endl;
529-
#endif
527+
// #if DEBUG_ALLOCATOR
528+
std::cout << "IntrusiveAllocator::MemoryBlock::deallocate((" << ptr << ", " << in_size << ") OUTWITH block : " << this << std::endl;
529+
// #endif
530530

531531
return false;
532532
}
@@ -872,6 +872,16 @@ IntrusiveAllocator::IntrusiveAllocator(std::unique_ptr<Allocator> in_nestedAlloc
872872

873873
IntrusiveAllocator::~IntrusiveAllocator()
874874
{
875+
std::cout<<"IntrusiveAllocator::~IntrusiveAllocator()"<<std::endl;
876+
std::cout<<" num_zero_allocations "<<num_zero_allocations<<std::endl;
877+
std::cout<<" num_nullptr_deallocations "<<num_nullptr_deallocations<<std::endl;
878+
std::cout<<" num_small_allocations "<<num_small_allocations<<std::endl;
879+
std::cout<<" num_large_allocations "<<num_large_allocations<<std::endl;
880+
std::cout<<" num_small_deallocations "<<num_small_deallocations<<std::endl;
881+
std::cout<<" num_large_deallocations "<<num_large_deallocations<<std::endl;
882+
std::cout<<" num_poor_large_deallocation_checks "<<num_poor_large_deallocation_checks<<std::endl;
883+
std::cout<<" num_no_deallocations "<<num_no_deallocations<<std::endl;
884+
std::cout<<" num_erroneous_large_deallocations "<<num_erroneous_large_deallocations<<std::endl;
875885
}
876886

877887
void IntrusiveAllocator::setBlockSize(AllocatorAffinity allocatorAffinity, size_t blockSize)
@@ -907,6 +917,12 @@ void* IntrusiveAllocator::allocate(std::size_t size, AllocatorAffinity allocator
907917
{
908918
std::scoped_lock<std::mutex> lock(mutex);
909919

920+
if (size==0)
921+
{
922+
++num_zero_allocations;
923+
return nullptr;
924+
}
925+
910926
// create a MemoryBlocks entry if one doesn't already exist
911927
if (allocatorAffinity > allocatorMemoryBlocks.size())
912928
{
@@ -923,18 +939,30 @@ void* IntrusiveAllocator::allocate(std::size_t size, AllocatorAffinity allocator
923939
if (size <= blocks->maximumAllocationSize)
924940
{
925941
ptr = blocks->allocate(size);
926-
if (ptr) return ptr;
942+
if (ptr)
943+
{
944+
++num_small_allocations;
945+
return ptr;
946+
}
927947
//std::cout<<"IntrusiveAllocator::allocate() Failed to allocator memory from memoryBlocks "<<blocks.get()<<std::endl;
928948
}
929949

930950
ptr = operator new(size, std::align_val_t{blocks->alignment});
931-
if (ptr) largeAllocations[ptr] = std::pair<size_t, size_t>(blocks->alignment, size);
951+
if (ptr)
952+
{
953+
largeAllocations[ptr] = std::pair<size_t, size_t>(blocks->alignment, size);
954+
++num_large_allocations;
955+
}
932956
//std::cout<<"IntrusiveAllocator::allocate() MemoryBlocks aligned large allocation = "<<ptr<<" with size = "<<size<<", alignment = "<<blocks->alignment<<" blocks->maximumAllocationSize = "<<blocks->maximumAllocationSize<<std::endl;
933957
return ptr;
934958
}
935959

936960
ptr = operator new(size, std::align_val_t{defaultAlignment});
937-
if (ptr) largeAllocations[ptr] = std::pair<size_t, size_t>(defaultAlignment, size);
961+
if (ptr)
962+
{
963+
largeAllocations[ptr] = std::pair<size_t, size_t>(defaultAlignment, size);
964+
++num_large_allocations;
965+
}
938966
//std::cout<<"IntrusiveAllocator::allocate() default aligned large allocation = "<<ptr<<" with size = "<<size<<", alignment = "<<defaultAlignment<<std::endl;
939967
return ptr;
940968
}
@@ -943,45 +971,67 @@ bool IntrusiveAllocator::deallocate(void* ptr, std::size_t size)
943971
{
944972
std::scoped_lock<std::mutex> lock(mutex);
945973

974+
if (ptr==nullptr)
975+
{
976+
++num_nullptr_deallocations;
977+
return true;
978+
}
979+
980+
auto la_itr = largeAllocations.find(ptr);
981+
bool largeAllocation = (la_itr != largeAllocations.end());
982+
946983
if (memoryBlocks.empty()) return false;
947984

948985
auto itr = memoryBlocks.upper_bound(ptr);
949986
if (itr != memoryBlocks.end())
950987
{
988+
951989
if (itr != memoryBlocks.begin())
952990
{
991+
953992
--itr;
954993
auto& block = itr->second;
955994
if (block->deallocate(ptr, size))
956995
{
996+
if (largeAllocation) { ++num_erroneous_large_deallocations; warn("A largeAllocation flagged as being in MemoryBlock"); return false; }
997+
else ++num_small_deallocations;
957998
return true;
958999
}
1000+
if (largeAllocation) { ++num_poor_large_deallocation_checks; info("B largeAllocation not flagged as being in MemoryBlock"); }
9591001
}
9601002
else
9611003
{
9621004
auto& block = itr->second;
9631005
if (block->deallocate(ptr, size))
9641006
{
1007+
if (largeAllocation) { ++num_erroneous_large_deallocations; warn("C largeAllocation flagged as being in MemoryBlock"); return false; }
1008+
else ++num_small_deallocations;
9651009
return true;
9661010
}
1011+
if (largeAllocation) { ++num_poor_large_deallocation_checks; info("D largeAllocation not flagged as being in MemoryBlock."); }
9671012
}
9681013
}
9691014
else
9701015
{
9711016
auto& block = memoryBlocks.rbegin()->second;
9721017
if (block->deallocate(ptr, size))
9731018
{
1019+
if (largeAllocation) { ++num_erroneous_large_deallocations; warn("E largeAllocation flagged as being in MemoryBlock"); return false; }
1020+
else ++num_small_deallocations;
9741021
return true;
9751022
}
1023+
if (largeAllocation) { ++num_poor_large_deallocation_checks; info("F largeAllocation not flagged as being in MemoryBlock."); }
9761024
}
9771025

978-
auto la_itr = largeAllocations.find(ptr);
1026+
//auto la_itr = largeAllocations.find(ptr);
9791027
if (la_itr != largeAllocations.end())
9801028
{
9811029
// large allocation;
9821030
// std::cout<<"IntrusiveAllocator::deallocate("<<ptr<<") deleting large allocation."<<std::endl;
9831031
operator delete(ptr, std::align_val_t{la_itr->second.first});
9841032
largeAllocations.erase(la_itr);
1033+
1034+
++num_large_deallocations;
9851035
return true;
9861036
}
9871037

@@ -990,6 +1040,8 @@ bool IntrusiveAllocator::deallocate(void* ptr, std::size_t size)
9901040
return true;
9911041
}
9921042

1043+
++num_no_deallocations;
1044+
9931045
return false;
9941046
}
9951047

0 commit comments

Comments
 (0)