Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
a5d57952cf1017c6196cec23c1eba34c7610d255
[simgrid.git] / src / xbt / mmalloc / mm_legacy.c
1 /* Copyright (c) 2010-2014. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 /* Redefine the classical malloc/free/realloc functions so that they fit well in the mmalloc framework */
8 #define _GNU_SOURCE
9
10 #include <stdlib.h>
11
12 #include <dlfcn.h>
13
14 #include "../../mc/mc_base.h"
15 #include "mmprivate.h"
16 #include "xbt_modinter.h"
17 #include "internal_config.h"
18 #include <math.h>
19
20 //#define MM_LEGACY_VERBOSE 1 /* define this to see which version of malloc gets used */
21
22 /* The mmalloc() package can use a single implicit malloc descriptor
23    for mmalloc/mrealloc/mfree operations which do not supply an explicit
24    descriptor.  This allows mmalloc() to provide
25    backwards compatibility with the non-mmap'd version. */
26 xbt_mheap_t __mmalloc_default_mdp = NULL;
27
28 static int __malloc_use_mmalloc;
29
30 int malloc_use_mmalloc(void)
31 {
32   return __malloc_use_mmalloc;
33 }
34
35 static xbt_mheap_t __mmalloc_current_heap = NULL;     /* The heap we are currently using. */
36
37 xbt_mheap_t mmalloc_get_current_heap(void)
38 {
39   return __mmalloc_current_heap;
40 }
41
42 void mmalloc_set_current_heap(xbt_mheap_t new_heap)
43 {
44   __mmalloc_current_heap = new_heap;
45 }
46
47 #ifdef MMALLOC_WANT_OVERRIDE_LEGACY
48
49 /* Fake implementations, they are used to fool dlsym:
50  * dlsym used calloc and falls back to some other mechanism
51  * if this fails.
52  */
53 static void* mm_fake_calloc(size_t nmemb, size_t size) { return NULL; }
54 static void* mm_fake_malloc(size_t n)                  { return NULL; }
55 static void* mm_fake_realloc(void *p, size_t s)        { return NULL; }
56
57 /* Function signatures for the main malloc functions: */
58 typedef void* (*mm_malloc_t)(size_t size);
59 typedef void  (*mm_free_t)(void*);
60 typedef void* (*mm_calloc_t)(size_t nmemb, size_t size);
61 typedef void* (*mm_realloc_t)(void *ptr, size_t size);
62
63 /* Function pointers to the real/next implementations: */
64 static mm_malloc_t mm_real_malloc   = mm_fake_malloc;
65 static mm_free_t mm_real_free;
66 static mm_calloc_t mm_real_calloc   = mm_fake_calloc;
67 static mm_realloc_t mm_real_realloc = mm_fake_realloc;
68
69 #define GET_HEAP() __mmalloc_current_heap
70
71 /** Constructor functions used to initialize the malloc implementation
72  */
73 static void __attribute__((constructor(101))) mm_legacy_constructor()
74 {
75   __malloc_use_mmalloc = getenv(MC_ENV_VARIABLE) ? 1 : 0;
76   if (__malloc_use_mmalloc) {
77     __mmalloc_current_heap = mmalloc_preinit();
78   } else {
79     mm_real_realloc  = (mm_realloc_t) dlsym(RTLD_NEXT, "realloc");
80     mm_real_malloc   = (mm_malloc_t)  dlsym(RTLD_NEXT, "malloc");
81     mm_real_free     = (mm_free_t)    dlsym(RTLD_NEXT, "free");
82     mm_real_calloc   = (mm_calloc_t)  dlsym(RTLD_NEXT, "calloc");
83   }
84 }
85
86 void *malloc(size_t n)
87 {
88   if (!__malloc_use_mmalloc) {
89     return mm_real_malloc(n);
90   }
91
92   xbt_mheap_t mdp = GET_HEAP();
93   if (!mdp)
94     return NULL;
95
96   LOCK(mdp);
97   void *ret = mmalloc(mdp, n);
98   UNLOCK(mdp);
99   return ret;
100 }
101
102 void *calloc(size_t nmemb, size_t size)
103 {
104   if (!__malloc_use_mmalloc) {
105     return mm_real_calloc(nmemb, size);
106   }
107
108   xbt_mheap_t mdp = GET_HEAP();
109   if (!mdp)
110     return NULL;
111
112   LOCK(mdp);
113   void *ret = mmalloc(mdp, nmemb*size);
114   UNLOCK(mdp);
115   // This was already done in the callee:
116   if(!(mdp->options & XBT_MHEAP_OPTION_MEMSET)) {
117     memset(ret, 0, nmemb * size);
118   }
119   return ret;
120 }
121
122 void *realloc(void *p, size_t s)
123 {
124   if (!__malloc_use_mmalloc) {
125     return mm_real_realloc(p, s);
126   }
127
128   xbt_mheap_t mdp = GET_HEAP();
129   if (!mdp)
130     return NULL;
131
132   LOCK(mdp);
133   void* ret = mrealloc(mdp, p, s);
134   UNLOCK(mdp);
135   return ret;
136 }
137
138 void free(void *p)
139 {
140   if (!__malloc_use_mmalloc) {
141     mm_real_free(p);
142     return;
143   }
144
145   if (!p)
146     return;
147
148   xbt_mheap_t mdp = GET_HEAP();
149   LOCK(mdp);
150   mfree(mdp, p);
151   UNLOCK(mdp);
152 }
153 #endif /* WANT_MALLOC_OVERRIDE */