[MEDIUM] add new memory management functions

Implement pool_destroy2, pool_flush2, pool_gc2. It is safe to call
pool_gc2 to free whatever memory possible.
This commit is contained in:
Willy Tarreau 2007-05-13 19:38:49 +02:00
parent 50e608d721
commit e6ce59deb7
2 changed files with 82 additions and 13 deletions

View 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--; \
})

View 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);
}