finish simple allocator frontend. Unit-test pass
This commit is contained in:
parent
5350ef6dbe
commit
f505c46d1d
3 changed files with 86 additions and 19 deletions
|
|
@ -51,11 +51,9 @@
|
|||
#include "lib/meta/generator.hpp"
|
||||
#include "lib/meta/typelist-util.hpp"
|
||||
#include "lib/format.hpp"
|
||||
//#include "lib/typed-counter.hpp"
|
||||
#include "lib/typed-counter.hpp"
|
||||
#include "include/logging.h"
|
||||
|
||||
|
||||
//#include <tr1/memory>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <memory>
|
||||
|
||||
|
|
@ -63,24 +61,71 @@
|
|||
|
||||
namespace lib {
|
||||
|
||||
// using std::tr1::shared_ptr;
|
||||
using lumiera::typelist::Types;
|
||||
using lumiera::typelist::IsInList;
|
||||
using lumiera::typelist::InstantiateForEach;
|
||||
|
||||
namespace {
|
||||
}
|
||||
|
||||
|
||||
/* === Policies for simple custom allocator === */
|
||||
|
||||
/**
|
||||
* Policy: use just plain heap allocations
|
||||
*/
|
||||
template<typename TY>
|
||||
class CustomAllocator
|
||||
: public std::allocator<TY>
|
||||
{ };
|
||||
|
||||
|
||||
/**
|
||||
* Policy: maintain explicit per type instance count
|
||||
* @note this imposes additional locking
|
||||
*/
|
||||
struct UseInstantiationCounting
|
||||
{
|
||||
template<class XX>
|
||||
size_t
|
||||
allocationCount() const
|
||||
{
|
||||
return allocCnt_.get<XX>();
|
||||
}
|
||||
|
||||
template<class XX>
|
||||
void
|
||||
incrementCount()
|
||||
{
|
||||
allocCnt_.inc<XX>();
|
||||
}
|
||||
|
||||
template<class XX>
|
||||
void
|
||||
decrementCount()
|
||||
{
|
||||
allocCnt_.dec<XX>();
|
||||
}
|
||||
|
||||
private:
|
||||
lib::TypedCounter allocCnt_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Policy: no additional instantiation accounting
|
||||
*/
|
||||
struct NoInstantiationCount
|
||||
{
|
||||
template<class XX> size_t allocationCount() const { return 0; }
|
||||
template<class XX> void incrementCount() { /* NOP */ }
|
||||
template<class XX> void decrementCount() { /* NOP */ }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* === Allocator frontend === */
|
||||
|
||||
/**
|
||||
* Frontend for explicit allocations, using a custom allocator.
|
||||
* This template is to be instantiated for the collection of types
|
||||
|
|
@ -90,13 +135,16 @@ namespace lib {
|
|||
*
|
||||
* @todo currently (as of 8/09) the low-level pooled allocator
|
||||
* isn't implemented; instead we do just heap allocations.
|
||||
* see Ticket #835
|
||||
* ////////////////////////////////////////////////////////////////////////////////////////////Ticket #835
|
||||
*/
|
||||
template<typename TYPES>
|
||||
template<typename TYPES
|
||||
,class COUNTER = NoInstantiationCount ///< Policy: support instance accounting?
|
||||
>
|
||||
class SimpleAllocator
|
||||
: InstantiateForEach< typename TYPES::List // for each of those types...
|
||||
, CustomAllocator // ...mix in the custom allocator
|
||||
: InstantiateForEach< typename TYPES::List // for each of those types...
|
||||
, CustomAllocator // ...mix in the custom allocator
|
||||
>
|
||||
, COUNTER
|
||||
{
|
||||
|
||||
/** forward plain memory allocation */
|
||||
|
|
@ -105,7 +153,9 @@ namespace lib {
|
|||
allocateSlot ()
|
||||
{
|
||||
TRACE (memory, "allocate %s", util::tyStr<XX>().c_str());
|
||||
return CustomAllocator<XX>::allocate (1);
|
||||
XX * newStorage = CustomAllocator<XX>::allocate (1);
|
||||
COUNTER::template incrementCount<XX>();
|
||||
return newStorage;
|
||||
}
|
||||
|
||||
template<class XX>
|
||||
|
|
@ -114,6 +164,7 @@ namespace lib {
|
|||
{
|
||||
TRACE (memory, "release %s", util::tyStr<XX>().c_str());
|
||||
CustomAllocator<XX>::deallocate (entry, 1);
|
||||
COUNTER::template decrementCount<XX>();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -126,8 +177,8 @@ namespace lib {
|
|||
|
||||
BOOST_STATIC_ASSERT (IsSupportedType::value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public: /* ==== build objects with managed allocation ==== */
|
||||
|
|
@ -234,10 +285,18 @@ namespace lib {
|
|||
releaseSlot<XX> (entry);
|
||||
}
|
||||
|
||||
|
||||
/** diagnostics */
|
||||
template<class XX>
|
||||
size_t
|
||||
numSlots() const
|
||||
{
|
||||
return COUNTER::template allocationCount<XX>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace lib
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1141,7 +1141,7 @@ return: 0
|
|||
END
|
||||
|
||||
|
||||
PLANNED "custom allocator(I)" SimpleAllocator_test <<END
|
||||
TEST "custom allocator(I)" SimpleAllocator_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@
|
|||
#include "lib/simple-allocator.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
|
||||
//#include <tr1/memory>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
|
|
@ -36,7 +34,6 @@ namespace test{
|
|||
|
||||
|
||||
using util::isSameObject;
|
||||
// using std::tr1::shared_ptr;
|
||||
using std::string;
|
||||
using std::rand;
|
||||
|
||||
|
|
@ -62,6 +59,13 @@ namespace test{
|
|||
checksum_ += (crap_[i] = rand() % 128);
|
||||
}
|
||||
|
||||
DummyObj (DummyObj const& o)
|
||||
{
|
||||
REQUIRE (siz);
|
||||
for (uint i=0; i<siz; ++i)
|
||||
checksum_ += (crap_[i] = o.crap_[i]);
|
||||
}
|
||||
|
||||
~DummyObj()
|
||||
{
|
||||
for (uint i=0; i<siz; ++i)
|
||||
|
|
@ -69,7 +73,8 @@ namespace test{
|
|||
}
|
||||
};
|
||||
|
||||
typedef SimpleAllocator<Types<DummyObj<1>,DummyObj<23>,string> > TestAllocator;
|
||||
typedef Types<DummyObj<1>,DummyObj<23>,string> SupportedTypes;
|
||||
typedef SimpleAllocator<SupportedTypes, UseInstantiationCounting> TestAllocator;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -148,6 +153,9 @@ namespace test{
|
|||
allocator.destroy (pDxx);
|
||||
allocator.destroy (pSxx);
|
||||
|
||||
CHECK (0 == allocator.numSlots<DummyObj<1> >());
|
||||
CHECK (0 == allocator.numSlots<DummyObj<23> >());
|
||||
CHECK (0 == allocator.numSlots<string>());
|
||||
CHECK (0 == checksum_);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue