diff --git a/src/proc/engine/buffer-metadata.hpp b/src/proc/engine/buffer-metadata.hpp index 87ce5e59c..47da8060b 100644 --- a/src/proc/engine/buffer-metadata.hpp +++ b/src/proc/engine/buffer-metadata.hpp @@ -593,13 +593,13 @@ namespace engine { * @note might create/register a new Entry as a side-effect */ Key const& - key (Key const& parentKey, void* concreteBuffer) + key (Key const& parentKey, void* concreteBuffer, LocalKey const& implID =UNSPECIFIC) { Key derivedKey = Key::forEntry (parentKey, concreteBuffer); Entry* existing = table_.fetch (derivedKey); return existing? *existing - : markLocked (parentKey,concreteBuffer); + : markLocked (parentKey,concreteBuffer,implID); } /** core operation to access or create a concrete buffer metadata entry. @@ -627,14 +627,14 @@ namespace engine { Entry& lock (Key const& parentKey ,void* concreteBuffer - ,LocalKey const& implID + ,LocalKey const& implID =UNSPECIFIC ,bool onlyNew =false) { if (!concreteBuffer) throw error::Invalid ("Attempt to lock a slot for a NULL buffer" , error::LUMIERA_ERROR_BOTTOM_VALUE); - Entry newEntry(parentKey, concreteBuffer); + Entry newEntry(parentKey, concreteBuffer, implID); Entry* existing = table_.fetch (newEntry); if (existing && onlyNew) @@ -698,7 +698,7 @@ namespace engine { * created, but is marked as FREE */ Entry& - markLocked (Key const& parentKey, void* buffer, LocalKey const& implID) + markLocked (Key const& parentKey, void* buffer, LocalKey const& implID =UNSPECIFIC) { if (!buffer) throw error::Fatal ("Attempt to lock for a NULL buffer. Allocation floundered?" diff --git a/src/proc/engine/buffer-provider.cpp b/src/proc/engine/buffer-provider.cpp index ddb4ade3a..af2fe02af 100644 --- a/src/proc/engine/buffer-provider.cpp +++ b/src/proc/engine/buffer-provider.cpp @@ -21,6 +21,7 @@ * *****************************************************/ +#include "lib/error.hpp" #include "proc/engine/buffer-provider.hpp" #include "proc/engine/buffer-metadata.hpp" #include "lib/util.hpp" @@ -76,9 +77,9 @@ namespace engine { BufferProvider::buildHandle (HashVal typeID, void* storage, LocalKey const& implID) { metadata::Key& typeKey = meta_->get (typeID); - metadata::Entry& entry = meta_->markLocked(typeKey, newBlock, implID); + metadata::Entry& entry = meta_->markLocked(typeKey, storage, implID); - return BuffHandle (BufferDescriptor(*this, entry), newBlock); + return BuffHandle (BufferDescriptor(*this, entry), storage); } @@ -139,9 +140,11 @@ namespace engine { * An emitted buffer should not be modified anymore. */ void - BufferProvider::emitBuffer (BuffHandle const&) + BufferProvider::emitBuffer (BuffHandle const& handle) { - + metadata::Entry& metaEntry = meta_->get (handle.entryID()); + mark_emitted (metaEntry.parentKey(), metaEntry.localKey()); + metaEntry.mark(EMITTED); } @@ -154,10 +157,13 @@ namespace engine { * @note EX_FREE */ void - BufferProvider::releaseBuffer (BuffHandle const&) - { - + BufferProvider::releaseBuffer (BuffHandle const& handle) + try { + metadata::Entry& metaEntry = meta_->get (handle.entryID()); + detachBuffer (metaEntry.parentKey(), metaEntry.localKey()); + metaEntry.mark(FREE); } + ERROR_LOG_AND_IGNORE (engine, "releasing a buffer from BufferProvider") bool diff --git a/src/proc/engine/buffhandle.hpp b/src/proc/engine/buffhandle.hpp index e1bd025ac..a12d26df8 100644 --- a/src/proc/engine/buffhandle.hpp +++ b/src/proc/engine/buffhandle.hpp @@ -74,7 +74,7 @@ namespace engine { BufferProvider* provider_; HashVal subClassification_; - BufferDescriptor(BufferProvider& manager, uint64_t detail) + BufferDescriptor(BufferProvider& manager, HashVal detail) : provider_(&manager) , subClassification_(detail) { } @@ -131,9 +131,9 @@ namespace engine { /** @internal a buffer handle may be obtained by "locking" * a buffer from the corresponding BufferProvider */ - BuffHandle(BufferDescriptor const& typeInfo, PBuff storage = 0) + BuffHandle(BufferDescriptor const& typeInfo, void* storage = 0) : descriptor_(typeInfo) - , pBuffer_(storage) + , pBuffer_(static_cast(storage)) { } // using standard copy operations @@ -151,6 +151,8 @@ namespace engine { 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 { @@ -165,6 +167,12 @@ namespace engine { && descriptor_.verifyValidity(); } + HashVal + entryID() const + { + return descriptor_; + } + size_t size() const { diff --git a/src/proc/engine/tracking-heap-block-provider.cpp b/src/proc/engine/tracking-heap-block-provider.cpp index c40a2a56d..1ba17d181 100644 --- a/src/proc/engine/tracking-heap-block-provider.cpp +++ b/src/proc/engine/tracking-heap-block-provider.cpp @@ -41,6 +41,8 @@ using lib::ScopedHolder; namespace engine { + namespace error = lumiera::error; + namespace diagn { typedef vector PoolVec; @@ -72,7 +74,7 @@ namespace engine { initialise (size_t blockSize) { blockList_.create(); - memBlockSize_(blockSize); + memBlockSize_ = blockSize; } // standard copy operations are valid, but will // raise an runtime error, once BlockPool is initialised. @@ -157,7 +159,7 @@ namespace engine { */ TrackingHeapBlockProvider::TrackingHeapBlockProvider() : BufferProvider ("Diagnostic_HeapAllocated") - , pool_() + , pool_(new diagn::PoolTable) { } TrackingHeapBlockProvider::~TrackingHeapBlockProvider() @@ -169,37 +171,39 @@ namespace engine { /* ==== Implementation of the BufferProvider interface ==== */ uint - TrackingHeapBlockProvider::announce (uint count, BufferDescriptor const& type) + TrackingHeapBlockProvider::prepareBuffers(uint, lib::HashVal) { UNIMPLEMENTED ("pre-register storage for buffers of a specific kind"); } BuffHandle - TrackingHeapBlockProvider::lockBufferFor (BufferDescriptor const& type) + TrackingHeapBlockProvider::provideLockedBuffer(HashVal typeID) { - diagn::BlockPool& blocks = getBlockPoolFor (type); - diagn::Block* newBlock = blocks.createBlock(); - return buildHandle (type, newBlock->accessMemory(), newBlock); + diagn::BlockPool& blocks = getBlockPoolFor (typeID); + diagn::Block& newBlock = blocks.createBlock(); + return buildHandle (typeID, newBlock.accessMemory(), &newBlock); } void - TrackingHeapBlockProvider::mark_emitted (BuffHandle const& handle) + TrackingHeapBlockProvider::mark_emitted (HashVal typeID, LocalKey const& implID) { - //TODO mark metadata - diagn::Block* block4buffer = locateBlock (handle); - diagn::BlockPool& pool = getBlockPoolFor (handle); + diagn::Block* block4buffer = locateBlock (typeID, implID); + if (!block4buffer) + throw error::Logic ("Attempt to emit a buffer not known to this BufferProvider" + , LUMIERA_ERROR_BUFFER_MANAGEMENT); + diagn::BlockPool& pool = getBlockPoolFor (typeID); this->manage (pool.transferResponsibility (block4buffer)); } /** mark a buffer as officially discarded */ void - TrackingHeapBlockProvider::releaseBuffer (BuffHandle const& handle) + TrackingHeapBlockProvider::detachBuffer (HashVal typeID, LocalKey const& implID) { - //TODO mark metadata - diagn::Block* block4buffer = locateBlock (handle); + diagn::Block* block4buffer = locateBlock (typeID, implID); + REQUIRE (block4buffer, "releasing a buffer not allocated through this provider"); block4buffer->markReleased(); } @@ -227,11 +231,20 @@ namespace engine { } diagn::BlockPool& - TrackingHeapBlockProvider::getBlockPoolFor (BufferDescriptor const& type) + TrackingHeapBlockProvider::getBlockPoolFor (HashVal typeID) { UNIMPLEMENTED ("access correct block pool, based on metadata"); } + diagn::Block* + TrackingHeapBlockProvider::locateBlock (HashVal typeID, void* storage) + { + diagn::BlockPool& pool = getBlockPoolFor (typeID); + ////TODO: step 1: try to access from pool + ////TODO: step 2: otherwise search already emitted blocks + UNIMPLEMENTED ("access correct block pool, based on metadata"); + } + diff --git a/src/proc/engine/tracking-heap-block-provider.hpp b/src/proc/engine/tracking-heap-block-provider.hpp index 25f89fada..53fffa17d 100644 --- a/src/proc/engine/tracking-heap-block-provider.hpp +++ b/src/proc/engine/tracking-heap-block-provider.hpp @@ -60,6 +60,7 @@ namespace engine { namespace diagn { + using boost::scoped_ptr; using boost::scoped_array; @@ -100,6 +101,12 @@ namespace engine { { return storage_.get(); } + + void + markReleased() + { + UNIMPLEMENTED ("diagn::Block accounting functionality"); + } }; class BlockPool; @@ -121,16 +128,15 @@ namespace engine { : public BufferProvider , public lib::ScopedPtrVect { - diagn::PoolTable pool_; + scoped_ptr pool_; public: /* === BufferProvider interface === */ - using BufferProvider::lockBufferFor; - virtual uint announce (uint count, BufferDescriptor const& type); - virtual BuffHandle lockBufferFor (BufferDescriptor const& type); - virtual void mark_emitted (BuffHandle const& handle); - virtual void releaseBuffer (BuffHandle const& handle); + virtual uint prepareBuffers (uint count, HashVal typeID); + virtual BuffHandle provideLockedBuffer (HashVal typeID); + virtual void mark_emitted (HashVal entryID, LocalKey const&); + virtual void detachBuffer (HashVal entryID, LocalKey const&); public: TrackingHeapBlockProvider(); @@ -143,7 +149,8 @@ namespace engine { private: bool withinStorageSize (uint bufferID) const; - diagn::BlockPool& getBlockPoolFor (BufferDescriptor const&); + diagn::BlockPool& getBlockPoolFor (HashVal typeID); + diagn::Block* locateBlock (HashVal typeID, void*); }; diff --git a/tests/components/proc/engine/tracking-heap-block-provider-test.cpp b/tests/components/proc/engine/tracking-heap-block-provider-test.cpp index 47fd1bcd4..cd31351ef 100644 --- a/tests/components/proc/engine/tracking-heap-block-provider-test.cpp +++ b/tests/components/proc/engine/tracking-heap-block-provider-test.cpp @@ -110,7 +110,7 @@ namespace test { uint dataID = 1 + rand() % 29; testBuff.accessAs() = testData(dataID); - provider.mark_emitted (testBuff); + provider.emitBuffer (testBuff); provider.releaseBuffer(testBuff); diagn::Block& block0 = provider.access_or_create(0); @@ -130,9 +130,9 @@ namespace test { for (uint i=0; i() = testNumbers[i] = rand() % 100000; - provider.mark_emitted (buff); + provider.emitBuffer (buff); provider.releaseBuffer(buff); } @@ -150,11 +150,11 @@ namespace test { BufferDescriptor buffType = provider.getDescriptorFor(TEST_ELM_SIZE); - BuffHandle bu1 = provider.lockBufferFor(buffType); - BuffHandle bu2 = provider.lockBufferFor(buffType); - BuffHandle bu3 = provider.lockBufferFor(buffType); - BuffHandle bu4 = provider.lockBufferFor(buffType); - BuffHandle bu5 = provider.lockBufferFor(buffType); + BuffHandle bu1 = provider.lockBuffer (buffType); + BuffHandle bu2 = provider.lockBuffer (buffType); + BuffHandle bu3 = provider.lockBuffer (buffType); + BuffHandle bu4 = provider.lockBuffer (buffType); + BuffHandle bu5 = provider.lockBuffer (buffType); CHECK (5 == provider.size()); @@ -176,11 +176,11 @@ namespace test { CHECK (23 == provider.accessAs(3)); CHECK (24 == provider.accessAs(4)); - provider.mark_emitted (bu3); - provider.mark_emitted (bu1); - provider.mark_emitted (bu5); - provider.mark_emitted (bu4); - provider.mark_emitted (bu2); + provider.emitBuffer (bu3); + provider.emitBuffer (bu1); + provider.emitBuffer (bu5); + provider.emitBuffer (bu4); + provider.emitBuffer (bu2); CHECK (3 == provider.accessAs(0)); CHECK (1 == provider.accessAs(1)); diff --git a/tests/components/proc/play/diagnostic-output-slot.hpp b/tests/components/proc/play/diagnostic-output-slot.hpp index 571c1dad0..1c566d198 100644 --- a/tests/components/proc/play/diagnostic-output-slot.hpp +++ b/tests/components/proc/play/diagnostic-output-slot.hpp @@ -75,7 +75,7 @@ namespace play { BuffHandle claimBufferFor(FrameID frameNr) { - buffProvider_->lockBufferFor (bufferType_); + return buffProvider_->lockBuffer (bufferType_); } @@ -98,8 +98,8 @@ namespace play { void pushout (BuffHandle const& data4output) { - buffProvider_->mark_emitted (data4output); - buffProvider_->releaseBuffer (data4output); + buffProvider_->emitBuffer (data4output); + buffProvider_->releaseBuffer(data4output); } void