A continuation of a story.
Consider safety software, where dynamic allocation with fragmentation is disallowed. Dynamic allocation is allowed only when class explicity defines operator new and delete to avoid fragmentation.
Now here we have a chance to optimize explicit definition of operator new and delete for any class we want to get. At the first glance, template class from which any class can inherit is the simplest and clearest way to use for the end user.
template<class T, unsigned size>
class MemoryPool
{
private:
struct Pool
{
bool allocated __attribute__ ((aligned (sizeof(void*))));
uint8_t memory[sizeof(T)] __attribute__ ((aligned (sizeof(void*))));
};
static std::array<uint8_t[sizeof(Pool)], size> memoryPool;
public:
void* operator new(std::size_t) noexcept
{
T* ret = nullptr;
for(auto it = memoryPool.begin(); it != memoryPool.end(); ++it)
{
/* ... */
}
return ret;
}
void operator delete(void* ptr) noexcept
{
for(auto it = memoryPool.begin(); it != memoryPool.end(); ++it)
{
/* ... */
}
}
};
If it were a fairy tale, declaration of class with MemoryPool would be sweet.
class Interface;
class Foo : public Interface, MemoryPool<Foo, 8>
{/*...*/};
class Bar : public Interface
{/*...*/};
And declaration of objects:
Foo* foo = new Foo(); // goes to dedicated memory pool
Bar* bar = new Bar(); // fails on build
But even when static std::array<uint8_t[sizeof(Pool)], size> memoryPool; is static and will go outside of the class, so it will not change the size of a class, the compiler complains that Foo is incomplete and can't deduce size of Foo
src/metal/dynamic.hpp:14:24: error: invalid application of 'sizeof' to incomplete type 'Foo'
uint8_t memory[sizeof(T)] __attribute__ ((aligned (sizeof(void*))));
Is it possible to workaround this 'incomplete type' error?
Or should I completly redesign the solution?
Aucun commentaire:
Enregistrer un commentaire