clarify implementation extension points of BufferProvider
decide especially how to pass on the implementation defined data like e.g. pointers to storage extents
This commit is contained in:
parent
d1d0f66fa8
commit
623bb401af
7 changed files with 87 additions and 53 deletions
|
|
@ -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?"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<PBuff>(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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ using lib::ScopedHolder;
|
|||
|
||||
namespace engine {
|
||||
|
||||
namespace error = lumiera::error;
|
||||
|
||||
namespace diagn {
|
||||
|
||||
typedef vector<Block*> 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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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::Block>
|
||||
{
|
||||
diagn::PoolTable pool_;
|
||||
scoped_ptr<diagn::PoolTable> 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*);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ namespace test {
|
|||
uint dataID = 1 + rand() % 29;
|
||||
testBuff.accessAs<TestFrame>() = 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<numElms; ++i)
|
||||
{
|
||||
BuffHandle buff = provider.lockBufferFor(buffType);
|
||||
BuffHandle buff = provider.lockBuffer(buffType);
|
||||
buff.accessAs<uint>() = 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<uint>(3));
|
||||
CHECK (24 == provider.accessAs<uint>(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<uint>(0));
|
||||
CHECK (1 == provider.accessAs<uint>(1));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue