Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add a mallocator system to recycle unused objects instead of free them and malloc...
[simgrid.git] / src / xbt / mallocator.c
1 #include "xbt/mallocator.h"
2 #include "xbt/asserts.h"
3 #include "xbt/sysdep.h"
4 #include "mallocator_private.h"
5
6 xbt_mallocator_t xbt_mallocator_new(int size,
7                                     pvoid_f_void_t new_f,
8                                     void_f_pvoid_t free_f,
9                                     void_f_pvoid_t reset_f) {
10   xbt_assert0(size > 0, "size must be positive");
11   xbt_assert0(new_f != NULL && free_f != NULL && reset_f != NULL,
12               "invalid parameter");
13   xbt_mallocator_t m = xbt_new0(s_xbt_mallocator_t, 1);
14
15   m->objects = xbt_new0(void*, size);
16   m->max_size = size;
17   m->current_size = 0;
18   m->new_f = new_f;
19   m->free_f = free_f;
20   m->reset_f = reset_f;
21
22   return m;
23 }
24
25 /* Destroy the mallocator and all its data */
26 void xbt_mallocator_free(xbt_mallocator_t m) {
27   xbt_assert0(m != NULL, "Invalid parameter");
28
29   int i;
30   for (i = 0; i < m->current_size; i++) {
31     m->free_f(m->objects[i]);
32   }
33   xbt_free(m->objects);
34   xbt_free(m);
35 }
36
37 /* Return an object (use this function instead of malloc) */
38 void *xbt_mallocator_get(xbt_mallocator_t m) {
39   xbt_assert0(m != NULL, "Invalid parameter");
40
41   void *object;
42   if (m->current_size > 0) {
43     /* there is at least an available object */
44     return m->objects[--m->current_size];
45   }
46   else {
47     /* otherwise we must allocate a new object */
48     object = m->new_f();
49     m->reset_f(object);
50     return object;
51   }
52 }
53
54 /* Release an object (use this function instead of free) */
55 void xbt_mallocator_release(xbt_mallocator_t m, void *object) {
56   xbt_assert0(m != NULL && object != NULL, "Invalid parameter");
57
58   if (m->current_size < m->max_size) {
59     /* there is enough place to push the object */
60     m->reset_f(object);
61     m->objects[m->current_size++] = object;
62   }
63   else {
64     /* otherwise we don't have a choice, we must free the object */
65     m->free_f(object);
66   }
67 }