]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] add new memory management functions
authorWilly Tarreau <w@1wt.eu>
Sun, 13 May 2007 17:38:49 +0000 (19:38 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 13 May 2007 17:38:49 +0000 (19:38 +0200)
Implement pool_destroy2, pool_flush2, pool_gc2. It is safe to call
pool_gc2 to free whatever memory possible.

include/common/memory.h
src/memory.c

index 77346b706ef9d5f05774cf6f6ef6e2d6de325053..0f142f028445e39a792e24b08b903b4cf0ba3cc1 100644 (file)
@@ -134,7 +134,7 @@ struct pool_head {
 /* Allocate a new entry for pool <pool>, and return it for immediate use.
  * NULL is returned if no memory is available for a new creation.
  */
-void *refill_pool_alloc(struct pool_head *pool);
+void *pool_refill_alloc(struct pool_head *pool);
 
 /* Try to find an existing shared pool with the same characteristics and
  * returns it, otherwise creates this one. NULL is returned if no memory
@@ -146,6 +146,23 @@ struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags)
  */
 void dump_pools(void);
 
+/*
+ * This function frees whatever can be freed in pool <pool>.
+ */
+void pool_flush2(struct pool_head *pool);
+
+/*
+ * This function frees whatever can be freed in all pools, but respecting
+ * the minimum thresholds imposed by owners.
+ */
+void pool_gc2();
+
+/*
+ * This function destroys a pull by freeing it completely.
+ * This should be called only under extreme circumstances.
+ */
+void pool_destroy2(struct pool_head *pool);
+
 /*
  * Returns a pointer to type <type> taken from the
  * pool <pool_type> or dynamically allocated. In the
@@ -155,11 +172,11 @@ void dump_pools(void);
 #define pool_alloc2(pool)                                       \
 ({                                                              \
         void *__p;                                              \
-        if ((__p = pool.free_list) == NULL)                     \
-                __p = pool_refill_alloc(&pool);                 \
+        if ((__p = pool->free_list) == NULL)                    \
+                __p = pool_refill_alloc(pool);                  \
         else {                                                  \
-                pool.free_list = *(void **)pool.free_list;      \
-                pool.used++;                                    \
+                pool->free_list = *(void **)pool->free_list;    \
+                pool->used++;                                   \
         }                                                       \
         __p;                                                    \
 })
@@ -174,9 +191,9 @@ void dump_pools(void);
  */
 #define pool_free2(pool, ptr)                           \
 ({                                                      \
-        *(void **)ptr = (void *)pool.free_list;         \
-        pool.free_list = (void *)ptr;                   \
-        pool.used--;                                    \
+        *(void **)ptr = (void *)pool->free_list;        \
+        pool->free_list = (void *)ptr;                  \
+        pool->used--;                                   \
 })
 
 
index 5dbbdd91f7cd4684d12665ec43f0dd846c64c645..dd542252bbbae3a25f62a9665e0b944b3e783c93 100644 (file)
@@ -66,7 +66,7 @@ struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags)
 /* Allocate a new entry for pool <pool>, and return it for immediate use.
  * NULL is returned if no memory is available for a new creation.
  */
-void *refill_pool_alloc(struct pool_head *pool)
+void *pool_refill_alloc(struct pool_head *pool)
 {
        void *ret;
 
@@ -80,6 +80,57 @@ void *refill_pool_alloc(struct pool_head *pool)
        return ret;
 }
 
+/*
+ * This function frees whatever can be freed in pool <pool>.
+ */
+void pool_flush2(struct pool_head *pool)
+{
+       void *temp, *next;
+       next = pool->free_list;
+       while (next) {
+               temp = next;
+               next = *(void **)temp;
+               pool->allocated--;
+               FREE(temp);
+       }
+       pool->free_list = next;
+
+       /* here, we should have pool->allocate == pool->used */
+}
+
+/*
+ * This function frees whatever can be freed in all pools, but respecting
+ * the minimum thresholds imposed by owners.
+ */
+void pool_gc2()
+{
+       struct pool_head *entry;
+       list_for_each_entry(entry, &pools, list) {
+               void *temp, *next;
+               //qfprintf(stderr, "Flushing pool %s\n", entry->name);
+               next = entry->free_list;
+               while (next &&
+                      entry->allocated > entry->minavail &&
+                      entry->allocated > entry->used) {
+                       temp = next;
+                       next = *(void **)temp;
+                       entry->allocated--;
+                       FREE(temp);
+               }
+               entry->free_list = next;
+       }
+}
+
+/*
+ * This function destroys a pull by freeing it completely.
+ * This should be called only under extreme circumstances.
+ */
+void pool_destroy2(struct pool_head *pool)
+{
+       pool_flush2(pool);
+       FREE(pool);
+}
+
 /* Dump statistics on pools usage.
  */
 void dump_pools(void)
@@ -91,15 +142,16 @@ void dump_pools(void)
        allocated = used = nbpools = 0;
        qfprintf(stderr, "Dumping pools usage.\n");
        list_for_each_entry(entry, &pools, list) {
-               qfprintf(stderr, "  - Pool %s (%d bytes) : %d allocated, %d used%s\n",
-                        entry->name, entry->size, entry->allocated, entry->used,
-                        (entry->flags & MEM_F_SHARED) ? " (SHARED)" : "");
+               qfprintf(stderr, "  - Pool %s (%d bytes) : %d allocated (%lu bytes), %d used%s\n",
+                        entry->name, entry->size, entry->allocated,
+                        entry->size * entry->allocated, entry->used,
+                        (entry->flags & MEM_F_SHARED) ? " [SHARED]" : "");
 
                allocated += entry->allocated * entry->size;
                used += entry->used * entry->size;
                nbpools++;
        }
-       qfprintf(stderr, "Total: %d pools, %lu allocated, %lu used.\n",
+       qfprintf(stderr, "Total: %d pools, %lu bytes allocated, %lu used.\n",
                 nbpools, allocated, used);
 }