You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by je...@apache.org on 2023/01/18 08:02:41 UTC
[nuttx] 02/03: mempool:use two-dimensional array avoid competition
This is an automated email from the ASF dual-hosted git repository.
jerpelea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit d846004533308f6b43fc0059f81e35a2fc5e32ea
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Thu Dec 22 21:18:09 2022 +0800
mempool:use two-dimensional array avoid competition
Signed-off-by: anjiahao <an...@xiaomi.com>
---
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 <strings.h>
+#include <nuttx/mutex.h>
#include <nuttx/kmalloc.h>
#include <nuttx/mm/mempool.h>
@@ -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;