Boost logo

Boost Users :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2003-10-22 07:29:34

John Aughey wrote:
> I have a class that implements a buffer pool that allocates block of
> memory, and the users "free" the memory when it is no longer needed
> back to the buffer pool. Future allocations simply return the front
> of the free list.
> Simple enough, and the class returns shared_array<T> objects to
> automatically free the memory back into the proper buffer pool.
> The problem is, this mechanism is used so that during real-time
> operation (this is a real-time system), there is absolutely no memory
> allocations required. However, inside shared_array, it uses
> detail::shared_count and inside shared_count it performs a new to
> create a sp_counted_base object. So for every smart pointer object
> that supplies a deleter, it must perform a new.
> My proposal would be to include another constructor to both
> shared_array (and probably it's corresponding smart pointer brothers)
> and to shared_count that looks like:
> shared_array(T *p, sp_counted_base *d) : px(p), pn(d) { }
> shared_count(sp_counted_base *d) : pi_(d) { }
> (I haven't implemented this yet, so the above may not be quite right)
> The purpose of this is to supply an sp_counted_base object to the
> shared_* object that does the delete functionality. This eliminates
> the new in the case where a sp_counted_base object can be supplied.
> In the case of the managed buffer pool mentioned above, the
> sp_counted_base object could be allocated with the corresponding
> buffer, and then re-used for subsequent "allocations" from the free
> list. This should result in no dynamic allocations to create a
> shared_* object with a corresponding deleter.
> I hope this makes sense. It should only require two new constuctors.

Yes, it makes perfect sense. Unfortunately it requires much more than just
two new constructors. sp_counted_base would need to be documented; many
shared_ptr operations would need to be respecified in terms of
sp_counted_base operations. This is, of course, possible to do for
boost::shared_ptr, but it would be unwise to overspecify
std::tr1::shared_ptr in such a way, and I am reluctant to add features to
boost::shared_ptr that have little chance to become standard.

There is one way to convince shared_ptr/shared_array to not allocate memory,
although I'm not sure whether it can be applied to your environment as-is.
First #define BOOST_SP_USE_QUICK_ALLOCATOR to make shared_ptr use
<boost/detail/quick_allocator.hpp>. At startup, where presumably dynamic
memory isn't strictly forbidden, instantiate a number of shared_ptr (or
shared_array, it doesn't matter) objects using the appropriate deleter. This
will make quick_allocator preallocate a number of pages (using ::operator
new[]). Destroy the temporary shared_ptr objects.

This sounds a bit painful, doesn't it. ;-) I'll think about streamlining the
process. If you have any ideas please let us know.

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at