BufferProvider: investigate and fix broken allocation
Since the BufferStore implementation component is now supposed to handle only the memory allocation, a complete end-to end data flow must be ensured, so that allocation / deallocation functions get all the relevant information. Notably, the `LocalTag` is now used as an implementation-defined conduit for further (opaque) marker data. Since all data passed over this API are simple values (even `LocalTag` is effectively a 64bit integer), we can now avoid relying on output parameters or similar side-effect tricks.
This commit is contained in:
parent
75cda5ebc6
commit
c3ebade5d2
7 changed files with 44 additions and 27 deletions
|
|
@ -138,10 +138,10 @@ namespace engine {
|
|||
BufferProvider::lockBuffer (BuffDescr const& type)
|
||||
{
|
||||
REQUIRE (was_created_by_this_provider (type));
|
||||
size_t buffSiz = getBufferSize (type);
|
||||
LocalTag implMarker;
|
||||
Buff& storage = bufferStore_->provideBuffer (buffSiz, type, implMarker);
|
||||
return buildHandle (type, &storage, implMarker);
|
||||
metadata::Entry& metaEntry = bufferStage_->get (type);
|
||||
size_t buffSiz = metaEntry.storageSize();
|
||||
auto [storage, implMarker] = bufferStore_->provideBuffer (buffSiz, type, metaEntry.localTag());
|
||||
return buildHandle (type, storage, implMarker);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -181,7 +181,8 @@ namespace engine {
|
|||
metadata::Entry& metaEntry = bufferStage_->get (handle.entryID());
|
||||
size_t buffSiz = metaEntry.storageSize();
|
||||
metaEntry.mark(FREE); // might invoke embedded dtor function
|
||||
bufferStore_->detachBuffer (buffSiz, metaEntry.parentKey(), metaEntry.localTag(), *handle);
|
||||
bufferStore_->detachBuffer (buffSiz, metaEntry.parentKey()
|
||||
,std::make_tuple (handle.rawStorage(), metaEntry.localTag()));
|
||||
bufferStage_->release (metaEntry);
|
||||
}
|
||||
ERROR_LOG_AND_IGNORE (engine, "releasing a buffer from BufferProvider")
|
||||
|
|
@ -226,7 +227,8 @@ namespace engine {
|
|||
metadata::Entry& metaEntry = bufferStage_->get (target.entryID());
|
||||
size_t buffSiz = metaEntry.storageSize();
|
||||
metaEntry.invalidate (invokeDtor);
|
||||
bufferStore_->detachBuffer (buffSiz, metaEntry.parentKey(), metaEntry.localTag(), *target);
|
||||
bufferStore_->detachBuffer (buffSiz, metaEntry.parentKey()
|
||||
,std::make_tuple (target.rawStorage(), metaEntry.localTag()));
|
||||
bufferStage_->release (metaEntry);
|
||||
}
|
||||
ERROR_LOG_AND_IGNORE (engine, "cleanup of buffer metadata while handling an error")
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@
|
|||
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
|
||||
namespace steam {
|
||||
|
|
@ -200,13 +201,15 @@ namespace engine {
|
|||
class BufferStore
|
||||
: util::NonCopyable
|
||||
{
|
||||
protected:
|
||||
using Slot = std::tuple<Buff*,LocalTag>;
|
||||
public:
|
||||
virtual ~BufferStore() { } ///< this is an interface
|
||||
|
||||
virtual uint prepareBuffers (uint cnt, size_t,HashVal typeID) =0;
|
||||
virtual Buff& provideBuffer (size_t,HashVal typeID, LocalTag&) =0;
|
||||
virtual void mark_emitted (size_t,HashVal, LocalTag const&) =0;
|
||||
virtual void detachBuffer (size_t,HashVal, LocalTag, Buff&) =0;
|
||||
virtual uint prepareBuffers (uint cnt, size_t,HashVal typeID) =0;
|
||||
virtual Slot provideBuffer (size_t,HashVal typeID, LocalTag) =0;
|
||||
virtual void mark_emitted (size_t,HashVal, LocalTag const&) =0;
|
||||
virtual void detachBuffer (size_t,HashVal, Slot alloc) =0;
|
||||
};
|
||||
|
||||
unique_ptr<BufferStage> bufferStage_; ///////////////////////////////////////////////////////////TICKET #1410 : must be turned into an internal interface
|
||||
|
|
|
|||
|
|
@ -141,14 +141,11 @@ namespace engine {
|
|||
template<typename BU>
|
||||
BU& accessAs();
|
||||
|
||||
|
||||
//////////////////////////////////////////TICKET #249 this operator looks obsolete. The Buff type is a placeholder type,
|
||||
//////////////////////////////////////////TODO it should never be accessed directly from within Lumiera engine code
|
||||
Buff&
|
||||
operator* () const
|
||||
Buff*
|
||||
rawStorage() const
|
||||
{
|
||||
ENSURE (pBuffer_);
|
||||
return *pBuffer_;
|
||||
return pBuffer_;
|
||||
}
|
||||
|
||||
operator HashVal() const { return descriptor_; }
|
||||
|
|
|
|||
|
|
@ -288,13 +288,13 @@ namespace engine {
|
|||
}
|
||||
|
||||
|
||||
Buff&
|
||||
HeapMemProvider::provideBuffer (size_t buffSiz, HashVal typeID, LocalTag&)
|
||||
BufferProviderSetup::Store::Slot
|
||||
HeapMemProvider::provideBuffer (size_t buffSiz, HashVal typeID, LocalTag)
|
||||
{
|
||||
BlockPool& blocks = getBlockPoolFor (buffSiz, typeID);
|
||||
Block& newBlock = blocks.createBlock();
|
||||
LocalTag specifics{&newBlock}; // used by this implementation to find the storage to release later
|
||||
return * asBuffer(newBlock.accessMemory());
|
||||
return std::make_tuple (asBuffer(newBlock.accessMemory()), specifics);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -320,8 +320,9 @@ namespace engine {
|
|||
|
||||
/** mark a buffer as officially discarded */
|
||||
void
|
||||
HeapMemProvider::detachBuffer (size_t buffSiz, HashVal typeID, LocalTag specifics, Buff& storage)
|
||||
HeapMemProvider::detachBuffer (size_t buffSiz, HashVal typeID, Slot alloc)
|
||||
{
|
||||
auto& [storage, specifics] = alloc;
|
||||
Block* block4buffer = locateBlock (buffSiz, typeID, specifics);
|
||||
REQUIRE (block4buffer, "releasing a buffer not allocated through this provider");
|
||||
REQUIRE (util::isSameAdr (storage, block4buffer->accessMemory()));
|
||||
|
|
|
|||
|
|
@ -84,9 +84,9 @@ namespace engine {
|
|||
/* === BufferStore interface === */
|
||||
|
||||
virtual uint prepareBuffers (uint cnt, size_t,HashVal typeID) override;
|
||||
virtual Buff& provideBuffer (size_t,HashVal, LocalTag&) override;
|
||||
virtual void mark_emitted (size_t,HashVal, LocalTag const&) override;
|
||||
virtual void detachBuffer (size_t,HashVal, LocalTag, Buff&) override;
|
||||
virtual Slot provideBuffer (size_t,HashVal, LocalTag) override;
|
||||
virtual void mark_emitted (size_t,HashVal, LocalTag const&) override;
|
||||
virtual void detachBuffer (size_t,HashVal, Slot alloc) override;
|
||||
|
||||
public:
|
||||
~HeapMemProvider();
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ namespace test {
|
|||
CHECK (m1.outBuff[0].accessAs<long>() == -55);
|
||||
|
||||
m1.connect(); // instruct the manifold to connect buffers to arguments
|
||||
CHECK (isSameAdr (m1.outArgs, *buff));
|
||||
CHECK (isSameAdr (m1.outArgs, buff.rawStorage()));
|
||||
CHECK (*m1.outArgs == -55);
|
||||
|
||||
m1.invoke(); // invoke the adapted processing function (fun_singleOut)
|
||||
|
|
@ -295,8 +295,8 @@ namespace test {
|
|||
|
||||
// connect arguments to buffers
|
||||
m2.connect();
|
||||
CHECK (isSameAdr (m2.inArgs, *buff));
|
||||
CHECK (isSameAdr (m2.outArgs, *buffOut));
|
||||
CHECK (isSameAdr (m2.inArgs, buff.rawStorage()));
|
||||
CHECK (isSameAdr (m2.outArgs, buffOut.rawStorage()));
|
||||
CHECK (*m2.outArgs == -55); ////////////////////////////////OOO should be -99
|
||||
|
||||
m2.invoke();
|
||||
|
|
|
|||
|
|
@ -111868,8 +111868,11 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1770835660209" ID="ID_1699942357" MODIFIED="1770835664104" TEXT="BufferProviderProtocol_test">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1770935307254" ID="ID_1256898924" MODIFIED="1770935316691" TEXT="DiagnosticBufferProvider_test">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1770935307254" ID="ID_1256898924" MODIFIED="1770947504816" TEXT="DiagnosticBufferProvider_test">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node BACKGROUND_COLOR="#eae2af" COLOR="#690f14" CREATED="1770947507396" ID="ID_1663548893" MODIFIED="1770947541484" TEXT="läuft nun bis auf fehlendes Tracking...">
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#2c619a" CREATED="1770835671749" ID="ID_661880079" MODIFIED="1770939247723" TEXT="der buildHandle()-Aufruf muß entflochten werden">
|
||||
<arrowlink COLOR="#3a91fe" DESTINATION="ID_1511113078" ENDARROW="Default" ENDINCLINATION="243;15;" ID="Arrow_ID_1668459979" STARTARROW="None" STARTINCLINATION="820;0;"/>
|
||||
|
|
@ -112690,6 +112693,17 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1770947363915" ID="ID_1352298488" MODIFIED="1770947427286" TEXT="aber ein Zwischending...">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1770947376890" ID="ID_2121271" MODIFIED="1770947388988" TEXT="Slot = tuple<Buffer*, LocalTag>">
|
||||
<node CREATED="1770947436245" ID="ID_1453619086" MODIFIED="1770947451096" TEXT="damit generell: Buffer* verwenden">
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
</node>
|
||||
<node CREATED="1770947452831" ID="ID_263962280" MODIFIED="1770947477138" TEXT="BuffHandle::rawStorage()"/>
|
||||
</node>
|
||||
<node CREATED="1770947390336" ID="ID_1722157621" MODIFIED="1770947419160" TEXT="das wird von der Allokation erzeugt..."/>
|
||||
<node CREATED="1770947399557" ID="ID_1598745754" MODIFIED="1770947411455" TEXT="und der de-Allokation wieder angeliefert"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue