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''
This commit is contained in:
Fischlurch 2026-03-24 22:34:10 +01:00
parent ec9b73d418
commit 54c2a30f54
5 changed files with 66 additions and 26 deletions

View file

@ -367,6 +367,12 @@ namespace util {
return const_cast<OBJ&> (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 ========= */

View file

@ -31,9 +31,11 @@
#include <utility>
#include <algorithm>
#include <functional>
#include <tuple>
#include <map>
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<Buff*, BuffHandle> buffIdx_;
using Claim = std::tuple<FrameID,BuffHandle>;
using BuffIdx = std::map<Buff*, Claim>;
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<AllocState> (outputTracker.numDataFeeds
,[&](ConStorage& storage){ storage.create<DummyConnection> (outputTracker); }
,[&,i=0](ConStorage& storage) mutable { storage.create<DummyConnection> (outputTracker, i++); }
);
}

View file

@ -41,8 +41,9 @@
#include "test/test-frame.hpp"
#include <unordered_set>
#include <vector>
#include <memory>
#include <vector>
#include <map>
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<uint, FrameInfo> recorded;
FrameInfo const&
frame (uint fraNr) const
{
///////////////////////////OOO access stored log
return lib::NullValue<FraInfo>::get();
auto pos = recorded.find (fraNr);
if (pos != recorded.end())
return pos->second;
else
return lib::NullValue<FrameInfo>::get();
}
auto
@ -116,10 +122,10 @@ namespace out {
;
}
};
template<typename BU>
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<typename BU>
inline bool
FraInfo::operator== (BU const& refVal) const
FrameInfo::operator== (BU const& refVal) const
{
return storage
and accessAs<BU>() == 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

View file

@ -93,7 +93,6 @@ namespace out {
{
Buff* buffer = asTarget(targetMarker).claimBufferFor (frameNr);
BuffAlloc storageSlot{buffer, siz, targetMarker};
TODO ("delegate buffer lock");
return storageSlot;
}

View file

@ -116,10 +116,6 @@ namespace out {
: public std::function<BuffHandle(FrameID)>
{
public:
template<typename FUN>
DataSink (FUN&& fun)
: std::function<BuffHandle(FrameID)>{std::forward<FUN> (fun)}
{ }
/////////////////////////////////////////////TICKET #1377 : presumably we want some stream-type hash ID here -- to allow building a processing-ID for each Render Node invocation
};