This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[RFC 1/2] Adding custom destructor for free.
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: libc-alpha at sourceware dot org
- Date: Mon, 11 Nov 2013 15:20:49 +0100
- Subject: [RFC 1/2] Adding custom destructor for free.
- Authentication-results: sourceware.org; auth=none
Hi,
For improving malloc a nice feature would be ability to assign a
function to a pointer that would do a custom free logic when called.
I wrote a proof-of-concept implementation to get comments, its interface
is
void *
dmalloc (size_t size, void *data,
void (*destroy)(void *p, void *size, void *data, void (*freep)(void *)))
This call returns a pointer that when a free of that pointer is called a
function destroy is invoked with size and data received by dmalloc.
Third argument is a pointer to original free routine, and function can
but does not have to free data by this function.
I have three applications in mind and will send a
prototypes that use this.
A major one is adding generic memory pool. Users often add a memory pool
to improve performance or to decrease memory overhead at cost of maintainability
and making memory usage less liquid.
Goal is provide a memory pool they can use to satisfy their needs which
has some added benefits, one is thread safety and effective returning
memory from other thread than original one.
Second application would be reference counting in c. It would allow to
return a char * strings that are shared and can be freed.
Third trick would be malloca that could be freed by a standard free
function (by making a stack destructor nop). This would be handy for
automatic conversion of heap allocation to stack-like conversion (which
could use alternative stack/split stack to satisfy large requests.)
I wonder if this would be a core functionality or by adding new
library?
Other comments?
#define _GNU_SOURCE
#include <dlfcn.h>
#include <malloc.h>
#include <stdint.h>
#define SENTINEL 8040899990803335949L
static int inited;
struct header
{
void *data;
size_t size;
void (*destroy)(void *, void *, void *, void (*)(void *));
uint64_t sentinel;
};
static void *(*reallocp)(void *, size_t);
static void (*freep)(void *);
static void
init ()
{
reallocp = dlsym (RTLD_NEXT, "realloc");
freep = dlsym (RTLD_NEXT, "free");
inited = 1;
}
void *
dmalloc (size_t s, void *data, void (*destroy)(void *, void *, void *, void (*)(void *)))
{
if (s > s + sizeof (struct header))
return NULL;
struct header *h = malloc (s + sizeof (struct header));
if (!h)
return NULL;
h->size = s;
h->data = data;
h->destroy = destroy;
h->sentinel = SENTINEL;
return h + 1;
}
void *
realloc (void *p, size_t s)
{
struct header *h = (struct header *) p;
h--;
if (h->sentinel == SENTINEL)
return reallocp (h, s + sizeof (struct header));
else
return reallocp (p, s);
}
void
free (void *p)
{
if (!inited)
init ();
if (!p)
return;
struct header *h = (struct header *) p;
h--;
if (h->sentinel == SENTINEL)
h->destroy ((void *) h, h->size, h->data , freep);
else
freep (p);
}