76b63e0e340c0227e5467e8b6909a02212716acd
[protos/libecoli.git] / lib / ecoli_malloc.h
1 /*
2  * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the University of California, Berkeley nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #ifndef ECOLI_MALLOC_
29 #define ECOLI_MALLOC_
30
31 #include <sys/types.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 typedef void *(*ec_malloc_t)(size_t size, const char *file, unsigned int line);
36 typedef void (*ec_free_t)(void *ptr, const char *file, unsigned int line);
37 typedef void *(*ec_realloc_t)(void *ptr, size_t size, const char *file,
38         unsigned int line);
39
40 struct ec_malloc_handler {
41         ec_malloc_t malloc;
42         ec_free_t free;
43         ec_realloc_t realloc;
44 };
45
46 extern struct ec_malloc_handler ec_malloc_handler;
47
48 int ec_malloc_register(ec_malloc_t usr_malloc, ec_free_t usr_free,
49         ec_realloc_t usr_realloc);
50 void ec_malloc_unregister(void);
51
52 /* internal */
53 void *__ec_malloc(size_t size, const char *file, unsigned int line);
54 void __ec_free(void *ptr, const char *file, unsigned int line);
55 void *__ec_calloc(size_t nmemb, size_t size, const char *file,
56         unsigned int line);
57 void *__ec_realloc(void *ptr, size_t size, const char *file, unsigned int line);
58 char *__ec_strdup(const char *s, const char *file, unsigned int line);
59 char *__ec_strndup(const char *s, size_t n, const char *file,
60         unsigned int line);
61
62 /* XXX rename into ec_malloc, and change macro to uppercase */
63 void *ec_malloc2(size_t size);
64 void ec_free2(void *ptr);
65
66 /* we use macros here to ensure the file/line stay correct when
67  * debugging the standard malloc with valgrind */
68
69 #define ec_malloc(sz) ({                                                \
70         void *ret_;                                                     \
71         if (ec_malloc_handler.malloc == NULL)                           \
72                 ret_ = malloc(sz);                                      \
73         else                                                            \
74                 ret_ = __ec_malloc(sz, __FILE__, __LINE__);             \
75         ret_;                                                           \
76         })
77
78 #define ec_free(ptr) ({                                                 \
79         if (ec_malloc_handler.free == NULL)                             \
80                 free(ptr);                                              \
81         else                                                            \
82                 __ec_free(ptr, __FILE__, __LINE__);                     \
83         })
84
85 #define ec_realloc(ptr, sz) ({                                          \
86         void *ret_;                                                     \
87         if (ec_malloc_handler.realloc == NULL)                          \
88                 ret_ = realloc(ptr, sz);                                \
89         else                                                            \
90                 ret_ = __ec_realloc(ptr, sz, __FILE__, __LINE__);       \
91         ret_;                                                           \
92         })
93
94 #define ec_calloc(n, sz) ({                                             \
95         void *ret_;                                                     \
96         if (ec_malloc_handler.malloc == NULL)                           \
97                 ret_ = calloc(n, sz);                                   \
98         else                                                            \
99                 ret_ = __ec_calloc(n, sz, __FILE__, __LINE__);          \
100         ret_;                                                           \
101         })
102
103 #define ec_strdup(s) ({                                                 \
104         void *ret_;                                                     \
105         if (ec_malloc_handler.malloc == NULL)                           \
106                 ret_ = strdup(s);                                       \
107         else                                                            \
108                 ret_ = __ec_strdup(s, __FILE__, __LINE__);              \
109         ret_;                                                           \
110         })
111
112 #define ec_strndup(s, n) ({                                             \
113         void *ret_;                                                     \
114         if (ec_malloc_handler.malloc == NULL)                           \
115                 ret_ = strndup(s, n);                                   \
116         else                                                            \
117                 ret_ = __ec_strndup(s, n, __FILE__, __LINE__);          \
118         ret_;                                                           \
119         })
120
121
122 #endif