mempool:change mempool_multiple way of initialization

Signed-off-by: anjiahao <anjiahao@xiaomi.com>
This commit is contained in:
anjiahao 2022-11-26 23:44:38 +08:00 committed by Xiang Xiao
parent 49ffd99eaf
commit 6b530fceae
13 changed files with 195 additions and 132 deletions

View File

@ -39,11 +39,16 @@
****************************************************************************/ ****************************************************************************/
struct mempool_s; struct mempool_s;
typedef CODE void *(*mempool_alloc_t)(FAR struct mempool_s *pool, typedef CODE FAR void *(*mempool_alloc_t)(FAR struct mempool_s *pool,
size_t size); size_t size);
typedef CODE void (*mempool_free_t)(FAR struct mempool_s *pool, typedef CODE void (*mempool_free_t)(FAR struct mempool_s *pool,
FAR void *addr); FAR void *addr);
typedef CODE FAR void *(*mempool_multiple_alloc_t)(FAR void *args,
size_t alignment,
size_t size);
typedef CODE void (*mempool_multiple_free_t)(FAR void *args, FAR void *addr);
#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL) #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMPOOL)
struct mempool_procfs_entry_s struct mempool_procfs_entry_s
{ {
@ -91,23 +96,6 @@ struct mempool_s
#endif #endif
}; };
struct mempool_multiple_s
{
FAR struct mempool_s *pools; /* The memory pool array */
size_t npools; /* The number of memory pool array elements */
/* Private data for multiple memory pool */
/* This delta describes the relationship between the block size of each
* mempool in multiple mempool by user initialized. It is automatically
* detected by the mempool_multiple_init function. If the delta is not
* equal to 0, the block size of the pool in the multiple mempool is an
* arithmetic progressions, otherwise it is an increasing progressions.
*/
size_t delta;
};
struct mempoolinfo_s struct mempoolinfo_s
{ {
unsigned long arena; /* This is the total size of mempool */ unsigned long arena; /* This is the total size of mempool */
@ -294,15 +282,27 @@ void mempool_procfs_unregister(FAR struct mempool_procfs_entry_s *entry);
* *
* Input Parameters: * Input Parameters:
* name - The name of memory pool. * name - The name of memory pool.
* mpool - The handle of the multiple memory pool to be used. * poolsize - The block size array for pools in multiples pool.
* npools - How many pools in multiples pool.
* alloc - The alloc memory function for multiples pool.
* free - The free memory function for multiples pool.
* arg - The alloc & free memory fuctions used arg.
* expandsize - The expend mempry for all pools in multiples pool.
* *
* Returned Value: * Returned Value:
* Zero on success; A negated errno value is returned on any failure. * Return an initialized multiple pool pointer on success,
* otherwise NULL is returned.
* *
****************************************************************************/ ****************************************************************************/
int mempool_multiple_init(FAR struct mempool_multiple_s *mpool, struct mempool_multiple_s;
FAR const char *name);
FAR struct mempool_multiple_s *
mempool_multiple_init(FAR const char *name,
FAR size_t *poolsize, size_t npools,
mempool_multiple_alloc_t alloc,
mempool_multiple_free_t free,
FAR void *arg, size_t expandsize);
/**************************************************************************** /****************************************************************************
* Name: mempool_multiple_alloc * Name: mempool_multiple_alloc

View File

@ -98,31 +98,6 @@ static inline void mempool_add_queue(FAR sq_queue_t *queue,
} }
} }
static inline FAR void *mempool_malloc(FAR struct mempool_s *pool,
size_t size)
{
if (pool->alloc != NULL)
{
return pool->alloc(pool, size);
}
else
{
return kmm_malloc(size);
}
}
static inline void mempool_mfree(FAR struct mempool_s *pool, FAR void *addr)
{
if (pool->free != NULL)
{
return pool->free(pool, addr);
}
else
{
return kmm_free(addr);
}
}
#if CONFIG_MM_BACKTRACE >= 0 #if CONFIG_MM_BACKTRACE >= 0
static inline void mempool_add_backtrace(FAR struct mempool_s *pool, static inline void mempool_add_backtrace(FAR struct mempool_s *pool,
FAR struct mempool_backtrace_s *buf) FAR struct mempool_backtrace_s *buf)
@ -193,7 +168,7 @@ int mempool_init(FAR struct mempool_s *pool, FAR const char *name)
blocksize; blocksize;
size_t size = ninterrupt * blocksize + sizeof(sq_entry_t); size_t size = ninterrupt * blocksize + sizeof(sq_entry_t);
pool->ibase = mempool_malloc(pool, size); pool->ibase = pool->alloc(pool, size);
if (pool->ibase == NULL) if (pool->ibase == NULL)
{ {
return -ENOMEM; return -ENOMEM;
@ -213,7 +188,7 @@ int mempool_init(FAR struct mempool_s *pool, FAR const char *name)
size_t size = ninitial * blocksize + sizeof(sq_entry_t); size_t size = ninitial * blocksize + sizeof(sq_entry_t);
FAR char *base; FAR char *base;
base = mempool_malloc(pool, size); base = pool->alloc(pool, size);
if (base == NULL) if (base == NULL)
{ {
mempool_free(pool, pool->ibase); mempool_free(pool, pool->ibase);
@ -292,7 +267,7 @@ retry:
size_t nexpand = (pool->expandsize - sizeof(sq_entry_t)) / size_t nexpand = (pool->expandsize - sizeof(sq_entry_t)) /
blocksize; blocksize;
size_t size = nexpand * blocksize + sizeof(sq_entry_t); size_t size = nexpand * blocksize + sizeof(sq_entry_t);
FAR char *base = mempool_malloc(pool, size); FAR char *base = pool->alloc(pool, size);
if (base == NULL) if (base == NULL)
{ {
@ -609,7 +584,7 @@ int mempool_deinit(FAR struct mempool_s *pool)
while ((blk = mempool_remove_queue(&pool->equeue)) != NULL) while ((blk = mempool_remove_queue(&pool->equeue)) != NULL)
{ {
blk = (FAR sq_entry_t *)((FAR char *)blk - count * blocksize); blk = (FAR sq_entry_t *)((FAR char *)blk - count * blocksize);
mempool_mfree(pool, blk); pool->free(pool, blk);
if (pool->expandsize > sizeof(sq_entry_t)) if (pool->expandsize > sizeof(sq_entry_t))
{ {
count = (pool->expandsize - sizeof(sq_entry_t)) / blocksize; count = (pool->expandsize - sizeof(sq_entry_t)) / blocksize;
@ -618,7 +593,7 @@ int mempool_deinit(FAR struct mempool_s *pool)
if (pool->ibase) if (pool->ibase)
{ {
mempool_mfree(pool, pool->ibase); pool->free(pool, pool->ibase);
} }
if (pool->wait && pool->expandsize == 0) if (pool->wait && pool->expandsize == 0)

View File

@ -34,6 +34,27 @@
#define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))
#define ALIGN_BIT (1 << 1) #define ALIGN_BIT (1 << 1)
struct mempool_multiple_s
{
FAR struct mempool_s * pools; /* The memory pool array */
size_t npools; /* The number of memory pool array elements */
FAR void *arg; /* This pointer is used to store the user's
* private data
*/
mempool_multiple_alloc_t alloc; /* The alloc function for mempool */
mempool_multiple_free_t free; /* The free function for mempool */
/* This delta describes the relationship between the block size of each
* mempool in multiple mempool by user initialized. It is automatically
* detected by the mempool_multiple_init function. If the delta is not
* equal to 0, the block size of the pool in the multiple mempool is an
* arithmetic progressions, otherwise it is an increasing progressions.
*/
size_t delta;
};
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -41,10 +62,16 @@
static inline struct mempool_s * static inline struct mempool_s *
mempool_multiple_find(FAR struct mempool_multiple_s *mpool, size_t size) mempool_multiple_find(FAR struct mempool_multiple_s *mpool, size_t size)
{ {
size_t right = mpool->npools; size_t right;
size_t left = 0; size_t left = 0;
size_t mid; size_t mid;
if (mpool == NULL)
{
return NULL;
}
right = mpool->npools;
if (mpool->delta != 0) if (mpool->delta != 0)
{ {
left = mpool->pools[0].blocksize; left = mpool->pools[0].blocksize;
@ -92,49 +119,89 @@ mempool_multiple_find(FAR struct mempool_multiple_s *mpool, size_t size)
* *
* Input Parameters: * Input Parameters:
* name - The name of memory pool. * name - The name of memory pool.
* mpool - The handle of the multiple memory pool to be used. * poolsize - The block size array for pools in multiples pool.
* npools - How many pools in multiples pool.
* alloc - The alloc memory function for multiples pool.
* free - The free memory function for multiples pool.
* arg - The alloc & free memory fuctions used arg.
* expandsize - The expend mempry for all pools in multiples pool.
* *
* Returned Value: * Returned Value:
* Zero on success; A negated errno value is returned on any failure. * Return an initialized multiple pool pointer on success,
* otherwise NULL is returned.
* *
****************************************************************************/ ****************************************************************************/
int mempool_multiple_init(FAR struct mempool_multiple_s *mpool, FAR struct mempool_multiple_s *
FAR const char *name) mempool_multiple_init(FAR const char *name,
FAR size_t *poolsize, size_t npools,
mempool_multiple_alloc_t alloc,
mempool_multiple_free_t free,
FAR void *arg, size_t expandsize)
{ {
size_t i; FAR struct mempool_multiple_s *mpool;
FAR struct mempool_s *pools;
int ret;
int i;
DEBUGASSERT(mpool != NULL && mpool->pools != NULL); mpool = alloc(arg, sizeof(uintptr_t), sizeof(struct mempool_multiple_s));
if (mpool == NULL)
mpool->delta = 0;
for (i = 1; i < mpool->npools; i++)
{ {
size_t delta = mpool->pools[i].blocksize - return NULL;
mpool->pools[i - 1].blocksize;
if (mpool->delta != 0 && delta != mpool->delta)
{
mpool->delta = 0;
break;
} }
mpool->delta = delta; pools = alloc(arg, sizeof(uintptr_t),
npools * sizeof(FAR struct mempool_s));
if (pools == NULL)
{
goto err_with_mpool;
} }
for (i = 0; i < mpool->npools; i++) mpool->pools = pools;
mpool->npools = npools;
mpool->alloc = alloc;
mpool->free = free;
mpool->arg = arg;
for (i = 0; i < npools; i++)
{ {
int ret = mempool_init(mpool->pools + i, name); pools[i].blocksize = poolsize[i];
pools[i].expandsize = expandsize;
pools[i].initialsize = 0;
pools[i].interruptsize = 0;
ret = mempool_init(pools + i, name);
if (ret < 0) if (ret < 0)
{ {
while (--i >= 0) while (--i >= 0)
{ {
mempool_deinit(mpool->pools + i); mempool_deinit(pools + i);
} }
return ret; goto err_with_pools;
}
if (i + 1 != npools)
{
size_t delta = pools[i + 1].blocksize - pools[i].blocksize;
if (i == 0)
{
mpool->delta = delta;
}
else if (delta != mpool->delta)
{
mpool->delta = 0;
}
} }
} }
return 0; return mpool;
err_with_pools:
free(arg, pools);
err_with_mpool:
free(arg, mpool);
return NULL;
} }
/**************************************************************************** /****************************************************************************
@ -427,4 +494,7 @@ void mempool_multiple_deinit(FAR struct mempool_multiple_s *mpool)
{ {
DEBUGVERIFY(mempool_deinit(mpool->pools + i)); DEBUGVERIFY(mempool_deinit(mpool->pools + i));
} }
mpool->free(mpool->arg, mpool->pools);
mpool->free(mpool->arg, mpool);
} }

View File

@ -234,9 +234,7 @@ struct mm_heap_s
/* The is a multiple mempool of the heap */ /* The is a multiple mempool of the heap */
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
struct mempool_multiple_s mm_mpool; FAR struct mempool_multiple_s *mm_mpool;
struct mempool_s mm_pools[CONFIG_MM_HEAP_MEMPOOL_THRESHOLD /
sizeof(uintptr_t)];
#endif #endif
#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMINFO) #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMINFO)

View File

@ -85,7 +85,7 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
if (MM_IS_FROM_MEMPOOL(mem)) if (MM_IS_FROM_MEMPOOL(mem))
{ {
mempool_multiple_free(&heap->mm_mpool, mem); mempool_multiple_free(heap->mm_mpool, mem);
return; return;
} }
#endif #endif

View File

@ -33,6 +33,14 @@
#include "mm_heap/mm.h" #include "mm_heap/mm.h"
#include "kasan/kasan.h" #include "kasan/kasan.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
# define MEMPOOL_NPOOLS (CONFIG_MM_HEAP_MEMPOOL_THRESHOLD / MM_MIN_CHUNK)
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@ -177,6 +185,9 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart,
FAR struct mm_heap_s *mm_initialize(FAR const char *name, FAR struct mm_heap_s *mm_initialize(FAR const char *name,
FAR void *heapstart, size_t heapsize) FAR void *heapstart, size_t heapsize)
{ {
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
size_t poolsize[MEMPOOL_NPOOLS];
#endif
FAR struct mm_heap_s *heap; FAR struct mm_heap_s *heap;
uintptr_t heap_adj; uintptr_t heap_adj;
int i; int i;
@ -226,20 +237,6 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
# endif # endif
#endif #endif
/* Initialize the multiple mempool in heap */
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
heap->mm_mpool.pools = heap->mm_pools;
heap->mm_mpool.npools = sizeof(heap->mm_pools) / sizeof(heap->mm_pools[0]);
for (i = 0; i < heap->mm_mpool.npools; i++)
{
heap->mm_pools[i].blocksize = (i + 1) * sizeof(uintptr_t);
heap->mm_pools[i].expandsize = CONFIG_MM_HEAP_MEMPOOL_EXPAND;
}
mempool_multiple_init(&heap->mm_mpool, name);
#endif
/* Add the initial region of memory to the heap */ /* Add the initial region of memory to the heap */
mm_addregion(heap, heapstart, heapsize); mm_addregion(heap, heapstart, heapsize);
@ -250,6 +247,20 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
# endif # endif
#endif #endif
/* Initialize the multiple mempool in heap */
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
for (i = 0; i < MEMPOOL_NPOOLS; i++)
{
poolsize[i] = (i + 1) * MM_MIN_CHUNK;
}
heap->mm_mpool = mempool_multiple_init(name, poolsize, MEMPOOL_NPOOLS,
(mempool_multiple_alloc_t)mm_memalign,
(mempool_multiple_free_t)mm_free, heap,
CONFIG_MM_HEAP_MEMPOOL_EXPAND);
#endif
return heap; return heap;
} }
@ -269,6 +280,10 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
void mm_uninitialize(FAR struct mm_heap_s *heap) void mm_uninitialize(FAR struct mm_heap_s *heap)
{ {
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
mempool_multiple_deinit(heap->mm_mpool);
#endif
#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMINFO) #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMINFO)
# if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) # if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
procfs_unregister_meminfo(&heap->mm_procfs); procfs_unregister_meminfo(&heap->mm_procfs);

View File

@ -153,7 +153,7 @@ int mm_mallinfo_task(FAR struct mm_heap_s *heap,
info->aordblks = 0; info->aordblks = 0;
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
mempool_multiple_info_task(&heap->mm_mpool, info); mempool_multiple_info_task(heap->mm_mpool, info);
#endif #endif
mm_foreach(heap, mallinfo_task_handler, info); mm_foreach(heap, mallinfo_task_handler, info);

View File

@ -121,7 +121,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
} }
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
ret = mempool_multiple_alloc(&heap->mm_mpool, size); ret = mempool_multiple_alloc(heap->mm_mpool, size);
if (ret != NULL) if (ret != NULL)
{ {
return ret; return ret;

View File

@ -49,7 +49,7 @@ size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
if (MM_IS_FROM_MEMPOOL(mem)) if (MM_IS_FROM_MEMPOOL(mem))
{ {
return mempool_multiple_alloc_size(&heap->mm_mpool, mem); return mempool_multiple_alloc_size(heap->mm_mpool, mem);
} }
#endif #endif

View File

@ -73,7 +73,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
} }
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
node = mempool_multiple_memalign(&heap->mm_mpool, alignment, size); node = mempool_multiple_memalign(heap->mm_mpool, alignment, size);
if (node != NULL) if (node != NULL)
{ {
return node; return node;

View File

@ -148,7 +148,7 @@ void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid)
} }
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
mempool_multiple_memdump(&heap->mm_mpool, pid); mempool_multiple_memdump(heap->mm_mpool, pid);
#endif #endif
mm_foreach(heap, memdump_handler, &pid); mm_foreach(heap, memdump_handler, &pid);

View File

@ -97,7 +97,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
if (MM_IS_FROM_MEMPOOL(oldmem)) if (MM_IS_FROM_MEMPOOL(oldmem))
{ {
newmem = mempool_multiple_realloc(&heap->mm_mpool, oldmem, size); newmem = mempool_multiple_realloc(heap->mm_mpool, oldmem, size);
if (newmem != NULL) if (newmem != NULL)
{ {
return newmem; return newmem;
@ -107,15 +107,15 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
if (newmem != NULL) if (newmem != NULL)
{ {
memcpy(newmem, oldmem, memcpy(newmem, oldmem,
mempool_multiple_alloc_size(&heap->mm_mpool, oldmem)); mempool_multiple_alloc_size(heap->mm_mpool, oldmem));
mempool_multiple_free(&heap->mm_mpool, oldmem); mempool_multiple_free(heap->mm_mpool, oldmem);
} }
return newmem; return newmem;
} }
else else
{ {
newmem = mempool_multiple_alloc(&heap->mm_mpool, size); newmem = mempool_multiple_alloc(heap->mm_mpool, size);
if (newmem != NULL) if (newmem != NULL)
{ {
memcpy(newmem, oldmem, MIN(size, mm_malloc_size(heap, oldmem))); memcpy(newmem, oldmem, MIN(size, mm_malloc_size(heap, oldmem)));

View File

@ -62,6 +62,10 @@
((*((FAR size_t *)(mem) - 1)) & MM_MPOOL_BIT) == 0 ((*((FAR size_t *)(mem) - 1)) & MM_MPOOL_BIT) == 0
#endif #endif
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
# define MEMPOOL_NPOOLS (CONFIG_MM_HEAP_MEMPOOL_THRESHOLD / tlsf_align_size())
#endif
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
@ -97,9 +101,7 @@ struct mm_heap_s
/* The is a multiple mempool of the heap */ /* The is a multiple mempool of the heap */
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
struct mempool_multiple_s mm_mpool; FAR struct mempool_multiple_s *mm_mpool;
struct mempool_s mm_pools[CONFIG_MM_HEAP_MEMPOOL_THRESHOLD /
sizeof(uintptr_t)];
#endif #endif
/* Free delay list, for some situation can't do free immdiately */ /* Free delay list, for some situation can't do free immdiately */
@ -654,7 +656,7 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
if (MM_IS_FROM_MEMPOOL(mem)) if (MM_IS_FROM_MEMPOOL(mem))
{ {
mempool_multiple_free(&heap->mm_mpool, mem); mempool_multiple_free(heap->mm_mpool, mem);
return; return;
} }
#endif #endif
@ -757,6 +759,7 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
{ {
FAR struct mm_heap_s *heap; FAR struct mm_heap_s *heap;
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
size_t poolsize[MEMPOOL_NPOOLS];
int i; int i;
#endif #endif
@ -770,20 +773,6 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
heapstart += sizeof(struct mm_heap_s); heapstart += sizeof(struct mm_heap_s);
heapsize -= sizeof(struct mm_heap_s); heapsize -= sizeof(struct mm_heap_s);
/* Initialize the multiple mempool in heap */
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
heap->mm_mpool.pools = heap->mm_pools;
heap->mm_mpool.npools = sizeof(heap->mm_pools) / sizeof(heap->mm_pools[0]);
for (i = 0; i < heap->mm_mpool.npools; i++)
{
heap->mm_pools[i].blocksize = (i + 1) * sizeof(uintptr_t);
heap->mm_pools[i].expandsize = CONFIG_MM_HEAP_MEMPOOL_EXPAND;
}
mempool_multiple_init(&heap->mm_mpool, name);
#endif
/* Allocate and create TLSF context */ /* Allocate and create TLSF context */
DEBUGASSERT(heapsize > tlsf_size()); DEBUGASSERT(heapsize > tlsf_size());
@ -812,6 +801,18 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
#endif #endif
#endif #endif
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
for (i = 0; i < MEMPOOL_NPOOLS; i++)
{
poolsize[i] = (i + 1) * tlsf_align_size();
}
heap->mm_mpool = mempool_multiple_init(name, poolsize, MEMPOOL_NPOOLS,
(mempool_multiple_alloc_t)mm_memalign,
(mempool_multiple_free_t)mm_free, heap,
CONFIG_MM_HEAP_MEMPOOL_EXPAND);
#endif
return heap; return heap;
} }
@ -870,7 +871,7 @@ int mm_mallinfo_task(FAR struct mm_heap_s *heap,
info->aordblks = 0; info->aordblks = 0;
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
mempool_multiple_info_task(&heap->mm_mpool, info); mempool_multiple_info_task(heap->mm_mpool, info);
#endif #endif
#if CONFIG_MM_REGIONS > 1 #if CONFIG_MM_REGIONS > 1
@ -926,7 +927,7 @@ void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid)
} }
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
mempool_multiple_memdump(&heap->mm_mpool, pid); mempool_multiple_memdump(heap->mm_mpool, pid);
#endif #endif
#if CONFIG_MM_REGIONS > 1 #if CONFIG_MM_REGIONS > 1
@ -955,7 +956,7 @@ size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
if (MM_IS_FROM_MEMPOOL(mem)) if (MM_IS_FROM_MEMPOOL(mem))
{ {
return mempool_multiple_alloc_size(&heap->mm_mpool, mem); return mempool_multiple_alloc_size(heap->mm_mpool, mem);
} }
#endif #endif
@ -982,7 +983,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
FAR void *ret; FAR void *ret;
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
ret = mempool_multiple_alloc(&heap->mm_mpool, size); ret = mempool_multiple_alloc(heap->mm_mpool, size);
if (ret != NULL) if (ret != NULL)
{ {
return ret; return ret;
@ -1037,7 +1038,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
FAR void *ret; FAR void *ret;
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
ret = mempool_multiple_memalign(&heap->mm_mpool, alignment, size); ret = mempool_multiple_memalign(heap->mm_mpool, alignment, size);
if (ret != NULL) if (ret != NULL)
{ {
return ret; return ret;
@ -1114,7 +1115,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
if (MM_IS_FROM_MEMPOOL(oldmem)) if (MM_IS_FROM_MEMPOOL(oldmem))
{ {
newmem = mempool_multiple_realloc(&heap->mm_mpool, oldmem, size); newmem = mempool_multiple_realloc(heap->mm_mpool, oldmem, size);
if (newmem != NULL) if (newmem != NULL)
{ {
return newmem; return newmem;
@ -1124,14 +1125,14 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
if (newmem != NULL) if (newmem != NULL)
{ {
memcpy(newmem, oldmem, size); memcpy(newmem, oldmem, size);
mempool_multiple_free(&heap->mm_mpool, oldmem); mempool_multiple_free(heap->mm_mpool, oldmem);
} }
return newmem; return newmem;
} }
else else
{ {
newmem = mempool_multiple_alloc(&heap->mm_mpool, size); newmem = mempool_multiple_alloc(heap->mm_mpool, size);
if (newmem != NULL) if (newmem != NULL)
{ {
memcpy(newmem, oldmem, MIN(size, mm_malloc_size(heap, oldmem))); memcpy(newmem, oldmem, MIN(size, mm_malloc_size(heap, oldmem)));
@ -1201,6 +1202,10 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
void mm_uninitialize(FAR struct mm_heap_s *heap) void mm_uninitialize(FAR struct mm_heap_s *heap)
{ {
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
mempool_multiple_deinit(heap->mm_mpool);
#endif
#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMINFO) #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMINFO)
# if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) # if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
procfs_unregister_meminfo(&heap->mm_procfs); procfs_unregister_meminfo(&heap->mm_procfs);