From: Mathieu Desnoyers Date: Wed, 7 Aug 2013 15:48:50 +0000 (-0400) Subject: malloc instrumentation: remove dependency on pthread X-Git-Tag: v2.3.0-rc2~9 X-Git-Url: http://git.liburcu.org/?p=lttng-ust.git;a=commitdiff_plain;h=4c3536e01190b118e0889ebb991b0eea6f98260e malloc instrumentation: remove dependency on pthread Signed-off-by: Mathieu Desnoyers --- diff --git a/liblttng-ust-libc-wrapper/lttng-ust-malloc.c b/liblttng-ust-libc-wrapper/lttng-ust-malloc.c index c7f747bd..4fe8fa97 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]; }