diff --git a/src/lib/test/tracking-allocator.cpp b/src/lib/test/tracking-allocator.cpp index 08fee70a9..a4fe83383 100644 --- a/src/lib/test/tracking-allocator.cpp +++ b/src/lib/test/tracking-allocator.cpp @@ -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 diff --git a/src/lib/test/tracking-allocator.hpp b/src/lib/test/tracking-allocator.hpp index 9c20c5113..8e5a6f2c0 100644 --- a/src/lib/test/tracking-allocator.hpp +++ b/src/lib/test/tracking-allocator.hpp @@ -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); diff --git a/tests/library/test/test-tracking-test.cpp b/tests/library/test/test-tracking-test.cpp index 05f97b2ad..1483708bb 100644 --- a/tests/library/test/test-tracking-test.cpp +++ b/tests/library/test/test-tracking-test.cpp @@ -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───╼━━━━━━━━━━━━━━━━━╾────────"< + + + + + + + + + + +

+ Ich habe nun beschlossen, sie zu bilden als Produkt +

+
    +
  • + interne laufende ID der Allokation +
  • +
  • + nominelle Größe der Basis-Allokation +
  • +
+ + +
+
+
@@ -83632,8 +83658,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
verwende die Speicheradresse direkt als Hash-Wert; muß dazu eine Hasher-Funktion implementieren und in den Typ der Hashtable aufnehmen

- - +