Block-Flow: implement cyclic usage of an extent pool
..with the ability to grow on demand.. ..possibly add the new extents in the middle, by first allocating at the end and then using the std::rotate() algo to bring them to the point in the middle where new extents are required
This commit is contained in:
parent
c1b16349f2
commit
e86cb017a5
2 changed files with 137 additions and 22 deletions
|
|
@ -32,7 +32,7 @@
|
|||
** and down to avoid holding larger amounts of unused memory, while the availability
|
||||
** of a baseline amount of memory can be enforced.
|
||||
**
|
||||
** @see ////TODO_test usage example
|
||||
** @see ExtentFamily_test
|
||||
** @see gear::BlockFlow usage example
|
||||
**
|
||||
** @todo WIP-WIP-WIP 7/2023 »Playback Vertical Slice«
|
||||
|
|
@ -51,6 +51,7 @@
|
|||
//#include "lib/util.hpp"
|
||||
|
||||
//#include <string>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
|
@ -68,12 +69,17 @@ namespace mem {
|
|||
/**
|
||||
* Memory manager to provide a sequence of Extents for cyclic usage.
|
||||
* @todo WIP-WIP 7/2023
|
||||
* @see NA_test
|
||||
* @see ExtentFamily_test
|
||||
*/
|
||||
template<typename T, size_t siz>
|
||||
class ExtentFamily
|
||||
: util::NonCopyable
|
||||
{
|
||||
/** number of excess new extents
|
||||
* to add whenever new storage is required
|
||||
*/
|
||||
static const size_t EXCESS_ALLOC{5};
|
||||
|
||||
public:
|
||||
struct Extent
|
||||
: std::array<T,siz>
|
||||
|
|
@ -108,6 +114,8 @@ namespace mem {
|
|||
using RawIter = typename Extents::iterator;
|
||||
|
||||
|
||||
/* ==== Management Data ==== */
|
||||
|
||||
Extents extents_;
|
||||
size_t start_,after_;
|
||||
|
||||
|
|
@ -125,17 +133,42 @@ namespace mem {
|
|||
extents_.reserve (expectedMaxExtents);
|
||||
}
|
||||
|
||||
/** claim next \a cnt extents, possibly allocate.
|
||||
* @note always allocating slightly in excess
|
||||
*/
|
||||
void
|
||||
openNew (size_t cnt)
|
||||
{
|
||||
UNIMPLEMENTED ("claim next cnt extents, possibly allocate");
|
||||
if (not canAccomodate (cnt))
|
||||
{//insufficient reserve -> allocate
|
||||
size_t oldSiz = extents_.size();
|
||||
size_t addSiz = cnt - freeSlotCnt()
|
||||
+ EXCESS_ALLOC;
|
||||
// add a strike of new extents at the end
|
||||
extents_.resize (oldSiz + addSiz);
|
||||
if (isWrapped())
|
||||
{// need the new elements in the middle, before the existing start_
|
||||
auto p = extents_.begin();
|
||||
auto first = p + start_;
|
||||
auto mid = p + oldSiz;
|
||||
auto last = p + oldSiz + addSiz;
|
||||
// relocate [fist..mid) after [mid..last)
|
||||
std::rotate (first, mid, last);
|
||||
start_ += addSiz;
|
||||
}
|
||||
}
|
||||
// now sufficient reserve extents are available
|
||||
ENSURE (canAccomodate (cnt));
|
||||
incWrap (after_, cnt);
|
||||
}
|
||||
|
||||
/** discard oldest \a cnt extents */
|
||||
void
|
||||
dropOld (size_t cnt)
|
||||
{
|
||||
UNIMPLEMENTED ("discard oldest cnt extents");
|
||||
}
|
||||
REQUIRE (cnt <= activeSlotCnt());
|
||||
incWrap (start_, cnt);
|
||||
} ////////////////////////////////////////////////////////////////////////////TICKET #1316 : should reduce excess allocation (with apropriate damping to avoid oscillations)
|
||||
|
||||
|
||||
/** allow transparent iteration of Extents, expanding storage on demand */
|
||||
|
|
@ -149,6 +182,49 @@ namespace mem {
|
|||
}
|
||||
|
||||
|
||||
private:
|
||||
bool
|
||||
isWrapped() const
|
||||
{
|
||||
return after_ < start_;
|
||||
} // note: both are equal only when empty
|
||||
|
||||
/** @return number of allocated slots actually used */
|
||||
size_t
|
||||
activeSlotCnt() const
|
||||
{
|
||||
REQUIRE (start_ <= extents_.size());
|
||||
REQUIRE (after_ <= extents_.size());
|
||||
|
||||
return not isWrapped()? after_ - start_
|
||||
: (after_ - 0)
|
||||
+(extents_.size() - start_);
|
||||
}
|
||||
|
||||
size_t
|
||||
freeSlotCnt() const
|
||||
{ // always keep one in reserve...
|
||||
REQUIRE (activeSlotCnt() < extents_.size());
|
||||
|
||||
return extents_.size() - activeSlotCnt();
|
||||
}
|
||||
|
||||
bool
|
||||
canAccomodate (size_t addCnt) const
|
||||
{
|
||||
return addCnt < freeSlotCnt(); // keep one in reserve
|
||||
}
|
||||
|
||||
/** increment index, but wrap at array end.
|
||||
* @remark using the array cyclically
|
||||
*/
|
||||
void
|
||||
incWrap (size_t& idx, size_t inc)
|
||||
{
|
||||
idx = (idx+inc) % extents_.size();
|
||||
}
|
||||
|
||||
|
||||
/* == Iteration control API (used by IterAdapter via ADL) == */
|
||||
|
||||
friend bool
|
||||
|
|
@ -163,11 +239,19 @@ namespace mem {
|
|||
UNIMPLEMENTED ("ExtentFamily iteration control: access next Extent, possibly expand allocation");
|
||||
}
|
||||
|
||||
|
||||
/// „backdoor“ to watch internals from tests
|
||||
friend class ExtentDiagnostic<T,siz>;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ===== Test / Diagnostic ===== */
|
||||
|
||||
template<typename T, size_t siz>
|
||||
struct ExtentDiagnostic
|
||||
{
|
||||
|
|
@ -178,7 +262,7 @@ namespace mem {
|
|||
size_t first() { return exFam_.start_; }
|
||||
size_t last() { return exFam_.after_; }
|
||||
size_t size() { return exFam_.extents_.size(); }
|
||||
size_t active() { UNIMPLEMENTED ("count active"); }
|
||||
size_t active() { return exFam_.activeSlotCnt(); }
|
||||
};
|
||||
|
||||
template<typename T, size_t siz>
|
||||
|
|
|
|||
|
|
@ -78517,8 +78517,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node COLOR="#338800" CREATED="1688434743454" ID="ID_722620082" MODIFIED="1688434762609" TEXT="ExtentFamily erzeugen mit pre-Allocation">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1688862941032" ID="ID_1514279635" MODIFIED="1688868055421" TEXT="Diagnose der tatsächlichen Speicherbelegung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1688862941032" ID="ID_1514279635" MODIFIED="1688960119406" TEXT="Diagnose der tatsächlichen Speicherbelegung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688863035539" ID="ID_557979292" MODIFIED="1688864962621" TEXT="belegen und Aufräumen">
|
||||
|
|
@ -78783,8 +78783,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688337270626" ID="ID_1810148055" MODIFIED="1688337284937" TEXT="»BlockFlow« : Implementation">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688398675985" ID="ID_291772625" MODIFIED="1688398683406" TEXT="Basis: ExtentFamily">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1688398675985" ID="ID_291772625" MODIFIED="1688960090391" TEXT="Basis: ExtentFamily">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688398685028" ID="ID_1348599303" MODIFIED="1688398807927" TEXT="Anforderungen">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1688398688699" ID="ID_1432998672" MODIFIED="1688398701914" TEXT="stellt eine Sequenz von »Extents« bereit"/>
|
||||
|
|
@ -78808,9 +78808,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688398813243" ID="ID_504623704" MODIFIED="1688398863035" TEXT="Aufbau testgetrieben...">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1688398813243" ID="ID_504623704" MODIFIED="1688960080656" TEXT="Aufbau testgetrieben...">
|
||||
<arrowlink COLOR="#eb4070" DESTINATION="ID_1132827905" ENDARROW="Default" ENDINCLINATION="-593;73;" ID="Arrow_ID_709934622" STARTARROW="None" STARTINCLINATION="-214;-18;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1688398884005" ID="ID_1188543253" MODIFIED="1688867997850" TEXT="Basis-Struktur">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1688432746255" ID="ID_880122043" MODIFIED="1688432851088" TEXT="Entscheidung: die Größe ist eine compile-time-Konstante">
|
||||
|
|
@ -78949,18 +78949,49 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688398893220" ID="ID_675575195" MODIFIED="1688398901316" TEXT="belegen / freigeben">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688437691137" ID="ID_292063242" MODIFIED="1688437712023" TEXT="prüfen auf ausreichende Reserve">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1688398893220" ID="ID_675575195" MODIFIED="1688960070966" TEXT="belegen / freigeben">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1688952897933" ID="ID_832611581" MODIFIED="1688955651916" TEXT="freie Reserve ermitteln">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688437762175" ID="ID_1456790340" MODIFIED="1688437794274" TEXT="sonst: Allokation erweitern">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688437770295" ID="ID_867206595" MODIFIED="1688437792757" TEXT="falls am Ende">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1688437691137" ID="ID_292063242" MODIFIED="1688960068981" TEXT="prüfen auf ausreichende Reserve">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688437784470" ID="ID_797852741" MODIFIED="1688437792758" TEXT="falls wrap-around">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1688437762175" ID="ID_1456790340" MODIFIED="1688960067652" TEXT="sonst: Allokation erweitern">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1688437770295" ID="ID_867206595" MODIFIED="1688960066248" TEXT="falls am Ende">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1688957825760" ID="ID_376842621" MODIFIED="1688957834883" TEXT="vector::resize() genügt"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1688437784470" ID="ID_797852741" MODIFIED="1688960065205" TEXT="falls wrap-around">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1688957839759" ID="ID_671792490" MODIFIED="1688957862703" TEXT="zusätzlich die neuen Elemente in die Pufferzone in der Mitte rotieren"/>
|
||||
<node CREATED="1688957863500" ID="ID_592181743" MODIFIED="1688958053349" TEXT="std::rotate() verwenden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...dieser tauscht per std::swap aus; und zwar rekursiv inkrementell: erst das Segment vom Ende an den Anfang und dann rekursiv wieder std::rotate für den Rest. Komplexität: linear
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1688958797642" ID="ID_205839494" MODIFIED="1688958807300" TEXT="Überschuß freigeben">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1688958808347" ID="ID_1777900061" MODIFIED="1688958867924" TEXT="Gefahr von Oszillationen ⟹ vorerst noch nicht implementiert">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1688958965134" ID="ID_559031085" MODIFIED="1688958983164" TEXT="vorerst wächst die Allokation nur">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1688958894805" ID="ID_1746833075" MODIFIED="1688958904528" TEXT="#1316 regulate Scheduler memory allocation">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node CREATED="1688958915756" ID="ID_292339303" MODIFIED="1688958930662" TEXT="man müßte einen typischen / durchschnittlichen Bedarf etablieren"/>
|
||||
<node CREATED="1688958931778" ID="ID_764223223" MODIFIED="1688958942454" TEXT="und dann mit einer gewissen Dämpfung darauf hinsteuern"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue