diff --git a/redis.c b/redis.c index 7c87178d69a0d466727cd95f0bddcf713ac1bd79..47c93f732474fdb74bbdae6461dc0b5a7f59a141 100644 --- a/redis.c +++ b/redis.c @@ -6999,6 +6999,9 @@ static void vmInit(void) { int pipefds[2]; size_t stacksize; + if (server.vm_max_threads != 0) + zmalloc_enable_thread_safeness(); /* we need thread safe zmalloc() */ + server.vm_fp = fopen("/tmp/redisvm","w+b"); if (server.vm_fp == NULL) { redisLog(REDIS_WARNING,"Impossible to open the swap file. Exiting."); diff --git a/zmalloc.c b/zmalloc.c index 64263756ea2ccb2a5391e028a449fffae4e66773..8bf73b262ccfad2cfc1089fc47267309b7baafce 100644 --- a/zmalloc.c +++ b/zmalloc.c @@ -40,7 +40,28 @@ #define PREFIX_SIZE sizeof(size_t) #endif +#define increment_used_memory(_n) do { \ + 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 { \ + 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) { @@ -55,11 +76,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 } @@ -77,8 +98,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; @@ -87,8 +108,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 } @@ -101,12 +122,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 } @@ -120,5 +141,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; } diff --git a/zmalloc.h b/zmalloc.h index 9e70e8778c5a46c3821a42ce51ec2d78ab4cb758..fbe790302a301fee07daf0bd0c3b5e6920ab0399 100644 --- a/zmalloc.h +++ b/zmalloc.h @@ -36,5 +36,6 @@ void *zrealloc(void *ptr, size_t size); void zfree(void *ptr); char *zstrdup(const char *s); size_t zmalloc_used_memory(void); +void zmalloc_enable_thread_safeness(void); #endif /* _ZMALLOC_H */