mm/mempool: support multiple memory pool

Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
Jiuzhu Dong
2022-08-14 10:28:05 +08:00
committed by Xiang Xiao
parent 868de3ca4b
commit a01f3beefd
5 changed files with 446 additions and 49 deletions
+30 -28
View File
@@ -50,58 +50,55 @@ static inline void mempool_add_list(FAR sq_queue_t *list, FAR void *base,
*
* Description:
* Initialize a memory pool.
* The user needs to specify the initialization information of mempool
* including bsize, ninitial, nexpand, ninterrupt.
*
* Input Parameters:
* pool - Address of the memory pool to be used.
* name - The name of memory pool.
* bsize - The block size of memory blocks in pool.
* ninitial - The initial count of memory blocks in pool.
* nexpand - The increment count of memory blocks in pool.
* If there is not enough memory blocks and it isn't zero,
* mempool_alloc will alloc nexpand memory blocks.
* ninterrupt - The block count of memory blocks in pool for interrupt
* context. These blocks only can use in interrupt context.
* pool - Address of the memory pool to be used.
* name - The name of memory pool.
*
* Returned Value:
* Zero on success; A negated errno value is returned on any failure.
*
****************************************************************************/
int mempool_init(FAR struct mempool_s *pool, FAR const char *name,
size_t bsize, size_t ninitial, size_t nexpand,
size_t ninterrupt)
int mempool_init(FAR struct mempool_s *pool, FAR const char *name)
{
size_t count = ninitial + ninterrupt;
size_t count;
if (pool == NULL || bsize == 0)
if (pool == NULL || pool->bsize == 0)
{
return -EINVAL;
}
pool->nused = 0;
pool->bsize = bsize;
pool->nexpand = nexpand;
pool->ninterrupt = ninterrupt;
sq_init(&pool->list);
sq_init(&pool->ilist);
sq_init(&pool->elist);
count = pool->ninitial + pool->ninterrupt;
if (count != 0)
{
FAR sq_entry_t *base;
base = kmm_malloc(sizeof(*base) + bsize * count);
base = kmm_malloc(sizeof(*base) + pool->bsize * count);
if (base == NULL)
{
return -ENOMEM;
}
sq_addfirst(base, &pool->elist);
mempool_add_list(&pool->ilist, base + 1, ninterrupt, bsize);
mempool_add_list(&pool->ilist, base + 1,
pool->ninterrupt, pool->bsize);
mempool_add_list(&pool->list, (FAR char *)(base + 1) +
ninterrupt * bsize, ninitial, bsize);
pool->ninterrupt * pool->bsize,
pool->ninitial, pool->bsize);
}
nxsem_init(&pool->wait, 0, 0);
if (pool->wait && pool->nexpand == 0)
{
nxsem_init(&pool->waitsem, 0, 0);
}
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL
mempool_procfs_register(&pool->procfs, name);
@@ -167,7 +164,8 @@ retry:
pool->bsize);
blk = sq_remfirst(&pool->list);
}
else if (nxsem_wait_uninterruptible(&pool->wait) < 0)
else if (!pool->wait ||
nxsem_wait_uninterruptible(&pool->waitsem) < 0)
{
return NULL;
}
@@ -220,14 +218,14 @@ void mempool_free(FAR struct mempool_s *pool, FAR void *blk)
pool->nused--;
spin_unlock_irqrestore(&pool->lock, flags);
if (pool->nexpand == 0)
if (pool->wait && pool->nexpand == 0)
{
int semcount;
nxsem_get_value(&pool->wait, &semcount);
nxsem_get_value(&pool->waitsem, &semcount);
if (semcount < 1)
{
nxsem_post(&pool->wait);
nxsem_post(&pool->waitsem);
}
}
}
@@ -262,11 +260,11 @@ int mempool_info(FAR struct mempool_s *pool, FAR struct mempoolinfo_s *info)
info->arena = (pool->nused + info->ordblks + info->iordblks) * pool->bsize;
spin_unlock_irqrestore(&pool->lock, flags);
info->sizeblks = pool->bsize;
if (pool->nexpand == 0)
if (pool->wait && pool->nexpand == 0)
{
int semcount;
nxsem_get_value(&pool->wait, &semcount);
nxsem_get_value(&pool->waitsem, &semcount);
info->nwaiter = -semcount;
}
else
@@ -310,6 +308,10 @@ int mempool_deinit(FAR struct mempool_s *pool)
kmm_free(blk);
}
nxsem_destroy(&pool->wait);
if (pool->wait && pool->nexpand == 0)
{
nxsem_destroy(&pool->waitsem);
}
return 0;
}