From d846004533308f6b43fc0059f81e35a2fc5e32ea Mon Sep 17 00:00:00 2001 From: anjiahao Date: Thu, 22 Dec 2022 21:18:09 +0800 Subject: [PATCH] mempool:use two-dimensional array avoid competition Signed-off-by: anjiahao --- include/nuttx/mm/mempool.h | 18 +++--- mm/Kconfig | 7 +++ mm/mempool/mempool_multiple.c | 108 ++++++++++++++++++++++------------ mm/mm_heap/mm_initialize.c | 7 ++- mm/tlsf/mm_tlsf.c | 7 ++- 5 files changed, 95 insertions(+), 52 deletions(-) diff --git a/include/nuttx/mm/mempool.h b/include/nuttx/mm/mempool.h index 7af6558728..4c7aeaeb5c 100644 --- a/include/nuttx/mm/mempool.h +++ b/include/nuttx/mm/mempool.h @@ -281,13 +281,14 @@ void mempool_procfs_unregister(FAR struct mempool_procfs_entry_s *entry); * relationship between the each block size of mempool in multiple mempool. * * Input Parameters: - * name - The name of memory pool. - * 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. + * name - The name of memory pool. + * 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. + * dict_expendsize - The expend number for multiple dictnoary * * Returned Value: * Return an initialized multiple pool pointer on success, @@ -302,7 +303,8 @@ 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); + FAR void *arg, size_t expandsize, + size_t dict_expendsize); /**************************************************************************** * Name: mempool_multiple_alloc diff --git a/mm/Kconfig b/mm/Kconfig index 8b572f142b..5dc5c9f85d 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -196,6 +196,13 @@ config MM_HEAP_MEMPOOL_EXPAND This size describes the size of each expansion of each memory pool with insufficient memory in the multi-level memory pool. +config MM_HEAP_MEMPOOL_DICTIONARY_EXPAND + int "The expand size for multiple mempool's dictonary" + default MM_HEAP_MEMPOOL_EXPAND + depends on MM_HEAP_MEMPOOL_THRESHOLD != 0 + ---help--- + This size describes the multiple mempool dictonary expend. + config FS_PROCFS_EXCLUDE_MEMPOOL bool "Exclude mempool" default DEFAULT_SMALL diff --git a/mm/mempool/mempool_multiple.c b/mm/mempool/mempool_multiple.c index d03b541f25..c8516ae79f 100644 --- a/mm/mempool/mempool_multiple.c +++ b/mm/mempool/mempool_multiple.c @@ -22,6 +22,8 @@ * Included Files ****************************************************************************/ +#include +#include #include #include @@ -73,9 +75,11 @@ struct mempool_multiple_s * expansion, and find the mempool by adding an index */ - size_t dict_alloc; - size_t dict_used; - FAR struct mpool_dict_s *dict; + mutex_t dict_lock; + size_t dict_used; + size_t dict_col_num_log2; + size_t dict_row_num; + FAR struct mpool_dict_s **dict; }; /**************************************************************************** @@ -133,23 +137,8 @@ static FAR void *mempool_multiple_alloc_callback(FAR struct mempool_s *pool, { FAR struct mempool_multiple_s *mpool = pool->priv; FAR void *ret; - - if (mpool->dict_used >= mpool->dict_alloc) - { - ret = mpool->alloc(mpool->arg, sizeof(uintptr_t), - mpool->dict_alloc * - sizeof(struct mpool_dict_s) * 2); - if (ret == NULL) - { - return NULL; - } - - memcpy(ret, mpool->dict, - mpool->dict_alloc * sizeof(struct mpool_dict_s)); - mpool->free(mpool->arg, mpool->dict); - mpool->dict = ret; - mpool->dict_alloc *= 2; - } + size_t row; + size_t col; ret = mpool->alloc(mpool->arg, mpool->expandsize, mpool->minpoolsize + size); @@ -158,10 +147,27 @@ static FAR void *mempool_multiple_alloc_callback(FAR struct mempool_s *pool, return NULL; } - mpool->dict[mpool->dict_used].pool = pool; - mpool->dict[mpool->dict_used].addr = ret; - mpool->dict[mpool->dict_used].size = mpool->minpoolsize + size; + nxmutex_lock(&mpool->dict_lock); + row = mpool->dict_used >> mpool->dict_col_num_log2; + + /* There is no new pointer address to store the dictionarys */ + + DEBUGASSERT(mpool->dict_row_num > row); + + col = mpool->dict_used - (row << mpool->dict_col_num_log2); + + if (mpool->dict[row] == NULL) + { + mpool->dict[row] = mpool->alloc(mpool->arg, sizeof(uintptr_t), + (1 << mpool->dict_col_num_log2) * + sizeof(struct mpool_dict_s)); + } + + mpool->dict[row][col].pool = pool; + mpool->dict[row][col].addr = ret; + mpool->dict[row][col].size = mpool->minpoolsize + size; *(FAR size_t *)ret = mpool->dict_used++; + nxmutex_unlock(&mpool->dict_lock); return (FAR char *)ret + mpool->minpoolsize; } @@ -194,6 +200,8 @@ mempool_multiple_get_dict(FAR struct mempool_multiple_s *mpool, { FAR void *addr; size_t index; + size_t row; + size_t col; if (mpool == NULL || blk == NULL) { @@ -208,13 +216,16 @@ mempool_multiple_get_dict(FAR struct mempool_multiple_s *mpool, return NULL; } - if (mpool->dict[index].addr != addr || - blk - addr >= mpool->dict[index].size) + row = index >> mpool->dict_col_num_log2; + col = index - (row << mpool->dict_col_num_log2); + if (mpool->dict[row] == NULL || + mpool->dict[row][col].addr != addr || + blk - addr >= mpool->dict[row][col].size) { return NULL; } - return &mpool->dict[index]; + return &mpool->dict[row][col]; } /**************************************************************************** @@ -235,14 +246,14 @@ mempool_multiple_get_dict(FAR struct mempool_multiple_s *mpool, * relationship between the each block size of mempool in multiple mempool. * * Input Parameters: - * name - The name of memory pool. - * 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. - * + * name - The name of memory pool. + * 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. + * dict_expendsize - The expend size for multiple dictnoary * Returned Value: * Return an initialized multiple pool pointer on success, * otherwise NULL is returned. @@ -254,7 +265,8 @@ 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) + FAR void *arg, size_t expandsize, + size_t dict_expendsize) { FAR struct mempool_multiple_s *mpool; FAR struct mempool_s *pools; @@ -335,15 +347,22 @@ mempool_multiple_init(FAR const char *name, } } - mpool->dict_alloc = maxpoolszie / sizeof(struct mpool_dict_s) + 1; mpool->dict_used = 0; - mpool->dict = alloc(arg, sizeof(uintptr_t), - mpool->dict_alloc * sizeof(struct mpool_dict_s)); + mpool->dict_col_num_log2 = fls(dict_expendsize / + sizeof(struct mpool_dict_s)); + + mpool->dict_row_num = dict_expendsize / sizeof(struct mpool_dict_s *); + mpool->dict = alloc(arg, sizeof(struct mpool_dict_s *), + sizeof(struct mpool_dict_s *) * mpool->dict_row_num); if (mpool->dict == NULL) { goto err_with_pools; } + memset(mpool->dict, 0, + mpool->dict_row_num * sizeof(struct mpool_dict_s *)); + nxmutex_init(&mpool->dict_lock); + return mpool; err_with_pools: @@ -643,7 +662,20 @@ void mempool_multiple_deinit(FAR struct mempool_multiple_s *mpool) DEBUGVERIFY(mempool_deinit(mpool->pools + i)); } + for (i = 0; i < mpool->dict_row_num; i++) + { + if (mpool->dict[i] != NULL) + { + mpool->free(mpool->arg, mpool->dict[i]); + } + else + { + break; + } + } + mpool->free(mpool->arg, mpool->dict); mpool->free(mpool->arg, mpool->pools); mpool->free(mpool->arg, mpool); + nxmutex_destroy(&mpool->dict_lock); } diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c index 533b5d8231..763c9387a2 100644 --- a/mm/mm_heap/mm_initialize.c +++ b/mm/mm_heap/mm_initialize.c @@ -256,9 +256,10 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name, } 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); + (mempool_multiple_alloc_t)mm_memalign, + (mempool_multiple_free_t)mm_free, heap, + CONFIG_MM_HEAP_MEMPOOL_EXPAND, + CONFIG_MM_HEAP_MEMPOOL_DICTIONARY_EXPAND); #endif return heap; diff --git a/mm/tlsf/mm_tlsf.c b/mm/tlsf/mm_tlsf.c index 0bd36e20dc..308fc1ca2c 100644 --- a/mm/tlsf/mm_tlsf.c +++ b/mm/tlsf/mm_tlsf.c @@ -801,9 +801,10 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name, } 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); + (mempool_multiple_alloc_t)mm_memalign, + (mempool_multiple_free_t)mm_free, heap, + CONFIG_MM_HEAP_MEMPOOL_EXPAND, + CONFIG_MM_HEAP_MEMPOOL_DICTIONARY_EXPAND); #endif return heap;