Sander Striker wrote:

I'll think out loud now:

Me too :-)


The solution might be adding specific allocation functions for SMS implementations. These functions could look something like this:

APR_DECLARE(void *) apr_sms_child_malloc(apr_sms_t *sms,
                                        apr_sms_t *child,
                                        apr_size_t size);

APR_DECLARE(apr_status_t) apr_sms_child_free(apr_sms_t *sms,
                                            apr_sms_t *child,
                                            void *mem);

Internally the framework will use the child_malloc_fn if present.  If
not, it will fall back to malloc_fn.

This is something that overthrows the KIS policy though...


I think this approach (or a variant thereof) has a lot of promise.

One way to look at the root cause of the sms-pool fragmentation
and performance issues is that the notion of "parent pool" implies
two things:
 1. If P is the parent of S, S must cease to exist when
    P is destroyed.
 2. If S needs more memory, it gets obtains it from P
    by calling the "malloc" method of P.

It often doesn't make sense for these two roles to be
combined in the same object.  Corollary: It doesn't make
sense for apr_sms_malloc(parent) to be the mechanism by
which a child allocates additional space.

For example, a pool created for a subrequest needs to go out
of scope when its parent does, but it doesn't derive any real
benefit from routing requests for additional blocks through its
parent.  We could get better performance if the role of the
parent SMS were to supply a "block source" to the child.  This
block souce would be a pointer to an SMS that the child should
call whenever it needed more memory.  The block source could be
the parent itself, or it could be any ancestor of the parent.
In the case of a succession of sms_trivials stacked on top of
an sms_std, each sms_trivial would supply the pointer to the sms_std
as the block source for its child(ren).  (The resulting setup
would then look like the original pools implementation, in the
sense that children would bypass their parents to get additional
blocks.  The difference is that the parent gets to decide what
type of block source its children use--so if a stack of SMSs are
supposed to use memory from a shared memory segment, each SMS
in the stack can ensure that its descendents are using the shared
mem block source rather than some malloc(3)-based block source.)

Thoughts?

Thanks,
--Brian





Reply via email to