mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-05 11:39:33 +00:00
MEDIUM: memory: improve pool_refill_alloc() to pass a refill count
Till now this function would only allocate one entry at a time. But with dynamic buffers we'll like to allocate the number of missing entries to properly refill the pool. Let's modify it to take a minimum amount of available entries. This means that when we know we need at least a number of available entries, we can ask to allocate all of them at once. It also ensures that we don't move the pointers back and forth between the caller and the pool, and that we don't call pool_gc2() for each failed malloc. Instead, it's called only once and the malloc is only allowed to fail once.
This commit is contained in:
parent
0262241e26
commit
a885f6dc65
@ -61,10 +61,15 @@ static inline void pool_destroy(void **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.
|
||||
/* Allocates new entries for pool <pool> until there are at least <avail> + 1
|
||||
* available, then returns the last one for immediate use, so that at least
|
||||
* <avail> are left available in the pool upon return. NULL is returned if the
|
||||
* last entry could not be allocated. It's important to note that at least one
|
||||
* allocation is always performed even if there are enough entries in the pool.
|
||||
* A call to the garbage collector is performed at most once in case malloc()
|
||||
* returns an error, before returning NULL.
|
||||
*/
|
||||
void *pool_refill_alloc(struct pool_head *pool);
|
||||
void *pool_refill_alloc(struct pool_head *pool, unsigned int avail);
|
||||
|
||||
/* Try to find an existing shared pool with the same characteristics and
|
||||
* returns it, otherwise creates this one. NULL is returned if no memory
|
||||
@ -121,7 +126,7 @@ static inline void *pool_alloc_dirty(struct pool_head *pool)
|
||||
void *p;
|
||||
|
||||
if ((p = pool_get_first(pool)) == NULL)
|
||||
p = pool_refill_alloc(pool);
|
||||
p = pool_refill_alloc(pool, 0);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
44
src/memory.c
44
src/memory.c
@ -79,26 +79,42 @@ struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags)
|
||||
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. A call
|
||||
* to the garbage collector is performed before returning NULL.
|
||||
/* Allocates new entries for pool <pool> until there are at least <avail> + 1
|
||||
* available, then returns the last one for immediate use, so that at least
|
||||
* <avail> are left available in the pool upon return. NULL is returned if the
|
||||
* last entry could not be allocated. It's important to note that at least one
|
||||
* allocation is always performed even if there are enough entries in the pool.
|
||||
* A call to the garbage collector is performed at most once in case malloc()
|
||||
* returns an error, before returning NULL.
|
||||
*/
|
||||
void *pool_refill_alloc(struct pool_head *pool)
|
||||
void *pool_refill_alloc(struct pool_head *pool, unsigned int avail)
|
||||
{
|
||||
void *ret;
|
||||
void *ptr = NULL;
|
||||
int failed = 0;
|
||||
|
||||
if (pool->limit && (pool->allocated >= pool->limit))
|
||||
return NULL;
|
||||
ret = CALLOC(1, pool->size);
|
||||
if (!ret) {
|
||||
pool_gc2();
|
||||
ret = CALLOC(1, pool->size);
|
||||
if (!ret)
|
||||
/* stop point */
|
||||
avail += pool->used;
|
||||
|
||||
while (1) {
|
||||
if (pool->limit && pool->allocated >= pool->limit)
|
||||
return NULL;
|
||||
|
||||
ptr = MALLOC(pool->size);
|
||||
if (!ptr) {
|
||||
if (failed)
|
||||
return NULL;
|
||||
failed++;
|
||||
pool_gc2();
|
||||
continue;
|
||||
}
|
||||
if (++pool->allocated > avail)
|
||||
break;
|
||||
|
||||
*(void **)ptr = (void *)pool->free_list;
|
||||
pool->free_list = ptr;
|
||||
}
|
||||
pool->allocated++;
|
||||
pool->used++;
|
||||
return ret;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user