Parameters: verify sane storage handling
- as it turns out: we need `UninitialisedStorage` to avoid spurious ctor calls - and the extent-index is computed by div, not mod !! With these fixes, I can now demonstrate that the allocation procees exactly as expected, the registry can be filled completely, and no memory is leaked or corrupted (the latter only verified with some probes)
This commit is contained in:
parent
1d0580cfb4
commit
c5f53aed84
3 changed files with 223 additions and 21 deletions
|
|
@ -38,6 +38,7 @@
|
|||
#include "lib/error.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/uninitialised-storage.hpp"
|
||||
//#include "lib/meta/trait.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
|
|
@ -68,7 +69,7 @@ namespace par {
|
|||
static constexpr uint EXTENT_SIZ = 256;
|
||||
static constexpr uint INDEX_SIZ = 256;
|
||||
|
||||
using Extent = std::array<ELM, EXTENT_SIZ>;
|
||||
using Extent = lib::UninitialisedStorage<ELM, EXTENT_SIZ>;
|
||||
using Index = std::array<std::atomic<Extent*>, INDEX_SIZ>;
|
||||
|
||||
Index index_{};
|
||||
|
|
@ -82,6 +83,10 @@ namespace par {
|
|||
|
||||
ELM& operator[] (ID) const;
|
||||
|
||||
/* == Registry state == */
|
||||
uint size() const { return size_; }
|
||||
uint numExtents() const { return size_? 1 + (size_-1) / EXTENT_SIZ : 0; }
|
||||
|
||||
~TypeRegistry();
|
||||
private:
|
||||
Extent* accessExtent (ID) const;
|
||||
|
|
@ -120,14 +125,14 @@ namespace par {
|
|||
|
||||
Lock sync{this};
|
||||
ID entryID{size_};
|
||||
auto& indexSlot = index_[entryID % EXTENT_SIZ];
|
||||
auto& indexSlot = index_[entryID / EXTENT_SIZ];
|
||||
Extent* extent = indexSlot.load (std::memory_order_acquire);
|
||||
if (not extent)
|
||||
indexSlot.store (new Extent{} // heap-allocate new Extent
|
||||
indexSlot.store (extent = new Extent{} // heap-allocate new Extent
|
||||
,std::memory_order_release);
|
||||
|
||||
void* storage = indexSlot + (entryID % EXTENT_SIZ);
|
||||
new (storage) ELM(std::forward<INIT> (initArg)...);
|
||||
extent->createAt (entryID % EXTENT_SIZ
|
||||
,std::forward<INIT> (initArg)...);
|
||||
++size_;
|
||||
return entryID;
|
||||
}
|
||||
|
|
@ -145,9 +150,8 @@ namespace par {
|
|||
try {
|
||||
for (uint slot=0; slot<size_; ++slot)
|
||||
{
|
||||
Extent*& extent = UN_CONST (accessExtent (slot));
|
||||
ELM& entry = (*extent)[slot % EXTENT_SIZ];
|
||||
entry.~ELM();
|
||||
Extent* extent = UN_CONST (accessExtent (slot));
|
||||
extent->destroyAt (slot % EXTENT_SIZ);
|
||||
}
|
||||
for (uint idxSlot=0; idxSlot<INDEX_SIZ; ++idxSlot)
|
||||
{
|
||||
|
|
@ -166,7 +170,7 @@ namespace par {
|
|||
inline TypeRegistry<ELM>::Extent*
|
||||
TypeRegistry<ELM>::accessExtent (ID entryID) const
|
||||
{
|
||||
auto& indexSlot = index_[entryID % EXTENT_SIZ];
|
||||
auto& indexSlot = index_[entryID / EXTENT_SIZ];
|
||||
return indexSlot.load (std::memory_order_acquire);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,18 +88,109 @@ namespace test{
|
|||
}
|
||||
|
||||
|
||||
/** @test
|
||||
* @todo WIP 9/26 🔁 define ⟶ implement
|
||||
/** @test verify coherent storage handling and proper clean-up
|
||||
* - slots are filled-up in sequence
|
||||
* - the ID corresponds to the slot-count
|
||||
* - new extents are opend precisely when the
|
||||
* previous Extent is filled completely
|
||||
* - Exceptions during slot-allocation are absorbed,
|
||||
* without blocking the slot or corrupting data
|
||||
* - the designate storage space can be utilised completely
|
||||
* - when the registry is full, further allocations are blocked
|
||||
* - but even a then the registry remains in sane state
|
||||
* - all destructors of all slots are invoked
|
||||
* @todo WIP 10/26 ✔ define ⟶ ✔ implement
|
||||
*/
|
||||
void
|
||||
verify_storageSanity()
|
||||
{
|
||||
UNIMPLEMENTED ("verify coherent storage handling and proper clean-up");
|
||||
Dummy::checksum() = 0;
|
||||
{ // track instances by checksum...
|
||||
Registry registry;
|
||||
CHECK (0 == registry.size());
|
||||
CHECK (0 == registry.numExtents());
|
||||
|
||||
RegID i0 = registry.makeSlot();
|
||||
CHECK (1 == registry.size());
|
||||
CHECK (1 == registry.numExtents());
|
||||
|
||||
CHECK (i0 == 0);
|
||||
int rand0 = registry[i0].getID();
|
||||
CHECK (0 < rand0);
|
||||
CHECK (Dummy::checksum() == registry[i0].getID());
|
||||
|
||||
RegID i1 = registry.makeSlot();
|
||||
CHECK (2 == registry.size());
|
||||
CHECK (1 == registry.numExtents());
|
||||
int rand1 = registry[i1].getID();
|
||||
|
||||
CHECK (i1 == 1);
|
||||
CHECK (Dummy::checksum() == registry[i0].getID()
|
||||
+ registry[i1].getID());
|
||||
|
||||
for (uint i=0; i<256; ++i)
|
||||
registry.makeSlot();
|
||||
// first Extent was filled up
|
||||
CHECK (256+2 == registry.size());
|
||||
CHECK (2 == registry.numExtents());
|
||||
CHECK (rand1 == registry[i1] .getID());
|
||||
CHECK (rand0 == registry[i0] .getID());
|
||||
|
||||
// Verify no leak in case of Exceptions during slot allocation
|
||||
int rand257 = registry[257].getID();
|
||||
CHECK (0 < rand257);
|
||||
long checkPre = Dummy::checksum();
|
||||
Dummy::activateCtorFailure();
|
||||
try {
|
||||
registry.makeSlot(-55);
|
||||
NOTREACHED ("did not throw");
|
||||
}
|
||||
catch (int& magic)
|
||||
{
|
||||
CHECK (magic == -55);
|
||||
// since the dtor is not called on ctor failure,
|
||||
// we have to fix the checksum explicitly here
|
||||
Dummy::checksum() -= (-55);
|
||||
Dummy::activateCtorFailure(false);
|
||||
}
|
||||
// now the important point:
|
||||
CHECK (256+2 == registry.size()); // next slot was not marked as claimed
|
||||
CHECK (2 == registry.numExtents());
|
||||
CHECK (Dummy::checksum() == checkPre);
|
||||
CHECK (rand257 == registry[257].getID());
|
||||
CHECK (rand1 == registry[i1] .getID());
|
||||
CHECK (rand0 == registry[i0] .getID());
|
||||
|
||||
// fill-up the second Extent completely
|
||||
for (uint i=2; i<256; ++i)
|
||||
registry.makeSlot();
|
||||
CHECK (2*256 == registry.size());
|
||||
CHECK (2 == registry.numExtents());
|
||||
|
||||
// and then fill up all the designated storage
|
||||
for (uint i=registry.size(); i<256*256; ++i)
|
||||
registry.makeSlot();
|
||||
CHECK (256*256 == registry.size());
|
||||
CHECK (256 == registry.numExtents());
|
||||
|
||||
// can not allocate further...
|
||||
checkPre = Dummy::checksum();
|
||||
VERIFY_FAIL ("space exhausted for type Dummy"
|
||||
, registry.makeSlot() );
|
||||
|
||||
// yet the registry is in sane state
|
||||
CHECK (Dummy::checksum() == checkPre);
|
||||
CHECK (rand0 == registry[i0] .getID());
|
||||
CHECK (rand1 == registry[i1] .getID());
|
||||
CHECK (rand257 == registry[257].getID());
|
||||
|
||||
}//automatic clean-up of Registry triggered here
|
||||
CHECK (0 == Dummy::checksum());
|
||||
}
|
||||
|
||||
|
||||
/** @test
|
||||
* @todo WIP 9/26 🔁 define ⟶ implement
|
||||
* @todo WIP 10/26 🔁 define ⟶ implement
|
||||
*/
|
||||
void
|
||||
verify_concurrentAccess()
|
||||
|
|
|
|||
|
|
@ -86291,8 +86291,8 @@ class ScaleRegistry
|
|||
<linktarget COLOR="#426aa5" DESTINATION="ID_435108847" ENDARROW="Default" ENDINCLINATION="28;-70;" ID="Arrow_ID_1818399541" SOURCE="ID_735608493" STARTARROW="None" STARTINCLINATION="-393;12;"/>
|
||||
<linktarget COLOR="#365ac0" DESTINATION="ID_435108847" ENDARROW="Default" ENDINCLINATION="-11;82;" ID="Arrow_ID_246372510" SOURCE="ID_438812693" STARTARROW="None" STARTINCLINATION="14;-8;"/>
|
||||
<node CREATED="1789159448086" ID="ID_1755995276" MODIFIED="1789159547368" TEXT="Feste Index-Tabelle + heap-allozierte Extents"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1790478166301" ID="ID_1258631659" MODIFIED="1792195251812" TEXT="Implementierung nach Standard-Schema (wie von Claude vorgeschlagen)">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1790478166301" ID="ID_1258631659" MODIFIED="1792201647439" TEXT="Implementierung nach Standard-Schema (wie von Claude vorgeschlagen)">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1792195119872" ID="ID_755422994" MODIFIED="1792195149285" TEXT="sehe (vorerst?) einen hart-gecodeten 16bit-Index-Space vor">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
|
|
@ -86312,20 +86312,99 @@ class ScaleRegistry
|
|||
<node CREATED="1792195292550" ID="ID_1991831189" MODIFIED="1792195314280" TEXT="die Slot-Auswahl erfolgt per Modulus">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1792195325746" ID="ID_1685989678" MODIFIED="1792195369088" TEXT="Belegung wird (implizii) durch ein size-Feld definiert">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1792195325746" ID="ID_1685989678" MODIFIED="1792200835146" TEXT="Belegung wird (implizit) durch ein size-Feld definiert">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1792195373545" HGAP="36" ID="ID_845978423" MODIFIED="1792195403780" TEXT="gilt nur wenn wir die Size bei jeder Neubelegung erhöhen" VSHIFT="3">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1792195373545" HGAP="36" ID="ID_845978423" MODIFIED="1792200799927" TEXT="gilt nur wenn wir die Size bei jeder Neubelegung erhöhen" VSHIFT="3">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1792200802117" ID="ID_1033251739" MODIFIED="1792200828503" TEXT="EX_SANE ⟹ transaktionales Verhalten an der Stelle"/>
|
||||
</node>
|
||||
<node CREATED="1792204213956" ID="ID_107103429" MODIFIED="1792204342333" TEXT="der Extent selber ist UninitialisedStorage">
|
||||
<linktarget COLOR="#4b37c9" DESTINATION="ID_107103429" ENDARROW="Default" ENDINCLINATION="-23;30;" ID="Arrow_ID_1397164980" SOURCE="ID_1969148911" STARTARROW="None" STARTINCLINATION="-93;-6;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1792204285692" ID="ID_590986949" MODIFIED="1792204294798" TEXT="das stellt auch schon in-place ctor/dtor bereit"/>
|
||||
<node CREATED="1792204295710" ID="ID_1004514102" MODIFIED="1792204304518" TEXT="und hat einen Subscript-Operator"/>
|
||||
<node COLOR="#98066e" CREATED="1792204305537" ID="ID_856918383" MODIFIED="1792204317881" TEXT="was will man mehr??">
|
||||
<font NAME="SansSerif" SIZE="10"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1792200841789" ID="ID_564663858" MODIFIED="1792201602058" TEXT="Clean-up: Destruktor">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1792200853109" ID="ID_1804538283" MODIFIED="1792200873441" TEXT="wir allozieren hier Extents ⟹ also sind wir für die verantwortlich">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1792200875231" ID="ID_28384533" MODIFIED="1792200912854" TEXT="ich hab eine Policy in Lumiera daß wir jede Allokation sauber aufräumen">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1792200915095" ID="ID_510570493" LINK="https://issues.lumiera.org/ticket/195" MODIFIED="1792201592604" TEXT="die Policy ist noch nirgends aufgeschrieben">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...außer in zwei sehr alten Tracking-Tickets
|
||||
</p>
|
||||
<p>
|
||||
Also ist das Problem, daß jemand, der neu im Projekt ist, diese Policy nicht findet
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#950a46" DESTINATION="ID_1553058398" ENDARROW="Default" ENDINCLINATION="-2162;163;" ID="Arrow_ID_1745743108" STARTARROW="None" STARTINCLINATION="125;1162;"/>
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f53" CREATED="1792201622823" ID="ID_1206249316" MODIFIED="1792201638389" TEXT="Vorsicht Falle: nicht alle Slots sind belegt">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1790478209106" ID="ID_1599776496" MODIFIED="1790478269240" TEXT="Testabdeckung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1790478219335" ID="ID_265184931" MODIFIED="1790478266894" TEXT="Standard-Nutzen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1790478219335" ID="ID_265184931" MODIFIED="1792201649437" TEXT="Standard-Nutzen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1790478228069" ID="ID_194433887" MODIFIED="1792207934918" TEXT="Memory-Konsistenz">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#df0277" CREATED="1792204102943" ID="ID_1794382952" MODIFIED="1792207761829" TEXT="erst mal denke ich: Kindergarten.....">
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
<icon BUILTIN="closed"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1792204124581" ID="ID_493858308" MODIFIED="1792204250440" TEXT="Dummy-Checksumme korrupt">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#bb0286" CREATED="1792204157016" ID="ID_1696818846" MODIFIED="1792204178459" TEXT="GUT DASS WIR DARÜBER GEREDET HABEN....">
|
||||
<font NAME="SansSerif" SIZE="10"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1792204183421" ID="ID_243269335" MODIFIED="1792204262945" TEXT="das std::array macht eine Default-Initialisierung aller Elemente">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node CREATED="1792204265342" ID="ID_1969148911" MODIFIED="1792204351217" TEXT="was wir eigentlich wollen ⟵ UninitialisedStorage">
|
||||
<arrowlink COLOR="#4b37c9" DESTINATION="ID_107103429" ENDARROW="Default" ENDINCLINATION="-23;30;" ID="Arrow_ID_1397164980" STARTARROW="None" STARTINCLINATION="-93;-6;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1792206829616" ID="ID_902979576" MODIFIED="1792207726955" TEXT="Memory-Corruption">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1792206937555" ID="ID_342404338" MODIFIED="1792207061332" TEXT="Objekte im ersten Extent sind korrumpiert"/>
|
||||
<node CREATED="1792206920901" ID="ID_1530740626" MODIFIED="1792206936517" TEXT="nach dem Überlauf in den nächsten Extent"/>
|
||||
<node CREATED="1792207657467" ID="ID_1411875772" MODIFIED="1792207667947" TEXT="mit mehreren Tests eingrenzen....">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1792207670063" ID="ID_1060014276" MODIFIED="1792207703521" TEXT="jaaaa .... banaler Fehler: den Extent berechnet man per div, nicht mod">
|
||||
<icon BUILTIN="smiley-oh"/>
|
||||
</node>
|
||||
<node COLOR="#eb00ff" CREATED="1792207706939" ID="ID_461398393" MODIFIED="1792207723618" TEXT="(soviel zum Kindergarten...)">
|
||||
<font NAME="SansSerif" SIZE="10"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1792207770559" ID="ID_65610285" MODIFIED="1792207933489" TEXT="somit gezeigt">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1792207790400" ID="ID_208694130" MODIFIED="1792207798975" TEXT="Extent-Überlauf wie erwartet"/>
|
||||
<node CREATED="1792207778639" ID="ID_1060787372" MODIFIED="1792207789404" TEXT="konsistente Belegung des Speichers"/>
|
||||
<node CREATED="1792207802306" ID="ID_1439326321" MODIFIED="1792207836217" TEXT="nach Exteption im Konstruktor ist der Slot unbelegt"/>
|
||||
<node CREATED="1792207837061" ID="ID_1232596455" MODIFIED="1792207846375" TEXT="es werden keine überschüssigen Objekte erzeugt / kopiert"/>
|
||||
<node CREATED="1792207848433" ID="ID_1119023990" MODIFIED="1792207862270" TEXT="der Speicher läßt sich komplett wie geplant belegen"/>
|
||||
<node CREATED="1792207863165" ID="ID_362511232" MODIFIED="1792207900809" TEXT="danach wirft jede weitere Allokation eine Exception"/>
|
||||
<node CREATED="1792207876696" ID="ID_506276452" MODIFIED="1792207886744" TEXT="aber die Registry bleibt trotzem valide"/>
|
||||
<node CREATED="1792207887665" ID="ID_1708245037" MODIFIED="1792207896452" TEXT="keine Memory-corruption"/>
|
||||
<node CREATED="1792207903239" ID="ID_140698597" MODIFIED="1792207930110" TEXT="alle Destruktoren aufgerufen"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1790478228069" ID="ID_194433887" MODIFIED="1790478263177" TEXT="Memory-Konsistenz">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1790478238100" ID="ID_1243204093" MODIFIED="1790478263177" TEXT="Concurrency safe">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
@ -199475,6 +199554,34 @@ that situation will improve in forseeable future.</pre>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1792200963321" ID="ID_977715558" MODIFIED="1792201064964" TEXT="Policies vollständig dokumentieren">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1792200973248" ID="ID_1553058398" MODIFIED="1792201526827" TEXT="keine »ich-weiß-schon«-Memory-Leaks">
|
||||
<linktarget COLOR="#950a46" DESTINATION="ID_1553058398" ENDARROW="Default" ENDINCLINATION="-2162;163;" ID="Arrow_ID_1745743108" SOURCE="ID_510570493" STARTARROW="None" STARTINCLINATION="125;1162;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1792201093264" ID="ID_267958438" MODIFIED="1792201103566" TEXT="jede Komponente muß 100% sauber herunterfahren"/>
|
||||
<node COLOR="#5b280f" CREATED="1792201105051" ID="ID_1016950981" MODIFIED="1792201178160" TEXT="keinen Speicher allozieren und dann »fahren lassen«">
|
||||
<icon BUILTIN="closed"/>
|
||||
</node>
|
||||
<node CREATED="1792201125588" ID="ID_1093524502" MODIFIED="1792201162126" TEXT="„das wird eh nie freigegeben“ ⟵ Argument nicht akzeptiert">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
<node CREATED="1792201182716" ID="ID_1787841677" MODIFIED="1792201288137" TEXT="Begründung">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1792201190718" ID="ID_114767434" MODIFIED="1792201198901" TEXT="das fördert eine schlampige Haltung"/>
|
||||
<node CREATED="1792201220450" ID="ID_481912438" MODIFIED="1792201235126" TEXT="verleitet dazu, »irgendwo unterwegs« Speicher zu belegen"/>
|
||||
<node CREATED="1792201200106" ID="ID_873731372" MODIFIED="1792201211063" TEXT="wenn man eine Allokation versteht, kann man sie auch freigeben"/>
|
||||
<node CREATED="1792201243028" ID="ID_1201322449" MODIFIED="1792201261779" TEXT="Allokation folgt einem Processing-scheme (und ist nicht »zufällig«)"/>
|
||||
<node CREATED="1792201264193" ID="ID_1183168307" MODIFIED="1792201276071" TEXT="für akzidentelle Allokationen gibt es smart-ptr"/>
|
||||
</node>
|
||||
<node CREATED="1792201444896" ID="ID_1528622794" MODIFIED="1792201448579" TEXT="Publikation">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1792201450444" ID="ID_1658351750" LINK="https://issues.lumiera.org/ticket/195" MODIFIED="1792201465871" TEXT=" #195 Clean shutdown"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1792201478154" ID="ID_21619646" LINK="https://issues.lumiera.org/ticket/198" MODIFIED="1792201490370" TEXT="#198 Quick shutdown"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1792201492208" ID="ID_469735320" MODIFIED="1792201505624" TEXT="TODO: geeignete Policy-Darstellung">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1762902461883" ID="ID_1559550337" MODIFIED="1762902464870" TEXT="Meta">
|
||||
<node CREATED="1762902465988" ID="ID_1902716840" MODIFIED="1762902476765" TEXT="Projektorganisation"/>
|
||||
<node CREATED="1762902477581" ID="ID_659681075" MODIFIED="1762902520594" TEXT="Authors / Attribution">
|
||||
|
|
|
|||
Loading…
Reference in a new issue