malloc instrumentation: remove dependency on pthread
[lttng-ust.git] / liblttng-ust-libc-wrapper / lttng-ust-malloc.c
... / ...
CommitLineData
1/*
2 * Copyright (C) 2009 Pierre-Marc Fournier
3 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 *
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.
9 *
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.
14 *
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
18 */
19
20#define _GNU_SOURCE
21#include <dlfcn.h>
22#include <sys/types.h>
23#include <stdio.h>
24#include <urcu/system.h>
25#include <urcu/uatomic.h>
26
27#define TRACEPOINT_DEFINE
28#define TRACEPOINT_CREATE_PROBES
29#include "ust_libc.h"
30
31#define STATIC_CALLOC_LEN 4096
32static char static_calloc_buf[STATIC_CALLOC_LEN];
33static unsigned long static_calloc_buf_offset;
34
35static void *static_calloc(size_t nmemb, size_t size)
36{
37 unsigned long prev_offset, new_offset, res_offset;
38
39 /*
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.
44 */
45 res_offset = CMM_LOAD_SHARED(static_calloc_buf_offset);
46 do {
47 prev_offset = res_offset;
48 if (nmemb * size > sizeof(static_calloc_buf) - prev_offset) {
49 return NULL;
50 }
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];
55}
56
57void *malloc(size_t size)
58{
59 static void *(*plibc_malloc)(size_t size);
60 void *retval;
61
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");
66 return NULL;
67 }
68 }
69 retval = plibc_malloc(size);
70 tracepoint(ust_libc, malloc, size, retval);
71 return retval;
72}
73
74void free(void *ptr)
75{
76 static void (*plibc_free)(void *ptr);
77
78 /* Check whether the memory was allocated with
79 * static_calloc, in which case there is nothing
80 * to free.
81 */
82 if ((char *)ptr >= static_calloc_buf &&
83 (char *)ptr < static_calloc_buf + STATIC_CALLOC_LEN) {
84 return;
85 }
86
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");
91 return;
92 }
93 }
94 tracepoint(ust_libc, free, ptr);
95 plibc_free(ptr);
96}
97
98void *calloc(size_t nmemb, size_t size)
99{
100 static void *(*volatile plibc_calloc)(size_t nmemb, size_t size);
101 void *retval;
102
103 if (plibc_calloc == NULL) {
104 /*
105 * Temporarily redirect to static_calloc,
106 * until the dlsym lookup has completed.
107 */
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");
112 return NULL;
113 }
114 }
115 retval = plibc_calloc(nmemb, size);
116 tracepoint(ust_libc, calloc, nmemb, size, retval);
117 return retval;
118}
119
120void *realloc(void *ptr, size_t size)
121{
122 static void *(*plibc_realloc)(void *ptr, size_t size);
123 void *retval;
124
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");
129 return NULL;
130 }
131 }
132 retval = plibc_realloc(ptr, size);
133 tracepoint(ust_libc, realloc, ptr, size, retval);
134 return retval;
135}
This page took 0.022793 seconds and 4 git commands to generate.