]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/mem_pool.c
const char * additions
[bacula/bacula] / bacula / src / lib / mem_pool.c
index 1762cea4bc9a6af885a0aac67f23fdee09a55502..55240b15127e31669874481a4cbf19c950e9e632 100644 (file)
  *  with the desired size and it will adjust only if necessary.
  *
  *          Kern E. Sibbald
+ *
+ *   Version $Id$
  */
 
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
 #include "bacula.h"
 
 struct s_pool_ctl {
-   size_t size;                      /* default size */
-   size_t max_size;                  /* max allocated */
-   size_t max_used;                  /* max buffers used */
-   size_t in_use;                    /* number in use */
+   int32_t size;                     /* default size */
+   int32_t max_size;                 /* max allocated */
+   int32_t max_used;                 /* max buffers used */
+   int32_t in_use;                   /* number in use */
    struct abufhead *free_buf;        /* pointer to free buffers */
 };
 
+/* Bacula Name length plus extra */
+#define NLEN (MAX_NAME_LENGTH+2)
+
+/* #define STRESS_TEST_POOL */
+#ifndef STRESS_TEST_POOL
+/*
+ * Define default Pool buffer sizes
+ */
 static struct s_pool_ctl pool_ctl[] = {
    {  256,  256, 0, 0, NULL },       /* PM_NOPOOL no pooling */
+   {  NLEN, NLEN,0, 0, NULL },       /* PM_NAME Bacula name */
    {  256,  256, 0, 0, NULL },       /* PM_FNAME filename buffers */
    {  512,  512, 0, 0, NULL },       /* PM_MESSAGE message buffer */
    { 1024, 1024, 0, 0, NULL }        /* PM_EMSG error message buffer */
 };
+#else
+
+/* This is used ONLY when stress testing the code */
+static struct s_pool_ctl pool_ctl[] = {
+   {   20,   20, 0, 0, NULL },       /* PM_NOPOOL no pooling */
+   {  NLEN, NLEN,0, 0, NULL },       /* PM_NAME Bacula name */
+   {   20,   20, 0, 0, NULL },       /* PM_FNAME filename buffers */
+   {   20,   20, 0, 0, NULL },       /* PM_MESSAGE message buffer */
+   {   20,   20, 0, 0, NULL }        /* PM_EMSG error message buffer */
+};
+#endif
+
 
 /*  Memory allocation control structures and storage.  */
 struct abufhead {
-   size_t ablen;                     /* Buffer length in bytes */
+   int32_t ablen;                    /* Buffer length in bytes */
    int32_t pool;                     /* pool */
    struct abufhead *next;            /* pointer to next free buffer */
 };
@@ -69,13 +92,10 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
 
-extern POOLMEM *sm_malloc(char *fname, int lineno, int nbytes);
-
-POOLMEM *sm_get_pool_memory(char *fname, int lineno, int pool)
+POOLMEM *sm_get_pool_memory(const char *fname, int lineno, int pool)
 {
    struct abufhead *buf;
 
-   sm_check(fname, lineno, True);
    if (pool > PM_MAX) {
       Emsg2(M_ABORT, 0, "MemPool index %d larger than max %d\n", pool, PM_MAX);
    }
@@ -88,12 +108,12 @@ POOLMEM *sm_get_pool_memory(char *fname, int lineno, int pool)
         pool_ctl[pool].max_used = pool_ctl[pool].in_use;
       }
       V(mutex);
-      Dmsg3(150, "sm_get_pool_memory reuse %x to %s:%d\n", buf, fname, lineno);
+      Dmsg3(300, "sm_get_pool_memory reuse %x to %s:%d\n", buf, fname, lineno);
       sm_new_owner(fname, lineno, (char *)buf);
       return (POOLMEM *)((char *)buf+HEAD_SIZE);
    }
       
-   if ((buf = (struct abufhead *) sm_malloc(fname, lineno, pool_ctl[pool].size+HEAD_SIZE)) == NULL) {
+   if ((buf = (struct abufhead *)sm_malloc(fname, lineno, pool_ctl[pool].size+HEAD_SIZE)) == NULL) {
       V(mutex);
       Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", pool_ctl[pool].size);
    }
@@ -104,18 +124,17 @@ POOLMEM *sm_get_pool_memory(char *fname, int lineno, int pool)
       pool_ctl[pool].max_used = pool_ctl[pool].in_use;
    }
    V(mutex);
-   Dmsg3(150, "sm_get_pool_memory give %x to %s:%d\n", buf, fname, lineno);
+   Dmsg3(300, "sm_get_pool_memory give %x to %s:%d\n", buf, fname, lineno);
    return (POOLMEM *)((char *)buf+HEAD_SIZE);
 }
 
 /* Get nonpool memory of size requested */
-POOLMEM *sm_get_memory(char *fname, int lineno, size_t size)
+POOLMEM *sm_get_memory(const char *fname, int lineno, int32_t size)
 {
    struct abufhead *buf;
    int pool = 0;
 
-   sm_check(fname, lineno, True);
-   if ((buf = (struct abufhead *) sm_malloc(fname, lineno, size+HEAD_SIZE)) == NULL) {
+   if ((buf = (struct abufhead *)sm_malloc(fname, lineno, size+HEAD_SIZE)) == NULL) {
       Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", size);
    }
    buf->ablen = size;
@@ -127,8 +146,87 @@ POOLMEM *sm_get_memory(char *fname, int lineno, size_t size)
    return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
 }
 
+
+/* Return the size of a memory buffer */
+int32_t sm_sizeof_pool_memory(const char *fname, int lineno, POOLMEM *obuf)
+{
+   char *cp = (char *)obuf;
+
+   ASSERT(obuf);
+   cp -= HEAD_SIZE;
+   return ((struct abufhead *)cp)->ablen;
+}
+
+/* Realloc pool memory buffer */
+POOLMEM *sm_realloc_pool_memory(const char *fname, int lineno, POOLMEM *obuf, int32_t size)
+{
+   char *cp = (char *)obuf;
+   void *buf;
+   int pool;
+
+   ASSERT(obuf);
+   P(mutex);
+   cp -= HEAD_SIZE;
+   buf = sm_realloc(fname, lineno, cp, size+HEAD_SIZE);
+   if (buf == NULL) {
+      V(mutex);
+      Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", size);
+   }
+   ((struct abufhead *)buf)->ablen = size;
+   pool = ((struct abufhead *)buf)->pool;
+   if (size > pool_ctl[pool].max_size) {
+      pool_ctl[pool].max_size = size;
+   }
+   V(mutex);
+   return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
+}
+
+POOLMEM *sm_check_pool_memory_size(const char *fname, int lineno, POOLMEM *obuf, int32_t size)
+{
+   ASSERT(obuf);
+   if (size <= sizeof_pool_memory(obuf)) {
+      return obuf;
+   }
+   return realloc_pool_memory(obuf, size);
+}
+
+/* Free a memory buffer */
+void sm_free_pool_memory(const char *fname, int lineno, POOLMEM *obuf)
+{
+   struct abufhead *buf;
+   int pool;
+
+   ASSERT(obuf);
+   P(mutex);
+   buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
+   pool = buf->pool;
+   pool_ctl[pool].in_use--;
+   if (pool == 0) {
+      free((char *)buf);             /* free nonpooled memory */
+   } else {                          /* otherwise link it to the free pool chain */
+#ifdef DEBUG
+      struct abufhead *next;
+      /* Don't let him free the same buffer twice */
+      for (next=pool_ctl[pool].free_buf; next; next=next->next) {
+        if (next == buf) {
+            Dmsg4(300, "bad free_pool_memory %x pool=%d from %s:%d\n", buf, pool, fname, lineno);
+           V(mutex);                 /* unblock the pool */
+           ASSERT(next != buf);      /* attempt to free twice */
+        }
+      }
+#endif
+      buf->next = pool_ctl[pool].free_buf;
+      pool_ctl[pool].free_buf = buf;
+   }
+   Dmsg4(300, "free_pool_memory %x pool=%d from %s:%d\n", buf, pool, fname, lineno);
+   V(mutex);
+}
+
+
 #else
 
+/* =================================================================== */
+
 POOLMEM *get_pool_memory(int pool)
 {
    struct abufhead *buf;
@@ -157,7 +255,7 @@ POOLMEM *get_pool_memory(int pool)
 }
 
 /* Get nonpool memory of size requested */
-POOLMEM *get_memory(size_t size)
+POOLMEM *get_memory(int32_t size)
 {
    struct abufhead *buf;
    int pool = 0;
@@ -174,52 +272,25 @@ POOLMEM *get_memory(size_t size)
    }
    return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
 }
-#endif /* SMARTALLOC */
-
-
-
-/* Free a memory buffer */
-void free_pool_memory(POOLMEM *obuf)
-{
-   struct abufhead *buf;
-   int pool;
-
-   sm_check(__FILE__, __LINE__, False);
-   ASSERT(obuf);
-   P(mutex);
-   buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
-   pool = buf->pool;
-   pool_ctl[pool].in_use--;
-   if (pool == 0) {
-      free((char *)buf);             /* free nonpooled memory */
-   } else {                          /* otherwise link it to the free pool chain */
-      buf->next = pool_ctl[pool].free_buf;
-      pool_ctl[pool].free_buf = buf;
-   }
-   Dmsg2(150, "free_pool_memory %x pool=%d\n", buf, pool);
-   V(mutex);
-}
 
 
 /* Return the size of a memory buffer */
-size_t sizeof_pool_memory(POOLMEM *obuf)
+int32_t sizeof_pool_memory(POOLMEM *obuf)
 {
    char *cp = (char *)obuf;
 
-   sm_check(__FILE__, __LINE__, False);
    ASSERT(obuf);
    cp -= HEAD_SIZE;
    return ((struct abufhead *)cp)->ablen;
 }
 
 /* Realloc pool memory buffer */
-POOLMEM *realloc_pool_memory(POOLMEM *obuf, size_t size)
+POOLMEM *realloc_pool_memory(POOLMEM *obuf, int32_t size)
 {
    char *cp = (char *)obuf;
    void *buf;
    int pool;
 
-   sm_check(__FILE__, __LINE__, False);
    ASSERT(obuf);
    P(mutex);
    cp -= HEAD_SIZE;
@@ -234,13 +305,11 @@ POOLMEM *realloc_pool_memory(POOLMEM *obuf, size_t size)
       pool_ctl[pool].max_size = size;
    }
    V(mutex);
-   sm_check(__FILE__, __LINE__, False);
    return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
 }
 
-POOLMEM *check_pool_memory_size(POOLMEM *obuf, size_t size)
+POOLMEM *check_pool_memory_size(POOLMEM *obuf, int32_t size)
 {
-   sm_check(__FILE__, __LINE__, False);
    ASSERT(obuf);
    if (size <= sizeof_pool_memory(obuf)) {
       return obuf;
@@ -248,15 +317,52 @@ POOLMEM *check_pool_memory_size(POOLMEM *obuf, size_t size)
    return realloc_pool_memory(obuf, size);
 }
 
+/* Free a memory buffer */
+void free_pool_memory(POOLMEM *obuf)
+{
+   struct abufhead *buf;
+   int pool;
+
+   ASSERT(obuf);
+   P(mutex);
+   buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
+   pool = buf->pool;
+   pool_ctl[pool].in_use--;
+   if (pool == 0) {
+      free((char *)buf);             /* free nonpooled memory */
+   } else {                          /* otherwise link it to the free pool chain */
+#ifdef DEBUG
+      struct abufhead *next;
+      /* Don't let him free the same buffer twice */
+      for (next=pool_ctl[pool].free_buf; next; next=next->next) {
+        if (next == buf) {
+           V(mutex);
+           ASSERT(next != buf);  /* attempt to free twice */
+        }
+      }
+#endif
+      buf->next = pool_ctl[pool].free_buf;
+      pool_ctl[pool].free_buf = buf;
+   }
+   Dmsg2(300, "free_pool_memory %x pool=%d\n", buf, pool);
+   V(mutex);
+}
+
+#endif /* SMARTALLOC */
+
+
+
+
+
+
 /* Release all pooled memory */
 void close_memory_pool()
 {
    struct abufhead *buf, *next;
-   int i;
 
    sm_check(__FILE__, __LINE__, False);
    P(mutex);
-   for (i=1; i<=PM_MAX; i++) {
+   for (int i=1; i<=PM_MAX; i++) {
       buf = pool_ctl[i].free_buf;
       while (buf) {
         next = buf->next;
@@ -272,7 +378,7 @@ void close_memory_pool()
 
 static char *pool_name(int pool)
 {
-   static char *name[] = {"NoPool", "FNAME ", "MSG   ", "EMSG  "};
+   static char *name[] = {"NoPool", "NAME  ", "FNAME ", "MSG   ", "EMSG  "};
    static char buf[30];
 
    if (pool >= 0 && pool <= PM_MAX) {
@@ -286,10 +392,8 @@ static char *pool_name(int pool)
  */ 
 void print_memory_pool_stats()
 {
-   int i;
-
    Dmsg0(-1, "Pool   Maxsize  Maxused  Inuse\n");
-   for (i=0; i<=PM_MAX; i++)
+   for (int i=0; i<=PM_MAX; i++)
       Dmsg4(-1, "%5s  %7d  %7d  %5d\n", pool_name(i), pool_ctl[i].max_size,
         pool_ctl[i].max_used, pool_ctl[i].in_use);