470,833 Members | 1,329 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,833 developers. It's quick & easy.

Static Region Allocator...

This region allocator is not dynamic and can be fed with a buffer residing
on the stack of the calling thread. Therefore, you can use this in an
environment which does not have a heap; its basically analogous to `alloca'.
However, it does not align each buffer on a boundary sufficient for _any_
type. Instead, it dynamically calculates the types alignment requirements
and mutates the offset accordingly. This makes it more efficient wrt
conserving space. For instance, it does not need to align a char pointer on
a max-boundary. Here is the code (pre-alpha sketch) which should compile
fine:
__________________________________________________ ______________________
#include <cstdio>
#include <cstddef>
#include <cassert>
#include <new>
#if ! defined(NDEBUG)
# include <typeinfo>
# define DBG_PRINTF(mp_exp) std::printf mp_exp
#else
# define DBG_PRINTF(mp_exp)
#endif


#define ALIGN_POW2(mp_this, mp_type) ((mp_type)( \
(((std::ptrdiff_t const)(mp_this)) + 1) & (-2) \
))
#define ALIGN(mp_this, mp_type, mp_align) ((mp_type)( \
(((std::ptrdiff_t const)(mp_this)) + \
ALIGN_POW2(mp_align, std::ptrdiff_t const) - 1) \
& (-ALIGN_POW2(mp_align, std::ptrdiff_t const)) \
))


class stack_region_allocator {
unsigned char* const m_buf;
std::size_t const m_size;
std::size_t m_offset;
unsigned m_count;
public:
stack_region_allocator(
unsigned char* const buf,
std::size_t const size
) throw(std::bad_alloc)
: m_buf(buf),
m_size(size),
m_offset(0),
m_count(0) {
if (! m_buf || ! m_size) {
assert(m_buf);
assert(m_size);
throw std::bad_alloc();
}
}

~stack_region_allocator() throw() {
assert(! m_offset);
assert(! m_count);
}
public:
template<typename T>
T* allocate(
std::size_t count = 1
) throw(std::bad_alloc) {

struct offset_calc {
char pad;
T object;
};

if (! count) {
count = 1;
}

DBG_PRINTF(("typename: %s\n", typeid(T).name()));
DBG_PRINTF(("object count: %lu\n",
(unsigned long)count));

DBG_PRINTF(("object size: %lu\n",
(unsigned long)sizeof(T)));

std::size_t const alignment = offsetof(offset_calc, object);
DBG_PRINTF(("object alignment: %lu\n",
(unsigned long)alignment));

std::size_t const osize = count * sizeof(T);
DBG_PRINTF(("allocation size: %lu\n",
(unsigned long)osize));

unsigned char* const origin = m_buf + m_offset;
DBG_PRINTF(("origin buffer: %p\n", (void*)origin));

unsigned char* const align = (alignment != 1) ?
ALIGN(origin, unsigned char*, alignment) : origin;
DBG_PRINTF(("align buffer: %p\n", (void*)align));

std::ptrdiff_t const diff = align - origin;
DBG_PRINTF(("difference size: %d\n", diff));

std::size_t const offset = m_offset + diff;
DBG_PRINTF(("offset pre-size: %lu\n",
(unsigned long)offset));

if (offset + osize m_size) {
throw std::bad_alloc();
}

m_offset = offset + osize;
DBG_PRINTF(("offset post-size: %lu\n\
--------------------------------------\n",
(unsigned long)(offset + osize)));

++m_count;

return reinterpret_cast<T*>(align);
}

void deallocate(void*) throw() {
if (! (--m_count)) {
m_offset = 0;
}
}

void reset() throw() {
m_count = 0;
m_offset = 0;
}
};


struct foo {
char c[5];
short s[2];
int i[3];
double d[3];
long double ld[2];
};
int main() {
{
unsigned char buf[1024 * 8] = { '\0' };
stack_region_allocator region(buf, sizeof(buf));
long double* ld1 = region.allocate<long double>();
char* c = region.allocate<char>(125);
long double* ld2 = region.allocate<long double>(4);
double* d = region.allocate<double>(2);
short* s = region.allocate<short>(7);
float* f = region.allocate<float>(5);
foo* _fo = region.allocate<foo>(0);
foo* _foa = region.allocate<foo>(12);
char* c2 = region.allocate<char>(13);
char* c3 = region.allocate<char>(17);
short* s1 = region.allocate<short>(3);
foo* _foa1 = region.allocate<foo>(3);
region.reset();
}
std::puts("\n\n\n_________________________________ ___________\
_________________\npress <ENTERto exit...");
std::getchar();
return 0;
}

__________________________________________________ ______________________


Here is a link to the same code just in case it gets mangled by the
newsreader:

http://pastebin.com/f7cfdef4d


Any thoughts? Is it CRAP!?

;^o

--
Chris M. Thomasson
http://appcore.home.comcast.net

Jun 27 '08 #1
1 1890
"Chris Thomasson" <cr*****@comcast.netwrote in message
news:Do******************************@comcast.com. ..
This region allocator is not dynamic and can be fed with a buffer residing
on the stack of the calling thread. Therefore, you can use this in an
environment which does not have a heap; its basically analogous to
`alloca'. However, it does not align each buffer on a boundary sufficient
for _any_ type. Instead, it dynamically calculates the types alignment
requirements and mutates the offset accordingly. This makes it more
efficient wrt conserving space. For instance, it does not need to align a
char pointer on a max-boundary. Here is the code (pre-alpha sketch) which
should compile fine:
[...]
Any thoughts? Is it CRAP!?
Here is how to use it with a non-POD type:
__________________________________________________ ____________
#include <string>
#include <cstdio>
#include <new>
#define PRINTF_THIS(mp_type, mp_func) \
std::printf("(%p)->" mp_type "::" mp_func "\n", (void*)this)
struct foo_ctor {
std::string const m_name;

foo_ctor(std::string const& name) : m_name(name) {
PRINTF_THIS("foo_ctor", "foo_ctor()");
}

~foo_ctor() {
PRINTF_THIS("foo_ctor", "~foo_ctor()");
}

void display_name() {
PRINTF_THIS("foo_ctor", "display_name()");
std::printf("%s\n", m_name.c_str());
}
};
int main() {
{
unsigned char buf[1024 * 8] = { '\0' };
stack_region_allocator region(buf, sizeof(buf));
foo_ctor* fctor = new (region.allocate<foo_ctor>()) foo_ctor("Chris");
fctor->display_name();
fctor->~foo_ctor();
region.reset();
}
std::puts("\n\n\n_________________________________ ___________\
_________________\npress <ENTERto exit...");
std::getchar();
return 0;
}

__________________________________________________ ____________
No need to call delete; just the dtor.

;^o
Jun 27 '08 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Bernhard Kick | last post: by
3 posts views Thread by Diebels | last post: by
3 posts views Thread by Chris Thomasson | last post: by
11 posts views Thread by Chris Thomasson | last post: by
5 posts views Thread by Bob Doe | last post: by
8 posts views Thread by Chris M. Thomasson | last post: by
reply views Thread by mihailmihai484 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.