foonathan/memory

Wrap a memory_pool in a thread_safe_allocator?

mcourteaux opened this issue · 1 comments

A memory_pool manages nodes of fixed size, is stateful, and not thread-safe. The fixed-size nodes implies that the allocate_node() function does not take any arguments.

thread_safe_allocator<> takes size and alignment arguments and forwards it (after locking the mutex) to the underlying allocator.

However, the underlying allocator is a memory_pool, which does not accept a size argument. How do you make a thread-safe memory pool?

If the answer is "you can't", then which allocator do I wrap in the thread_safe_allocator to obtain the same behavior with a free-list?

I managed! This was not straightforward. Some more examples in the documentation would be nice.

struct timer; // my object type
foonathan::memory::thread_safe_allocator<foonathan::memory::memory_pool<>> pool {
    foonathan::memory::memory_pool<>(
      foonathan::memory::list_node_size<timer>::value, 4096
    )};

void *storage = pool.allocate_node(sizeof(timer), alignof(timer));

So, basically, you loose the syntax where you can just allocate_node() without any arguments, as it goes through the allocator_traits system. This is all very overwhelming when trying this out for the first time.

Bonus question: is there a way to not have this pool immediately allocate a block? I'd like to put this pool as a global in my program, but that means the first block gets immediately allocated during static initialization of the program in C++, which is very annoying to deal with. I'd like it to not allocate anything until the first call to any allocate_node() function and then have it kick off it's first real allocation on the underlying allocator.