Brian Pane wrote:
Cliff Woolley wrote:
...
apr_bucket_free() knows nothing about buckets, so ignore the fact that a
bucket contains an apr_bucket_alloc_t* (see below). The block allocated
by apr_bucket_alloc() will have internal information stored immediately
prior to (or following?) the location returned from apr_bucket_alloc. In
other words, apr_bucket_alloc will over-allocate so that it has a few
bytes for its own purposes. You and I had talked about that a while back
and agreed that that seemed a reasonable way to handle the problem.
Cool, I'd forgotten about storing the metadata stored right in
front of the block returned by apr_bucket_alloc(); that will solve
the problem very cleanly.
I just ran an httpd with an instrumented version of apr_bucket_alloc to collect data about the sizes of the buckets being allocated. The results look like this:
alloc size percent (rounded up of total to next power bucket of two) allocs
8 10%
16 15%
32 73%
8192 2%
The 8KB allocations are from apr_brigade_write(). These 8KB blocks imply a design constraint for the bucket allocator: it can't quite be a simple power-of-two allocator. Each allocation of an 8KB block will really need 8KB+sizeof(void*) bytes, in order to hold the apr_bucket_alloc_t* in front of the block. So if the underlying allocator is strictly applying a power-of-two rule, it will create 16KB blocks for these. (I think we'll run into this problem if the apr_brigade_alloc() function uses the same node_malloc() function that's currently used in apr_pool_t, for example.)
--Brian
