X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=liblttng-ust-libc-wrapper%2Flttng-ust-malloc.c;h=33ed18be09d5ea48eb5f0cabd73ce27ca151da46;hb=86a4e97112c40b1ec823c60de8138d6bb55262fe;hp=3212ff0bacca50f7e8511977ce66b708113f3c81;hpb=476037d9a24fdd5e339e3565743aadb9cb8a0a96;p=lttng-ust.git diff --git a/liblttng-ust-libc-wrapper/lttng-ust-malloc.c b/liblttng-ust-libc-wrapper/lttng-ust-malloc.c index 3212ff0b..33ed18be 100644 --- a/liblttng-ust-libc-wrapper/lttng-ust-malloc.c +++ b/liblttng-ust-libc-wrapper/lttng-ust-malloc.c @@ -21,14 +21,42 @@ #include #include #include +#include +#include #define TRACEPOINT_DEFINE #define TRACEPOINT_CREATE_PROBES #include "ust_libc.h" +#define STATIC_CALLOC_LEN 4096 +static char static_calloc_buf[STATIC_CALLOC_LEN]; +static unsigned long static_calloc_buf_offset; + +static void *static_calloc(size_t nmemb, size_t size) +{ + unsigned long prev_offset, new_offset, res_offset; + + /* + * Protect static_calloc_buf_offset from concurrent updates + * using a cmpxchg loop rather than a mutex to remove a + * dependency on pthread. This will minimize the risk of bad + * interaction between mutex and malloc instrumentation. + */ + res_offset = CMM_LOAD_SHARED(static_calloc_buf_offset); + do { + prev_offset = res_offset; + if (nmemb * size > sizeof(static_calloc_buf) - prev_offset) { + return NULL; + } + new_offset = prev_offset + nmemb * size; + } while ((res_offset = uatomic_cmpxchg(&static_calloc_buf_offset, + prev_offset, new_offset)) != prev_offset); + return &static_calloc_buf[prev_offset]; +} + void *malloc(size_t size) { - static void *(*plibc_malloc)(size_t size) = NULL; + static void *(*plibc_malloc)(size_t size); void *retval; if (plibc_malloc == NULL) { @@ -45,7 +73,16 @@ void *malloc(size_t size) void free(void *ptr) { - static void *(*plibc_free)(void *ptr) = NULL; + static void (*plibc_free)(void *ptr); + + /* Check whether the memory was allocated with + * static_calloc, in which case there is nothing + * to free. + */ + if ((char *)ptr >= static_calloc_buf && + (char *)ptr < static_calloc_buf + STATIC_CALLOC_LEN) { + return; + } if (plibc_free == NULL) { plibc_free = dlsym(RTLD_NEXT, "free"); @@ -57,3 +94,76 @@ void free(void *ptr) tracepoint(ust_libc, free, ptr); plibc_free(ptr); } + +void *calloc(size_t nmemb, size_t size) +{ + static void *(*volatile plibc_calloc)(size_t nmemb, size_t size); + void *retval; + + if (plibc_calloc == NULL) { + /* + * Temporarily redirect to static_calloc, + * until the dlsym lookup has completed. + */ + plibc_calloc = static_calloc; + plibc_calloc = dlsym(RTLD_NEXT, "calloc"); + if (plibc_calloc == NULL) { + fprintf(stderr, "callocwrap: unable to find calloc\n"); + return NULL; + } + } + retval = plibc_calloc(nmemb, size); + tracepoint(ust_libc, calloc, nmemb, size, retval); + return retval; +} + +void *realloc(void *ptr, size_t size) +{ + static void *(*plibc_realloc)(void *ptr, size_t size); + void *retval; + + if (plibc_realloc == NULL) { + plibc_realloc = dlsym(RTLD_NEXT, "realloc"); + if (plibc_realloc == NULL) { + fprintf(stderr, "reallocwrap: unable to find realloc\n"); + return NULL; + } + } + retval = plibc_realloc(ptr, size); + tracepoint(ust_libc, realloc, ptr, size, retval); + return retval; +} + +void *memalign(size_t alignment, size_t size) +{ + static void *(*plibc_memalign)(size_t alignment, size_t size); + void *retval; + + if (plibc_memalign == NULL) { + plibc_memalign = dlsym(RTLD_NEXT, "memalign"); + if (plibc_memalign == NULL) { + fprintf(stderr, "memalignwrap: unable to find memalign\n"); + return NULL; + } + } + retval = plibc_memalign(alignment, size); + tracepoint(ust_libc, memalign, alignment, size, retval); + return retval; +} + +int posix_memalign(void **memptr, size_t alignment, size_t size) +{ + static int(*plibc_posix_memalign)(void **memptr, size_t alignment, size_t size); + int retval; + + if (plibc_posix_memalign == NULL) { + plibc_posix_memalign = dlsym(RTLD_NEXT, "posix_memalign"); + if (plibc_posix_memalign == NULL) { + fprintf(stderr, "posix_memalignwrap: unable to find posix_memalign\n"); + return ENOMEM; + } + } + retval = plibc_posix_memalign(memptr, alignment, size); + tracepoint(ust_libc, posix_memalign, *memptr, alignment, size, retval); + return retval; +}