BufferProvider: assess status and consider approach to OutputSlot (see #1395)

The first round of the [ticket:1410 BufferProvider clean-up] is roughly complete.
 * a much cleaner diagnostic interface has been defined and implemented
 * this allowed to modernise the `DiagnosticBufferProvider_test`
   and the `BufferProviderProtocol_test`
 * the implementation scheme has been split in two realms
 * the old heap-memory based implementation has been re-arranged,
   so that the aforementioned tests are **green** again.

Now is the point to draft a solution to get the interfaces of
`BufferProvider` and `OutputSlot` aligned, so that the latter
can expose its lifecycle through the former.

Today, I have analysed various aspects and developed a pathway
to get into that task, and next I will reshape the previously
failed `OutputProxyProvider_test` into a prototype to
validate this idea
This commit is contained in:
Fischlurch 2026-02-19 23:21:01 +01:00
parent 6c880c5d10
commit 722c12e312
8 changed files with 835 additions and 192 deletions

View file

@ -43,8 +43,6 @@
** once we have to build a metadata store that works well in a massively
** concurrent environment, where requests for state transition emanate
** any time form within all worker threads!
** @todo 2/2026 Do we really have to _store_ the actual buffer address into the
** metadata::Entry, as opposed to just using this information for hash computation?
**
** @see buffer-provider.hpp
** @see BufferMetadata_test
@ -277,6 +275,9 @@ namespace engine {
* instance. For the latter, Entry serves as representation and access point
* to the individual metadata; this includes using the TypeHandler for
* building and destroying buffer structures.
*
* @remark 2/2026 the plan is to use this entry beyond metadata handling
* and especially to describe a buffer within a layered allocator
*/
class Entry
: public Key

View file

@ -140,6 +140,10 @@ namespace engine {
* the client should be prepared for exceptions. The #announce operation allows
* to establish a reliably available baseline.
* @todo 2/2025 might need to accept a cache key as additional parameter //////////////////////////////////TICKET #1392 : get cache key from computation to the cache backend
* @todo 2/2026 my intention is to use metadata::Entry within a threadsafe allocator
* to pass buffers around. For this to be possible, buffer-metadata.hpp needs
* some refactoring, and then the BufferStore::provideBuffer would have to
* return a metadata::Entry
*/
BuffHandle
BufferProvider::lockBuffer (BuffDescr const& type)

View file

@ -1,8 +1,8 @@
/*
BUFFER-PROXY-PROVIDER.hpp - Adapter to access existing allocation via buffer handling protocol
BUFFER-PROXY-ADAPTOR.hpp - Adaptor to access existing allocation via buffer handling protocol
Copyright (C)
2024, Hermann Vosseler <Ichthyostega@web.de>
2024,2026 Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
@ -11,17 +11,17 @@
*/
/** @file buffer-proxy-provider.hpp
/** @file buffer-proxy-adaptor.hpp
** Adapter to expose a given memory block through a BuffHandle.
** This allows to integrate a specific data access (e.g. related to input / output)
** with the buffer lifecycle protocol as defined by BufferProvider.
** This implementation building-block allows to integrate some specific data access
** (e.g. related to input / output) through the buffer lifecycle protocol as defined by BufferProvider.
** @todo BROKEN as of 12/2024 //////////////////////////////////////////////////////////////////////////////TICKET #1387 : can not properly compose BufferProvider
** @see output-slot.hpp
** @see output-proxy-provider-test.cpp
*/
#ifndef STEAM_ENGINE_BUFFER_PROXY_PROVIDER_H
#define STEAM_ENGINE_BUFFER_PROXY_PROVIDER_H
#ifndef STEAM_ENGINE_BUFFER_PROXY_ADAPTOR_H
#define STEAM_ENGINE_BUFFER_PROXY_ADAPTOR_H
#include "lib/error.hpp"
@ -51,11 +51,19 @@ namespace engine {
/**
* Adapter to expose access to data blocks via BuffHandle and the BufferProvider protocol.
* @todo WIP-WIP 12/2024 this is a design sketch to explore extension capabilities of BufferProvider
* @todo 2/2026 broken by refactoring of BufferProvider //////////////////////////////////////////////TICKET #1410 : refactoring to separate external and implementation API
* Adapter to expose access controlled access to some memory resource
* through a [»Buffer Type«](\ref BuffDescr) and a BuffHandle as front-end,
* in accordance with the BufferProvider protocol.
*
* This template is an implementation building block and needs to be instantiated
* with a policy or configuration to define the flexible parts of the behaviour
* - what a Buffer Type means
* - is there only one resource or is this setup statefull?
* - callback functors for the lifecycle stages related to the client's access
* @todo WIP-WIP 2/2026 used as prototype to forge a path ahead to resolve
* the structural problems with OutputSlot vs. BufferProvider ///////////////////////////////////////TICKET #1415 : prototyping to resolve structural mismatch between OutputSlot / DataSink / BufferProvider
*/
class BufferProxyProvider
class BufferProxyAdaptor
: util::NonCopyable
{
@ -106,8 +114,8 @@ namespace engine {
public:
template<class LIS, typename = lib::meta::disable_if_self<BufferProxyProvider, LIS>>
BufferProxyProvider (LIS&& listener)
template<class LIS, typename = lib::meta::disable_if_self<BufferProxyAdaptor, LIS>>
BufferProxyAdaptor (LIS&& listener)
: passThroughProvider_{std::forward<LIS> (listener)}
{ }
@ -130,4 +138,4 @@ namespace engine {
}} // namespace steam::engine
#endif /*STEAM_ENGINE_BUFFER_PROXY_PROVIDER_H*/
#endif /*STEAM_ENGINE_BUFFER_PROXY_ADAPTOR_H*/

View file

@ -1,55 +0,0 @@
/*
BufferProxyProvider - Adapt existing allocation for access through the Buffer protocol
Copyright (C)
2024, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
* *****************************************************************/
/** @file buffer-proxy-provider.cpp
** Implementation details of a forwarding BufferProvider stub implementation.
*/
#include "lib/error.hpp"
#include "steam/engine/buffer-proxy-provider.hpp"
//#include "steam/engine/buffer-metadata.hpp"
//#include "lib/util.hpp"
//using util::isSameAdr;
namespace steam {
namespace engine {
// storage for the default-marker constants
// const TypeHandler TypeHandler::RAW{};
namespace { // impl. details and definitions
// const uint DEFAULT_DESCRIPTOR = 0;
}
/** build a new
*/
// BufferProvider::BufferProvider (Literal implementationID)
// : meta_(new BufferMetadata (implementationID))
// { }
//
// BufferProvider::~BufferProvider() { }
/** @internal verify the given descriptor.
*/
}} // namespace engine

View file

@ -77,8 +77,8 @@ namespace engine {
HashVal hash{0};
boost::hash_combine (hash, typeid(CTOR).hash_code());
boost::hash_combine (hash, typeid(DTOR).hash_code());
return hash;
}
return hash; ////////////////////////////////////////////////////////////////////////////TICKET #1411 : this qualification fails to distinguish different bindings of the same type
} ///////////////// (notably different constructor argument values for the same class type to emplace)
}//(End)placement-new helpers

View file

@ -283,7 +283,7 @@ namespace test {
// and get a new buffer to capture the output
BuffHandle buffOut = provider.lockBufferFor<Buffer> (-99);
CHECK (buff.accessAs<long>() == r1);
CHECK (buffOut.accessAs<long>() == -55); ///////////////////////////////////////OOO should be -99 --> aliasing of buffer meta records due to bug with hash generation
CHECK (buffOut.accessAs<long>() == -55); /////////////////////////////////////////////////////////TICKET #1411 : should be -99 --> aliasing of buffer meta records due to bug with hash generation
// configure the Manifold-2 with this input and output buffer
m2.inBuff.createAt (0, buff);
@ -291,13 +291,13 @@ namespace test {
CHECK (m2.inBuff[0].isValid());
CHECK (m2.inBuff[0].accessAs<long>() == r1 );
CHECK (m2.outBuff[0].isValid());
CHECK (m2.outBuff[0].accessAs<long>() == -55); ////////////////////////////////OOO should be -99
CHECK (m2.outBuff[0].accessAs<long>() == -55); //////////////////////////////////////////////////TICKET #1411 : should be -99
// connect arguments to buffers
m2.connect();
CHECK (isSameAdr (m2.inArgs, buff.rawStorage()));
CHECK (isSameAdr (m2.outArgs, buffOut.rawStorage()));
CHECK (*m2.outArgs == -55); ////////////////////////////////OOO should be -99
CHECK (*m2.outArgs == -55); //////////////////////////////////////////////////TICKET #1411 : should be -99
m2.invoke();
CHECK (buffOut.accessAs<long>() == r1+1);
@ -335,12 +335,12 @@ namespace test {
BuffHandle buffI2 = provider.lockBufferFor<Buffer> (-22);
CHECK (buffI0.accessAs<long>() == r1 ); // (result from Example-1)
CHECK (buffI1.accessAs<long>() == r1+1); // (result from Example-2)
CHECK (buffI2.accessAs<long>() == -55 ); ///////////////////////////////////////OOO should be -22
CHECK (buffI2.accessAs<long>() == -55 ); /////////////////////////////////////////////////////////TICKET #1411 : should be -22
// prepare a compound buffer and an extra buffer for output...
BuffHandle buffO0 = provider.lockBufferFor<Sequence> (Sequence{-111,-222,-333});
BuffHandle buffO1 = provider.lockBufferFor<Buffer> (-33);
CHECK ((buffO0.accessAs<Sequence>() == Sequence{-111,-222,-333}));
CHECK (buffO1.accessAs<long>() == -55 ); ///////////////////////////////////////OOO should be -33
CHECK (buffO1.accessAs<long>() == -55 ); /////////////////////////////////////////////////////////TICKET #1411 : should be -33
// configure the Manifold-3 with these input and output buffers
m3.inBuff.createAt (0, buffI0);
@ -355,20 +355,20 @@ namespace test {
auto& [o00,o01,o02] = *oa0;
CHECK (*ia0 == r1 );
CHECK (*ia1 == r1+1);
CHECK (*ia2 == -55 ); /////////////////////////////////////////////////////OOO should be -22
CHECK (*ia2 == -55 ); ///////////////////////////////////////////////////////////////////////TICKET #1411 : should be -22
CHECK ( o00 == -111);
CHECK ( o01 == -222);
CHECK ( o02 == -333);
CHECK (*oa1 == -55 ); /////////////////////////////////////////////////////OOO should be -33
CHECK (*oa1 == -55 ); ///////////////////////////////////////////////////////////////////////TICKET #1411 : should be -33
m3.invoke();
CHECK (*ia0 == r1 ); // Input buffers unchanged
CHECK (*ia1 == r1+1);
CHECK (*ia2 == -55 ); /////////////////////////////////////////////////////OOO should be -22
CHECK (*ia2 == -55 ); ///////////////////////////////////////////////////////////////////////TICKET #1411 : should be -22
CHECK ( o00 == *ia0+1); // Output buffers as processed by the function
CHECK ( o01 == *ia1+1);
CHECK ( o02 == *ia2+1);
CHECK (*oa1 == -55 + *ia0+*ia1+*ia2); ///////////////////////////////////////////OOO should be -33
CHECK (*oa1 == -55 + *ia0+*ia1+*ia2); /////////////////////////////////////////////////////////////TICKET #1411 : should be -33
//_________________________________
@ -407,12 +407,12 @@ namespace test {
m4.outBuff.createAt(0, buffO1);
CHECK (*ia0 == r1 ); // existing values in the buffers....
CHECK (*ia1 == r1+1);
CHECK (*ia2 == -55 ); /////////////////////////////////////////////////////OOO should be -22
CHECK (*oa1 == -55 + *ia0+*ia1+*ia2); ///////////////////////////////////////////OOO should be -33
CHECK (*ia2 == -55 ); ///////////////////////////////////////////////////////////////////////TICKET #1411 : should be -22
CHECK (*oa1 == -55 + *ia0+*ia1+*ia2); /////////////////////////////////////////////////////////////TICKET #1411 : should be -33
m4.connect();
m4.invoke(); // processing combines input buffers with parameters
CHECK (*oa1 == (r2+r3) * (r1 + r1+1 -55)); /////////////////////////////////////OOO should be -22
CHECK (*oa1 == (r2+r3) * (r1 + r1+1 -55)); ///////////////////////////////////////////////////////TICKET #1411 : should be -22
//______________________________________

View file

@ -19,7 +19,7 @@
#include "lib/test/run.hpp"
//#include "steam/play/diagnostic-output-slot.hpp"
#include "steam/engine/buffer-proxy-provider.hpp"
#include "steam/engine/buffer-proxy-adaptor.hpp"
#include "steam/engine/test-rand-ontology.hpp"
@ -40,6 +40,7 @@ namespace test {
* @todo 2/2026 broken by refactoring of BufferProvider //////////////////////////////////////////////TICKET #1410 : refactoring to separate external and implementation API
* @todo however, something along this lines *must*
* be made possible, somehow, for OutputSlot...
* @todo 2/2026 now using this setup for prototyping /////////////////////////////////////////////////TICKET #1415 : explore this design idea through prototyping
*/
class OutputProxyProvider_test : public Test
{
@ -54,7 +55,7 @@ namespace test {
lastState = state;
};
// setup with notification callback
BufferProxyProvider proxPro{listener};
BufferProxyAdaptor proxPro{listener};
// Assuming some data block is »given«
seedRand();

File diff suppressed because it is too large Load diff