]> git.saurik.com Git - redis.git/blobdiff - zmalloc.c
Merge remote branch 'pietern/zfixes'
[redis.git] / zmalloc.c
index d453238136dcd87078c02c534ca21021c3e6fd1d..8658376a3462c9e4278c97eaf914b07dd6deaa8d 100644 (file)
--- a/zmalloc.c
+++ b/zmalloc.c
@@ -1,6 +1,6 @@
 /* zmalloc - total amount of allocated memory aware version of malloc()
  *
- * Copyright (c) 2006-2009, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <pthread.h>
 #include "config.h"
 
 #if defined(__sun)
 #define PREFIX_SIZE sizeof(size_t)
 #endif
 
+#define increment_used_memory(__n) do { \
+    size_t _n = (__n); \
+    if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
+    if (zmalloc_thread_safe) { \
+        pthread_mutex_lock(&used_memory_mutex);  \
+        used_memory += _n; \
+        pthread_mutex_unlock(&used_memory_mutex); \
+    } else { \
+        used_memory += _n; \
+    } \
+} while(0)
+
+#define decrement_used_memory(__n) do { \
+    size_t _n = (__n); \
+    if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
+    if (zmalloc_thread_safe) { \
+        pthread_mutex_lock(&used_memory_mutex);  \
+        used_memory -= _n; \
+        pthread_mutex_unlock(&used_memory_mutex); \
+    } else { \
+        used_memory -= _n; \
+    } \
+} while(0)
+
 static size_t used_memory = 0;
+static int zmalloc_thread_safe = 0;
+pthread_mutex_t used_memory_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static void zmalloc_oom(size_t size) {
-    fprintf(stderr, "zmalloc: Out of memory trying to allocate %lu bytes\n",
+    fprintf(stderr, "zmalloc: Out of memory trying to allocate %zu bytes\n",
         size);
     fflush(stderr);
     abort();
@@ -53,11 +80,11 @@ void *zmalloc(size_t size) {
 
     if (!ptr) zmalloc_oom(size);
 #ifdef HAVE_MALLOC_SIZE
-    used_memory += redis_malloc_size(ptr);
+    increment_used_memory(redis_malloc_size(ptr));
     return ptr;
 #else
     *((size_t*)ptr) = size;
-    used_memory += size+PREFIX_SIZE;
+    increment_used_memory(size+PREFIX_SIZE);
     return (char*)ptr+PREFIX_SIZE;
 #endif
 }
@@ -75,8 +102,8 @@ void *zrealloc(void *ptr, size_t size) {
     newptr = realloc(ptr,size);
     if (!newptr) zmalloc_oom(size);
 
-    used_memory -= oldsize;
-    used_memory += redis_malloc_size(newptr);
+    decrement_used_memory(oldsize);
+    increment_used_memory(redis_malloc_size(newptr));
     return newptr;
 #else
     realptr = (char*)ptr-PREFIX_SIZE;
@@ -85,8 +112,8 @@ void *zrealloc(void *ptr, size_t size) {
     if (!newptr) zmalloc_oom(size);
 
     *((size_t*)newptr) = size;
-    used_memory -= oldsize;
-    used_memory += size;
+    decrement_used_memory(oldsize);
+    increment_used_memory(size);
     return (char*)newptr+PREFIX_SIZE;
 #endif
 }
@@ -99,12 +126,12 @@ void zfree(void *ptr) {
 
     if (ptr == NULL) return;
 #ifdef HAVE_MALLOC_SIZE
-    used_memory -= redis_malloc_size(ptr);
+    decrement_used_memory(redis_malloc_size(ptr));
     free(ptr);
 #else
     realptr = (char*)ptr-PREFIX_SIZE;
     oldsize = *((size_t*)realptr);
-    used_memory -= oldsize+PREFIX_SIZE;
+    decrement_used_memory(oldsize+PREFIX_SIZE);
     free(realptr);
 #endif
 }
@@ -118,5 +145,14 @@ char *zstrdup(const char *s) {
 }
 
 size_t zmalloc_used_memory(void) {
-    return used_memory;
+    size_t um;
+
+    if (zmalloc_thread_safe) pthread_mutex_lock(&used_memory_mutex);
+    um = used_memory;
+    if (zmalloc_thread_safe) pthread_mutex_unlock(&used_memory_mutex);
+    return um;
+}
+
+void zmalloc_enable_thread_safeness(void) {
+    zmalloc_thread_safe = 1;
 }