From: thiery Date: Thu, 3 Aug 2006 14:08:18 +0000 (+0000) Subject: Add a mallocator system to recycle unused objects instead of free them and malloc... X-Git-Tag: v3.3~2675 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/e048b9d6c83f24e8649df8ae09759d4616ec0d30?ds=sidebyside Add a mallocator system to recycle unused objects instead of free them and malloc new ones git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@2684 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/include/xbt/mallocator.h b/include/xbt/mallocator.h new file mode 100644 index 0000000000..ff13879736 --- /dev/null +++ b/include/xbt/mallocator.h @@ -0,0 +1,22 @@ +#ifndef _XBT_MALLOCATOR_H +#define _XBT_MALLOCATOR_H + +#include "xbt/function_types.h" +#include "xbt/misc.h" /* SG_BEGIN_DECL */ + +SG_BEGIN_DECL() + +/* mallocator data type (opaque structure) */ +typedef struct s_xbt_mallocator *xbt_mallocator_t; + +/* creation and destruction */ +xbt_mallocator_t xbt_mallocator_new(int size, pvoid_f_void_t new_f, void_f_pvoid_t free_f, void_f_pvoid_t reset_f); +void xbt_mallocator_free(xbt_mallocator_t mallocator); + +/* object handling */ +void *xbt_mallocator_get(xbt_mallocator_t mallocator); +void xbt_mallocator_release(xbt_mallocator_t mallocator, void *object); + +SG_END_DECL() + +#endif /* _XBT_MALLOCATOR_H */ diff --git a/src/xbt/mallocator.c b/src/xbt/mallocator.c new file mode 100644 index 0000000000..52d77026d3 --- /dev/null +++ b/src/xbt/mallocator.c @@ -0,0 +1,67 @@ +#include "xbt/mallocator.h" +#include "xbt/asserts.h" +#include "xbt/sysdep.h" +#include "mallocator_private.h" + +xbt_mallocator_t xbt_mallocator_new(int size, + pvoid_f_void_t new_f, + void_f_pvoid_t free_f, + void_f_pvoid_t reset_f) { + xbt_assert0(size > 0, "size must be positive"); + xbt_assert0(new_f != NULL && free_f != NULL && reset_f != NULL, + "invalid parameter"); + xbt_mallocator_t m = xbt_new0(s_xbt_mallocator_t, 1); + + m->objects = xbt_new0(void*, size); + m->max_size = size; + m->current_size = 0; + m->new_f = new_f; + m->free_f = free_f; + m->reset_f = reset_f; + + return m; +} + +/* Destroy the mallocator and all its data */ +void xbt_mallocator_free(xbt_mallocator_t m) { + xbt_assert0(m != NULL, "Invalid parameter"); + + int i; + for (i = 0; i < m->current_size; i++) { + m->free_f(m->objects[i]); + } + xbt_free(m->objects); + xbt_free(m); +} + +/* Return an object (use this function instead of malloc) */ +void *xbt_mallocator_get(xbt_mallocator_t m) { + xbt_assert0(m != NULL, "Invalid parameter"); + + void *object; + if (m->current_size > 0) { + /* there is at least an available object */ + return m->objects[--m->current_size]; + } + else { + /* otherwise we must allocate a new object */ + object = m->new_f(); + m->reset_f(object); + return object; + } +} + +/* Release an object (use this function instead of free) */ +void xbt_mallocator_release(xbt_mallocator_t m, void *object) { + xbt_assert0(m != NULL && object != NULL, "Invalid parameter"); + + if (m->current_size < m->max_size) { + /* there is enough place to push the object */ + m->reset_f(object); + m->objects[m->current_size++] = object; + } + else { + /* otherwise we don't have a choice, we must free the object */ + m->free_f(object); + } +} diff --git a/src/xbt/mallocator_private.h b/src/xbt/mallocator_private.h new file mode 100644 index 0000000000..bd5aeddcfa --- /dev/null +++ b/src/xbt/mallocator_private.h @@ -0,0 +1,13 @@ +#ifndef _XBT_DICT_PRIVATE_H__ +#define _XBT_DICT_PRIVATE_H__ + +typedef struct s_xbt_mallocator { + int current_size; /* number of objects currently stored */ + void **objects; /* objects stored by the mallocator and available for the user */ + int max_size; /* maximum number of objects */ + pvoid_f_void_t *new_f; /* function to call when we are running out of objects */ + void_f_pvoid_t *free_f; /* function to call when we have got too many objects */ + void_f_pvoid_t *reset_f; /* function to call when an object is released by the user */ +} s_xbt_mallocator_t; + +#endif