Library: get the simple testcase to work

- create two vectors, attached to the `TrackingAllocator`
- emplace Tracker-Objects
- move an object to the other vector
- destroy the containers

🠲 Event-Log looks plausible!
This commit is contained in:
Fischlurch 2024-06-16 03:22:32 +02:00
parent a3fb6f46ed
commit 32bea9521b
3 changed files with 120 additions and 110 deletions

View file

@ -35,6 +35,7 @@
//#include "lib/format-string.hpp"
//#include "lib/format-cout.hpp"
//#include "lib/unique-malloc-owner.hpp"
#include "lib/iter-explorer.hpp"
#include "lib/depend.hpp"
#include "lib/uninitialised-storage.hpp"
#include "lib/util.hpp"
@ -49,6 +50,7 @@ using std::make_pair;
//using std::string;
using util::contains;
using util::joinDash;
using util::showAddr;
namespace lib {
namespace test{
@ -72,22 +74,31 @@ namespace test{
: util::MoveOnly
{
UninitialisedDynBlock<byte> buff{};
size_t entryID;
};
using AllocTab = std::unordered_map<const Location, Allocation, LocationHash>;
Literal poolID_;
AllocTab allocs_{};
AllocTab allocs_;
HashVal checksum_;
size_t entryNr_;
public:
MemoryPool (Literal id)
: poolID_{id}
, allocs_{}
, checksum_{0}
, entryNr_{0}
{ }
Allocation& addAlloc (size_t bytes);
void discardAlloc (void* loc);
void discardAlloc (void* loc, size_t);
HashVal getChecksum() const;
size_t getAllocationCnt() const;
size_t calcAllocSize() const;
};
@ -164,15 +175,18 @@ namespace test{
void*
TrackingAllocator::allocate (size_t n)
TrackingAllocator::allocate (size_t cnt)
{
UNIMPLEMENTED ("allocate memory block of size n");
ENSURE (mem_);
return mem_->addAlloc (cnt)
.buff.front();
}
void
TrackingAllocator::deallocate (void* loc) noexcept
TrackingAllocator::deallocate (void* loc, size_t cnt) noexcept
{
UNIMPLEMENTED ("allocate memory block of size n");
ENSURE (mem_);
mem_->discardAlloc (loc, cnt);
}
MemoryPool::Allocation&
@ -182,24 +196,49 @@ namespace test{
newAlloc.buff.allocate (bytes);
Location loc = newAlloc.buff.front();
ASSERT (not contains (allocs_, loc));
logAlloc (poolID_, "allocate", bytes, loc);
newAlloc.entryID = ++entryNr_;
logAlloc (poolID_, "allocate", entryNr_, bytes, showAddr(loc));
checksum_ += entryNr_ * bytes;
return allocs_.emplace (loc, move(newAlloc))
.first->second;
}
void
MemoryPool::discardAlloc (void* loc)
MemoryPool::discardAlloc (void* loc, size_t bytes)
{
if (contains (allocs_, loc))
{
auto& entry = allocs_[loc];
ASSERT (entry.buff);
ASSERT (entry.buff.front() == loc);
logAlloc (poolID_, "deallocate", entry.buff.size());
if (entry.buff.size() != bytes)
logAlarm ("SizeMismatch", entry.entryID, bytes, showAddr(loc));
logAlloc (poolID_, "deallocate", entry.entryID, bytes, showAddr(loc));
checksum_ -= entryNr_ * bytes;
allocs_.erase(loc);
}
else // deliberately no exception here (for better diagnostics)
logAlarm("FreeUnknown", loc);
logAlarm ("FreeUnknown", bytes, showAddr(loc));
}
HashVal
MemoryPool::getChecksum() const
{
return checksum_;
}
size_t
MemoryPool::getAllocationCnt() const
{
return allocs_.size();
}
size_t
MemoryPool::calcAllocSize() const
{
return explore(allocs_)
.transform ([](auto& it){ return it->second.buff.size(); })
.resultSum();
}
@ -209,22 +248,28 @@ namespace test{
EventLog TrackingAllocator::log{"test::TrackingAllocator"};
/** get Checksum for mem-pool */
HashVal
TrackingAllocator::checksum (Literal pool)
TrackingAllocator::checksum (Literal poolID)
{
UNIMPLEMENTED ("get Checksum for mem-pool");
PoolHandle pool = PoolRegistry::locate (poolID);
return pool->getChecksum();
}
/** get allocation count for mem-pool */
size_t
TrackingAllocator::numAlloc (Literal pool)
TrackingAllocator::numAlloc (Literal poolID)
{
UNIMPLEMENTED ("get allocation count for mem-pool");
PoolHandle pool = PoolRegistry::locate (poolID);
return pool->getAllocationCnt();
}
/** calculate currently allotted Bytes for mem-pool */
size_t
TrackingAllocator::numBytes (Literal pool)
TrackingAllocator::numBytes (Literal poolID)
{
UNIMPLEMENTED ("calc allotted Bytes for mem-pool");
PoolHandle pool = PoolRegistry::locate (poolID);
return pool->calcAllocSize();
}

View file

@ -75,7 +75,7 @@ namespace test {
[[nodiscard]] void* allocate (size_t n);
void deallocate (void*) noexcept;
void deallocate (void*, size_t =0) noexcept;
friend bool
@ -130,7 +130,7 @@ namespace test {
TY*
TrackAlloc<TY>::allocate (size_t cnt)
{
UNIMPLEMENTED ("type-sized alloc");
return static_cast<TY*> (TrackingAllocator::allocate (cnt * sizeof(TY)));
}
/**
@ -141,79 +141,9 @@ namespace test {
void
TrackAlloc<TY>::deallocate (TY* loc, size_t cnt) noexcept
{
UNIMPLEMENTED ("type-sized de-alloc");
TrackingAllocator::deallocate (loc, cnt * sizeof(TY));
}
/**
* Placeholder implementation for a custom allocator
* @todo shall be replaced by an AllocationCluster eventually
* @todo 5/2024 to be reworked and aligned with a prospective C++20 Allocator Concept /////////////////////TICKET #1366
* @remark using `std::list` container, since re-entrant allocation calls are possible,
* meaning that further allocations will be requested recursively from a ctor.
* Moreover, for the same reason we separate the allocation from the ctor call,
* so we can capture the address of the new allocation prior to any possible
* re-entrant call, and handle clean-up of allocation without requiring any
* additional state flags.....
*/
template<typename TY>
class AllocatorHandle
{
struct Allocation
{
alignas(TY)
std::byte buf_[sizeof(TY)];
template<typename...ARGS>
TY&
create (ARGS&& ...args)
{
return *new(&buf_) TY {std::forward<ARGS> (args)...};
}
TY&
access()
{
return * std::launder (reinterpret_cast<TY*> (&buf_));
}
void
discard() /// @warning strong assumption made here: Payload was created
{
access().~TY();
}
};
std::list<Allocation> storage_;
public:
template<typename...ARGS>
TY&
operator() (ARGS&& ...args)
{ // EX_STRONG
auto pos = storage_.emplace (storage_.end()); ////////////////////////////////////////////////////TICKET #230 : real implementation should care for concurrency here
try {
return pos->create (std::forward<ARGS> (args)...);
}
catch(...)
{
storage_.erase (pos); // EX_FREE
const char* errID = lumiera_error();
ERROR (memory, "Allocation failed with unknown exception. "
"Lumiera errorID=%s", errID?errID:"??");
throw;
}
}
/** @note need to do explicit clean-up, since a ctor-call might have been failed,
* and we have no simple way to record this fact internally in Allocation,
* short of wasting additional memory for a flag to mark this situation */
~AllocatorHandle()
try {
for (auto& alloc : storage_)
alloc.discard();
}
ERROR_LOG_AND_IGNORE (memory, "clean-up of custom AllocatorHandle")
};

View file

@ -83558,10 +83558,30 @@ Date:&#160;&#160;&#160;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 CREATED="1718492999206" ID="ID_94881308" MODIFIED="1718493015632" TEXT="Vector an den globalen Pool ankoppeln"/>
<node CREATED="1718493041125" ID="ID_1894747169" MODIFIED="1718493584012" TEXT="anderen Vector an einen privaten Pool ankoppeln"/>
<node CREATED="1718493020625" ID="ID_149523402" MODIFIED="1718493030293" TEXT="einige Dummy-Objekte einf&#xfc;gen"/>
<node CREATED="1718493068940" ID="ID_943352942" MODIFIED="1718493073781" TEXT="Statistiken pr&#xfc;fen"/>
<node COLOR="#338800" CREATED="1718492999206" ID="ID_94881308" MODIFIED="1718503992073" TEXT="Vector an den globalen Pool ankoppeln">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718493041125" ID="ID_1894747169" MODIFIED="1718503990629" TEXT="anderen Vector an einen privaten Pool ankoppeln">
<icon BUILTIN="flag-yellow"/>
</node>
<node COLOR="#338800" CREATED="1718493020625" ID="ID_149523402" MODIFIED="1718503980986" TEXT="einige Dummy-Objekte einf&#xfc;gen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1718503970700" ID="ID_134542786" MODIFIED="1718503977643" TEXT="ein Dummy-Objekt verschieben">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718493068940" ID="ID_943352942" MODIFIED="1718504000321" TEXT="Statistiken pr&#xfc;fen">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718503984658" ID="ID_700056398" MODIFIED="1718504040854" TEXT="Checksumme plausibel">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718504012333" ID="ID_1666449875" MODIFIED="1718504029760" TEXT="Log auswerten">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1718504043109" ID="ID_755264460" MODIFIED="1718504064399" TEXT="1.Wurf &#x27f6; sieht korrekt aus">
<icon BUILTIN="ksmiletris"/>
</node>
</node>
</node>
</node>
</node>
@ -83587,17 +83607,26 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node COLOR="#338800" CREATED="1718489717485" ID="ID_1890743066" MODIFIED="1718501225010" TEXT="das Front-End ist ein verpackter Shared-Ptr">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1718491430872" ID="ID_146190908" MODIFIED="1718491450055" TEXT="brauche eine getypte Sub-Klasse als Standard-Allocator(Adapter)">
<node CREATED="1718491670798" ID="ID_846381324" MODIFIED="1718491676634" TEXT="Name: TrackAlloc&lt;TY&gt;"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718494826583" ID="ID_721892573" MODIFIED="1718494833802" TEXT="delegierende impl">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1718491430872" ID="ID_146190908" MODIFIED="1718503926202" TEXT="brauche eine getypte Sub-Klasse als Standard-Allocator(Adapter)">
<icon BUILTIN="yes"/>
<node COLOR="#338800" CREATED="1718491670798" ID="ID_846381324" MODIFIED="1718503946639">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
Name: <font face="Monospaced"><b>TrackAlloc&lt;TY&gt;</b></font>
</p>
</body>
</html></richcontent>
<icon BUILTIN="forward"/>
</node>
<node COLOR="#338800" CREATED="1718494826583" ID="ID_721892573" MODIFIED="1718503929924" TEXT="delegierende impl">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1718494843824" ID="ID_15578546" MODIFIED="1718501419835" TEXT="MemoryPool f&#xfc;hrt eine Hashtable aller Allokationen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
verwende die Speicheradresse direkt als Hash-Wert; mu&#223; dazu eine Hasher-Funktion implementieren und in den Typ der Hashtable aufnehmen
@ -83609,12 +83638,18 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node COLOR="#338800" CREATED="1718494864443" ID="ID_1936586349" MODIFIED="1718501206051" TEXT="Allokation belegen und freigeben">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1718503846862" ID="ID_1256627112" MODIFIED="1718503888673" TEXT="vergebe jeder Allokation eine laufende ID-Nummer">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1718503865225" ID="ID_1057103832" MODIFIED="1718503893272" TEXT="au&#xdf;erdem kennt sie auch ihre eigene Gr&#xf6;&#xdf;e (UninitialisedDynBlock)">
<icon BUILTIN="idea"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718489730263" ID="ID_5464621" MODIFIED="1718494857263" TEXT="der MemoryPool verwendet Mutex-Locking">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1718494880219" ID="ID_1016934813" MODIFIED="1718496931942" TEXT="Meta-Registry aller Pools">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1718494880219" ID="ID_1016934813" MODIFIED="1718503899936" TEXT="Meta-Registry aller Pools">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1718496910802" ID="ID_7557345" MODIFIED="1718496918116" TEXT="statischer (Singleton)-Zugang">
<icon BUILTIN="button_ok"/>
</node>
@ -83626,8 +83661,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718494895881" ID="ID_1075022808" MODIFIED="1718494905847" TEXT="Zugriff auf Pool &#xfc;ber den Namen">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1718494895881" ID="ID_1075022808" MODIFIED="1718503904931" TEXT="Zugriff auf Pool &#xfc;ber den Namen">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1718497139158" ID="ID_504091335" MODIFIED="1718497165458" TEXT="der globale Pool ist lediglich eine hart gecodete fallback-ID">
<icon BUILTIN="idea"/>
</node>
@ -83638,14 +83673,14 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718494907182" ID="ID_1199907969" MODIFIED="1718494918916" TEXT="Informations-Funktionen">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718494920027" ID="ID_1244146950" MODIFIED="1718495028271" TEXT="Checksumme f&#xfc;r einen Pool">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1718494920027" ID="ID_1244146950" MODIFIED="1718503831384" TEXT="Checksumme f&#xfc;r einen Pool">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718494938195" ID="ID_1072075538" MODIFIED="1718495028271" TEXT="Anzahl aktive Allokationen pro Pool">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1718494938195" ID="ID_1072075538" MODIFIED="1718503910777" TEXT="Anzahl aktive Allokationen pro Pool">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718494948897" ID="ID_220648009" MODIFIED="1718495028272" TEXT="Summe belegter Bytes berechnen">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1718494948897" ID="ID_220648009" MODIFIED="1718503912474" TEXT="Summe belegter Bytes berechnen">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718494960176" ID="ID_1007231429" MODIFIED="1718495028272" TEXT="Zugriff auf belegte Bytes f&#xfc;r Einzel-Allokation">
<icon BUILTIN="flag-yellow"/>