mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-02 19:42:41 +00:00
[MEDIUM] enhance behaviour of mempools v2
- keep the number of users of each pool - call the garbage collector on out of memory conditions - sort the pools by size for faster creation - force the alignment size to 16 bytes instead of 4*sizeof(void *)
This commit is contained in:
parent
1d4154a7c0
commit
7dcd46d471
@ -125,7 +125,8 @@ struct pool_head {
|
||||
unsigned int minavail; /* how many chunks are expected to be used */
|
||||
unsigned int size; /* chunk size */
|
||||
unsigned int flags; /* MEM_F_* */
|
||||
char name[9]; /* name of the pool */
|
||||
unsigned int users; /* number of pools sharing this zone */
|
||||
char name[12]; /* name of the pool */
|
||||
};
|
||||
|
||||
|
||||
|
43
src/memory.c
43
src/memory.c
@ -26,6 +26,8 @@ static struct list pools = LIST_HEAD_INIT(pools);
|
||||
struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags)
|
||||
{
|
||||
struct pool_head *pool;
|
||||
struct pool_head *entry;
|
||||
struct list *start;
|
||||
unsigned int align;
|
||||
|
||||
/* We need to store at least a (void *) in the chunks. Since we know
|
||||
@ -34,20 +36,29 @@ struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags)
|
||||
* ease merging of entries. Note that the rounding is a power of two.
|
||||
*/
|
||||
|
||||
align = 4 * sizeof(void *);
|
||||
align = 16;
|
||||
size = (size + align - 1) & -align;
|
||||
|
||||
start = &pools;
|
||||
pool = NULL;
|
||||
if (flags & MEM_F_SHARED) {
|
||||
struct pool_head *entry;
|
||||
list_for_each_entry(entry, &pools, list) {
|
||||
if (!(entry->flags & MEM_F_SHARED))
|
||||
continue;
|
||||
if (entry->size == size) {
|
||||
|
||||
list_for_each_entry(entry, &pools, list) {
|
||||
if (entry->size == size) {
|
||||
/* either we can share this place and we take it, or
|
||||
* we look for a sharable one or for the next position
|
||||
* before which we will insert a new one.
|
||||
*/
|
||||
if (flags & entry->flags & MEM_F_SHARED) {
|
||||
/* we can share this one */
|
||||
pool = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (entry->size > size) {
|
||||
/* insert before this one */
|
||||
start = &entry->list;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pool) {
|
||||
@ -58,13 +69,15 @@ struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags)
|
||||
strlcpy2(pool->name, name, sizeof(pool->name));
|
||||
pool->size = size;
|
||||
pool->flags = flags;
|
||||
LIST_ADDQ(&pools, &pool->list);
|
||||
LIST_ADDQ(start, &pool->list);
|
||||
}
|
||||
pool->users++;
|
||||
return pool;
|
||||
}
|
||||
|
||||
/* 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. A call
|
||||
* to the garbage collector is performed before returning NULL.
|
||||
*/
|
||||
void *pool_refill_alloc(struct pool_head *pool)
|
||||
{
|
||||
@ -73,8 +86,12 @@ void *pool_refill_alloc(struct pool_head *pool)
|
||||
if (pool->limit && (pool->allocated >= pool->limit))
|
||||
return NULL;
|
||||
ret = MALLOC(pool->size);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
if (!ret) {
|
||||
pool_gc2();
|
||||
ret = MALLOC(pool->size);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
}
|
||||
pool->allocated++;
|
||||
pool->used++;
|
||||
return ret;
|
||||
@ -142,10 +159,10 @@ 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 (%lu bytes), %d used%s\n",
|
||||
qfprintf(stderr, " - Pool %s (%d bytes) : %d allocated (%lu bytes), %d used, %d users%s\n",
|
||||
entry->name, entry->size, entry->allocated,
|
||||
entry->size * entry->allocated, entry->used,
|
||||
(entry->flags & MEM_F_SHARED) ? " [SHARED]" : "");
|
||||
entry->users, (entry->flags & MEM_F_SHARED) ? " [SHARED]" : "");
|
||||
|
||||
allocated += entry->allocated * entry->size;
|
||||
used += entry->used * entry->size;
|
||||
|
Loading…
Reference in New Issue
Block a user