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;
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);
typedef CODE void (*mempool_free_t)(FAR struct mempool_s *pool,
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)
struct mempool_procfs_entry_s
{
@ -91,23 +96,6 @@ struct mempool_s
#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
{
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:
* 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:
* 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 const char *name);
struct mempool_multiple_s;
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

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
static inline void mempool_add_backtrace(FAR struct mempool_s *pool,
FAR struct mempool_backtrace_s *buf)
@ -193,7 +168,7 @@ int mempool_init(FAR struct mempool_s *pool, FAR const char *name)
blocksize;
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)
{
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);
FAR char *base;
base = mempool_malloc(pool, size);
base = pool->alloc(pool, size);
if (base == NULL)
{
mempool_free(pool, pool->ibase);
@ -292,7 +267,7 @@ retry:
size_t nexpand = (pool->expandsize - sizeof(sq_entry_t)) /
blocksize;
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)
{
@ -609,7 +584,7 @@ int mempool_deinit(FAR struct mempool_s *pool)
while ((blk = mempool_remove_queue(&pool->equeue)) != NULL)
{
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))
{
count = (pool->expandsize - sizeof(sq_entry_t)) / blocksize;
@ -618,7 +593,7 @@ int mempool_deinit(FAR struct mempool_s *pool)
if (pool->ibase)
{
mempool_mfree(pool, pool->ibase);
pool->free(pool, pool->ibase);
}
if (pool->wait && pool->expandsize == 0)

View File

@ -34,6 +34,27 @@
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#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
****************************************************************************/
@ -41,10 +62,16 @@
static inline struct mempool_s *
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 mid;
if (mpool == NULL)
{
return NULL;
}
right = mpool->npools;
if (mpool->delta != 0)
{
left = mpool->pools[0].blocksize;
@ -92,49 +119,89 @@ mempool_multiple_find(FAR struct mempool_multiple_s *mpool, size_t size)
*
* Input Parameters:
* 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:
* 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 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)
{
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->delta = 0;
for (i = 1; i < mpool->npools; i++)
mpool = alloc(arg, sizeof(uintptr_t), sizeof(struct mempool_multiple_s));
if (mpool == NULL)
{
size_t delta = mpool->pools[i].blocksize -
mpool->pools[i - 1].blocksize;
if (mpool->delta != 0 && delta != mpool->delta)
{
mpool->delta = 0;
break;
return NULL;
}
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)
{
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));
}
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 */
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
struct mempool_multiple_s mm_mpool;
struct mempool_s mm_pools[CONFIG_MM_HEAP_MEMPOOL_THRESHOLD /
sizeof(uintptr_t)];
FAR struct mempool_multiple_s *mm_mpool;
#endif
#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 (MM_IS_FROM_MEMPOOL(mem))
{
mempool_multiple_free(&heap->mm_mpool, mem);
mempool_multiple_free(heap->mm_mpool, mem);
return;
}
#endif

View File

@ -33,6 +33,14 @@
#include "mm_heap/mm.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
****************************************************************************/
@ -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 void *heapstart, size_t heapsize)
{
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
size_t poolsize[MEMPOOL_NPOOLS];
#endif
FAR struct mm_heap_s *heap;
uintptr_t heap_adj;
int i;
@ -226,20 +237,6 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
# 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 */
mm_addregion(heap, heapstart, heapsize);
@ -250,6 +247,20 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
# 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;
}
@ -269,6 +280,10 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
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_BUILD_FLAT) || defined(__KERNEL__)
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;
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
mempool_multiple_info_task(&heap->mm_mpool, info);
mempool_multiple_info_task(heap->mm_mpool, info);
#endif
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
ret = mempool_multiple_alloc(&heap->mm_mpool, size);
ret = mempool_multiple_alloc(heap->mm_mpool, size);
if (ret != NULL)
{
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 (MM_IS_FROM_MEMPOOL(mem))
{
return mempool_multiple_alloc_size(&heap->mm_mpool, mem);
return mempool_multiple_alloc_size(heap->mm_mpool, mem);
}
#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
node = mempool_multiple_memalign(&heap->mm_mpool, alignment, size);
node = mempool_multiple_memalign(heap->mm_mpool, alignment, size);
if (node != NULL)
{
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
mempool_multiple_memdump(&heap->mm_mpool, pid);
mempool_multiple_memdump(heap->mm_mpool, pid);
#endif
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 (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)
{
return newmem;
@ -107,15 +107,15 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
if (newmem != NULL)
{
memcpy(newmem, oldmem,
mempool_multiple_alloc_size(&heap->mm_mpool, oldmem));
mempool_multiple_free(&heap->mm_mpool, oldmem);
mempool_multiple_alloc_size(heap->mm_mpool, oldmem));
mempool_multiple_free(heap->mm_mpool, oldmem);
}
return newmem;
}
else
{
newmem = mempool_multiple_alloc(&heap->mm_mpool, size);
newmem = mempool_multiple_alloc(heap->mm_mpool, size);
if (newmem != NULL)
{
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
#endif
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
# define MEMPOOL_NPOOLS (CONFIG_MM_HEAP_MEMPOOL_THRESHOLD / tlsf_align_size())
#endif
/****************************************************************************
* Private Types
****************************************************************************/
@ -97,9 +101,7 @@ struct mm_heap_s
/* The is a multiple mempool of the heap */
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
struct mempool_multiple_s mm_mpool;
struct mempool_s mm_pools[CONFIG_MM_HEAP_MEMPOOL_THRESHOLD /
sizeof(uintptr_t)];
FAR struct mempool_multiple_s *mm_mpool;
#endif
/* 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 (MM_IS_FROM_MEMPOOL(mem))
{
mempool_multiple_free(&heap->mm_mpool, mem);
mempool_multiple_free(heap->mm_mpool, mem);
return;
}
#endif
@ -757,6 +759,7 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
{
FAR struct mm_heap_s *heap;
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
size_t poolsize[MEMPOOL_NPOOLS];
int i;
#endif
@ -770,20 +773,6 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
heapstart += 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 */
DEBUGASSERT(heapsize > tlsf_size());
@ -812,6 +801,18 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
#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;
}
@ -870,7 +871,7 @@ int mm_mallinfo_task(FAR struct mm_heap_s *heap,
info->aordblks = 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
#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
mempool_multiple_memdump(&heap->mm_mpool, pid);
mempool_multiple_memdump(heap->mm_mpool, pid);
#endif
#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 (MM_IS_FROM_MEMPOOL(mem))
{
return mempool_multiple_alloc_size(&heap->mm_mpool, mem);
return mempool_multiple_alloc_size(heap->mm_mpool, mem);
}
#endif
@ -982,7 +983,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
FAR void *ret;
#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)
{
return ret;
@ -1037,7 +1038,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
FAR void *ret;
#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)
{
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 (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)
{
return newmem;
@ -1124,14 +1125,14 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
if (newmem != NULL)
{
memcpy(newmem, oldmem, size);
mempool_multiple_free(&heap->mm_mpool, oldmem);
mempool_multiple_free(heap->mm_mpool, oldmem);
}
return newmem;
}
else
{
newmem = mempool_multiple_alloc(&heap->mm_mpool, size);
newmem = mempool_multiple_alloc(heap->mm_mpool, size);
if (newmem != NULL)
{
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)
{
#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_BUILD_FLAT) || defined(__KERNEL__)
procfs_unregister_meminfo(&heap->mm_procfs);