mirror of
https://github.com/apache/nuttx.git
synced 2026-05-30 21:36:28 +08:00
Optimize multipe mempool memory space usage
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
This commit is contained in:
@@ -354,10 +354,14 @@ FAR void *mempool_multiple_realloc(FAR struct mempool_multiple_s *mpool,
|
|||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* mpool - The handle of multiple memory pool to be used.
|
* mpool - The handle of multiple memory pool to be used.
|
||||||
* blk - The pointer of memory block.
|
* blk - The pointer of memory block.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; Negative number mean the block doesn't come from pool.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
|
int mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
|
||||||
FAR void *blk);
|
FAR void *blk);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mempool_multiple_alloc_size
|
* Name: mempool_multiple_alloc_size
|
||||||
@@ -370,12 +374,13 @@ void mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
|
|||||||
* blk - The pointer of memory block.
|
* blk - The pointer of memory block.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* The size of memory block.
|
* The size of memory block on success. Negative number mean the block
|
||||||
|
* doesn't come from pool.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
size_t mempool_multiple_alloc_size(FAR struct mempool_multiple_s *mpool,
|
ssize_t mempool_multiple_alloc_size(FAR struct mempool_multiple_s *mpool,
|
||||||
FAR void *blk);
|
FAR void *blk);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mempool_multiple_memalign
|
* Name: mempool_multiple_memalign
|
||||||
|
|||||||
+1
-1
@@ -190,7 +190,7 @@ config MM_HEAP_MEMPOOL_THRESHOLD
|
|||||||
|
|
||||||
config MM_HEAP_MEMPOOL_EXPAND
|
config MM_HEAP_MEMPOOL_EXPAND
|
||||||
int "The expand size for each mempool in multiple mempool"
|
int "The expand size for each mempool in multiple mempool"
|
||||||
default 1024
|
default 4096
|
||||||
depends on MM_HEAP_MEMPOOL_THRESHOLD != 0
|
depends on MM_HEAP_MEMPOOL_THRESHOLD != 0
|
||||||
---help---
|
---help---
|
||||||
This size describes the size of each expansion of each memory
|
This size describes the size of each expansion of each memory
|
||||||
|
|||||||
@@ -38,9 +38,8 @@
|
|||||||
# define MM_PTR_FMT_WIDTH 19
|
# define MM_PTR_FMT_WIDTH 19
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ALIGN_UP
|
#undef ALIGN_UP
|
||||||
# define ALIGN_UP(x, a) (((x) + ((a) - 1)) & (~((a) - 1)))
|
#define ALIGN_UP(x, a) (((x) + ((a) - 1)) & (~((a) - 1)))
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
|
|||||||
+225
-76
@@ -29,21 +29,36 @@
|
|||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define SIZEOF_HEAD sizeof(FAR struct mempool_s *)
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
#undef ALIGN_UP
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
#define ALIGN_UP(x, a) ((((size_t)x) + ((a) - 1)) & (~((a) - 1)))
|
||||||
#define ALIGN_BIT (1 << 1)
|
#undef ALIGN_DOWN
|
||||||
|
#define ALIGN_DOWN(x, a) ((size_t)(x) & (~((a) - 1)))
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct mpool_dict_s
|
||||||
|
{
|
||||||
|
FAR struct mempool_s *pool; /* Record pool when expanding */
|
||||||
|
FAR void *addr; /* Record expand memary address */
|
||||||
|
size_t size; /* Record expand memary size */
|
||||||
|
};
|
||||||
|
|
||||||
struct mempool_multiple_s
|
struct mempool_multiple_s
|
||||||
{
|
{
|
||||||
FAR struct mempool_s * pools; /* The memory pool array */
|
FAR struct mempool_s * pools; /* The memory pool array */
|
||||||
size_t npools; /* The number of memory pool array elements */
|
size_t npools; /* The number of memory pool array elements */
|
||||||
|
size_t expandsize; /* The number not will use it to init erery
|
||||||
FAR void *arg; /* This pointer is used to store the user's
|
* pool expandsize
|
||||||
* private data
|
*/
|
||||||
*/
|
size_t minpoolsize; /* The number is align for each memory pool */
|
||||||
mempool_multiple_alloc_t alloc; /* The alloc function for mempool */
|
FAR void *arg; /* This pointer is used to store the user's
|
||||||
mempool_multiple_free_t free; /* The free function for mempool */
|
* 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
|
/* This delta describes the relationship between the block size of each
|
||||||
* mempool in multiple mempool by user initialized. It is automatically
|
* mempool in multiple mempool by user initialized. It is automatically
|
||||||
@@ -53,6 +68,14 @@ struct mempool_multiple_s
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
size_t delta;
|
size_t delta;
|
||||||
|
|
||||||
|
/* It is used to record the information recorded by the mempool during
|
||||||
|
* expansion, and find the mempool by adding an index
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t dict_alloc;
|
||||||
|
size_t dict_used;
|
||||||
|
FAR struct mpool_dict_s *dict;
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -75,6 +98,11 @@ mempool_multiple_find(FAR struct mempool_multiple_s *mpool, size_t size)
|
|||||||
if (mpool->delta != 0)
|
if (mpool->delta != 0)
|
||||||
{
|
{
|
||||||
left = mpool->pools[0].blocksize;
|
left = mpool->pools[0].blocksize;
|
||||||
|
if (left >= size)
|
||||||
|
{
|
||||||
|
return &mpool->pools[0];
|
||||||
|
}
|
||||||
|
|
||||||
mid = (size - left + mpool->delta - 1) / mpool->delta;
|
mid = (size - left + mpool->delta - 1) / mpool->delta;
|
||||||
return mid < right ? &mpool->pools[mid] : NULL;
|
return mid < right ? &mpool->pools[mid] : NULL;
|
||||||
}
|
}
|
||||||
@@ -100,6 +128,95 @@ mempool_multiple_find(FAR struct mempool_multiple_s *mpool, size_t size)
|
|||||||
return &mpool->pools[left];
|
return &mpool->pools[left];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FAR void *mempool_multiple_alloc_callback(FAR struct mempool_s *pool,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mpool->alloc(mpool->arg, mpool->expandsize,
|
||||||
|
mpool->minpoolsize + size);
|
||||||
|
if (ret == NULL)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
*(FAR size_t *)ret = mpool->dict_used++;
|
||||||
|
return (FAR char *)ret + mpool->minpoolsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mempool_multiple_free_callback(FAR struct mempool_s *pool,
|
||||||
|
FAR void *addr)
|
||||||
|
{
|
||||||
|
FAR struct mempool_multiple_s *mpool = pool->priv;
|
||||||
|
|
||||||
|
return mpool->free(mpool->arg, (FAR char *)addr - mpool->minpoolsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mempool_multiple_get_dict
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Obtain the dict through mpool and blk
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mpool - The handle of the multiple memory pool to be used.
|
||||||
|
* blk - The pointer of memory block.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Address of the dict to be used or NULL is not find.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static FAR struct mpool_dict_s *
|
||||||
|
mempool_multiple_get_dict(FAR struct mempool_multiple_s *mpool,
|
||||||
|
FAR void *blk)
|
||||||
|
{
|
||||||
|
FAR void *addr;
|
||||||
|
size_t index;
|
||||||
|
|
||||||
|
if (mpool == NULL || blk == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = (FAR void *)ALIGN_DOWN(blk, mpool->expandsize);
|
||||||
|
|
||||||
|
index = *(FAR size_t *)addr;
|
||||||
|
if (index >= mpool->dict_used)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mpool->dict[index].addr != addr ||
|
||||||
|
blk - addr >= mpool->dict[index].size)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &mpool->dict[index];
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -141,9 +258,31 @@ mempool_multiple_init(FAR const char *name,
|
|||||||
{
|
{
|
||||||
FAR struct mempool_multiple_s *mpool;
|
FAR struct mempool_multiple_s *mpool;
|
||||||
FAR struct mempool_s *pools;
|
FAR struct mempool_s *pools;
|
||||||
|
size_t maxpoolszie;
|
||||||
|
size_t minpoolsize;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (expandsize & (expandsize - 1))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxpoolszie = poolsize[0];
|
||||||
|
minpoolsize = poolsize[0];
|
||||||
|
for (i = 0; i < npools; i++)
|
||||||
|
{
|
||||||
|
if (maxpoolszie < poolsize[i])
|
||||||
|
{
|
||||||
|
maxpoolszie = poolsize[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minpoolsize > poolsize[i])
|
||||||
|
{
|
||||||
|
minpoolsize = poolsize[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mpool = alloc(arg, sizeof(uintptr_t), sizeof(struct mempool_multiple_s));
|
mpool = alloc(arg, sizeof(uintptr_t), sizeof(struct mempool_multiple_s));
|
||||||
if (mpool == NULL)
|
if (mpool == NULL)
|
||||||
{
|
{
|
||||||
@@ -159,6 +298,8 @@ mempool_multiple_init(FAR const char *name,
|
|||||||
|
|
||||||
mpool->pools = pools;
|
mpool->pools = pools;
|
||||||
mpool->npools = npools;
|
mpool->npools = npools;
|
||||||
|
mpool->expandsize = expandsize;
|
||||||
|
mpool->minpoolsize = minpoolsize;
|
||||||
mpool->alloc = alloc;
|
mpool->alloc = alloc;
|
||||||
mpool->free = free;
|
mpool->free = free;
|
||||||
mpool->arg = arg;
|
mpool->arg = arg;
|
||||||
@@ -166,17 +307,16 @@ mempool_multiple_init(FAR const char *name,
|
|||||||
for (i = 0; i < npools; i++)
|
for (i = 0; i < npools; i++)
|
||||||
{
|
{
|
||||||
pools[i].blocksize = poolsize[i];
|
pools[i].blocksize = poolsize[i];
|
||||||
pools[i].expandsize = expandsize;
|
pools[i].expandsize = expandsize - mpool->minpoolsize;
|
||||||
pools[i].initialsize = 0;
|
pools[i].initialsize = 0;
|
||||||
pools[i].interruptsize = 0;
|
pools[i].interruptsize = 0;
|
||||||
|
pools[i].priv = mpool;
|
||||||
|
pools[i].alloc = mempool_multiple_alloc_callback;
|
||||||
|
pools[i].free = mempool_multiple_free_callback;
|
||||||
|
|
||||||
ret = mempool_init(pools + i, name);
|
ret = mempool_init(pools + i, name);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
while (--i >= 0)
|
|
||||||
{
|
|
||||||
mempool_deinit(pools + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto err_with_pools;
|
goto err_with_pools;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,9 +335,23 @@ 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));
|
||||||
|
if (mpool->dict == NULL)
|
||||||
|
{
|
||||||
|
goto err_with_pools;
|
||||||
|
}
|
||||||
|
|
||||||
return mpool;
|
return mpool;
|
||||||
|
|
||||||
err_with_pools:
|
err_with_pools:
|
||||||
|
while (--i >= 0)
|
||||||
|
{
|
||||||
|
mempool_deinit(pools + i);
|
||||||
|
}
|
||||||
|
|
||||||
free(arg, pools);
|
free(arg, pools);
|
||||||
err_with_mpool:
|
err_with_mpool:
|
||||||
free(arg, mpool);
|
free(arg, mpool);
|
||||||
@@ -225,22 +379,28 @@ err_with_mpool:
|
|||||||
FAR void *mempool_multiple_alloc(FAR struct mempool_multiple_s *mpool,
|
FAR void *mempool_multiple_alloc(FAR struct mempool_multiple_s *mpool,
|
||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
FAR struct mempool_s *end = mpool->pools + mpool->npools;
|
FAR struct mempool_s *end;
|
||||||
FAR struct mempool_s *pool;
|
FAR struct mempool_s *pool;
|
||||||
|
|
||||||
pool = mempool_multiple_find(mpool, size + SIZEOF_HEAD);
|
if (size < 1)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pool = mempool_multiple_find(mpool, size);
|
||||||
if (pool == NULL)
|
if (pool == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end = mpool->pools + mpool->npools;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
FAR void *blk = mempool_alloc(pool);
|
FAR void *blk = mempool_alloc(pool);
|
||||||
if (blk != NULL)
|
|
||||||
|
if (blk)
|
||||||
{
|
{
|
||||||
*(FAR struct mempool_s **)blk = pool;
|
return blk;
|
||||||
return (FAR char *)blk + SIZEOF_HEAD;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (++pool < end);
|
while (++pool < end);
|
||||||
@@ -267,33 +427,30 @@ FAR void *mempool_multiple_alloc(FAR struct mempool_multiple_s *mpool,
|
|||||||
FAR void *mempool_multiple_realloc(FAR struct mempool_multiple_s *mpool,
|
FAR void *mempool_multiple_realloc(FAR struct mempool_multiple_s *mpool,
|
||||||
FAR void *oldblk, size_t size)
|
FAR void *oldblk, size_t size)
|
||||||
{
|
{
|
||||||
|
FAR struct mpool_dict_s *dict;
|
||||||
FAR void *blk;
|
FAR void *blk;
|
||||||
|
|
||||||
|
if (oldblk == NULL)
|
||||||
|
{
|
||||||
|
return mempool_multiple_alloc(mpool, size);
|
||||||
|
}
|
||||||
|
|
||||||
if (size < 1)
|
if (size < 1)
|
||||||
{
|
{
|
||||||
mempool_multiple_free(mpool, oldblk);
|
mempool_multiple_free(mpool, oldblk);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dict = mempool_multiple_get_dict(mpool, oldblk);
|
||||||
|
if (dict == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
blk = mempool_multiple_alloc(mpool, size);
|
blk = mempool_multiple_alloc(mpool, size);
|
||||||
if (blk != NULL && oldblk != NULL)
|
if (blk != NULL && oldblk != NULL)
|
||||||
{
|
{
|
||||||
FAR struct mempool_s *oldpool;
|
size = MIN(size, dict->pool->blocksize);
|
||||||
|
|
||||||
oldpool = *(FAR struct mempool_s **)
|
|
||||||
((FAR char *)oldblk - SIZEOF_HEAD);
|
|
||||||
if ((uintptr_t)oldpool & ALIGN_BIT)
|
|
||||||
{
|
|
||||||
oldpool = (FAR struct mempool_s *)
|
|
||||||
((uintptr_t)oldpool & ~ALIGN_BIT);
|
|
||||||
size = MIN(size, oldpool->blocksize -
|
|
||||||
*(FAR size_t *)((FAR char *)oldblk - 2 * SIZEOF_HEAD));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size = MIN(size, oldpool->blocksize - SIZEOF_HEAD);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(blk, oldblk, size);
|
memcpy(blk, oldblk, size);
|
||||||
mempool_multiple_free(mpool, oldblk);
|
mempool_multiple_free(mpool, oldblk);
|
||||||
}
|
}
|
||||||
@@ -311,25 +468,28 @@ FAR void *mempool_multiple_realloc(FAR struct mempool_multiple_s *mpool,
|
|||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* mpool - The handle of multiple memory pool to be used.
|
* mpool - The handle of multiple memory pool to be used.
|
||||||
* blk - The pointer of memory block.
|
* blk - The pointer of memory block.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; Negative number on any failure.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
|
int mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
|
||||||
FAR void *blk)
|
FAR void *blk)
|
||||||
{
|
{
|
||||||
FAR struct mempool_s *pool;
|
FAR struct mpool_dict_s *dict;
|
||||||
FAR char *mem;
|
|
||||||
|
|
||||||
DEBUGASSERT(mpool != NULL && blk != NULL);
|
dict = mempool_multiple_get_dict(mpool, blk);
|
||||||
|
if (dict == NULL)
|
||||||
mem = (FAR char *)blk - SIZEOF_HEAD;
|
|
||||||
pool = *(FAR struct mempool_s **)mem;
|
|
||||||
if ((uintptr_t)pool & ALIGN_BIT)
|
|
||||||
{
|
{
|
||||||
pool = (FAR struct mempool_s *)((uintptr_t)pool & ~ALIGN_BIT);
|
return -EINVAL;
|
||||||
mem = (FAR char *)blk - *(FAR size_t *)(mem - SIZEOF_HEAD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mempool_free(pool, mem);
|
blk = (FAR char *)blk - (((FAR char *)blk -
|
||||||
|
((FAR char *)dict->addr + mpool->minpoolsize)) %
|
||||||
|
dict->pool->blocksize);
|
||||||
|
mempool_free(dict->pool, blk);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -343,29 +503,24 @@ void mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
|
|||||||
* blk - The pointer of memory block.
|
* blk - The pointer of memory block.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* The size of memory block.
|
* The size of memory block on success. Negative number on any failure.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
size_t mempool_multiple_alloc_size(FAR struct mempool_multiple_s *mpool,
|
ssize_t mempool_multiple_alloc_size(FAR struct mempool_multiple_s *mpool,
|
||||||
FAR void *blk)
|
FAR void *blk)
|
||||||
{
|
{
|
||||||
FAR struct mempool_s *pool;
|
FAR struct mpool_dict_s *dict;
|
||||||
FAR char *mem;
|
|
||||||
|
|
||||||
DEBUGASSERT(blk != NULL);
|
DEBUGASSERT(blk != NULL);
|
||||||
|
|
||||||
mem = (FAR char *)blk - SIZEOF_HEAD;
|
dict = mempool_multiple_get_dict(mpool, blk);
|
||||||
pool = *(FAR struct mempool_s **)mem;
|
if (dict == NULL)
|
||||||
if ((uintptr_t)pool & ALIGN_BIT)
|
|
||||||
{
|
{
|
||||||
pool = (FAR struct mempool_s *)((uintptr_t)pool & ~ALIGN_BIT);
|
return -EINVAL;
|
||||||
return pool->blocksize - *(FAR size_t *)(mem - SIZEOF_HEAD);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return pool->blocksize - SIZEOF_HEAD;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return dict->pool->blocksize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -398,31 +553,24 @@ size_t mempool_multiple_alloc_size(FAR struct mempool_multiple_s *mpool,
|
|||||||
FAR void *mempool_multiple_memalign(FAR struct mempool_multiple_s *mpool,
|
FAR void *mempool_multiple_memalign(FAR struct mempool_multiple_s *mpool,
|
||||||
size_t alignment, size_t size)
|
size_t alignment, size_t size)
|
||||||
{
|
{
|
||||||
FAR struct mempool_s *end = mpool->pools + mpool->npools;
|
FAR struct mempool_s *end;
|
||||||
FAR struct mempool_s *pool;
|
FAR struct mempool_s *pool;
|
||||||
|
|
||||||
DEBUGASSERT((alignment & (alignment - 1)) == 0);
|
DEBUGASSERT((alignment & (alignment - 1)) == 0);
|
||||||
|
|
||||||
pool = mempool_multiple_find(mpool, size + alignment + 2 * SIZEOF_HEAD);
|
pool = mempool_multiple_find(mpool, size + alignment);
|
||||||
if (pool == NULL)
|
if (pool == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end = mpool->pools + mpool->npools;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
FAR char *blk = mempool_alloc(pool);
|
FAR char *blk = mempool_alloc(pool);
|
||||||
if (blk != NULL)
|
if (blk != NULL)
|
||||||
{
|
{
|
||||||
FAR char *mem;
|
return (FAR void *)ALIGN_UP(blk, alignment);
|
||||||
|
|
||||||
mem = blk + 2 * SIZEOF_HEAD;
|
|
||||||
mem = (FAR char *)(((uintptr_t)mem + alignment - 1) &
|
|
||||||
~(alignment - 1));
|
|
||||||
*(FAR uintptr_t *)(mem - SIZEOF_HEAD) =
|
|
||||||
(uintptr_t)pool | ALIGN_BIT;
|
|
||||||
*(FAR size_t *)(mem - 2 * SIZEOF_HEAD) = mem - blk;
|
|
||||||
return mem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (++pool < end);
|
while (++pool < end);
|
||||||
@@ -495,6 +643,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->dict);
|
||||||
mpool->free(mpool->arg, mpool->pools);
|
mpool->free(mpool->arg, mpool->pools);
|
||||||
mpool->free(mpool->arg, mpool);
|
mpool->free(mpool->arg, mpool);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,11 +134,6 @@
|
|||||||
|
|
||||||
#define SIZEOF_MM_FREENODE sizeof(struct mm_freenode_s)
|
#define SIZEOF_MM_FREENODE sizeof(struct mm_freenode_s)
|
||||||
|
|
||||||
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
|
|
||||||
# define MM_IS_FROM_MEMPOOL(mem) \
|
|
||||||
((*((FAR mmsize_t *)mem - 1) & MM_ALLOC_BIT) == 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|||||||
@@ -83,9 +83,8 @@ 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 (mempool_multiple_free(heap->mm_mpool, mem) >= 0)
|
||||||
{
|
{
|
||||||
mempool_multiple_free(heap->mm_mpool, mem);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -38,6 +38,14 @@
|
|||||||
size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
|
size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
|
||||||
{
|
{
|
||||||
FAR struct mm_freenode_s *node;
|
FAR struct mm_freenode_s *node;
|
||||||
|
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
|
||||||
|
ssize_t size = mempool_multiple_alloc_size(heap->mm_mpool, mem);
|
||||||
|
|
||||||
|
if (size >= 0)
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Protect against attempts to query a NULL reference */
|
/* Protect against attempts to query a NULL reference */
|
||||||
|
|
||||||
@@ -46,13 +54,6 @@ size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
|
|
||||||
if (MM_IS_FROM_MEMPOOL(mem))
|
|
||||||
{
|
|
||||||
return mempool_multiple_alloc_size(heap->mm_mpool, mem);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Map the memory chunk into a free node */
|
/* Map the memory chunk into a free node */
|
||||||
|
|
||||||
node = (FAR struct mm_freenode_s *)((FAR char *)mem - SIZEOF_MM_ALLOCNODE);
|
node = (FAR struct mm_freenode_s *)((FAR char *)mem - SIZEOF_MM_ALLOCNODE);
|
||||||
|
|||||||
+8
-20
@@ -95,30 +95,18 @@ 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))
|
newmem = mempool_multiple_realloc(heap->mm_mpool, oldmem, size);
|
||||||
|
if (newmem != NULL)
|
||||||
|
{
|
||||||
|
return newmem;
|
||||||
|
}
|
||||||
|
else if (size <= CONFIG_MM_HEAP_MEMPOOL_THRESHOLD ||
|
||||||
|
mempool_multiple_alloc_size(heap->mm_mpool, oldmem) >= 0)
|
||||||
{
|
{
|
||||||
newmem = mempool_multiple_realloc(heap->mm_mpool, oldmem, size);
|
|
||||||
if (newmem != NULL)
|
|
||||||
{
|
|
||||||
return newmem;
|
|
||||||
}
|
|
||||||
|
|
||||||
newmem = mm_malloc(heap, size);
|
newmem = mm_malloc(heap, size);
|
||||||
if (newmem != NULL)
|
if (newmem != NULL)
|
||||||
{
|
{
|
||||||
memcpy(newmem, oldmem,
|
memcpy(newmem, oldmem, size);
|
||||||
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);
|
|
||||||
if (newmem != NULL)
|
|
||||||
{
|
|
||||||
memcpy(newmem, oldmem, MIN(size, mm_malloc_size(heap, oldmem)));
|
|
||||||
mm_free(heap, oldmem);
|
mm_free(heap, oldmem);
|
||||||
return newmem;
|
return newmem;
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-28
@@ -56,12 +56,6 @@
|
|||||||
|
|
||||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||||
|
|
||||||
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
|
|
||||||
# define MM_MPOOL_BIT (1 << 0)
|
|
||||||
# define MM_IS_FROM_MEMPOOL(mem) \
|
|
||||||
((*((FAR size_t *)(mem) - 1)) & MM_MPOOL_BIT) == 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
|
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
|
||||||
# define MEMPOOL_NPOOLS (CONFIG_MM_HEAP_MEMPOOL_THRESHOLD / tlsf_align_size())
|
# define MEMPOOL_NPOOLS (CONFIG_MM_HEAP_MEMPOOL_THRESHOLD / tlsf_align_size())
|
||||||
#endif
|
#endif
|
||||||
@@ -654,9 +648,8 @@ 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 (mempool_multiple_free(heap->mm_mpool, mem) >= 0)
|
||||||
{
|
{
|
||||||
mempool_multiple_free(heap->mm_mpool, mem);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -954,9 +947,10 @@ void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid)
|
|||||||
size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
|
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))
|
ssize_t size = mempool_multiple_alloc_size(heap->mm_mpool, mem);
|
||||||
|
if (size >= 0)
|
||||||
{
|
{
|
||||||
return mempool_multiple_alloc_size(heap->mm_mpool, mem);
|
return size;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1113,29 +1107,18 @@ 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))
|
newmem = mempool_multiple_realloc(heap->mm_mpool, oldmem, size);
|
||||||
|
if (newmem != NULL)
|
||||||
{
|
{
|
||||||
newmem = mempool_multiple_realloc(heap->mm_mpool, oldmem, size);
|
|
||||||
if (newmem != NULL)
|
|
||||||
{
|
|
||||||
return newmem;
|
|
||||||
}
|
|
||||||
|
|
||||||
newmem = mm_malloc(heap, size);
|
|
||||||
if (newmem != NULL)
|
|
||||||
{
|
|
||||||
memcpy(newmem, oldmem, size);
|
|
||||||
mempool_multiple_free(heap->mm_mpool, oldmem);
|
|
||||||
}
|
|
||||||
|
|
||||||
return newmem;
|
return newmem;
|
||||||
}
|
}
|
||||||
else
|
else if (size <= CONFIG_MM_HEAP_MEMPOOL_THRESHOLD ||
|
||||||
|
mempool_multiple_alloc_size(heap->mm_mpool, oldmem) >= 0)
|
||||||
{
|
{
|
||||||
newmem = mempool_multiple_alloc(heap->mm_mpool, size);
|
newmem = mm_malloc(heap, size);
|
||||||
if (newmem != NULL)
|
if (newmem != 0)
|
||||||
{
|
{
|
||||||
memcpy(newmem, oldmem, MIN(size, mm_malloc_size(heap, oldmem)));
|
memcpy(newmem, oldmem, size);
|
||||||
mm_free(heap, oldmem);
|
mm_free(heap, oldmem);
|
||||||
return newmem;
|
return newmem;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user