flesh out the buffer metadata API

functionality just stubbed still
This commit is contained in:
Fischlurch 2011-10-08 02:21:29 +02:00
parent 4df45c44e9
commit 3acf804988
2 changed files with 95 additions and 47 deletions

View file

@ -57,7 +57,7 @@
#include "lib/error.hpp"
#include "lib/symbol.hpp"
//#include <boost/noncopyable.hpp>
#include <boost/noncopyable.hpp>
namespace engine {
@ -65,8 +65,7 @@ namespace engine {
using lib::Literal;
namespace error = lumiera::error;
//using error::LUMIERA_ERROR_INVALID;
typedef uint64_t LocalKey;
typedef size_t HashVal;
@ -105,6 +104,7 @@ namespace engine {
class Metadata
: boost::noncopyable
{
public:
class Entry
@ -119,6 +119,7 @@ namespace engine {
HashVal parentKey() const { return parent_;}
virtual BufferState state() const =0;
virtual const void* access() const =0;
virtual Entry& mark (BufferState newState) =0;
};
@ -158,9 +159,6 @@ namespace engine {
UNIMPLEMENTED ("access, possibly create metadata records");
}
Entry&
markLocked (HashVal parentKey, const void* buffer);
bool
isKnown (HashVal key) const
{
@ -173,8 +171,12 @@ namespace engine {
UNIMPLEMENTED ("diagnostics: actually locked buffer instance record?");
}
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #834
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #834
/* == memory management == */
Entry& markLocked (HashVal parentKey, const void* buffer);
void release (HashVal key);
};
@ -183,7 +185,7 @@ namespace engine {
/* === Implementation === */
namespace {
using error::LUMIERA_ERROR_LIFECYCLE;
using error::LUMIERA_ERROR_BOTTOM_VALUE;
@ -197,6 +199,16 @@ namespace engine {
return NIL;
}
virtual const void*
access() const
{
throw error::Logic ("This metadata entry is still abstract. "
"It can't be associated with a concrete buffer. "
"You need to invoke markLocked (buffer)."
, LUMIERA_ERROR_LIFECYCLE
);
}
virtual Entry&
mark (BufferState newState)
{
@ -220,12 +232,18 @@ namespace engine {
virtual BufferState
state() const
{
__must_not_be_NIL();
return state_;
}
virtual Entry&
markLocked (const void* buffer)
virtual const void*
access() const
{
__must_not_be_NIL();
__must_not_be_FREE();
ENSURE (buffer_);
return buffer_;
}
virtual Entry&
@ -233,12 +251,9 @@ namespace engine {
{
switch (this->state_)
{
case NIL:
throw error::Fatal ("Concrete buffer entry with state==NIL encountered."
"State transition logic broken (programming error)");
case FREE:
throw error::Logic ("Need a new buffer pointer in order to lock an entry."
, LUMIERA_ERROR_LIFECYCLE );
case NIL: __must_not_be_NIL();
case FREE: __must_not_be_FREE();
case LOCKED:
if (newState == EMITTED) break; // allow transition
@ -246,7 +261,7 @@ namespace engine {
if (newState == BLOCKED) break; // allow transition
case BLOCKED:
if (newState == FREE) // note fall through for LOCKED and EMITTED too
if (newState == FREE) // note fall through for LOCKED and EMITTED too
{
buffer_ = 0;
break; // allow transition
@ -257,39 +272,54 @@ namespace engine {
state_ = newState;
return *this;
}
void
__must_not_be_NIL() const
{
if (NIL == state_)
throw error::Fatal ("Concrete buffer entry with state==NIL encountered."
"State transition logic broken (programming error)");
}
void
__must_not_be_FREE() const
{
if (FREE == state_)
throw error::Logic ("Buffer is inaccessible (marked as free). "
"Need a new buffer pointer in order to lock an entry. "
"You should invoke markLocked(buffer) prior to access."
, LUMIERA_ERROR_LIFECYCLE );
}
};
}
/** */
BufferState
Metadata::Entry::state () const
{
UNIMPLEMENTED ("buffer state accounting");
}
Metadata::Entry&
Metadata::Entry::mark (BufferState newState)
{
UNIMPLEMENTED ("buffer state transitions");
return *this;
}
Metadata::Entry&
Metadata::markLocked (HashVal parentKey, const void* buffer)
{
UNIMPLEMENTED ("transition to locked state");
if (!buffer)
throw error::Fatal ("Attempt to lock for a NULL buffer. Allocation floundered?"
, LUMIERA_ERROR_BOTTOM_VALUE);
HashVal newKey = this->key (parentKey, buffer);
if (isLocked(newKey))
throw error::Logic ("Attempt to lock a slot for a new buffer, "
"while actually the old buffer is still locked."
, LUMIERA_ERROR_LIFECYCLE );
return this->get(newKey);
}
{
UNIMPLEMENTED ("transition to locked state");
if (!buffer)
throw error::Fatal ("Attempt to lock for a NULL buffer. Allocation floundered?"
, LUMIERA_ERROR_BOTTOM_VALUE);
HashVal newKey = this->key (parentKey, buffer);
if (isLocked(newKey))
throw error::Logic ("Attempt to lock a slot for a new buffer, "
"while actually the old buffer is still locked."
, LUMIERA_ERROR_LIFECYCLE );
return this->get(newKey);
}
void
Metadata::release (HashVal key)
{
UNIMPLEMENTED ("metadata memory management");
}

View file

@ -141,6 +141,7 @@ namespace test {
CHECK (!isSameObject (m1,m2));
CHECK (NIL == m1.state());
CHECK (LOCKED == m2.state());
CHECK (SOME_POINTER == m2.access());
HashVal keyX = meta_->key(key1, SOME_POINTER);
CHECK (meta_->isLocked(keyX));
@ -152,11 +153,28 @@ namespace test {
CHECK ( isSameObject (m2, meta_->get(keyX)));
CHECK ( key1 == m2.parentKey());
m2.mark(FREE); // Warning: don't use the m2 reference anymore!
// now able to do state transitions
CHECK (LOCKED == m2.state());
m2.mark(EMITTED);
CHECK (EMITTED == m2.state());
CHECK (SOME_POINTER == m2.access());
CHECK ( meta_->isLocked(keyX));
CHECK ( meta_->isKnown(keyX));
// but the FREE state is a dead end
m2.mark(FREE);
CHECK (!meta_->isLocked(keyX));
CHECK ( meta_->isKnown(keyX));
CHECK ( meta_->isKnown(key1));
VERIFY_ERROR (LIFECYCLE, m2.access());
VERIFY_ERROR (LIFECYCLE, m2.mark(LOCKED));
CHECK ( isSameObject (m2, meta_->get(keyX))); // still accessible
meta_->release(keyX);
CHECK (!meta_->isLocked(keyX));
CHECK (!meta_->isKnown(keyX));
CHECK ( meta_->isKnown(key1));
VERIFY_ERROR (INVALID, meta_->get(keyX));
VERIFY_ERROR (INVALID, meta_->get(keyX)); // now unaccessible
}