diff --git a/src/steam/engine/buffer-metadata.hpp b/src/steam/engine/buffer-metadata.hpp index 484dbd6af..6dfb85ac0 100644 --- a/src/steam/engine/buffer-metadata.hpp +++ b/src/steam/engine/buffer-metadata.hpp @@ -217,17 +217,20 @@ namespace engine { forEntry (Key const& parent, const void* bufferAddr, LocalTag const& localTag =LocalTag::UNKNOWN) { Key newKey{parent}; // copy of parent as baseline + if (nontrivial(localTag)) + { + if (nontrivial(parent.specifics_)) + throw error::Logic{"Implementation defined local key should not be overridden. " + "Underlying buffer type already defines a nontrivial LocalTag"}; + newKey.parent_ = HashVal(parent); + newKey.hashID_ = chainedHash(newKey.hashID_, localTag); + newKey.specifics_ = localTag; + } if (bufferAddr) { newKey.parent_ = HashVal(parent); - newKey.hashID_ = chainedHash(parent, bufferAddr); - if (nontrivial(localTag)) - { - if (nontrivial(parent.specifics_)) - throw error::Logic{"Implementation defined local key should not be overridden. " - "Underlying buffer type already defines a nontrivial LocalTag"}; - newKey.specifics_ = localTag; - } } + newKey.hashID_ = chainedHash(newKey.hashID_, bufferAddr); + } return newKey; } @@ -482,9 +485,8 @@ namespace engine { Entry& store (Entry const& newEntry) { - using std::make_pair; REQUIRE (!fetch (newEntry), "duplicate buffer metadata entry"); - MetadataStore::iterator pos = entries_.insert (make_pair (HashVal(newEntry), newEntry)) + MetadataStore::iterator pos = entries_.emplace (HashVal(newEntry), newEntry) .first; ENSURE (pos != entries_.end()); @@ -610,7 +612,7 @@ namespace engine { Key const& key (Key const& parentKey, void* concreteBuffer, LocalTag const& specifics =LocalTag::UNKNOWN) { - Key derivedKey = Key::forEntry (parentKey, concreteBuffer); + Key derivedKey = Key::forEntry (parentKey, concreteBuffer, specifics); Entry* existing = table_.fetch (derivedKey); return existing? *existing @@ -619,16 +621,18 @@ namespace engine { /** core operation to access or create a concrete buffer metadata entry. * The hashID of the entry in question is built, based on the parentKey, - * which denotes a buffer type, and the concrete buffer address. If yet - * unknown, a new concrete buffer metadata Entry is created and initialised - * to LOCKED state. Otherwise just the existing Entry is fetched. + * which denotes a buffer type, optionally a implementation defined LocalTag, + * and the concrete buffer address. If yet unknown, a new concrete buffer + * metadata Entry is created and initialised to LOCKED state. Otherwise + * just the existing Entry is fetched and locked. * @note this function really \em activates the buffer. * In case the type (Key) involves a TypeHandler (functor), * its constructor function will be invoked, if actually a new * entry gets created. Typically this mechanism will be used * to placement-create an object into the buffer. - * @param parentKey a key describing the \em type of the buffer + * @param parentKey a key describing the _type_ of the buffer * @param concreteBuffer storage pointer, must not be NULL + * @param specifics an implementation defined tag * @param onlyNew disallow fetching an existing entry * @throw error::Logic when #onlyNew is set, but an equivalent entry * was registered previously. This indicates a serious error @@ -660,8 +664,8 @@ namespace engine { throw error::Logic{"Attempt to re-lock a buffer still in use" , LERR_(LIFECYCLE)}; - if (!existing) - return store_and_lock (newEntry); // actual creation + if (not existing) + return store_as_locked (newEntry); // actual creation else return existing->lock (concreteBuffer); } @@ -753,7 +757,7 @@ namespace engine { Key trackKey (PAR parent, DEF specialisation) { - Key newKey (parent,specialisation); + Key newKey{parent, specialisation}; maybeStore (newKey); return newKey; } @@ -762,12 +766,20 @@ namespace engine { maybeStore (Key const& key) { if (isKnown (key)) return; - table_.store (Entry (key, NULL)); + table_.store (Entry{key, nullptr}); } + /** store a fully populated entry immediately starting with locked state + * @remark the (optional) constructor function for a type embedded into the + * buffer is invoked when a _persistent_ entry transitions to _locked_ state; + * since a new buffer created with storage location is already marked as _locked,_ + * for sake of consistency the embedded constructor must now be invoked; if this + * fails, the state has to be transitioned back to FREE before re-throwing. + */ Entry& - store_and_lock (Entry const& metadata) + store_as_locked (Entry const& metadata) { + REQUIRE (metadata.isLocked()); Entry& newEntry = table_.store (metadata); try { diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index f10810761..4d4c28beb 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -4686,9 +4686,7 @@ - - - +

aber ist nicht auf dem Visitor-Interface darstellbar @@ -4702,9 +4700,7 @@ - - - +

....über einen GenNode-Visitor nachdenken @@ -4785,9 +4781,7 @@ - - - +

...das wäre eine Protokoll-Erweiterung @@ -4803,9 +4797,7 @@ - - - +

letztlich verworfen; siehe Ticket #1058 @@ -4838,9 +4830,7 @@ - - - +

...das heißt, @@ -5118,9 +5108,7 @@ - - - +

...der aber irgendwann (demnächst in diesem Theater) umgebaut/zurückgebaut werden soll @@ -5909,9 +5897,7 @@ - - - +

Style-Scheme for Lumiera @@ -7746,9 +7732,7 @@ - - - +

VariadicArgumentPicker_test @@ -10012,9 +9996,7 @@ - - - +

...das ist nämlich der triviale Workaround @@ -13607,9 +13589,7 @@ - - - +

Man möchte, daß für spezielle Sub-Elemente, @@ -52562,9 +52542,7 @@ - - - +

...ist jetzt geklärt. @@ -52657,9 +52635,7 @@ - - - +

...wenn es doch offenbar für den "fire-and-forget"-Fall @@ -88649,8 +88625,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
heißt: wir vergeben diese nulläre Optimierung und legen fest, daß das Ergebnis einfach in einem Buffer im Arbeitsspeicher liegt. Jeder Render-Job bekommt dann einen explizit gecodeten Kopier-Schritt

- -
+
@@ -88660,8 +88635,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
das müßte eine Marke sein, die die spezielle BufferProvider-Implementierung — also der OutputBufferProvider — erkennt und daraufhin den konkreten extrnen Output-Buffer herausgibt

- -
+
@@ -88682,8 +88656,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Diese Annahme kann man ziemlich sicher machen; eine Abweichung davon wäre nur möglich bei einem ziemlich speziellen Setup, bei dem dann setets mehrere Ergebnise auf verschiedenen Ebenen aber im gleichen Rechenprozeß anfallen

- - +
@@ -88727,8 +88700,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
...dieser eigentliche Buffer kann auch nochmal per TypeHandler einen »Inlay-Type« bekommen; aber hier beim TrackingHeapBlockProvider ist ja der entscheidenden Punkt, jede Allokation nochmal sekundär zu verzeichnen und nachzuverfolgen, um entsprechende Verifikationen in den Tests zu ermöglichen

- - +
@@ -88759,8 +88731,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
deshalb habe ich genau für diesen Zweck bereits einen Mechanismus geschaffen

- - +
@@ -88770,8 +88741,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
dieses LocalTag ist aber nicht überall auf das Buffer-Provider-API herausgeführt

- -
+
@@ -88801,9 +88771,28 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
im Besonderen an die Reihenfolge denken ... mir fällt auf, daß ich chainedHash  verwende; damit wäre der Hash-Key pfadabhängig

+ + + + + + + + + + + + + + +

+ ...und zwar je nachdem, in welcher Reihenfolge das LocalTag und die Buffer-Adresse gegeben waren: war das LocalTag zuerst da, dann würde das bereits Teil des Hash; wenn dann später jemand mit der gleichen Buffer-Adresse ankommt, aber ohne das LocalTag, dann wird der bestehende (schlimmstenfalls bereits gelockte) Eintrag nicht gefunden ⟹ es wird ein neuer Eintrag erzeugt und somit zweimal gelockt. +

+
- + +