Boost logo

Boost :

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

Hi Luke,

[...] 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
> automatically.

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
> destructed.


monotonic::local<> storage;
     std::list<int, monotonic::allocator<int> > list; // uses local storage,
not global

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>
        struct region_allocator;

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
> monotonic?

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:

boost::scratch_memory::storage<> storage;
    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
storage<0, N>.

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
> default.

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, gregod at, cpdaniel at, john at