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>
24 #include <urcu/system.h>
25 #include <urcu/uatomic.h>
27 #define TRACEPOINT_DEFINE
28 #define TRACEPOINT_CREATE_PROBES
31 #define STATIC_CALLOC_LEN 4096
32 static char static_calloc_buf
[STATIC_CALLOC_LEN
];
33 static unsigned long static_calloc_buf_offset
;
35 static void *static_calloc(size_t nmemb
, size_t size
)
37 unsigned long prev_offset
, new_offset
, res_offset
;
40 * Protect static_calloc_buf_offset from concurrent updates
41 * using a cmpxchg loop rather than a mutex to remove a
42 * dependency on pthread. This will minimize the risk of bad
43 * interaction between mutex and malloc instrumentation.
45 res_offset
= CMM_LOAD_SHARED(static_calloc_buf_offset
);
47 prev_offset
= res_offset
;
48 if (nmemb
* size
> sizeof(static_calloc_buf
) - prev_offset
) {
51 new_offset
= prev_offset
+ nmemb
* size
;
52 } while ((res_offset
= uatomic_cmpxchg(&static_calloc_buf_offset
,
53 prev_offset
, new_offset
)) != prev_offset
);
54 return &static_calloc_buf
[prev_offset
];
57 void *malloc(size_t size
)
59 static void *(*plibc_malloc
)(size_t size
);
62 if (plibc_malloc
== NULL
) {
63 plibc_malloc
= dlsym(RTLD_NEXT
, "malloc");
64 if (plibc_malloc
== NULL
) {
65 fprintf(stderr
, "mallocwrap: unable to find malloc\n");
69 retval
= plibc_malloc(size
);
70 tracepoint(ust_libc
, malloc
, size
, retval
);
76 static void (*plibc_free
)(void *ptr
);
78 /* Check whether the memory was allocated with
79 * static_calloc, in which case there is nothing
82 if ((char *)ptr
>= static_calloc_buf
&&
83 (char *)ptr
< static_calloc_buf
+ STATIC_CALLOC_LEN
) {
87 if (plibc_free
== NULL
) {
88 plibc_free
= dlsym(RTLD_NEXT
, "free");
89 if (plibc_free
== NULL
) {
90 fprintf(stderr
, "mallocwrap: unable to find free\n");
94 tracepoint(ust_libc
, free
, ptr
);
98 void *calloc(size_t nmemb
, size_t size
)
100 static void *(*volatile plibc_calloc
)(size_t nmemb
, size_t size
);
103 if (plibc_calloc
== NULL
) {
105 * Temporarily redirect to static_calloc,
106 * until the dlsym lookup has completed.
108 plibc_calloc
= static_calloc
;
109 plibc_calloc
= dlsym(RTLD_NEXT
, "calloc");
110 if (plibc_calloc
== NULL
) {
111 fprintf(stderr
, "callocwrap: unable to find calloc\n");
115 retval
= plibc_calloc(nmemb
, size
);
116 tracepoint(ust_libc
, calloc
, nmemb
, size
, retval
);
120 void *realloc(void *ptr
, size_t size
)
122 static void *(*plibc_realloc
)(void *ptr
, size_t size
);
125 if (plibc_realloc
== NULL
) {
126 plibc_realloc
= dlsym(RTLD_NEXT
, "realloc");
127 if (plibc_realloc
== NULL
) {
128 fprintf(stderr
, "reallocwrap: unable to find realloc\n");
132 retval
= plibc_realloc(ptr
, size
);
133 tracepoint(ust_libc
, realloc
, ptr
, size
, retval
);
137 void *memalign(size_t alignment
, size_t size
)
139 static void *(*plibc_memalign
)(size_t alignment
, size_t size
);
142 if (plibc_memalign
== NULL
) {
143 plibc_memalign
= dlsym(RTLD_NEXT
, "memalign");
144 if (plibc_memalign
== NULL
) {
145 fprintf(stderr
, "memalignwrap: unable to find memalign\n");
149 retval
= plibc_memalign(alignment
, size
);
150 tracepoint(ust_libc
, memalign
, alignment
, size
, retval
);
154 int posix_memalign(void **memptr
, size_t alignment
, size_t size
)
156 static int(*plibc_posix_memalign
)(void **memptr
, size_t alignment
, size_t size
);
159 if (plibc_posix_memalign
== NULL
) {
160 plibc_posix_memalign
= dlsym(RTLD_NEXT
, "posix_memalign");
161 if (plibc_posix_memalign
== NULL
) {
162 fprintf(stderr
, "posix_memalignwrap: unable to find posix_memalign\n");
166 retval
= plibc_posix_memalign(memptr
, alignment
, size
);
167 tracepoint(ust_libc
, posix_memalign
, *memptr
, alignment
, size
, retval
);
This page took 0.033769 seconds and 4 git commands to generate.