Library: tracking diagnostic allocator now complete and tested

This commit is contained in:
Fischlurch 2024-06-16 23:55:22 +02:00
parent 10edc31eac
commit 055df59dde
4 changed files with 304 additions and 53 deletions

View file

@ -34,11 +34,8 @@
** - each MemoryPool contains a hashtable, where each active allocation is
** stored, using the storage-location as hashtable key. Each such entry
** gets a further consecutive internal ID, which is visible in the EventLog
** - ////////////////////OOO Mutex locking
**
** @see tracking-allocator.hpp
** @see TestTracking_test#demonstrate_checkAllocator()
**
*/
@ -82,7 +79,7 @@ namespace test{
: util::MoveOnly
{
UninitialisedDynBlock<byte> buff{};
size_t entryID;
size_t entryID{0};
};
using AllocTab = std::unordered_map<const Location, Allocation, LocationHash>;
@ -135,18 +132,22 @@ namespace test{
}
/** keep track of any distinct memory pools used */
class PoolRegistry
: util::NonCopyable
{
std::unordered_map<Literal, std::weak_ptr<MemoryPool>> pools_{};
public:
{ // note: obsolete entries never discarded
using PoolTab = std::unordered_map<Literal, std::weak_ptr<MemoryPool>>;
PoolTab pools_{};
public:
static PoolHandle locate (Literal poolID);
private:
PoolHandle fetch_or_create (Literal poolID);
};
/** singleton for default pool */
Depend<MemoryPool> globalPool;
Depend<PoolRegistry> poolReg;
@ -187,7 +188,7 @@ namespace test{
/**
* Allot a memory block with size \a bytes.
* Allot a memory block of given size \a bytes.
* This allocation is recorded in the associated MemoryPool
* and proper deallocation can thus be verified.
* @return a `void*` to the start of the bare memory location
@ -245,6 +246,7 @@ namespace test{
logAlarm ("FreeUnknown", bytes, showAddr(loc));
}
MemoryPool::Allocation const*
MemoryPool::findAlloc (Location loc) const
{
@ -280,7 +282,7 @@ namespace test{
EventLog TrackingAllocator::log{"test::TrackingAllocator"};
/** get Checksum for mem-pool */
/** get Checksum for specific mem-pool */
HashVal
TrackingAllocator::checksum (Literal poolID)
{
@ -296,7 +298,7 @@ namespace test{
return pool.use_count() - 1;
}
/** get allocation count for mem-pool */
/** get active allocation count for mem-pool */
size_t
TrackingAllocator::numAlloc (Literal poolID)
{
@ -350,5 +352,4 @@ namespace test{
}} // namespace lib::test

View file

@ -22,7 +22,7 @@
/** @file tracking-allocator.hpp
** unittest helper code: a custom allocator to track memory usage.
** Unittest helper code: a custom allocator to track memory usage.
** By registering each allocation and deallocation, correct memory handling
** can be verified and memory usage can be investigated in practice.
** \par TrackingAllocator
@ -43,6 +43,11 @@
** @remark these classes also work in concert with the building blocks
** from allocator-handle.hpp; notably it is possible to create
** a OwnUniqueAdapter front-end for fabricating `unique_ptr`
** @warning deliberately *not threadsafe*
** - generally speaking, allocation should be kept outside of
** any multithreaded environment, or at least requires
** dedicated care beyond any standard scheme
** - this is a test feature...
** @see TestTracking_test
*/
@ -157,6 +162,12 @@ namespace test {
using value_type = TY;
// define that (non-equivalent) allocators migrate alongside on assignments....
using propagate_on_container_copy_assignment = std::true_type; ///< for sake of consistency
using propagate_on_container_move_assignment = std::true_type; ///< otherwise all elements must be copied
using propagate_on_container_swap = std::true_type; ///< otherwise they would have to deallocate cross-wise
[[nodiscard]] TY* allocate (size_t cnt);
void deallocate (TY*, size_t) noexcept;
};

View file

@ -32,7 +32,6 @@
#include "lib/allocator-handle.hpp"
#include "lib/format-cout.hpp"
#include "lib/format-util.hpp"
#include "lib/test/diagnostic-output.hpp"///////////////////////TODO
#include <string>
@ -88,8 +87,11 @@ namespace test{
Tracker delta(23); // (7) create δ with ID 23
delta = move(gamma); // (8) move-assign δ ⟵ γ
log.event ("ID",delta.val); // (9) thus δ now bears the ID 55 (moved αγ ⟶ δ)
CHECK (delta.val == 55);
}
log.event("ID",alpha.val); // (X) and thus α is now a zombie object
CHECK (alpha.val == Tracker::DEFUNCT);
cout << "____Tracker-Log_______________\n"
<< util::join(Tracker::log, "\n")
@ -112,6 +114,7 @@ namespace test{
}
/** @test dummy object with a tracking checksum.
*/
void
@ -160,11 +163,14 @@ namespace test{
}
/** @test custom allocator to track memory handling
* - use the base allocator to perform raw memory allocation
* - demonstrate checksum and diagnostic functions
* - use a standard adapter to create objects with `unique_ptr`
* - use as _custom allocator_ within STL containers
* - can use several distinct pools
* - swapping containers will move allocators alongside
*/
void
demonstrate_checkAllocator()
@ -190,7 +196,7 @@ namespace test{
CHECK (TrackingAllocator::numBytes() == 55);
CHECK (allo.manages (mem));
CHECK (allo.getSize (mem) == 55);
CHECK (allo.getSize (mem) == 55); // individual registration recalls the allocation's size
HashVal memID = allo.getID (mem);
CHECK (0 < memID);
CHECK (TrackingAllocator::checksum() == memID*55);
@ -259,18 +265,22 @@ namespace test{
CHECK (TrackingAllocator::checksum() == 0);
Tracker *t1, *t2, *t3, *t4;
// define a vector type to use the TrackingAllocator internally
using TrackVec = std::vector<Tracker, TrackAlloc<Tracker>>;
// the following pointers are used later to identify log entries...
Tracker *t1, *t2, *t3, *t4, *t5, *t6;
{ // Test-3 : use as STL allocator
log.event("Test-3");
using SpyVec = std::vector<Tracker, TrackAlloc<Tracker>>;
log.event("fill with 3 default instances");
SpyVec vec1(3);
TrackVec vec1(3);
int v3 = vec1.back().val;
SpyVec vec2;
TrackVec vec2;
log.event("move last instance over into other vector");
vec2.emplace_back (move (vec1[2]));
CHECK (vec2.back().val == v3);
@ -300,12 +310,115 @@ namespace test{
.beforeCall("dtor").on(t3)
.beforeCall("deallocate").on(GLOBAL)
);
CHECK (TrackingAllocator::checksum() == 0);
{ // Test-4 : intermingled use of several pools
log.event("Test-4");
TrackAlloc<Tracker> allo1{"POOL-1"};
TrackAlloc<Tracker> allo2{"POOL-2"};
CHECK (allo1 != allo2);
CHECK (TrackingAllocator::use_count(GLOBAL) == 0);
CHECK (TrackingAllocator::use_count("POOL-1") == 1); // referred by allo1
CHECK (TrackingAllocator::use_count("POOL-2") == 1); // referred by allo2
CHECK (TrackingAllocator::checksum ("POOL-1") == 0);
CHECK (TrackingAllocator::checksum ("POOL-2") == 0);
TrackVec vec1{allo1};
TrackVec vec2{allo2};
CHECK (TrackingAllocator::use_count("POOL-1") == 2); // now also referred by the copy in the vectors
CHECK (TrackingAllocator::use_count("POOL-2") == 2);
log.event("reserve space in vectors");
vec1.reserve(20);
vec2.reserve(2);
CHECK (TrackingAllocator::numBytes("POOL-1") == 20*sizeof(Tracker));
CHECK (TrackingAllocator::numBytes("POOL-2") == 2*sizeof(Tracker));
CHECK (TrackingAllocator::numBytes(GLOBAL) == 0);
CHECK (TrackingAllocator::numBytes() == 0);
log.event("create elements in vec1");
vec1.resize(5);
vec1.back().val = 11;
log.event("add element to vec2");
vec2.push_back (Tracker{22});
// capture object locations for log verification later
t1 = & vec1[0];
t2 = & vec1[1];
t3 = & vec1[2];
t4 = & vec1[3];
t5 = & vec1[4];
t6 = & vec2.front();
log.event ("swap vectors");
std::swap (vec1, vec2);
CHECK (vec1.back().val == 22);
CHECK (vec2.back().val == 11);
CHECK (vec1.size() == 1);
CHECK (vec2.size() == 5);
// the allocators were migrated alongside with the swap
CHECK (TrackingAllocator::numBytes("POOL-1") == 20*sizeof(Tracker));
CHECK (TrackingAllocator::numBytes("POOL-2") == 2*sizeof(Tracker));
// this can be demonstrated....
log.event ("clear the elements migrated to vec2");
vec2.clear();
vec2.shrink_to_fit();
CHECK (vec2.capacity() == 0);
CHECK (TrackingAllocator::numBytes("POOL-1") == 0 );
CHECK (TrackingAllocator::numBytes("POOL-2") == 2*sizeof(Tracker));
CHECK (vec1.size() == 1);
CHECK (vec1.capacity() == 2); // unaffected
log.event ("leave scope");
}
CHECK (log.verifyEvent("Test-4")
.beforeEvent("reserve space in vectors")
.beforeCall("allocate").on("POOL-1").argPos(0, 20*sizeof(Tracker))
.beforeCall("allocate").on("POOL-2").argPos(0, 2*sizeof(Tracker))
.beforeEvent("create elements in vec1")
.beforeCall("ctor").on(t1)
.beforeCall("ctor").on(t2)
.beforeCall("ctor").on(t3)
.beforeCall("ctor").on(t4)
.beforeCall("ctor").on(t5)
.beforeEvent("add element to vec2")
.beforeCall("ctor").arg(22)
.beforeCall("ctor-move").on(t6).arg("Track{22}")
.beforeCall("dtor").arg(Tracker::DEFUNCT)
.beforeEvent("swap vectors")
.beforeEvent("clear the elements migrated to vec2")
.beforeCall("dtor").on(t1)
.beforeCall("dtor").on(t2)
.beforeCall("dtor").on(t3)
.beforeCall("dtor").on(t4)
.beforeCall("dtor").on(t5).arg(11)
.beforeCall("deallocate").on("POOL-1").argPos(0, 20*sizeof(Tracker))
.beforeEvent("leave scope")
.beforeCall("dtor").on(t6).arg(22)
.beforeCall("deallocate").on("POOL-2").argPos(0, 2*sizeof(Tracker))
);
// everything clean and all pools empty again...
CHECK (TrackingAllocator::use_count(GLOBAL) == 0);
CHECK (TrackingAllocator::use_count("POOL-1") == 0);
CHECK (TrackingAllocator::use_count("POOL-2") == 0);
CHECK (TrackingAllocator::checksum("POOL-1") == 0);
CHECK (TrackingAllocator::checksum("POOL-2") == 0);
CHECK (TrackingAllocator::checksum(GLOBAL) == 0);
cout << "____Tracking-Allo-Log_________\n"
<< util::join(Tracker::log, "\n")
<< "\n───╼━━━━━━━━━━━━━━━━━╾────────"<<endl;
CHECK (TrackingAllocator::checksum() == 0);
}
};

View file

@ -65300,8 +65300,8 @@
<node CREATED="1716677865819" ID="ID_884450390" MODIFIED="1716677938838" TEXT="BlockFlow (f&#xfc;r Scheduler-Activities)">
<arrowlink COLOR="#504f86" DESTINATION="ID_1478014419" ENDARROW="Default" ENDINCLINATION="-665;-48;" ID="Arrow_ID_1014939669" STARTARROW="None" STARTINCLINATION="-1064;85;"/>
</node>
<node CREATED="1718495068144" ID="ID_1722995316" MODIFIED="1718495182358" TEXT="Tracking-Allocator f&#xfc;r Tests">
<arrowlink COLOR="#24309b" DESTINATION="ID_360498640" ENDARROW="Default" ENDINCLINATION="-850;-83;" ID="Arrow_ID_1221752034" STARTARROW="None" STARTINCLINATION="-909;93;"/>
<node CREATED="1718495068144" ID="ID_1722995316" MODIFIED="1718581744590" TEXT="Tracking-Allocator f&#xfc;r Tests">
<arrowlink COLOR="#24309b" DESTINATION="ID_360498640" ENDARROW="Default" ENDINCLINATION="-963;-85;" ID="Arrow_ID_1221752034" STARTARROW="None" STARTINCLINATION="-909;93;"/>
</node>
</node>
</node>
@ -83525,24 +83525,29 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#2c878c" CREATED="1718412901000" ID="ID_1589785077" MODIFIED="1718412970228" TEXT="YESS!!! der Compiler fri&#xdf;t das">
<icon BUILTIN="ksmiletris"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1718581460854" ID="ID_1938493773" MODIFIED="1718581521324" TEXT="erst mal mit einem nachvollziebaren Allocator verifizieren...">
<arrowlink COLOR="#49596d" DESTINATION="ID_360498640" ENDARROW="Default" ENDINCLINATION="177;-168;" ID="Arrow_ID_1985044400" STARTARROW="None" STARTINCLINATION="-601;28;"/>
<icon BUILTIN="yes"/>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718368775878" ID="ID_1921994351" LINK="#ID_28139752" MODIFIED="1718368785941" TEXT="testen">
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718368775878" ID="ID_1921994351" LINK="#ID_28139752" MODIFIED="1718581587832" TEXT="testen">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1718462814861" ID="ID_360498640" MODIFIED="1718495176574" TEXT="brauche einen Test-Allocator">
<linktarget COLOR="#24309b" DESTINATION="ID_360498640" ENDARROW="Default" ENDINCLINATION="-850;-83;" ID="Arrow_ID_1221752034" SOURCE="ID_1722995316" STARTARROW="None" STARTINCLINATION="-909;93;"/>
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1718462814861" FOLDED="true" ID="ID_360498640" MODIFIED="1718581744590" TEXT="brauche einen &#xbb;tracking&#xab; Test-Allocator">
<linktarget COLOR="#24309b" DESTINATION="ID_360498640" ENDARROW="Default" ENDINCLINATION="-963;-85;" ID="Arrow_ID_1221752034" SOURCE="ID_1722995316" STARTARROW="None" STARTINCLINATION="-909;93;"/>
<linktarget COLOR="#49596d" DESTINATION="ID_360498640" ENDARROW="Default" ENDINCLINATION="177;-168;" ID="Arrow_ID_1985044400" SOURCE="ID_1938493773" STARTARROW="None" STARTINCLINATION="-601;28;"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1718462822608" ID="ID_1246144327" MODIFIED="1718462832939" TEXT="soll Heap-Allocations machen"/>
<node CREATED="1718462833600" ID="ID_148354832" MODIFIED="1718462843746" TEXT="aber jede Allocation registrieren"/>
<node CREATED="1718462844949" ID="ID_878000215" MODIFIED="1718462853370" TEXT="Schnittstelle: Standard-Allocator"/>
<node CREATED="1718462854892" ID="ID_1522781067" MODIFIED="1718462863507" TEXT="ansiedeln bei den &#xbb;Test-Trackern&#xab;">
<node CREATED="1718462864539" ID="ID_834960302" MODIFIED="1718462870302" TEXT="Ha! die gibt es noch gar nicht"/>
<node CREATED="1718462871338" ID="ID_616892475" MODIFIED="1718462876676" TEXT="also: die Header reorganisieren"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1718462880129" ID="ID_1726310256" MODIFIED="1718467906896" TEXT="Test-Test">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1718462880129" FOLDED="true" ID="ID_1726310256" MODIFIED="1718581426715" TEXT="Test-Test">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1718462887129" ID="ID_908994270" MODIFIED="1718467842351" TEXT="demonstrate_logObject">
<icon BUILTIN="button_ok"/>
<node CREATED="1718463949770" ID="ID_252224741" MODIFIED="1718463958992" TEXT="Vorlage / Beispiel: LateBindInstance_test">
@ -83572,17 +83577,15 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node COLOR="#435e98" CREATED="1718486592101" ID="ID_121488607" MODIFIED="1718486605209" TEXT="throw from ctor"/>
<node COLOR="#435e98" CREATED="1718486596443" ID="ID_1250015263" MODIFIED="1718486605209" TEXT="verify checksum"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1718462887129" ID="ID_1322153003" MODIFIED="1718558813469" TEXT="demonstrate_checkAllocator">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1718462887129" ID="ID_1322153003" MODIFIED="1718581313289" TEXT="demonstrate_checkAllocator">
<icon BUILTIN="button_ok"/>
<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>
<head/>
<body>
<p>
Ich habe nun beschlossen, sie zu bilden als Produkt
@ -83596,8 +83599,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</li>
</ul>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node COLOR="#338800" CREATED="1718552444472" ID="ID_1140313787" MODIFIED="1718558761295" TEXT="unique-ownership-Front-End">
@ -83607,8 +83609,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<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 COLOR="#338800" CREATED="1718493041125" ID="ID_1894747169" MODIFIED="1718581309784" TEXT="anderen Vector an einen privaten Pool ankoppeln">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1718493020625" ID="ID_149523402" MODIFIED="1718503980986" TEXT="einige Dummy-Objekte einf&#xfc;gen">
<icon BUILTIN="button_ok"/>
@ -83631,11 +83633,15 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node COLOR="#435e98" CREATED="1718558790449" ID="ID_1151700316" MODIFIED="1718558806413" TEXT="auch einzelne Instanzen verifiziert">
<font NAME="SansSerif" SIZE="12"/>
</node>
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1718581316923" ID="ID_1160750557" LINK="#ID_179982765" MODIFIED="1718581392644" TEXT="grmpf ... Falle mit swap entdeckt">
<icon BUILTIN="clanbomber"/>
<icon BUILTIN="smiley-angry"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1718489410226" ID="ID_593247865" MODIFIED="1718495041962" TEXT="Design">
</node>
<node COLOR="#435e98" CREATED="1718489410226" ID="ID_593247865" MODIFIED="1718571818029" TEXT="Design">
<icon BUILTIN="yes"/>
<node CREATED="1718489502694" ID="ID_1159188868" MODIFIED="1718489514638" TEXT="Backend: eine opaque Klasse MemoryPool">
<node CREATED="1718489522522" ID="ID_1654685241" MODIFIED="1718489535581" TEXT="f&#xfc;hrt eine Hashtable mit allen ausgegebenen Allokationen"/>
@ -83652,8 +83658,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1718489611591" ID="ID_1909546439" MODIFIED="1718489675778" TEXT="eine Checksumme f&#xfc;r jeden Pool"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1718489712994" ID="ID_1366290941" MODIFIED="1718501228365" TEXT="Implementierung">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1718489712994" ID="ID_1366290941" MODIFIED="1718571814417" TEXT="Implementierung">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1718489717485" ID="ID_1890743066" MODIFIED="1718501225010" TEXT="das Front-End ist ein verpackter Shared-Ptr">
<icon BUILTIN="button_ok"/>
</node>
@ -83694,8 +83700,46 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<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 COLOR="#5b280f" CREATED="1718489730263" ID="ID_5464621" MODIFIED="1718570758863" TEXT="der MemoryPool verwendet Mutex-Locking">
<icon BUILTIN="button_cancel"/>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1718570760063" ID="ID_454338402" MODIFIED="1718570765667" TEXT="YAGNI">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#cb0d9f" CREATED="1718571495232" HGAP="28" ID="ID_1683473439" MODIFIED="1718571663265" TEXT="tats&#xe4;chlich sogar Zeitverschwendung" VSHIFT="2">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...das ist die Art von bequemen Besch&#228;ftigungen, die sich nach <i>viel Arbeit </i>anf&#252;hlen, tats&#228;chlich aber nur darin bestehen, ein gewohntes Schema durchzuziehen ... man erbt von lib::Sync, man bastelt die Guards in jede Methode, man zimmert einen geilen Test mit dem Threadwrapper. Dadurch wird <b>der neue Code keinen Deut besser</b>.
</p>
</body>
</html></richcontent>
<font ITALIC="true" NAME="SansSerif" SIZE="11"/>
</node>
</node>
<node COLOR="#5b280f" CREATED="1718570767883" ID="ID_1984607473" MODIFIED="1718571729994" TEXT="erscheit mit abwegig f&#xfc;r ein TEST-Feature">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Der Zweck der TrackingFactory ist es, das saubere Verhalten eines Custom-Allocators zu belegen. In Grenzf&#228;llen k&#246;nnte das zwar auch Concurrency involvieren &#8212; jedoch ist es aus heutigem Verst&#228;ndnis generell <b>nicht mehr &#252;blich, Allokationen in der &#187;hei&#223;en Zone&#171; zu machen</b>. Typischerweise verwendet man genau daf&#252;r einen Builder oder einen Pool und teilt die Ressourcen schon im Vorhinen den Threads zu.
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="stop-sign"/>
</node>
<node CREATED="1718571040189" ID="ID_1360340759" MODIFIED="1718571734976">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
im Zweifelsfall w&#228;re ein Adapter <i>&#252;ber </i>der Factory einfacher
</p>
</body>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
</node>
<node COLOR="#338800" CREATED="1718494880219" ID="ID_1016934813" MODIFIED="1718503899936" TEXT="Meta-Registry aller Pools">
<icon BUILTIN="button_ok"/>
@ -83720,8 +83764,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="1718494907182" ID="ID_1199907969" MODIFIED="1718494918916" TEXT="Informations-Funktionen">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1718494907182" ID="ID_1199907969" MODIFIED="1718571811592" TEXT="Informations-Funktionen">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1718494920027" ID="ID_1244146950" MODIFIED="1718503831384" TEXT="Checksumme f&#xfc;r einen Pool">
<icon BUILTIN="button_ok"/>
</node>
@ -83731,15 +83775,37 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<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">
<node COLOR="#338800" CREATED="1718494960176" ID="ID_1007231429" MODIFIED="1718571690056" TEXT="Zugriff auf belegte Bytes f&#xfc;r Einzel-Allokation">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#5b280f" CREATED="1718495002832" ID="ID_992819817" MODIFIED="1718571742887" TEXT="Gesamtsummen berechnen">
<icon BUILTIN="button_cancel"/>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1718571749693" ID="ID_1117628364" MODIFIED="1718571772279" TEXT="ebenfalls YAGNI">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
</node>
<node CREATED="1718571773814" ID="ID_1829070836" MODIFIED="1718571809636" TEXT="wozu soll das gut sein?">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
kann man gef&#228;lligst <i>selber machen</i>
</p>
</body>
</html></richcontent>
<font NAME="SansSerif" SIZE="8"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eebe7a" COLOR="#a50125" CREATED="1718577732236" ID="ID_179982765" MODIFIED="1718577855946" TEXT="Falle bei Swap">
<arrowlink COLOR="#e30965" DESTINATION="ID_535885464" ENDARROW="Default" ENDINCLINATION="-234;307;" ID="Arrow_ID_551077019" STARTARROW="None" STARTINCLINATION="-389;62;"/>
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718581783068" ID="ID_1789618356" MODIFIED="1718581797769" TEXT="standardkonformen custom-Allocator ankoppeln">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718495002832" ID="ID_992819817" MODIFIED="1718495028273" TEXT="Gesamtsummen berechnen">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
@ -83748,7 +83814,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1717794532666" ID="ID_1285152534" MODIFIED="1717810981399" TEXT="Implementierungs-Logik aufbauen">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1717794550220" ID="ID_1034302214" MODIFIED="1717794631737" TEXT="das ist hier eine besondere Herausforderung....">
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1717794550220" HGAP="4" ID="ID_1034302214" MODIFIED="1718581604449" STYLE="bubble" TEXT="das ist hier eine besondere Herausforderung...." VSHIFT="15">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -83757,6 +83823,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</p>
</body>
</html></richcontent>
<edge COLOR="#a24d4d"/>
<icon BUILTIN="messagebox_warning"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717794645742" ID="ID_1610453521" MODIFIED="1717796458652" TEXT="Methode: den Lebenszyklus konzeptionell durchgehen">
@ -84009,7 +84076,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="broken-line"/>
</node>
</node>
<node COLOR="#865c48" CREATED="1718122077386" ID="ID_959961694" MODIFIED="1718201948324" TEXT="kann keinen anderen Typ platzieren (selbst wenn kleiner)">
<node COLOR="#865c48" CREATED="1718122077386" FOLDED="true" ID="ID_959961694" MODIFIED="1718201948324" TEXT="kann keinen anderen Typ platzieren (selbst wenn kleiner)">
<icon BUILTIN="closed"/>
<node COLOR="#5b280f" CREATED="1718157829884" ID="ID_1228814618" MODIFIED="1718201060734" TEXT="spricht nicht an">
<icon BUILTIN="broken-line"/>
@ -129632,6 +129699,65 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
</node>
<node CREATED="1715700887866" ID="ID_524521259" MODIFIED="1715700900117" TEXT="ein stateful-Allocator mu&#xdf; als ctor-Parameter verdrahtet werden"/>
</node>
<node CREATED="1718577265491" ID="ID_1993314304" MODIFIED="1718577282448" TEXT="Vorsicht bei unterscheidbaren Allocator-Instanzen">
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1718577284088" ID="ID_163377382" MODIFIED="1718577380048">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
wenn ein Allocator nur seine eignen Allokationen hanhaben soll &#10233; <b><font size="4">Gefahr</font></b>
</p>
</body>
</html>
</richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...und das ist leider der Fall, sobald die Allokationen in irgend einer Form von spezieller Datenstruktur verwaltet werden, die wir auch f&#252;r die de-Allokation wieder brauchen...
</p>
</body>
</html></richcontent>
<icon BUILTIN="clanbomber"/>
</node>
<node CREATED="1718577380972" ID="ID_732953505" MODIFIED="1718577440884" TEXT="&#xc4;quivalenz mu&#xdf; unbedingt korrekt definiert sein">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Allokatoren &#228;quivalent &#10234; eine Instanz kann von der anderen Instanz erzeugte Objekte deallozieren
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1718577446747" ID="ID_535885464" LINK="https://www.foonathan.net/2015/10/allocatorawarecontainer-propagation-pitfalls/" MODIFIED="1718577841515" TEXT="ZWINGEND Klarstellung f&#xfc;r copy-/move-Assiggn und Swap notwendig">
<linktarget COLOR="#e30965" DESTINATION="ID_535885464" ENDARROW="Default" ENDINCLINATION="-234;307;" ID="Arrow_ID_551077019" SOURCE="ID_179982765" STARTARROW="None" STARTINCLINATION="-389;62;"/>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1718577514217" ID="ID_1741966052" MODIFIED="1718577524340" TEXT="default ist leider, die Allokatoren nicht mitzubewegen"/>
<node CREATED="1718577545541" ID="ID_1827257155" MODIFIED="1718577554168" TEXT="f&#xfc;r move-Assignment ist das eine Katastrophe"/>
<node CREATED="1718577554900" ID="ID_1693250793" MODIFIED="1718577574373" TEXT="und f&#xfc;r swap bedeutet der default &#xd83e;&#xdc46; undefined behaviour"/>
<node CREATED="1718577579585" ID="ID_100278165" MODIFIED="1718577581365" TEXT="L&#xf6;sung">
<node CREATED="1718577619865" ID="ID_1025435794" MODIFIED="1718577691306" STYLE="bubble">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
<font face="Monospaced" size="2">using propagate_on_container_copy_assignment = std::true_type; </font>
</p>
<p>
<font face="Monospaced" size="2">using propagate_on_container_move_assignment = std::true_type; </font>
</p>
<p>
<font face="Monospaced" size="2">using propagate_on_container_swap = std::true_type; </font>
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1718577700923" ID="ID_144890944" MODIFIED="1718577719898" TEXT="dadurch wird stets der Quell-Alokator mitverschoben"/>
</node>
</node>
</node>
</node>
</node>
<node CREATED="1711405781006" FOLDED="true" ID="ID_135618716" LINK="https://en.cppreference.com/w/cpp/language/class_template_argument_deduction#Deduction_for_class_templates" MODIFIED="1711406693840" TEXT="Deduction Guides (CTAD)">