Library: investigate alignment issues

The solution implemented thus far turns out to be not sufficient
for ''over-aligned-data'', as the raw-allocator can not perform the
''magic work'' because we're exposing only `std::byte` data.
This commit is contained in:
Fischlurch 2024-06-17 16:58:07 +02:00
parent 055df59dde
commit dc6c8e0858
4 changed files with 149 additions and 13 deletions

View file

@ -73,7 +73,7 @@ namespace lib {
namespace {// Storage implementation details
template<class I>
template<class I, class E =I, size_t space = sizeof(I)>
struct ArrayBucket
{
ArrayBucket (size_t bytes, size_t elmSize = sizeof(I))
@ -91,9 +91,8 @@ namespace lib {
Deleter deleter;
/** mark start of the storage area */
alignas(I)
alignas(void*)
std::byte storage[sizeof(I)];
alignas(E)
std::byte storage[space];
static size_t

View file

@ -28,6 +28,7 @@
#include "lib/test/run.hpp"
#include "lib/test/tracking-dummy.hpp"
#include "lib/test/tracking-allocator.hpp"
#include "lib/test/test-coll.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/test/diagnostic-output.hpp"////////////////TODO
@ -508,6 +509,26 @@ namespace test{
alignas(32)
char charm = 'u';
};
SHOW_EXPR(sizeof(Ali))
SHOW_EXPR(alignof(Ali))
SHOW_EXPR(sizeof(ArrayBucket<Ali>))
SHOW_EXPR(alignof(ArrayBucket<Ali>))
SHOW_EXPR(sizeof(ArrayBucket<Ali, Ali, 10>))
SHOW_EXPR(alignof(ArrayBucket<Ali, Ali, 10>))
SHOW_EXPR(sizeof(ArrayBucket<char, Ali, 10>))
SHOW_EXPR(alignof(ArrayBucket<char, Ali, 10>))
std::allocator<ArrayBucket<Ali>> aliAllo;
std::allocator<std::byte> byteAllo;
ArrayBucket<Ali> * locAli = aliAllo.allocate(1);
std::byte* locByte = byteAllo.allocate(96);
SHOW_EXPR(loc(locAli))
SHOW_EXPR(loc(locAli) % alignof(Ali))
SHOW_EXPR(loc(locByte))
SHOW_EXPR(loc(locByte) % alignof(Ali))
aliAllo.destroy(locAli);
byteAllo.destroy(locByte);
auto elms = makeSeveral<Ali>().fillElm(5).build();
CHECK (5 == elms.size());
@ -551,11 +572,18 @@ namespace test{
/** @test TODO demonstrate integration with a custom allocator
* @todo WIP 6/24 🔁 define implement
* @todo WIP 6/24 🔁 define 🔁 implement
*/
void
check_CustomAllocator()
{
{
auto builder = makeSeveral<Dummy>()
.withAllocator<test::TrackAlloc>();
SHOW_TYPE(decltype(builder))
SHOW_EXPR(builder.size())
SHOW_EXPR(builder.capacity())
}
}
};

View file

@ -175,7 +175,7 @@ namespace test{
void
demonstrate_checkAllocator()
{
// setup a common lock for the tracking objects and -allocator
// setup a common event-log for the tracking objects and -allocator
auto& log = TrackingAllocator::log;
Tracker::log.clear("Tracking-Allocator-Test");
Tracker::log.joinInto(log);

View file

@ -81799,7 +81799,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="idea"/>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#4e3b7f" CREATED="1718034857705" FOLDED="true" ID="ID_725324060" MODIFIED="1718294109135" TEXT="Alignment beachten">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#4e3b7f" CREATED="1718034857705" ID="ID_725324060" MODIFIED="1718586182698" TEXT="Alignment beachten">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1718035817292" ID="ID_908227037" MODIFIED="1718035826853" TEXT="Verwendungen von sizeof(TY)">
<icon BUILTIN="idea"/>
@ -81884,8 +81884,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="yes"/>
</node>
</node>
<node COLOR="#338800" CREATED="1718066378097" ID="ID_1766969093" MODIFIED="1718067200842" TEXT="Anpassungen am Code (&#xbb;grob korrekt&#xab;)">
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1718066378097" ID="ID_1766969093" MODIFIED="1718588133769" TEXT="Anpassungen am Code">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1718066394480" ID="ID_326301567" MODIFIED="1718067158583" TEXT="Puffer-Alignment &#x27f6; void*">
<icon BUILTIN="button_ok"/>
</node>
@ -81895,6 +81895,99 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node COLOR="#338800" CREATED="1718067163803" ID="ID_1053644006" MODIFIED="1718067198266" TEXT="&quot;sizeof(TY)&quot; &#x27fc; reqSiz&lt;TY&gt;()">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718586230120" ID="ID_1182714506" MODIFIED="1718586304461" TEXT="Puffer f&#xfc;r Alignment-Anpassung vorhalten">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1718586710311" ID="ID_180065995" MODIFIED="1718586719200" TEXT="Overhead erkennen"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1718586719814" ID="ID_492092838" MODIFIED="1718586735029" TEXT="Folgeproblem: Gr&#xf6;&#xdf;e der Gesamt-Allokation f&#xfc;r clean-up">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1718586736516" ID="ID_1186615431" MODIFIED="1718586891007" TEXT="bisher lie&#xdf; sich diese leicht errechnen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
auf Basis der buffSiz, d.h. der Gr&#246;&#223;e des reinen Nutzdatenpuffers; auf diese konnte man noch den statisch ermittelbaren Overhead aufschlagen
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1718586893951" ID="ID_449167461" MODIFIED="1718587158319" TEXT="aber wir haben das Problem, da&#xdf; nun irgendein Offset oben drauf kommt">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
Der Allocator macht nur eine raw-storage-Allocation, da is nix mit Alignment. Insofern kann der Beginn des gelieferten Speicherbereichs auch &#8222;daneben liegen&#8220; &#8212; so da&#223; wir einen Korrektur-Offset brauchen. Und der l&#228;&#223;t sich nicht systematisch erschlie&#223;en
</p>
</body>
</html>
</richcontent>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1718588145261" ID="ID_922709678" MODIFIED="1718634806800" TEXT="also &#xbb;back to square one&#xab; &#x2014; wir m&#xfc;ssen den Offset speichern...">
<icon BUILTIN="help"/>
<node CREATED="1718634808255" ID="ID_1712579568" MODIFIED="1718634813576" TEXT="nein m&#xfc;ssen wir nicht">
<icon BUILTIN="ksmiletris"/>
</node>
<node CREATED="1718634816323" ID="ID_1531636233" MODIFIED="1718634923456" TEXT="dem Allokator kann der volle Typ gegeben werden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
Der Aufruf des Allokators erfolgt aus dem Builder, und <i>an der Stelle ist ohne Weiteres der volle Typ konstelliert</i>
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1718634854895" ID="ID_872082102" MODIFIED="1718634878162" TEXT="nur das Front-End ist auf den vereinfachten Typ festgelegt"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718586250781" ID="ID_984021528" MODIFIED="1718586384880" TEXT="das ArrayBucket korrekt im Puffer platzieren">
<linktarget COLOR="#d4095b" DESTINATION="ID_984021528" ENDARROW="Default" ENDINCLINATION="-356;23;" ID="Arrow_ID_628657346" SOURCE="ID_1877181499" STARTARROW="None" STARTINCLINATION="552;-65;"/>
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1718587577355" ID="ID_305228810" MODIFIED="1718587885224" TEXT="mit dem Allocator-Framework passiert das nicht korrekt">
<icon BUILTIN="broken-line"/>
<node CREATED="1718587596641" ID="ID_810422938" MODIFIED="1718587728564" TEXT="es g&#xe4;be eine spezielle Variante von operator new, die ein Alignment nimmt">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...to allocate storage required for a single object whose alignment requirement exceeds __STDCPP_DEFAULT_NEW_ALIGNMENT__
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1718587730599" ID="ID_1733586133" MODIFIED="1718587745801" TEXT="die gilt aber nur f&#xfc;r Heap-Allocationen, nicht f&#xfc;r placement-New"/>
<node CREATED="1718587887730" ID="ID_1109606143" MODIFIED="1718587909154" TEXT="normalerweise w&#xfc;rde man (deshalb!) schon die Raw-Allocation getypt machen">
<icon BUILTIN="broken-line"/>
</node>
<node CREATED="1718587914837" ID="ID_1255089684" MODIFIED="1718587997588" TEXT="also &#x201e;bei&#xdf;t&#x201c; uns jetzt wieder genau das Problem mit der dynamischen Puffergr&#xf6;&#xdf;e">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...weshalb ich ja keinen wirklich passenden statischen Typ f&#252;r ArrayBucket angeben kann, weil die Puffergr&#246;&#223;e erst zur Laufzeit bekannt wird.
</p>
</body>
</html>
</richcontent>
</node>
</node>
<node CREATED="1718588000183" ID="ID_1990467161" MODIFIED="1718588028739" TEXT="&#x27f9; selber machen (aus Gr&#xfc;nden der Klarheit)">
<node CREATED="1718588032517" ID="ID_1492285935" MODIFIED="1718588046931" TEXT="das ist so ein t&#xfc;ckisches Problem, das formuliert man besser explizit"/>
</node>
</node>
<node COLOR="#338800" CREATED="1718067214231" ID="ID_1276439764" LINK="#ID_1830672111" MODIFIED="1718293971538" TEXT="testen"/>
</node>
</node>
@ -83725,8 +83818,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
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>
</html></richcontent>
<icon BUILTIN="stop-sign"/>
</node>
<node CREATED="1718571040189" ID="ID_1360340759" MODIFIED="1718571734976">
@ -84222,6 +84314,24 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</body>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1718586280657" ID="ID_1877181499" MODIFIED="1718586384880" TEXT="leider gen&#xfc;gt das noch nicht...">
<arrowlink COLOR="#d4095b" DESTINATION="ID_984021528" ENDARROW="Default" ENDINCLINATION="-356;23;" ID="Arrow_ID_628657346" STARTARROW="None" STARTINCLINATION="552;-65;"/>
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1718586388686" ID="ID_1438922097" MODIFIED="1718586483948" TEXT="mu&#xdf; explizit das ArrayBucket platzieren">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
Vorsicht Falle: der Allocator <i>kann das gar nicht machen, </i>wenn man ihm im Sinn von &#187;placement new&#171; explizit die Position vorgibt
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="broken-line"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1718202490965" ID="ID_247674037" MODIFIED="1718297858099" TEXT="Handhabung von non-copyable-Objekten">
<linktarget COLOR="#638ad5" DESTINATION="ID_247674037" ENDARROW="Default" ENDINCLINATION="-777;-16;" ID="Arrow_ID_10606647" SOURCE="ID_1146034926" STARTARROW="None" STARTINCLINATION="-438;67;"/>
@ -129709,8 +129819,7 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
wenn ein Allocator nur seine eignen Allokationen hanhaben soll &#10233; <b><font size="4">Gefahr</font></b>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>