From 945636c446d93f898057bd8eed507bd766ba206a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 16 Feb 2026 23:57:12 +0100 Subject: [PATCH] BufferProvider: connect the first wire-tap to record locked state ...this turns out to be surprisingly difficult, due to various subclass / protected visibility problems. Not sure if the component design within `DiagnosticBufferProvider` is sane yet... --- src/steam/engine/buffer-provider.cpp | 12 ++- src/steam/engine/buffer-provider.hpp | 1 + .../engine/diagnostic-buffer-provider.cpp | 76 +++++++++++++------ .../engine/diagnostic-buffer-provider.hpp | 15 ++-- wiki/thinkPad.ichthyo.mm | 23 +++++- 5 files changed, 95 insertions(+), 32 deletions(-) diff --git a/src/steam/engine/buffer-provider.cpp b/src/steam/engine/buffer-provider.cpp index 973e5e3b3..922c91fbe 100644 --- a/src/steam/engine/buffer-provider.cpp +++ b/src/steam/engine/buffer-provider.cpp @@ -81,7 +81,7 @@ namespace engine { BufferProvider::getDescriptorFor (size_t storageSize) { auto& typeKey = bufferStage_->defineBufferType (storageSize, TypeHandler::RAW); - return BuffDescr (*this, typeKey); + return buildDescriptor (typeKey); } @@ -89,7 +89,7 @@ namespace engine { BufferProvider::getDescriptorFor(size_t storageSize, TypeHandler specialTreatment) { auto& typeKey = bufferStage_->defineBufferType (storageSize, move (specialTreatment)); - return BuffDescr (*this, typeKey); + return buildDescriptor (typeKey); } @@ -143,7 +143,7 @@ namespace engine { auto [storage, localTag] = bufferStore_->provideBuffer (typeKey.storageSize(), type, typeKey.localTag()); auto& stateKey = bufferStage_->mark_locked (typeKey, storage, localTag); - return BuffHandle (BuffDescr(*this, HashVal(stateKey)), storage); + return BuffHandle (buildDescriptor(stateKey), storage); } // NOTE: not the underlying parent descriptor! @@ -211,6 +211,12 @@ namespace engine { /* === BuffDescr and BuffHandle === */ + BuffDescr + BufferProvider::buildDescriptor (HashVal key) + { + return {*this, key}; + } + bool BufferProvider::was_created_by_this_provider (BuffDescr const& descr) const { diff --git a/src/steam/engine/buffer-provider.hpp b/src/steam/engine/buffer-provider.hpp index 08424778a..073a32a0c 100644 --- a/src/steam/engine/buffer-provider.hpp +++ b/src/steam/engine/buffer-provider.hpp @@ -187,6 +187,7 @@ namespace engine { protected: ~BufferProvider(); + BuffDescr buildDescriptor (HashVal); bool was_created_by_this_provider (BuffDescr const&) const; using Buff = StreamType::ImplFacade::DataBuffer; ///< marker type for an actual data buffer diff --git a/src/steam/engine/diagnostic-buffer-provider.cpp b/src/steam/engine/diagnostic-buffer-provider.cpp index ec6f28644..791442347 100644 --- a/src/steam/engine/diagnostic-buffer-provider.cpp +++ b/src/steam/engine/diagnostic-buffer-provider.cpp @@ -30,6 +30,7 @@ #include "lib/util.hpp" #include +#include #include @@ -42,27 +43,34 @@ namespace engine { using diagn::StateReg; using std::unique_ptr; using std::ranges::find_if; + using std::move; + + using metadata::Key; - /** - * Implementation of tracking and instrumentation - */ - struct DiagnosticBufferProvider::BlockTracker - : util::NonCopyable - { - StateReg created; - StateReg emitted; - StateReg released; - }; - - Block::Block (BuffHandle const& handle) - : handle{handle} + + /* ====== Accounting API ====== */ + + Block::Block (BuffDescr typeDescriptor, Key stateKey, Buff* mem) + : handle{typeDescriptor, mem} + , storage{mem} { } Block::Block (BuffDescr const& descr) : handle{descr} { } + void + StateReg::record (PBlock blockRef) + { + reg_.emplace_back (move (blockRef)); + } + + void + StateReg::record (Block block) + { + record (std::make_shared (block)); + } size_t StateReg::cnt() const @@ -93,6 +101,32 @@ namespace engine { , LERR_(BOTTOM_VALUE)); } + bool + StateReg::contains (HashVal handle) const + { + return bool(byHandle (handle)); + } + + + + /** + * Implementation of tracking and instrumentation + */ + struct DiagnosticBufferProvider::BlockTracker + : util::NonCopyable + { + StateReg created; + StateReg emitted; + StateReg released; + + void + record_locked (BuffDescr typeDescriptor, Key stateKey, Buff* mem) + { + REQUIRE (not created.contains (typeDescriptor)); + created.record (Block{typeDescriptor, stateKey, mem}); + } + }; + class DiagnosticBufferProvider::InstrumentedStageProxy : public BufferProviderSetup::Stage @@ -102,6 +136,7 @@ namespace engine { StageImp stage_; Tracker& tracker_; + DiagnosticBufferProvider& provider_; /* === BufferStage proxy implementation === */ @@ -127,7 +162,9 @@ namespace engine { ID mark_locked (ID typeKey, Buff* storage, LocalTag implMark) override { - return stage_->mark_locked (typeKey, storage, implMark); + ID stateKey = stage_->mark_locked (typeKey, storage, implMark); + tracker_.record_locked (provider_.buildDescriptor(stateKey), stateKey, storage); + return stateKey; } ID @@ -155,18 +192,13 @@ namespace engine { } public: - InstrumentedStageProxy (StageImp rawImpl, Tracker& tracker) + InstrumentedStageProxy (StageImp rawImpl, Tracker& tracker, DiagnosticBufferProvider& provider) : stage_{move(rawImpl)} , tracker_{tracker} + , provider_{provider} { } }; - /* ====== Accounting API ====== */ - void - StateReg::record (BuffHandle const& handle) - { - reg_.emplace_back (std::make_shared (handle)); - } DiagnosticBufferProvider::DiagnosticBufferProvider() @@ -174,7 +206,7 @@ namespace engine { , heapStore_{dynamic_cast (*bufferStore_)} //////////////////////////////////////////TICKET 1410 : obsolete after switch to newtracking-API , tracker_{std::make_unique()} { - decorate (bufferStage_, *tracker_); + decorate (bufferStage_, *tracker_, *this); } DiagnosticBufferProvider::~DiagnosticBufferProvider() diff --git a/src/steam/engine/diagnostic-buffer-provider.hpp b/src/steam/engine/diagnostic-buffer-provider.hpp index 93d92251e..c8cf39b66 100644 --- a/src/steam/engine/diagnostic-buffer-provider.hpp +++ b/src/steam/engine/diagnostic-buffer-provider.hpp @@ -37,6 +37,8 @@ namespace engine { namespace error = lumiera::error; + using Buff = StreamType::ImplFacade::DataBuffer; ///////////TODO consider to define that marker type at some suitable central location + class HeapMemBufferStore; //////////////////////////////OOO fällt dann weg nach dem Umbau class BufferDiagnostic; @@ -46,10 +48,10 @@ namespace engine { struct Block { BuffHandle handle; - void* storage{nullptr}; - void* accessMemory() const { return storage; } + Buff* storage{nullptr}; + Buff* accessMemory() const { return storage; } - Block (BuffHandle const&); + Block (BuffDescr, metadata::Key, Buff* mem); Block (BuffDescr const&); operator HashVal() const { return handle; } }; @@ -58,7 +60,8 @@ namespace engine { class StateReg : util::NonCopyable { - using Registry = std::vector>; + using PBlock = std::shared_ptr; + using Registry = std::vector; Registry reg_; public: @@ -66,10 +69,12 @@ namespace engine { using Result = lib::Result; Result operator[] (size_t seqNr) const; Result byHandle (HashVal handle) const; + bool contains (HashVal handle) const; size_t cnt() const; /* ========= Accounting API ========= */ - void record (BuffHandle const&); + void record (Block); + void record (PBlock); }; }//(End)diagnostic descriptors. diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 444216144..4ff31d47b 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -112855,6 +112855,26 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + + +

+ ...und zwar, weil wir ein BuffHandle speichern wollen, das einen BufferProvider einschließt. Dazu brauchen wir die Rückreferenz auf den Provider. Und das darf eigentlich nur BufferProvider selber... +

+ + +
+ +
+ + + + + + @@ -113165,8 +113185,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) Deshalb nenne ich es auch ein »Protocol« — wollten wir etwas wirklich wasserdichtes,  dann müßten wir die Struktur ganz anders anlegen, und vermutlich auch deutlich rigider, und mehr interne Zugriffe verwenden.

- - +