mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +08:00
mm/mempool: support multiple memory pool
Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
+130
-17
@@ -48,19 +48,29 @@ struct mempool_procfs_entry_s
|
|||||||
|
|
||||||
struct mempool_s
|
struct mempool_s
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL
|
size_t bsize; /* The size for every block in mempool */
|
||||||
struct mempool_procfs_entry_s procfs; /* The entry of procfs */
|
size_t ninitial; /* The initialize number of block in normal mempool */
|
||||||
#endif
|
size_t ninterrupt; /* The number of block in interrupt mempool */
|
||||||
|
size_t nexpand; /* The number of expand block every time for mempool */
|
||||||
|
bool wait; /* The flag of need to wait when mempool is empty */
|
||||||
|
|
||||||
|
/* Private data for memory pool */
|
||||||
|
|
||||||
sq_queue_t list; /* The free block list in normal mempool */
|
sq_queue_t list; /* The free block list in normal mempool */
|
||||||
sq_queue_t ilist; /* The free block list in interrupt mempool */
|
sq_queue_t ilist; /* The free block list in interrupt mempool */
|
||||||
sq_queue_t elist; /* The expand block list for normal mempool */
|
sq_queue_t elist; /* The expand block list for normal mempool */
|
||||||
size_t bsize; /* The size for every block in mempool */
|
|
||||||
size_t ninterrupt; /* The number of block in interrupt mempool */
|
|
||||||
size_t nexpand; /* The number of expand block every time for mempool */
|
|
||||||
size_t nused; /* The number of used block in mempool */
|
size_t nused; /* The number of used block in mempool */
|
||||||
spinlock_t lock; /* The protect lock to mempool */
|
spinlock_t lock; /* The protect lock to mempool */
|
||||||
sem_t wait; /* The semaphore of waiter get free block */
|
sem_t waitsem; /* The semaphore of waiter get free block */
|
||||||
|
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL
|
||||||
|
struct mempool_procfs_entry_s procfs; /* The entry of procfs */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mempool_multiple_s
|
||||||
|
{
|
||||||
|
FAR struct mempool_s *pools; /* The memory pool array */
|
||||||
|
size_t npools; /* The number of memory pool array elements */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mempoolinfo_s
|
struct mempoolinfo_s
|
||||||
@@ -91,26 +101,19 @@ extern "C"
|
|||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Initialize a memory pool.
|
* Initialize a memory pool.
|
||||||
|
* The user needs to specify the initialization information of mempool
|
||||||
|
* including bsize, ninitial, nexpand, ninterrupt.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* pool - Address of the memory pool to be used.
|
* pool - Address of the memory pool to be used.
|
||||||
* name - The name of memory pool.
|
* 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.
|
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero on success; A negated errno value is returned on any failure.
|
* Zero on success; A negated errno value is returned on any failure.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mempool_init(FAR struct mempool_s *pool, FAR const char *name,
|
int mempool_init(FAR struct mempool_s *pool, FAR const char *name);
|
||||||
size_t bsize, size_t ninitial, size_t nexpand,
|
|
||||||
size_t ninterrupt);
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mempool_alloc
|
* Name: mempool_alloc
|
||||||
@@ -204,6 +207,116 @@ void mempool_procfs_register(FAR struct mempool_procfs_entry_s *entry,
|
|||||||
void mempool_procfs_unregister(FAR struct mempool_procfs_entry_s *entry);
|
void mempool_procfs_unregister(FAR struct mempool_procfs_entry_s *entry);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_init
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize multiple memory pool, each element represents a memory pool.
|
||||||
|
* The user needs to specify the initialization information of each mempool
|
||||||
|
* in the array, including bsize, ninitial, nexpand, ninterrupt, wait.
|
||||||
|
* These mempool will be initialized by mempool_init. The name of all
|
||||||
|
* mempool are "name".
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* name - The name of memory pool.
|
||||||
|
* mpool - The handle of the multiple memory pool to be used.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; A negated errno value is returned on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mempool_multiple_init(FAR struct mempool_multiple_s *mpool,
|
||||||
|
FAR const char *name);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_alloc
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Allocate an block from specific multiple memory pool.
|
||||||
|
* If the mempool of the corresponding size doesn't have free block,
|
||||||
|
* it will continue to alloc memory for a larger memory pool until last
|
||||||
|
* mempool in multiple mempools.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mpool - The handle of multiple memory pool to be used.
|
||||||
|
* size - The size of alloc blk.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* The pointer to the allocated block on success; NULL on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR void *mempool_multiple_alloc(FAR struct mempool_multiple_s *mpool,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_free
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Release an memory block to the multiple mempry pool. The blk must have
|
||||||
|
* been returned by a previous call to mempool_multiple_alloc.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mpool - The handle of multiple memory pool to be used.
|
||||||
|
* blk - The pointer of memory block.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
|
||||||
|
FAR void *blk);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_fixed_alloc
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Allocate an block from specific multiple memory pool.
|
||||||
|
* If the mempool of the corresponding size doesn't have free block,
|
||||||
|
* then wait until free happened or return NULL.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mpool - The handle of multiple memory pool to be used.
|
||||||
|
* size - The size of alloc blk.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* The pointer to the allocated block on success; NULL on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR void *mempool_multiple_fixed_alloc(FAR struct mempool_multiple_s *mpool,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_fixed_free
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Release an memory block to the multiple mempry pool. The blk must have
|
||||||
|
* been returned by a previous call to mempool_multiple_fixed_alloc.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mpool - The handle of multiple memory pool to be used.
|
||||||
|
* blk - The pointer of memory block.
|
||||||
|
* size - The size of alloc blk.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mempool_multiple_fixed_free(FAR struct mempool_multiple_s *mpool,
|
||||||
|
FAR void *blk, size_t size);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_deinit
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Deallocate multiple memory pool.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mpool - The handle of multiple memory pool to be used.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; A negated errno value is returned on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mempool_multiple_deinit(FAR struct mempool_multiple_s *mpool);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
ifeq ($(CONFIG_MM_MEMPOOL),y)
|
ifeq ($(CONFIG_MM_MEMPOOL),y)
|
||||||
|
|
||||||
CSRCS += mempool.c
|
CSRCS += mempool.c mempool_multiple.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_FS_PROCFS),y)
|
ifeq ($(CONFIG_FS_PROCFS),y)
|
||||||
|
|
||||||
|
|||||||
+28
-26
@@ -50,58 +50,55 @@ static inline void mempool_add_list(FAR sq_queue_t *list, FAR void *base,
|
|||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Initialize a memory pool.
|
* Initialize a memory pool.
|
||||||
|
* The user needs to specify the initialization information of mempool
|
||||||
|
* including bsize, ninitial, nexpand, ninterrupt.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* pool - Address of the memory pool to be used.
|
* pool - Address of the memory pool to be used.
|
||||||
* name - The name of memory pool.
|
* 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.
|
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero on success; A negated errno value is returned on any failure.
|
* Zero on success; A negated errno value is returned on any failure.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mempool_init(FAR struct mempool_s *pool, FAR const char *name,
|
int mempool_init(FAR struct mempool_s *pool, FAR const char *name)
|
||||||
size_t bsize, size_t ninitial, size_t nexpand,
|
|
||||||
size_t ninterrupt)
|
|
||||||
{
|
{
|
||||||
size_t count = ninitial + ninterrupt;
|
size_t count;
|
||||||
|
|
||||||
if (pool == NULL || bsize == 0)
|
if (pool == NULL || pool->bsize == 0)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pool->nused = 0;
|
pool->nused = 0;
|
||||||
pool->bsize = bsize;
|
|
||||||
pool->nexpand = nexpand;
|
|
||||||
pool->ninterrupt = ninterrupt;
|
|
||||||
sq_init(&pool->list);
|
sq_init(&pool->list);
|
||||||
sq_init(&pool->ilist);
|
sq_init(&pool->ilist);
|
||||||
sq_init(&pool->elist);
|
sq_init(&pool->elist);
|
||||||
|
|
||||||
|
count = pool->ninitial + pool->ninterrupt;
|
||||||
if (count != 0)
|
if (count != 0)
|
||||||
{
|
{
|
||||||
FAR sq_entry_t *base;
|
FAR sq_entry_t *base;
|
||||||
|
|
||||||
base = kmm_malloc(sizeof(*base) + bsize * count);
|
base = kmm_malloc(sizeof(*base) + pool->bsize * count);
|
||||||
if (base == NULL)
|
if (base == NULL)
|
||||||
{
|
{
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
sq_addfirst(base, &pool->elist);
|
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) +
|
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
|
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL
|
||||||
mempool_procfs_register(&pool->procfs, name);
|
mempool_procfs_register(&pool->procfs, name);
|
||||||
@@ -167,7 +164,8 @@ retry:
|
|||||||
pool->bsize);
|
pool->bsize);
|
||||||
blk = sq_remfirst(&pool->list);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -220,14 +218,14 @@ void mempool_free(FAR struct mempool_s *pool, FAR void *blk)
|
|||||||
|
|
||||||
pool->nused--;
|
pool->nused--;
|
||||||
spin_unlock_irqrestore(&pool->lock, flags);
|
spin_unlock_irqrestore(&pool->lock, flags);
|
||||||
if (pool->nexpand == 0)
|
if (pool->wait && pool->nexpand == 0)
|
||||||
{
|
{
|
||||||
int semcount;
|
int semcount;
|
||||||
|
|
||||||
nxsem_get_value(&pool->wait, &semcount);
|
nxsem_get_value(&pool->waitsem, &semcount);
|
||||||
if (semcount < 1)
|
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;
|
info->arena = (pool->nused + info->ordblks + info->iordblks) * pool->bsize;
|
||||||
spin_unlock_irqrestore(&pool->lock, flags);
|
spin_unlock_irqrestore(&pool->lock, flags);
|
||||||
info->sizeblks = pool->bsize;
|
info->sizeblks = pool->bsize;
|
||||||
if (pool->nexpand == 0)
|
if (pool->wait && pool->nexpand == 0)
|
||||||
{
|
{
|
||||||
int semcount;
|
int semcount;
|
||||||
|
|
||||||
nxsem_get_value(&pool->wait, &semcount);
|
nxsem_get_value(&pool->waitsem, &semcount);
|
||||||
info->nwaiter = -semcount;
|
info->nwaiter = -semcount;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -310,6 +308,10 @@ int mempool_deinit(FAR struct mempool_s *pool)
|
|||||||
kmm_free(blk);
|
kmm_free(blk);
|
||||||
}
|
}
|
||||||
|
|
||||||
nxsem_destroy(&pool->wait);
|
if (pool->wait && pool->nexpand == 0)
|
||||||
|
{
|
||||||
|
nxsem_destroy(&pool->waitsem);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,279 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* mm/mempool/mempool_multiple.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/kmalloc.h>
|
||||||
|
#include <nuttx/mm/mempool.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define SIZEOF_HEAD sizeof(FAR struct mempool_s *)
|
||||||
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline struct mempool_s *
|
||||||
|
mempool_multiple_find(FAR struct mempool_multiple_s *mpool, size_t size)
|
||||||
|
{
|
||||||
|
FAR struct mempool_s *low = mpool->pools;
|
||||||
|
FAR struct mempool_s *mid;
|
||||||
|
size_t n = mpool->npools;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
n >>= 1;
|
||||||
|
mid = low + n;
|
||||||
|
if (size > mid->bsize)
|
||||||
|
{
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
low = ++mid;
|
||||||
|
}
|
||||||
|
else if (n == 0 || size == mid->bsize)
|
||||||
|
{
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_init
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize multiple memory pool, each element represents a memory pool.
|
||||||
|
* The user needs to specify the initialization information of each mempool
|
||||||
|
* in the array, including bsize, ninitial, nexpand, ninterrupt, wait.
|
||||||
|
* These mempool will be initialized by mempool_init. The name of all
|
||||||
|
* mempool are "name".
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* name - The name of memory pool.
|
||||||
|
* mpool - The handle of the multiple memory pool to be used.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; A negated errno value is returned on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mempool_multiple_init(FAR struct mempool_multiple_s *mpool,
|
||||||
|
FAR const char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (mpool == NULL || mpool->pools == NULL)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < mpool->npools; i++)
|
||||||
|
{
|
||||||
|
int ret = mempool_init(mpool->pools + i, name);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
while (--i >= 0)
|
||||||
|
{
|
||||||
|
mempool_deinit(mpool->pools + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_alloc
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Allocate an block from specific multiple memory pool.
|
||||||
|
* If the mempool of the corresponding size doesn't have free block,
|
||||||
|
* it will continue to alloc memory for a larger memory pool until last
|
||||||
|
* mempool in multiple mempools.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mpool - The handle of multiple memory pool to be used.
|
||||||
|
* size - The size of alloc blk.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* The pointer to the allocated block on success; NULL on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR void *mempool_multiple_alloc(FAR struct mempool_multiple_s *mpool,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
FAR struct mempool_s *pool;
|
||||||
|
|
||||||
|
pool = mempool_multiple_find(mpool, size + SIZEOF_HEAD);
|
||||||
|
if (pool != NULL)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
FAR void *blk = mempool_alloc(pool);
|
||||||
|
if (blk != NULL)
|
||||||
|
{
|
||||||
|
*(FAR struct mempool_s **)blk = pool;
|
||||||
|
return (FAR char *)blk + SIZEOF_HEAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (++pool< mpool->pools + mpool->npools);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_free
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Release an memory block to the multiple mempry pool. The blk must have
|
||||||
|
* been returned by a previous call to mempool_multiple_alloc.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mpool - The handle of multiple memory pool to be used.
|
||||||
|
* blk - The pointer of memory block.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
|
||||||
|
FAR void *blk)
|
||||||
|
{
|
||||||
|
FAR struct mempool_s *pool;
|
||||||
|
FAR void *mem;
|
||||||
|
|
||||||
|
if (blk != NULL)
|
||||||
|
{
|
||||||
|
mem = (FAR char *)blk - SIZEOF_HEAD;
|
||||||
|
pool = *(FAR struct mempool_s **)mem;
|
||||||
|
|
||||||
|
mempool_free(pool, mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_fixed_alloc
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Allocate an block from specific multiple memory pool.
|
||||||
|
* If the mempool of the corresponding size doesn't have free block,
|
||||||
|
* then wait until free happened or return NULL.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mpool - The handle of multiple memory pool to be used.
|
||||||
|
* size - The size of alloc blk.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* The pointer to the allocated block on success; NULL on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR void *mempool_multiple_fixed_alloc(FAR struct mempool_multiple_s *mpool,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
FAR struct mempool_s *pool;
|
||||||
|
|
||||||
|
pool = mempool_multiple_find(mpool, size);
|
||||||
|
if (pool != NULL)
|
||||||
|
{
|
||||||
|
return mempool_alloc(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_fixed_free
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Release an memory block to the multiple mempry pool. The blk must have
|
||||||
|
* been returned by a previous call to mempool_multiple_fixed_alloc.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mpool - The handle of multiple memory pool to be used.
|
||||||
|
* blk - The pointer of memory block.
|
||||||
|
* size - The size of alloc blk.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mempool_multiple_fixed_free(FAR struct mempool_multiple_s *mpool,
|
||||||
|
FAR void *blk, size_t size)
|
||||||
|
{
|
||||||
|
if (blk != NULL)
|
||||||
|
{
|
||||||
|
FAR struct mempool_s *pool = mempool_multiple_find(mpool, size);
|
||||||
|
if (pool != NULL)
|
||||||
|
{
|
||||||
|
mempool_free(pool, blk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_deinit
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Deallocate multiple memory pool.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mpool - The handle of multiple memory pool to be used.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; A negated errno value is returned on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mempool_multiple_deinit(FAR struct mempool_multiple_s *mpool)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (mpool == NULL)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < mpool->npools; i++)
|
||||||
|
{
|
||||||
|
if (mpool->pools[i].nused != 0)
|
||||||
|
{
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < mpool->npools; i++)
|
||||||
|
{
|
||||||
|
mempool_deinit(mpool->pools + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
#include <nuttx/mm/mempool.h>
|
#include <nuttx/mm/mempool.h>
|
||||||
|
#include <nuttx/nuttx.h>
|
||||||
#include <nuttx/fs/procfs.h>
|
#include <nuttx/fs/procfs.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -150,12 +151,14 @@ static ssize_t mempool_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
{
|
{
|
||||||
if (totalsize < buflen)
|
if (totalsize < buflen)
|
||||||
{
|
{
|
||||||
|
FAR struct mempool_s *pool = container_of(entry, struct mempool_s,
|
||||||
|
procfs);
|
||||||
struct mempoolinfo_s minfo;
|
struct mempoolinfo_s minfo;
|
||||||
|
|
||||||
buffer += copysize;
|
buffer += copysize;
|
||||||
buflen -= copysize;
|
buflen -= copysize;
|
||||||
|
|
||||||
mempool_info((FAR struct mempool_s *)entry, &minfo);
|
mempool_info(pool, &minfo);
|
||||||
linesize = procfs_snprintf(procfile->line, MEMPOOLINFO_LINELEN,
|
linesize = procfs_snprintf(procfile->line, MEMPOOLINFO_LINELEN,
|
||||||
"%12s:%11lu%9lu%9lu%9lu%9lu%9lu\n",
|
"%12s:%11lu%9lu%9lu%9lu%9lu%9lu\n",
|
||||||
entry->name, minfo.arena,
|
entry->name, minfo.arena,
|
||||||
|
|||||||
Reference in New Issue
Block a user