mm/tlsf:add mempool to optimize small block perfomance
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
This commit is contained in:
parent
bdcb1f6a25
commit
cb404167a7
@ -38,6 +38,7 @@
|
|||||||
#include <nuttx/fs/procfs.h>
|
#include <nuttx/fs/procfs.h>
|
||||||
#include <nuttx/mutex.h>
|
#include <nuttx/mutex.h>
|
||||||
#include <nuttx/mm/mm.h>
|
#include <nuttx/mm/mm.h>
|
||||||
|
#include <nuttx/mm/mempool.h>
|
||||||
|
|
||||||
#include "tlsf/tlsf.h"
|
#include "tlsf/tlsf.h"
|
||||||
#include "kasan/kasan.h"
|
#include "kasan/kasan.h"
|
||||||
@ -52,6 +53,14 @@
|
|||||||
# define MM_PTR_FMT_WIDTH 19
|
# define MM_PTR_FMT_WIDTH 19
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -84,6 +93,14 @@ struct mm_heap_s
|
|||||||
|
|
||||||
tlsf_t mm_tlsf; /* The tlfs context */
|
tlsf_t mm_tlsf; /* The tlfs context */
|
||||||
|
|
||||||
|
/* 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)];
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Free delay list, for some situation can't do free immdiately */
|
/* Free delay list, for some situation can't do free immdiately */
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
@ -617,6 +634,14 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
|
||||||
|
if (MM_IS_FROM_MEMPOOL(mem))
|
||||||
|
{
|
||||||
|
mempool_multiple_free(&heap->mm_mpool, mem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mm_lock(heap) == 0)
|
if (mm_lock(heap) == 0)
|
||||||
{
|
{
|
||||||
kasan_poison(mem, mm_malloc_size(mem));
|
kasan_poison(mem, mm_malloc_size(mem));
|
||||||
@ -714,6 +739,9 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
|
|||||||
FAR void *heapstart, size_t heapsize)
|
FAR void *heapstart, size_t heapsize)
|
||||||
{
|
{
|
||||||
FAR struct mm_heap_s *heap;
|
FAR struct mm_heap_s *heap;
|
||||||
|
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
|
||||||
|
int i;
|
||||||
|
#endif
|
||||||
|
|
||||||
minfo("Heap: name=%s start=%p size=%zu\n", name, heapstart, heapsize);
|
minfo("Heap: name=%s start=%p size=%zu\n", name, heapstart, heapsize);
|
||||||
|
|
||||||
@ -725,6 +753,20 @@ 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());
|
||||||
@ -887,6 +929,13 @@ void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid)
|
|||||||
|
|
||||||
size_t mm_malloc_size(FAR void *mem)
|
size_t mm_malloc_size(FAR void *mem)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
|
||||||
|
if (MM_IS_FROM_MEMPOOL(mem))
|
||||||
|
{
|
||||||
|
return mempool_multiple_alloc_size(mem);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_MM_BACKTRACE >= 0
|
#if CONFIG_MM_BACKTRACE >= 0
|
||||||
return tlsf_block_size(mem) - sizeof(struct memdump_backtrace_s);
|
return tlsf_block_size(mem) - sizeof(struct memdump_backtrace_s);
|
||||||
#else
|
#else
|
||||||
@ -909,6 +958,14 @@ 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
|
||||||
|
ret = mempool_multiple_alloc(&heap->mm_mpool, size);
|
||||||
|
if (ret != NULL)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Free the delay list first */
|
/* Free the delay list first */
|
||||||
|
|
||||||
free_delaylist(heap);
|
free_delaylist(heap);
|
||||||
@ -956,6 +1013,14 @@ 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
|
||||||
|
ret = mempool_multiple_memalign(&heap->mm_mpool, alignment, size);
|
||||||
|
if (ret != NULL)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Free the delay list first */
|
/* Free the delay list first */
|
||||||
|
|
||||||
free_delaylist(heap);
|
free_delaylist(heap);
|
||||||
@ -1012,7 +1077,6 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
|
|||||||
{
|
{
|
||||||
FAR void *newmem;
|
FAR void *newmem;
|
||||||
|
|
||||||
#ifdef CONFIG_MM_KASAN
|
|
||||||
if (oldmem == NULL)
|
if (oldmem == NULL)
|
||||||
{
|
{
|
||||||
return mm_malloc(heap, size);
|
return mm_malloc(heap, size);
|
||||||
@ -1024,6 +1088,38 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
newmem = mm_malloc(heap, size);
|
||||||
|
if (newmem != NULL)
|
||||||
|
{
|
||||||
|
memcpy(newmem, oldmem, size);
|
||||||
|
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(oldmem)));
|
||||||
|
mm_free(heap, oldmem);
|
||||||
|
return newmem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_MM_KASAN
|
||||||
|
|
||||||
newmem = mm_malloc(heap, size);
|
newmem = mm_malloc(heap, size);
|
||||||
if (newmem)
|
if (newmem)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user