Re: [patch] calling g_malloc & co via a vtable



On Mon, 2 Oct 2000, Alexander Larsson wrote:

> Here is a patch that adds a vtable to g_malloc, g_malloc0, g_realloc and
> g_free. It also adds g_try_malloc and g_try_realloc (not guaranteed to
> return non-NULL).

great, this is pretty much what i had in mind.
as you've probably seen in this thread and can be proven from earlier
threads on malloc virtualization/callbacks on this thread, it's close
to impossible to reach complete consensus on how out-of-mem situations
should be handled.
that's pretty much why i decided that for glib we'll go with a vtable
such as yours and let the masochists deal with the internals if they
really have to ;)

> Is any one interested? Any comments? Here are a few questions:

yep, thanks for beating me at it, it's one more item to remove from my
personal queue.

> Has anyone tested the dmalloc.h stuff recently? It looks like it will
> break some stuff that takes the address of g_free. Maybe i should rip it
> out, or move it to a GAllocFunctions (but that would loose the file and
> line no reporting).

get rid of it entirely.

> The memory check and profiling has got a lot of ifdefs in it. Since they
> are now in a vtable you could actually compile them in all the time. Or
> just rip them out and let the application do such stuff by themselves.

get rid of those as well, i really want all ifdefs in that code to vanish.
this:

/* standard allocators */
g_malloc, g_malloc0, g_free, g_realloc, g_try_malloc, g_try_realloc, g_new, g_new0

/* allocator implementation */
struct _GMemVTable
{
  /* mandatory */
  gpointer (*malloc)      (gulong size);
  gpointer (*realloc)     (gpointer mem, gulong size);
  gpointer (*try_malloc)  (gulong size);
  gpointer (*try_realloc) (gpointer mem, gulong size);
  void     (*free)        (gpointer mem);
  /* optional */
  gpointer (*malloc0)     (gulong size);
};
void	 g_mem_set_vtable (const GMemVTable *vtable);

/* specialized variants */
extern const GMemVTable g_mem_vtable_check;
extern const GMemVTable g_mem_vtable_profiling;
void	 g_mem_profile      (void);
void	 g_mem_check        (gpointer mem);

is what the API should be limited to.
g_mem_set_vtable() has to be documented to only be callable
_prior_ to any other glib function, and it should puke if any
GMemVTable's mandatory parts aren't provided. *malloc0 can be
implemented in terms of *malloc + memset which is why it's optional.

> One thing that i'd like to add, which is pretty usefull in embedded
> systems is a memory pressure callback. It would be called when
> malloc() fails to let the developer try to free some memory (flushing
> caches etc). What do you think of this? It could be done by the user using
> a custom GAllocFunctions, but then Gtk+ and Glib couldn't use it.

nope, if required, people can implement this themselves.
the semantics are:

(*malloc)	GLib bails out if this returns NULL
(*realloc)	GLib bails out if this returns NULL
(*try_malloc)	GLib passes on the returned NULL
(*try_realloc)	GLib passes on the returned NULL
(*free)		always succeeds
(*malloc0)	same as (*malloc)

your memory pressure callback would be called from *malloc or *realloc
if they returned NULL, and if there's something that could be done about
it, the user can do that from his implementations of these functions (he
may have his own callback implementation there).
on the glib side, lets just keep things simple and virtualized so it's
tweakable if required.

notes on your implementation, g_malloc() and friends still have to be
real GLib functions to enforce guarrantees we make on the API.

gmem.c:

static GMemVTable *g_mem_vtable = glib_default_mem_vtable;

gpointer
g_malloc (gulong size)
{
  if (size)
    {
      gpointer mem = g_mem_vtable->malloc (size);
      
      if (!mem)
        g_error ("failed to allocate %ld bytes", size);
      
      return mem;
    }
  
  return NULL;
}

that is, if someone passed in a vtable with GMemVTable.malloc
pointing to glibc's malloc(3), we'd still catch the NULL return.

> 
> / Alex
> 


---
ciaoTJ





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]