mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-18 13:05:38 +00:00
[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:
parent
50e608d721
commit
e6ce59deb7
@ -134,7 +134,7 @@ struct pool_head {
|
|||||||
/* Allocate a new entry for pool <pool>, and return it for immediate use.
|
/* 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.
|
* 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
|
/* Try to find an existing shared pool with the same characteristics and
|
||||||
* returns it, otherwise creates this one. NULL is returned if no memory
|
* 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);
|
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
|
* Returns a pointer to type <type> taken from the
|
||||||
* pool <pool_type> or dynamically allocated. In the
|
* pool <pool_type> or dynamically allocated. In the
|
||||||
@ -155,11 +172,11 @@ void dump_pools(void);
|
|||||||
#define pool_alloc2(pool) \
|
#define pool_alloc2(pool) \
|
||||||
({ \
|
({ \
|
||||||
void *__p; \
|
void *__p; \
|
||||||
if ((__p = pool.free_list) == NULL) \
|
if ((__p = pool->free_list) == NULL) \
|
||||||
__p = pool_refill_alloc(&pool); \
|
__p = pool_refill_alloc(pool); \
|
||||||
else { \
|
else { \
|
||||||
pool.free_list = *(void **)pool.free_list; \
|
pool->free_list = *(void **)pool->free_list; \
|
||||||
pool.used++; \
|
pool->used++; \
|
||||||
} \
|
} \
|
||||||
__p; \
|
__p; \
|
||||||
})
|
})
|
||||||
@ -174,9 +191,9 @@ void dump_pools(void);
|
|||||||
*/
|
*/
|
||||||
#define pool_free2(pool, ptr) \
|
#define pool_free2(pool, ptr) \
|
||||||
({ \
|
({ \
|
||||||
*(void **)ptr = (void *)pool.free_list; \
|
*(void **)ptr = (void *)pool->free_list; \
|
||||||
pool.free_list = (void *)ptr; \
|
pool->free_list = (void *)ptr; \
|
||||||
pool.used--; \
|
pool->used--; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
62
src/memory.c
62
src/memory.c
@ -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.
|
/* 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.
|
* 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;
|
void *ret;
|
||||||
|
|
||||||
@ -80,6 +80,57 @@ void *refill_pool_alloc(struct pool_head *pool)
|
|||||||
return ret;
|
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.
|
/* Dump statistics on pools usage.
|
||||||
*/
|
*/
|
||||||
void dump_pools(void)
|
void dump_pools(void)
|
||||||
@ -91,15 +142,16 @@ void dump_pools(void)
|
|||||||
allocated = used = nbpools = 0;
|
allocated = used = nbpools = 0;
|
||||||
qfprintf(stderr, "Dumping pools usage.\n");
|
qfprintf(stderr, "Dumping pools usage.\n");
|
||||||
list_for_each_entry(entry, &pools, list) {
|
list_for_each_entry(entry, &pools, list) {
|
||||||
qfprintf(stderr, " - Pool %s (%d bytes) : %d allocated, %d used%s\n",
|
qfprintf(stderr, " - Pool %s (%d bytes) : %d allocated (%lu bytes), %d used%s\n",
|
||||||
entry->name, entry->size, entry->allocated, entry->used,
|
entry->name, entry->size, entry->allocated,
|
||||||
(entry->flags & MEM_F_SHARED) ? " (SHARED)" : "");
|
entry->size * entry->allocated, entry->used,
|
||||||
|
(entry->flags & MEM_F_SHARED) ? " [SHARED]" : "");
|
||||||
|
|
||||||
allocated += entry->allocated * entry->size;
|
allocated += entry->allocated * entry->size;
|
||||||
used += entry->used * entry->size;
|
used += entry->used * entry->size;
|
||||||
nbpools++;
|
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);
|
nbpools, allocated, used);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user