Subject: Re: [boost] Proposal: Monotonic Containers - Comparison with boost::pool, boost::fast_pool and TBB
From: Christian Schladetsch (christian.schladetsch_at_[hidden])
Date: 2009-06-22 19:03:16
[...] I have two ideas. First, put a counter in monotonic that is
> incremented when allocations happen and decremented when deallocations
> happen. If the counter is ever zero you blow away all the buffers
This is a good idea; I'll add it. I currently keep track of allocation
counts for informative reasons only for debug builds.
> Second, you create a scoped object that encapsulates the idea of the
> monotonic storage's lifetime and delete the buffers when the object is
std::list<int, monotonic::allocator<int> > list; // uses local storage,
Finally, you add a template parameter to monotonic to allow many programmers
> working in the same application to declare their own monotonic type that has
> separate buffers and lifetime from eachother.
The nterface is:
/// a monotonic region allocator uses a specified storage.
/// Each region uses independent
/// storage that may be used and reset.
template <class T, size_t Region = 0>
This is used like:
typedef std::list<int, monotonic::region_allocator<int, 0> > List;
typedef std::list<int, monotonic::region_allocator<int, 42> > OtherList;
etc. Basically, it allows you to have up to
monotonic::DefaultSizes::MaxRegions of independantly controlled regions of
In this way managing the memory owned monotonic can be easy and safe. The
> only problem left is therefore misuse. I'm trying to understand the risk of
> misuse, and it looks like running out of memory is the primary risk.
I mentioned earlier that it may be beneficial to add introspection to debug
builds that warn about misuse, and I increasingly think it will be
> Perhaps I missed this part of the discussion, but why is it named
The name has been questioned earlier as well. The motivation for the name
came from the fact that memory usage only ever increases - monotonically.
I agree that the name is somewhat vague, especially considering that it can
be used as a general stack+heap storage system, as well as an allocator.
> I would think something that describes its intended usage would be better.
> boost::scratch_memory, for example. Anyone who keeps objects allocated
> with an allocator called scratch_memory around for the lifetime of his
> program has some obvious explaining to do.
I like this because it makes it clear that it is primarily for temporay use.
It also works for the following:
string &str = storage.create<string>("spam");
boost::array<Foo, 16> &foos = storage.create<boost::array<Foo, 16> >();
The usage is a bit clearer than boost::monotonic::storage<>
> I also think that a more general interface would be to allow the user to
> supply and address and size of memory to use as the initial scratch memory
> with the automatic (on by default) ability to grow beyond that buffer if
> needed with system allocation on the heap using the chain.
This is a good idea and can be adopted. Currently, storage<StackSize,
MinHeapIncrement> uses the stack first, then the heap. You can of course
make it just on the stack with storage<N, 0> or just on the heap with
However it could be made so that the first link in the chain is supplied by
the user. See
> Thread safty should be controlled by a template parameter and enabled by
Currently, thread-safety is controlled by the allocator type:
monotonic::allocator<T> // single-threaded
monotonic::shared_allocator<T> // multi-threaded via mutex
monotonic::local_allocator<T> // uses thread-local-storage for the storage
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk