mm/mempool: optimize alloc/free performance

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
dongjiuzhu1 2022-09-09 16:01:49 +08:00 committed by Xiang Xiao
parent 8994c8efa2
commit 4e179e8a85
2 changed files with 54 additions and 80 deletions

View File

@ -88,12 +88,10 @@ static inline void mempool_mfree(FAR struct mempool_s *pool, FAR void *addr)
int mempool_init(FAR struct mempool_s *pool, FAR const char *name) int mempool_init(FAR struct mempool_s *pool, FAR const char *name)
{ {
FAR sq_entry_t *base;
size_t count; size_t count;
if (pool == NULL || pool->bsize == 0) DEBUGASSERT(pool != NULL && pool->bsize != 0);
{
return -EINVAL;
}
pool->nused = 0; pool->nused = 0;
sq_init(&pool->list); sq_init(&pool->list);
@ -101,25 +99,20 @@ int mempool_init(FAR struct mempool_s *pool, FAR const char *name)
sq_init(&pool->elist); sq_init(&pool->elist);
count = pool->ninitial + pool->ninterrupt; count = pool->ninitial + pool->ninterrupt;
if (count != 0) base = mempool_malloc(pool, sizeof(*base) +
pool->bsize * count);
if (base == NULL)
{ {
FAR sq_entry_t *base; return -ENOMEM;
base = mempool_malloc(pool, sizeof(*base) +
pool->bsize * count);
if (base == NULL)
{
return -ENOMEM;
}
sq_addfirst(base, &pool->elist);
mempool_add_list(&pool->ilist, base + 1,
pool->ninterrupt, pool->bsize);
mempool_add_list(&pool->list, (FAR char *)(base + 1) +
pool->ninterrupt * pool->bsize,
pool->ninitial, pool->bsize);
} }
sq_addfirst(base, &pool->elist);
mempool_add_list(&pool->ilist, base + 1,
pool->ninterrupt, pool->bsize);
mempool_add_list(&pool->list, (FAR char *)(base + 1) +
pool->ninterrupt * pool->bsize,
pool->ninitial, pool->bsize);
if (pool->wait && pool->nexpand == 0) if (pool->wait && pool->nexpand == 0)
{ {
nxsem_init(&pool->waitsem, 0, 0); nxsem_init(&pool->waitsem, 0, 0);
@ -154,10 +147,7 @@ FAR void *mempool_alloc(FAR struct mempool_s *pool)
FAR sq_entry_t *blk; FAR sq_entry_t *blk;
irqstate_t flags; irqstate_t flags;
if (pool == NULL) DEBUGASSERT(pool != NULL);
{
return NULL;
}
retry: retry:
flags = spin_lock_irqsave(&pool->lock); flags = spin_lock_irqsave(&pool->lock);
@ -223,19 +213,24 @@ out_with_lock:
void mempool_free(FAR struct mempool_s *pool, FAR void *blk) void mempool_free(FAR struct mempool_s *pool, FAR void *blk)
{ {
irqstate_t flags; irqstate_t flags;
FAR char *base;
if (blk == NULL || pool == NULL) DEBUGASSERT(pool != NULL && blk != NULL);
{
return;
}
flags = spin_lock_irqsave(&pool->lock); flags = spin_lock_irqsave(&pool->lock);
base = (FAR char *)(sq_peek(&pool->elist) + 1); if (pool->ninterrupt)
if (pool->ninterrupt && (FAR char *)blk >= base &&
(FAR char *)blk < base + pool->ninterrupt * pool->bsize)
{ {
sq_addfirst(blk, &pool->ilist); FAR char *base;
base = (FAR char *)(sq_peek(&pool->elist) + 1);
if ((FAR char *)blk >= base &&
(FAR char *)blk < base + pool->ninterrupt * pool->bsize)
{
sq_addfirst(blk, &pool->ilist);
}
else
{
sq_addfirst(blk, &pool->list);
}
} }
else else
{ {
@ -274,10 +269,7 @@ int mempool_info(FAR struct mempool_s *pool, FAR struct mempoolinfo_s *info)
{ {
irqstate_t flags; irqstate_t flags;
if (pool == NULL || info == NULL) DEBUGASSERT(pool != NULL && info != NULL);
{
return -EINVAL;
}
flags = spin_lock_irqsave(&pool->lock); flags = spin_lock_irqsave(&pool->lock);
info->ordblks = sq_count(&pool->list); info->ordblks = sq_count(&pool->list);
@ -315,10 +307,7 @@ int mempool_deinit(FAR struct mempool_s *pool)
{ {
FAR sq_entry_t *blk; FAR sq_entry_t *blk;
if (pool == NULL) DEBUGASSERT(pool != NULL);
{
return -EINVAL;
}
if (pool->nused != 0) if (pool->nused != 0)
{ {

View File

@ -32,7 +32,6 @@
#define SIZEOF_HEAD sizeof(FAR struct mempool_s *) #define SIZEOF_HEAD sizeof(FAR struct mempool_s *)
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -57,7 +56,7 @@ mempool_multiple_find(FAR struct mempool_multiple_s *mpool, size_t size)
low = ++mid; low = ++mid;
} }
else if (n == 0 || size == mid->bsize) else if (size == mid->bsize || n == 0)
{ {
return mid; return mid;
} }
@ -92,10 +91,7 @@ int mempool_multiple_init(FAR struct mempool_multiple_s *mpool,
{ {
int i; int i;
if (mpool == NULL || mpool->pools == NULL) DEBUGASSERT(mpool != NULL && mpool->pools != NULL);
{
return -EINVAL;
}
for (i = 0; i < mpool->npools; i++) for (i = 0; i < mpool->npools; i++)
{ {
@ -135,22 +131,21 @@ int mempool_multiple_init(FAR struct mempool_multiple_s *mpool,
FAR void *mempool_multiple_alloc(FAR struct mempool_multiple_s *mpool, FAR void *mempool_multiple_alloc(FAR struct mempool_multiple_s *mpool,
size_t size) size_t size)
{ {
FAR struct mempool_s *end = mpool->pools + mpool->npools;
FAR struct mempool_s *pool; FAR struct mempool_s *pool;
pool = mempool_multiple_find(mpool, size + SIZEOF_HEAD); pool = mempool_multiple_find(mpool, size + SIZEOF_HEAD);
if (pool != NULL) DEBUGASSERT(pool != NULL);
do
{ {
do FAR void *blk = mempool_alloc(pool);
if (blk != NULL)
{ {
FAR void *blk = mempool_alloc(pool); *(FAR struct mempool_s **)blk = pool;
if (blk != NULL) return (FAR char *)blk + SIZEOF_HEAD;
{
*(FAR struct mempool_s **)blk = pool;
return (FAR char *)blk + SIZEOF_HEAD;
}
} }
while (++pool< mpool->pools + mpool->npools);
} }
while (++pool< end);
return NULL; return NULL;
} }
@ -173,13 +168,11 @@ void mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
FAR struct mempool_s *pool; FAR struct mempool_s *pool;
FAR void *mem; FAR void *mem;
if (blk != NULL) DEBUGASSERT(mpool != NULL && blk != NULL);
{
mem = (FAR char *)blk - SIZEOF_HEAD;
pool = *(FAR struct mempool_s **)mem;
mempool_free(pool, mem); mem = (FAR char *)blk - SIZEOF_HEAD;
} pool = *(FAR struct mempool_s **)mem;
mempool_free(pool, mem);
} }
/**************************************************************************** /****************************************************************************
@ -205,12 +198,8 @@ FAR void *mempool_multiple_fixed_alloc(FAR struct mempool_multiple_s *mpool,
FAR struct mempool_s *pool; FAR struct mempool_s *pool;
pool = mempool_multiple_find(mpool, size); pool = mempool_multiple_find(mpool, size);
if (pool != NULL) DEBUGASSERT(pool != NULL);
{ return mempool_alloc(pool);
return mempool_alloc(pool);
}
return NULL;
} }
/**************************************************************************** /****************************************************************************
@ -229,14 +218,13 @@ FAR void *mempool_multiple_fixed_alloc(FAR struct mempool_multiple_s *mpool,
void mempool_multiple_fixed_free(FAR struct mempool_multiple_s *mpool, void mempool_multiple_fixed_free(FAR struct mempool_multiple_s *mpool,
FAR void *blk, size_t size) FAR void *blk, size_t size)
{ {
if (blk != NULL) FAR struct mempool_s *pool;
{
FAR struct mempool_s *pool = mempool_multiple_find(mpool, size); DEBUGASSERT(mpool != NULL && blk != NULL);
if (pool != NULL)
{ pool = mempool_multiple_find(mpool, size);
mempool_free(pool, blk); DEBUGASSERT(pool != NULL);
} mempool_free(pool, blk);
}
} }
/**************************************************************************** /****************************************************************************
@ -257,10 +245,7 @@ int mempool_multiple_deinit(FAR struct mempool_multiple_s *mpool)
{ {
int i; int i;
if (mpool == NULL) DEBUGASSERT(mpool != NULL);
{
return -EINVAL;
}
for (i = 0; i < mpool->npools; i++) for (i = 0; i < mpool->npools; i++)
{ {