Library: verify fundamental properties of TrackingAllocator
* implement some further statistic and diagnostic helpers * explicitly create and discard a base allocation for test
This commit is contained in:
parent
32bea9521b
commit
be3cf61111
4 changed files with 118 additions and 11 deletions
|
|
@ -96,6 +96,8 @@ namespace test{
|
|||
Allocation& addAlloc (size_t bytes);
|
||||
void discardAlloc (void* loc, size_t);
|
||||
|
||||
Allocation const* findAlloc (Location) const;
|
||||
|
||||
HashVal getChecksum() const;
|
||||
size_t getAllocationCnt() const;
|
||||
size_t calcAllocSize() const;
|
||||
|
|
@ -150,7 +152,7 @@ namespace test{
|
|||
PoolHandle
|
||||
PoolRegistry::fetch_or_create (Literal poolID)
|
||||
{
|
||||
auto entry = pools_[poolID];
|
||||
auto& entry = pools_[poolID];
|
||||
auto handle = entry.lock();
|
||||
if (handle) return handle;
|
||||
|
||||
|
|
@ -183,7 +185,7 @@ namespace test{
|
|||
}
|
||||
|
||||
void
|
||||
TrackingAllocator::deallocate (void* loc, size_t cnt) noexcept
|
||||
TrackingAllocator::deallocate (Location loc, size_t cnt) noexcept
|
||||
{
|
||||
ENSURE (mem_);
|
||||
mem_->discardAlloc (loc, cnt);
|
||||
|
|
@ -204,23 +206,31 @@ namespace test{
|
|||
}
|
||||
|
||||
void
|
||||
MemoryPool::discardAlloc (void* loc, size_t bytes)
|
||||
MemoryPool::discardAlloc (Location loc, size_t bytes)
|
||||
{
|
||||
if (contains (allocs_, loc))
|
||||
{
|
||||
auto& entry = allocs_[loc];
|
||||
ASSERT (entry.buff);
|
||||
ASSERT (entry.buff.front() == loc);
|
||||
if (entry.buff.size() != bytes)
|
||||
logAlarm ("SizeMismatch", entry.entryID, bytes, showAddr(loc));
|
||||
if (entry.buff.size() != bytes) // *deliberately* tolerating wrong data
|
||||
logAlarm ("SizeMismatch", entry.entryID, bytes, showAddr(loc)); // but log as incident to support diagnostics
|
||||
logAlloc (poolID_, "deallocate", entry.entryID, bytes, showAddr(loc));
|
||||
checksum_ -= entryNr_ * bytes;
|
||||
checksum_ -= entryNr_ * bytes; // Note: using the given size (if wrong ⟿ checksum mismatch)
|
||||
allocs_.erase(loc);
|
||||
}
|
||||
else // deliberately no exception here (for better diagnostics)
|
||||
logAlarm ("FreeUnknown", bytes, showAddr(loc));
|
||||
}
|
||||
|
||||
MemoryPool::Allocation const*
|
||||
MemoryPool::findAlloc (Location loc) const
|
||||
{
|
||||
return contains (allocs_, loc)? & allocs_.at(loc)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
|
||||
HashVal
|
||||
MemoryPool::getChecksum() const
|
||||
{
|
||||
|
|
@ -256,6 +266,14 @@ namespace test{
|
|||
return pool->getChecksum();
|
||||
}
|
||||
|
||||
/** determine number of active front-end handles */
|
||||
size_t
|
||||
TrackingAllocator::use_count (Literal poolID)
|
||||
{
|
||||
PoolHandle pool = PoolRegistry::locate (poolID);
|
||||
return pool.use_count() - 1;
|
||||
}
|
||||
|
||||
/** get allocation count for mem-pool */
|
||||
size_t
|
||||
TrackingAllocator::numAlloc (Literal poolID)
|
||||
|
|
@ -272,7 +290,32 @@ namespace test{
|
|||
return pool->calcAllocSize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** probe if this allocator pool did allocate the given memory location */
|
||||
bool
|
||||
TrackingAllocator::manages (Location memLoc) const
|
||||
{
|
||||
return bool(mem_->findAlloc (memLoc));
|
||||
}
|
||||
|
||||
/** retrieve the registered size of this allocation, if known. */
|
||||
size_t
|
||||
TrackingAllocator::getSize(Location memLoc) const
|
||||
{
|
||||
auto* entry = mem_->findAlloc (memLoc);
|
||||
return entry? entry->buff.size()
|
||||
: 0;
|
||||
}
|
||||
|
||||
/** retrieve the internal registration ID for this allocation. */
|
||||
HashVal
|
||||
TrackingAllocator::getID (Location memLoc) const
|
||||
{
|
||||
auto* entry = mem_->findAlloc (memLoc);
|
||||
return entry? entry->entryID
|
||||
: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace lib::test
|
||||
|
|
|
|||
|
|
@ -73,9 +73,10 @@ namespace test {
|
|||
|
||||
// standard copy operations acceptable
|
||||
|
||||
using Location = void*;
|
||||
|
||||
[[nodiscard]] void* allocate (size_t n);
|
||||
void deallocate (void*, size_t =0) noexcept;
|
||||
[[nodiscard]] Location allocate (size_t n);
|
||||
void deallocate (Location, size_t =0) noexcept;
|
||||
|
||||
|
||||
friend bool
|
||||
|
|
@ -92,7 +93,12 @@ namespace test {
|
|||
|
||||
/* ===== Diagnostics ===== */
|
||||
|
||||
bool manages (Location) const;
|
||||
size_t getSize(Location) const;
|
||||
HashVal getID (Location) const;
|
||||
|
||||
static HashVal checksum (Literal pool =GLOBAL);
|
||||
static size_t use_count (Literal pool =GLOBAL);
|
||||
static size_t numAlloc (Literal pool =GLOBAL);
|
||||
static size_t numBytes (Literal pool =GLOBAL);
|
||||
|
||||
|
|
|
|||
|
|
@ -169,6 +169,32 @@ namespace test{
|
|||
Tracker::log.clear("Tracking-Allocator-Test");
|
||||
Tracker::log.joinInto(log);
|
||||
|
||||
CHECK (TrackingAllocator::checksum() == 0, "Testsuite is broken");
|
||||
CHECK (TrackingAllocator::use_count() == 0);
|
||||
{
|
||||
TrackingAllocator allo;
|
||||
CHECK (TrackingAllocator::use_count() == 1);
|
||||
CHECK (TrackingAllocator::numAlloc() == 0);
|
||||
CHECK (TrackingAllocator::numBytes() == 0);
|
||||
|
||||
void* mem = allo.allocate (55);
|
||||
CHECK (TrackingAllocator::numAlloc() == 1);
|
||||
CHECK (TrackingAllocator::numBytes() == 55);
|
||||
|
||||
CHECK (allo.manages (mem));
|
||||
CHECK (allo.getSize (mem) == 55);
|
||||
HashVal memID = allo.getID (mem);
|
||||
CHECK (0 < memID);
|
||||
CHECK (TrackingAllocator::checksum() == memID*55);
|
||||
|
||||
allo.deallocate (mem, 42); // note: passing a wrong number here is marked as ERROR in the log
|
||||
CHECK (not allo.manages (mem));
|
||||
CHECK (allo.getSize (mem) == 0);
|
||||
CHECK (allo.getID (mem) == 0);
|
||||
CHECK (TrackingAllocator::use_count() == 1);
|
||||
CHECK (TrackingAllocator::numAlloc() == 0);
|
||||
CHECK (TrackingAllocator::numBytes() == 0);
|
||||
}
|
||||
|
||||
CHECK (TrackingAllocator::checksum() == 0);
|
||||
{
|
||||
|
|
@ -191,6 +217,13 @@ SHOW_EXPR(join(vec2))
|
|||
cout << "____Tracking-Allo-Log_________\n"
|
||||
<< util::join(Tracker::log, "\n")
|
||||
<< "\n───╼━━━━━━━━━━━━━━━━━╾────────"<<endl;
|
||||
|
||||
CHECK (log.verify("EventLogHeader").on("Tracking-Allocator-Test")
|
||||
.before("logJoin")
|
||||
.beforeCall("allocate").on(GLOBAL).argPos(1, 55)
|
||||
.beforeEvent("error", "SizeMismatch")
|
||||
.beforeCall("deallocate").on(GLOBAL).argPos(1, 42)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -83558,6 +83558,32 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node COLOR="#435e98" CREATED="1718486596443" ID="ID_1250015263" MODIFIED="1718486605209" TEXT="verify checksum"/>
|
||||
</node>
|
||||
<node CREATED="1718462887129" ID="ID_1322153003" MODIFIED="1718462969529" TEXT="demonstrate_checkAllocator">
|
||||
<node COLOR="#338800" CREATED="1718544835454" ID="ID_264718265" MODIFIED="1718544844296" TEXT="Basis-Allocator testen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1718544845477" ID="ID_1456085342" MODIFIED="1718544875735" STYLE="fork" TEXT="Roh-Allokation belegen und freigeben"/>
|
||||
<node COLOR="#435e98" CREATED="1718544856802" ID="ID_657924298" MODIFIED="1718544875737" STYLE="fork" TEXT="Statistiken verifizieren"/>
|
||||
<node COLOR="#435e98" CREATED="1718544862722" ID="ID_506802563" MODIFIED="1718544934040" STYLE="fork" TEXT="Systematik der Checksumme dokumentieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Ich habe nun beschlossen, sie zu bilden als Produkt
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
interne laufende ID der Allokation
|
||||
</li>
|
||||
<li>
|
||||
nominelle Größe der Basis-Allokation
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1718492999206" ID="ID_94881308" MODIFIED="1718503992073" TEXT="Vector an den globalen Pool ankoppeln">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
|
|
@ -83632,8 +83658,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
verwende die Speicheradresse direkt als Hash-Wert; muß dazu eine Hasher-Funktion implementieren und in den Typ der Hashtable aufnehmen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1718494864443" ID="ID_1936586349" MODIFIED="1718501206051" TEXT="Allokation belegen und freigeben">
|
||||
|
|
|
|||
Loading…
Reference in a new issue