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:
Fischlurch 2011-11-15 04:47:31 +01:00
parent d1d0f66fa8
commit 623bb401af
7 changed files with 87 additions and 53 deletions

View file

@ -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?"

View file

@ -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

View file

@ -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
{

View file

@ -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");
}

View file

@ -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*);
};

View file

@ -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));

View file

@ -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