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;
|
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? */
|
/* What is the size of the freenode? */
|
||||||
|
|
||||||
#define MM_PTR_SIZE sizeof(FAR struct mm_freenode_s *)
|
#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];
|
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 <assert.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/mm/mm.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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -72,11 +95,37 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We need to hold the MM semaphore while we muck with the
|
#ifdef __KERNEL__
|
||||||
* nodelist.
|
/* 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));
|
DEBUGASSERT(mm_heapmember(heap, mem));
|
||||||
|
|
||||||
/* Map the memory chunk into a free node */
|
/* 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;
|
heap->mm_nregions = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
/* Initialize mm_delaylist */
|
||||||
|
|
||||||
|
heap->mm_delaylist.flink = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Initialize the node array */
|
/* Initialize the node array */
|
||||||
|
|
||||||
memset(heap->mm_nodelist, 0, sizeof(struct mm_freenode_s) * MM_NNODES);
|
memset(heap->mm_nodelist, 0, sizeof(struct mm_freenode_s) * MM_NNODES);
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/mm/mm.h>
|
#include <nuttx/mm/mm.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -54,6 +55,45 @@
|
|||||||
# define NULL ((void *)0)
|
# define NULL ((void *)0)
|
||||||
#endif
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -76,6 +116,12 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
|
|||||||
void *ret = NULL;
|
void *ret = NULL;
|
||||||
int ndx;
|
int ndx;
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
/* Firstly, free mm_delaylist */
|
||||||
|
|
||||||
|
mm_free_delaylist(heap);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Ignore zero-length allocations */
|
/* Ignore zero-length allocations */
|
||||||
|
|
||||||
if (size < 1)
|
if (size < 1)
|
||||||
|
Loading…
Reference in New Issue
Block a user