Proposed addition of malloc_size_np()
Jason Evans
jasone at FreeBSD.org
Mon Mar 27 20:51:32 UTC 2006
On Mar 27, 2006, at 10:50 AM, John-Mark Gurney wrote:
> Jason Evans wrote this message on Mon, Mar 27, 2006 at 08:34 -0800:
>>
>> I can think of a few straightforward uses:
>
> [...]
>
>> 2) [...]
>
> This use case is incorrect...
Fair enough. That leaves three use cases.
>> 4) Porting code from Linux. Case in point: Xara Xtreme, currently
>> being
>> ported by Vasil Dimov. At the moment, he has to use dlmalloc.
>
> sad to say, but we seem to always inherit Linux's warts in the name of
> portability.. :( I'd say adopt a method similar to the ports tree,
> once
> we have 10+ ports depending upon it, then we can consider this.. but
> importing this function for a single program seems a bit excessive..
malloc_usable_size() is *not* a Linux wart. Instead, it mostly[1]
addresses a fundamental flaw in the malloc(3) API. We must go back
much farther than Linux if we really want to start disparaging malloc
(3). Consider that the allocator must know how large allocations are
so that it can do the right thing for realloc() and free(). Consider
also that the application must know how large its objects are so that
it can stay in bounds. That means that such information has to be
stored in two places. Following is a much more reasonable API that
doesn't burden the allocator with information that the application
should be able to provide:
void *
malloc(size_t size);
void *
calloc(size_t size);
void *
realloc(void *ptr, size_t size, size_t old_size);
void
free(void *ptr, size_t size);
That's not what we have though, and we're certainly not going to
completely redesign malloc(3) at this point. So, instead, we're
faced with trying to patch things up as well as is feasible without
breaking compatibility. Let's re-visit Poul-Henning's suggestion,
which involves a parallel API that exposes the internal sizes to the
application. The following is not identical to what he proposed, but
it has the same semantics:
void *
malloc_np(size_t *size);
void *
calloc_np(size_t *size);
void *
realloc_np(void *ptr, size_t *size, size_t *old_size);
void *
memalign_np(size_t alignment, size_t *size);
void *
free_np(void *ptr, size_t *size);
This serves much the same purpose as the idealized malloc(3) API I
outlined above but with the advantage that it can co-exist with the
current malloc(3) API. From an engineering perspective, this is
probably actually a better solution than malloc_usable_size(), but 1)
it's a much broader API, 2) it's nothing like what any other OSes
have done, and 3) in practice it really doesn't gain us anything over
malloc_usable_size() (in fact it doesn't solve the problem of porting
Linux and OS X software).
For my own personal needs, I really don't care whether we add
malloc_usable_size() or the broader API described above. However, I
do feel like the latter is an over-engineered solution to the
problem. To me, this isn't about reinventing a perfect wheel -- it's
about filing off a rough edge on the stone wheel we're stuck with.
Jason
[1] In a slightly more ideal world, we would add malloc_size()
instead of malloc_usable_size(), which would return the size that was
passed to malloc()/calloc()/realloc(). However, that would impose
implementation constraints on the allocator that would have far-
reaching implications. I don't want to get into the details here,
but suffice it to say that requiring support for malloc_size() would
require a lot of extra space overhead for many allocator designs,
including for phkmalloc and jemalloc.
More information about the freebsd-arch
mailing list