From 54c2a30f54d6e6bc45153945347b925e0fdfcf92 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 24 Mar 2026 22:34:10 +0100 Subject: [PATCH] OutputSlot: fill in the tracking implementation Straight-forward: - add a map keyed by observed frame numbers - individual connection needs to know its own seqNr :-( - also need to store and recall the frameNr in the buffer-Index Fix bug with DataSink constructor (value constructor shadows copy constructor => Stackoverflow) ''Complete construction and wiring sequence works as intended'' --- src/lib/util.hpp | 6 +++ src/vault/out/diagnostic-output-slot.cpp | 51 +++++++++++++++++++----- src/vault/out/diagnostic-output-slot.hpp | 30 ++++++++------ src/vault/out/output-buffer-proxy.hpp | 1 - src/vault/out/output-slot.hpp | 4 -- 5 files changed, 66 insertions(+), 26 deletions(-) diff --git a/src/lib/util.hpp b/src/lib/util.hpp index f834299a8..02f22e198 100644 --- a/src/lib/util.hpp +++ b/src/lib/util.hpp @@ -367,6 +367,12 @@ namespace util { return const_cast (ro); } + /** similar shortcut to repurpose a const accessor + * for implementing a similar non-const variant + * @warning beware! you might be subverting the contract + */ + #define UN_CONST(_CALL_) util::unConst (std::as_const(*this). _CALL_ ) + /* ======== address and identity ========= */ diff --git a/src/vault/out/diagnostic-output-slot.cpp b/src/vault/out/diagnostic-output-slot.cpp index 15467e009..317fe5cd5 100644 --- a/src/vault/out/diagnostic-output-slot.cpp +++ b/src/vault/out/diagnostic-output-slot.cpp @@ -31,9 +31,11 @@ #include #include #include +#include #include using util::contains; +using util::isSameAdr; // using std::vector; // using Config = DiagnosticOutputSlot::Config; using std::byte; @@ -45,6 +47,7 @@ using std::function; using vault::mem::NaiveBufferSetup; using vault::mem::BuffHandle; using vault::mem::BuffDescr; +using vault::mem::Buff; namespace vault { namespace out { @@ -98,6 +101,31 @@ namespace out { REQUIRE (feedNr < feed_.size()); return feed_[feedNr]; } + + void + recordClaim (uint feedNr, FrameID frame, Buff* buff) + { + diagn::FrameInfo& frameInfo = feed_[feedNr].recorded[frame]; + frameInfo.buffSize = bufferSize; + frameInfo.storage = buff; + frameInfo.locked = currentTime(); + } + + void + recordPublish (uint feedNr, FrameID frame, Buff* buff) + { + diagn::FrameInfo& frameInfo = feed_[feedNr].recorded[frame]; + REQUIRE (isSameAdr(frameInfo.storage, buff)); + frameInfo.emitted = currentTime(); + } + + void + recordRelease (uint feedNr, FrameID frame, Buff* buff) + { + diagn::FrameInfo& frameInfo = feed_[feedNr].recorded[frame]; + REQUIRE (isSameAdr(frameInfo.storage, buff)); + frameInfo.released = currentTime(); + } }; /** @@ -120,7 +148,11 @@ namespace out { { OutputTracker& tracker_; - std::map buffIdx_; + using Claim = std::tuple; + using BuffIdx = std::map; + + BuffIdx buffIdx_; + uint feedNr_; /* === Connection API === */ @@ -138,8 +170,8 @@ namespace out { REQUIRE (handle.isValid()); Buff* buff = handle.rawStorage(); ENSURE (not contains (buffIdx_, buff)); - buffIdx_.insert ({buff, handle}); - UNIMPLEMENTED ("track new buffer"); + buffIdx_.insert ({buff, Claim{frame,handle}}); + tracker_.recordClaim (feedNr_,frame, buff); return buff; } @@ -147,18 +179,18 @@ namespace out { publish (Buff* buff) override { REQUIRE (contains (buffIdx_,buff)); - auto handle = buffIdx_.find(buff)->second; + auto [frame,handle] = buffIdx_.find(buff)->second; handle.emit(); - UNIMPLEMENTED ("track publish buffer"); + tracker_.recordPublish (feedNr_,frame, buff); } void release (Buff* buff) override { REQUIRE (contains (buffIdx_,buff)); - auto handle = buffIdx_.find(buff)->second; + auto [frame,handle] = buffIdx_.find(buff)->second; handle.release(); - UNIMPLEMENTED ("track release buffer"); + tracker_.recordRelease (feedNr_,frame, buff); } void @@ -170,8 +202,9 @@ namespace out { public: - DummyConnection (OutputTracker& tracker) + DummyConnection (OutputTracker& tracker, uint thisFeed) : tracker_{tracker} + , feedNr_{thisFeed} { } }; @@ -217,7 +250,7 @@ namespace out { using ConStorage = AllocState::ConnectionStorage; return make_unique (outputTracker.numDataFeeds - ,[&](ConStorage& storage){ storage.create (outputTracker); } + ,[&,i=0](ConStorage& storage) mutable { storage.create (outputTracker, i++); } ); } diff --git a/src/vault/out/diagnostic-output-slot.hpp b/src/vault/out/diagnostic-output-slot.hpp index cd58389fb..114fa6d19 100644 --- a/src/vault/out/diagnostic-output-slot.hpp +++ b/src/vault/out/diagnostic-output-slot.hpp @@ -41,8 +41,9 @@ #include "test/test-frame.hpp" #include -#include #include +#include +#include namespace vault { @@ -61,6 +62,7 @@ namespace out { using vault::mem::BuffHandle; using vault::mem::BuffDescr; + using std::as_const; using std::shared_ptr; using std::make_unique; @@ -72,13 +74,12 @@ namespace out { const uint DEFAULT_DATAFEEDS = 5; } -/////////////////////////////////////////////////////////////////////// -/// /////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1395 : draft compatible Tracking-API + + namespace diagn { using Buff = vault::mem::Buff; - struct FraInfo + struct FrameInfo { TimeVar locked{Time::NEVER}; TimeVar emitted{Time::NEVER}; @@ -101,11 +102,16 @@ namespace out { struct FeedLog { - FraInfo const& + std::map recorded; + + FrameInfo const& frame (uint fraNr) const { - ///////////////////////////OOO access stored log - return lib::NullValue::get(); + auto pos = recorded.find (fraNr); + if (pos != recorded.end()) + return pos->second; + else + return lib::NullValue::get(); } auto @@ -116,10 +122,10 @@ namespace out { ; } }; - + template inline BU const& - FraInfo::accessAs() const + FrameInfo::accessAs() const { if (not storage) throw err::Logic ("buffer for this frame was never actually locked" @@ -129,7 +135,7 @@ namespace out { template inline bool - FraInfo::operator== (BU const& refVal) const + FrameInfo::operator== (BU const& refVal) const { return storage and accessAs() == refVal; @@ -149,7 +155,7 @@ namespace out { * - the implementation uses a special protocol output buffer, * which stores each "frame" in memory for later investigation * - the output data in the buffers handed over from client - * actually hold an TestFrame instance + * actually hold an TestFrame instance * - the maximum number of channels and the maximum number * of acceptable frames is limited to 5 and 100. * @warning any Captured (test) data from all individual instances diff --git a/src/vault/out/output-buffer-proxy.hpp b/src/vault/out/output-buffer-proxy.hpp index 5a16bd37e..42a5caaa1 100644 --- a/src/vault/out/output-buffer-proxy.hpp +++ b/src/vault/out/output-buffer-proxy.hpp @@ -93,7 +93,6 @@ namespace out { { Buff* buffer = asTarget(targetMarker).claimBufferFor (frameNr); BuffAlloc storageSlot{buffer, siz, targetMarker}; - TODO ("delegate buffer lock"); return storageSlot; } diff --git a/src/vault/out/output-slot.hpp b/src/vault/out/output-slot.hpp index 05c83cfea..fc3659841 100644 --- a/src/vault/out/output-slot.hpp +++ b/src/vault/out/output-slot.hpp @@ -116,10 +116,6 @@ namespace out { : public std::function { public: - template - DataSink (FUN&& fun) - : std::function{std::forward (fun)} - { } /////////////////////////////////////////////TICKET #1377 : presumably we want some stream-type hash ID here -- to allow building a processing-ID for each Render Node invocation };