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:
parent
6c880c5d10
commit
722c12e312
8 changed files with 835 additions and 192 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
//______________________________________
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in a new issue