2 * Copyright (C) 2009 Pierre-Marc Fournier
3 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <sys/types.h>
26 #define TRACEPOINT_DEFINE
27 #define TRACEPOINT_CREATE_PROBES
30 #define STATIC_CALLOC_LEN 4096
31 static char static_calloc_buf
[STATIC_CALLOC_LEN
];
32 static size_t static_calloc_buf_offset
;
33 static pthread_mutex_t static_calloc_mutex
= PTHREAD_MUTEX_INITIALIZER
;
35 static void *static_calloc(size_t nmemb
, size_t size
)
39 pthread_mutex_lock(&static_calloc_mutex
);
40 if (nmemb
* size
> sizeof(static_calloc_buf
) - static_calloc_buf_offset
) {
41 pthread_mutex_unlock(&static_calloc_mutex
);
44 prev_offset
= static_calloc_buf_offset
;
45 static_calloc_buf_offset
+= nmemb
* size
;
46 pthread_mutex_unlock(&static_calloc_mutex
);
47 return &static_calloc_buf
[prev_offset
];
50 void *malloc(size_t size
)
52 static void *(*plibc_malloc
)(size_t size
);
55 if (plibc_malloc
== NULL
) {
56 plibc_malloc
= dlsym(RTLD_NEXT
, "malloc");
57 if (plibc_malloc
== NULL
) {
58 fprintf(stderr
, "mallocwrap: unable to find malloc\n");
62 retval
= plibc_malloc(size
);
63 tracepoint(ust_libc
, malloc
, size
, retval
);
69 static void (*plibc_free
)(void *ptr
);
71 /* Check whether the memory was allocated with
72 * static_calloc, in which case there is nothing
75 if ((char *)ptr
>= static_calloc_buf
&&
76 (char *)ptr
< static_calloc_buf
+ STATIC_CALLOC_LEN
) {
80 if (plibc_free
== NULL
) {
81 plibc_free
= dlsym(RTLD_NEXT
, "free");
82 if (plibc_free
== NULL
) {
83 fprintf(stderr
, "mallocwrap: unable to find free\n");
87 tracepoint(ust_libc
, free
, ptr
);
91 void *calloc(size_t nmemb
, size_t size
)
93 static void *(*volatile plibc_calloc
)(size_t nmemb
, size_t size
);
96 if (plibc_calloc
== NULL
) {
98 * Temporarily redirect to static_calloc,
99 * until the dlsym lookup has completed.
101 plibc_calloc
= static_calloc
;
102 plibc_calloc
= dlsym(RTLD_NEXT
, "calloc");
103 if (plibc_calloc
== NULL
) {
104 fprintf(stderr
, "callocwrap: unable to find calloc\n");
108 retval
= plibc_calloc(nmemb
, size
);
109 tracepoint(ust_libc
, calloc
, nmemb
, size
, retval
);
113 void *realloc(void *ptr
, size_t size
)
115 static void *(*plibc_realloc
)(void *ptr
, size_t size
);
118 if (plibc_realloc
== NULL
) {
119 plibc_realloc
= dlsym(RTLD_NEXT
, "realloc");
120 if (plibc_realloc
== NULL
) {
121 fprintf(stderr
, "reallocwrap: unable to find realloc\n");
125 retval
= plibc_realloc(ptr
, size
);
126 tracepoint(ust_libc
, realloc
, ptr
, size
, retval
);