X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust-libc-wrapper%2Flttng-ust-malloc.c;h=33ed18be09d5ea48eb5f0cabd73ce27ca151da46;hb=600f634aea56e0c003759be5f5e2eb5ac450b742;hp=c7f747bdce5acb30fc6c13a276abdb643844d374;hpb=f95b2888c1e9580ee59f58c09d79cf5be5d7b306;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 c7f747bd..33ed18be 100644 --- a/liblttng-ust-libc-wrapper/lttng-ust-malloc.c +++ b/liblttng-ust-libc-wrapper/lttng-ust-malloc.c @@ -21,7 +21,8 @@ #include #include #include -#include +#include +#include #define TRACEPOINT_DEFINE #define TRACEPOINT_CREATE_PROBES @@ -29,21 +30,27 @@ #define STATIC_CALLOC_LEN 4096 static char static_calloc_buf[STATIC_CALLOC_LEN]; -static size_t static_calloc_buf_offset; -static pthread_mutex_t static_calloc_mutex = PTHREAD_MUTEX_INITIALIZER; +static unsigned long static_calloc_buf_offset; static void *static_calloc(size_t nmemb, size_t size) { - size_t prev_offset; + unsigned long prev_offset, new_offset, res_offset; - pthread_mutex_lock(&static_calloc_mutex); - if (nmemb * size > sizeof(static_calloc_buf) - static_calloc_buf_offset) { - pthread_mutex_unlock(&static_calloc_mutex); - return NULL; - } - prev_offset = static_calloc_buf_offset; - static_calloc_buf_offset += nmemb * size; - pthread_mutex_unlock(&static_calloc_mutex); + /* + * 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]; } @@ -126,3 +133,37 @@ void *realloc(void *ptr, size_t 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; +}