mm/mm_heap: add mm_delaylist to mm_heap_s struct
Change-Id: I2ffaec5557bf2dd2021baa6cda84bb5318425caa Signed-off-by: ligd <liguiding@fishsemi.com>
This commit is contained in:
parent
78eb9f73dd
commit
1d2396353e
@ -224,6 +224,13 @@ struct mm_freenode_s
|
||||
FAR struct mm_freenode_s *blink;
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
struct mm_delaynode_s
|
||||
{
|
||||
struct mm_delaynode_s *flink;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* What is the size of the freenode? */
|
||||
|
||||
#define MM_PTR_SIZE sizeof(FAR struct mm_freenode_s *)
|
||||
@ -263,6 +270,12 @@ struct mm_heap_s
|
||||
*/
|
||||
|
||||
struct mm_freenode_s mm_nodelist[MM_NNODES];
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/* Free delay list, for some situation can't do free immdiately */
|
||||
|
||||
struct mm_delaynode_s mm_delaylist;
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -42,8 +42,31 @@
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/mm/mm.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __KERNEL__
|
||||
static void mm_add_delaylist(FAR struct mm_heap_s *heap, FAR void *mem)
|
||||
{
|
||||
FAR struct mm_delaynode_s *new = mem;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Delay the deallocation until a more appropriate time. */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
new->flink = heap->mm_delaylist.flink;
|
||||
heap->mm_delaylist.flink = new;
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -72,11 +95,37 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
|
||||
return;
|
||||
}
|
||||
|
||||
/* We need to hold the MM semaphore while we muck with the
|
||||
* nodelist.
|
||||
*/
|
||||
#ifdef __KERNEL__
|
||||
/* Check current environment */
|
||||
|
||||
if (up_interrupt_context())
|
||||
{
|
||||
/* We are in ISR, add to mm_delaylist */
|
||||
|
||||
mm_add_delaylist(heap, mem);
|
||||
return;
|
||||
}
|
||||
else if (mm_trysemaphore(heap) == 0)
|
||||
{
|
||||
/* Got the sem, do free immediately */
|
||||
}
|
||||
else if (sched_idletask())
|
||||
{
|
||||
/* We are in IDLE task & can't get sem, add to mm_delaylist */
|
||||
|
||||
mm_add_delaylist(heap, mem);
|
||||
return;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* We need to hold the MM semaphore while we muck with the
|
||||
* nodelist.
|
||||
*/
|
||||
|
||||
mm_takesemaphore(heap);
|
||||
}
|
||||
|
||||
mm_takesemaphore(heap);
|
||||
DEBUGASSERT(mm_heapmember(heap, mem));
|
||||
|
||||
/* Map the memory chunk into a free node */
|
||||
|
@ -175,6 +175,12 @@ void mm_initialize(FAR struct mm_heap_s *heap, FAR void *heapstart,
|
||||
heap->mm_nregions = 0;
|
||||
#endif
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/* Initialize mm_delaylist */
|
||||
|
||||
heap->mm_delaylist.flink = NULL;
|
||||
#endif
|
||||
|
||||
/* Initialize the node array */
|
||||
|
||||
memset(heap->mm_nodelist, 0, sizeof(struct mm_freenode_s) * MM_NNODES);
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <debug.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/mm/mm.h>
|
||||
|
||||
/****************************************************************************
|
||||
@ -54,6 +55,45 @@
|
||||
# define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __KERNEL__
|
||||
static void mm_free_delaylist(FAR struct mm_heap_s *heap)
|
||||
{
|
||||
FAR struct mm_delaynode_s *tmp;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Move the delay list to local */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
tmp = heap->mm_delaylist.flink;
|
||||
heap->mm_delaylist.flink = NULL;
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* Test if the delayed is empty */
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
FAR void *address;
|
||||
|
||||
/* Get the first delayed deallocation */
|
||||
|
||||
address = tmp;
|
||||
tmp = tmp->flink;
|
||||
|
||||
/* The address should always be non-NULL since that was checked in the
|
||||
* 'while' condition above.
|
||||
*/
|
||||
|
||||
mm_free(heap, address);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -76,6 +116,12 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
|
||||
void *ret = NULL;
|
||||
int ndx;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/* Firstly, free mm_delaylist */
|
||||
|
||||
mm_free_delaylist(heap);
|
||||
#endif
|
||||
|
||||
/* Ignore zero-length allocations */
|
||||
|
||||
if (size < 1)
|
||||
|
Loading…
Reference in New Issue
Block a user