Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add a mallocator system to recycle unused objects instead of free them and malloc...
authorthiery <thiery@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 3 Aug 2006 14:08:18 +0000 (14:08 +0000)
committerthiery <thiery@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 3 Aug 2006 14:08:18 +0000 (14:08 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@2684 48e7efb5-ca39-0410-a469-dd3cf9ba447f

include/xbt/mallocator.h [new file with mode: 0644]
src/xbt/mallocator.c [new file with mode: 0644]
src/xbt/mallocator_private.h [new file with mode: 0644]

diff --git a/include/xbt/mallocator.h b/include/xbt/mallocator.h
new file mode 100644 (file)
index 0000000..ff13879
--- /dev/null
@@ -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 (file)
index 0000000..52d7702
--- /dev/null
@@ -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 (file)
index 0000000..bd5aedd
--- /dev/null
@@ -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