output_buffer: only realloc once, and memset just what we need
[fio.git] / smalloc.c
index 67cb7cc11d475b81aef3d53a7eb896eee31504bb..8412e7518464d6dbe3e7f218e33e47e855e8e26f 100644 (file)
--- a/smalloc.c
+++ b/smalloc.c
 #define SMALLOC_BPL    (SMALLOC_BPB * SMALLOC_BPI)
 
 #define INITIAL_SIZE   16*1024*1024    /* new pool size */
-#define MAX_POOLS      1               /* maximum number of pools to setup */
+#define MAX_POOLS      8               /* maximum number of pools to setup */
 
 #define SMALLOC_PRE_RED                0xdeadbeefU
 #define SMALLOC_POST_RED       0x5aa55aa5U
 
 unsigned int smalloc_pool_size = INITIAL_SIZE;
+#ifdef SMALLOC_REDZONE
 static const int int_mask = sizeof(int) - 1;
+#endif
 
 struct pool {
        struct fio_mutex *lock;                 /* protects this pool */
@@ -230,11 +232,21 @@ out_fail:
 
 void sinit(void)
 {
-       int ret;
+       int i, ret;
 
        lock = fio_rwlock_init();
-       ret = add_pool(&mp[0], INITIAL_SIZE);
-       assert(!ret);
+
+       for (i = 0; i < MAX_POOLS; i++) {
+               ret = add_pool(&mp[i], INITIAL_SIZE);
+               if (ret)
+                       break;
+       }
+
+       /*
+        * If we added at least one pool, we should be OK for most
+        * cases.
+        */
+       assert(i);
 }
 
 static void cleanup_pool(struct pool *pool)
@@ -353,8 +365,12 @@ void sfree(void *ptr)
 
        global_read_unlock();
 
-       assert(pool);
-       sfree_pool(pool, ptr);
+       if (pool) {
+               sfree_pool(pool, ptr);
+               return;
+       }
+
+       log_err("smalloc: ptr %p not from smalloc pool\n", ptr);
 }
 
 static void *__smalloc_pool(struct pool *pool, size_t size)
@@ -442,16 +458,17 @@ static void *smalloc_pool(struct pool *pool, size_t size)
 
 void *smalloc(size_t size)
 {
-       unsigned int i;
+       unsigned int i, end_pool;
 
        if (size != (unsigned int) size)
                return NULL;
 
        global_write_lock();
        i = last_pool;
+       end_pool = nr_pools;
 
        do {
-               for (; i < nr_pools; i++) {
+               for (; i < end_pool; i++) {
                        void *ptr = smalloc_pool(&mp[i], size);
 
                        if (ptr) {
@@ -461,40 +478,29 @@ void *smalloc(size_t size)
                        }
                }
                if (last_pool) {
-                       last_pool = 0;
+                       end_pool = last_pool;
+                       last_pool = i = 0;
                        continue;
                }
 
-               if (nr_pools + 1 > MAX_POOLS)
-                       break;
-               else {
-                       i = nr_pools;
-                       if (add_pool(&mp[nr_pools], size))
-                               goto out;
-               }
+               break;
        } while (1);
 
-out:
        global_write_unlock();
        return NULL;
 }
 
 void *scalloc(size_t nmemb, size_t size)
 {
-       void *ret;
-
-       ret = smalloc(nmemb * size);
-       if (ret)
-               memset(ret, 0, nmemb * size);
-
-       return ret;
+       return smalloc(nmemb * size);
 }
 
 char *smalloc_strdup(const char *str)
 {
-       char *ptr;
+       char *ptr = NULL;
 
        ptr = smalloc(strlen(str) + 1);
-       strcpy(ptr, str);
+       if (ptr)
+               strcpy(ptr, str);
        return ptr;
 }