]> git.saurik.com Git - redis.git/blobdiff - zmalloc.c
Enabled object encoding for multiple keys in MSET. Added a test for memory leaks...
[redis.git] / zmalloc.c
index 922856590e38e306a618d4b54cf7e5a22324251f..eb06da3b8925ab52e1c1d981c8ab2106e695433c 100644 (file)
--- a/zmalloc.c
+++ b/zmalloc.c
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include "config.h"
+
+#if defined(__sun)
+#define PREFIX_SIZE sizeof(long long)
+#else
+#define PREFIX_SIZE sizeof(size_t)
+#endif
 
 static size_t used_memory = 0;
 
+static void zmalloc_oom(size_t size) {
+    fprintf(stderr, "zmalloc: Out of memory trying to allocate %zu bytes\n",
+        size);
+    fflush(stderr);
+    abort();
+}
+
 void *zmalloc(size_t size) {
-    void *ptr = malloc(size+sizeof(size_t));
+    void *ptr = malloc(size+PREFIX_SIZE);
 
+    if (!ptr) zmalloc_oom(size);
+#ifdef HAVE_MALLOC_SIZE
+    used_memory += redis_malloc_size(ptr);
+    return ptr;
+#else
     *((size_t*)ptr) = size;
-    used_memory += size+sizeof(size_t);
-    return (char*)ptr+sizeof(size_t);
+    used_memory += size+PREFIX_SIZE;
+    return (char*)ptr+PREFIX_SIZE;
+#endif
 }
 
 void *zrealloc(void *ptr, size_t size) {
+#ifndef HAVE_MALLOC_SIZE
     void *realptr;
+#endif
     size_t oldsize;
     void *newptr;
 
     if (ptr == NULL) return zmalloc(size);
-    realptr = (char*)ptr-sizeof(size_t);
+#ifdef HAVE_MALLOC_SIZE
+    oldsize = redis_malloc_size(ptr);
+    newptr = realloc(ptr,size);
+    if (!newptr) zmalloc_oom(size);
+
+    used_memory -= oldsize;
+    used_memory += redis_malloc_size(newptr);
+    return newptr;
+#else
+    realptr = (char*)ptr-PREFIX_SIZE;
     oldsize = *((size_t*)realptr);
-    newptr = realloc(realptr,size+sizeof(size_t));
-    if (!newptr) return NULL;
+    newptr = realloc(realptr,size+PREFIX_SIZE);
+    if (!newptr) zmalloc_oom(size);
 
     *((size_t*)newptr) = size;
     used_memory -= oldsize;
     used_memory += size;
-    return (char*)newptr+sizeof(size_t);
+    return (char*)newptr+PREFIX_SIZE;
+#endif
 }
 
 void zfree(void *ptr) {
+#ifndef HAVE_MALLOC_SIZE
     void *realptr;
     size_t oldsize;
+#endif
 
     if (ptr == NULL) return;
-    realptr = (char*)ptr-sizeof(size_t);
+#ifdef HAVE_MALLOC_SIZE
+    used_memory -= redis_malloc_size(ptr);
+    free(ptr);
+#else
+    realptr = (char*)ptr-PREFIX_SIZE;
     oldsize = *((size_t*)realptr);
-    used_memory -= oldsize+sizeof(size_t);
+    used_memory -= oldsize+PREFIX_SIZE;
     free(realptr);
+#endif
 }
 
 char *zstrdup(const char *s) {