malloc instrumentation: remove dependency on pthread
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 7 Aug 2013 15:48:50 +0000 (11:48 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 7 Aug 2013 15:48:50 +0000 (11:48 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
liblttng-ust-libc-wrapper/lttng-ust-malloc.c

index c7f747bdce5acb30fc6c13a276abdb643844d374..4fe8fa97324e92ca14ac7edcd5efaf8b683b2ab8 100644 (file)
@@ -21,7 +21,8 @@
 #include <dlfcn.h>
 #include <sys/types.h>
 #include <stdio.h>
-#include <pthread.h>
+#include <urcu/system.h>
+#include <urcu/uatomic.h>
 
 #define TRACEPOINT_DEFINE
 #define TRACEPOINT_CREATE_PROBES
 
 #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];
 }
 
This page took 0.025104 seconds and 4 git commands to generate.