diff --git a/include/nuttx/mm/mm.h b/include/nuttx/mm/mm.h index bc215bda0b8..d32a3464b8b 100644 --- a/include/nuttx/mm/mm.h +++ b/include/nuttx/mm/mm.h @@ -227,7 +227,7 @@ struct mm_freenode_s FAR struct mm_freenode_s *blink; }; -#ifdef __KERNEL__ +#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) struct mm_delaynode_s { struct mm_delaynode_s *flink; @@ -274,10 +274,10 @@ struct mm_heap_s struct mm_freenode_s mm_nodelist[MM_NNODES]; -#ifdef __KERNEL__ +#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) /* Free delay list, for some situation can't do free immdiately */ - struct mm_delaynode_s mm_delaylist; + struct mm_delaynode_s *mm_delaylist; #endif }; diff --git a/mm/mm_heap/mm_free.c b/mm/mm_heap/mm_free.c index fbe093de3b9..bfac73f37bb 100644 --- a/mm/mm_heap/mm_free.c +++ b/mm/mm_heap/mm_free.c @@ -43,25 +43,24 @@ #include #include -#include #include /**************************************************************************** * Private Functions ****************************************************************************/ -#ifdef __KERNEL__ +#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) static void mm_add_delaylist(FAR struct mm_heap_s *heap, FAR void *mem) { - FAR struct mm_delaynode_s *new = mem; + FAR struct mm_delaynode_s *tmp = 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; + tmp->flink = heap->mm_delaylist; + heap->mm_delaylist = tmp; leave_critical_section(flags); } @@ -85,6 +84,9 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem) FAR struct mm_freenode_s *node; FAR struct mm_freenode_s *prev; FAR struct mm_freenode_s *next; +#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) + int ret; +#endif minfo("Freeing %p\n", mem); @@ -95,7 +97,7 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem) return; } -#ifdef __KERNEL__ +#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) /* Check current environment */ if (up_interrupt_context()) @@ -105,13 +107,16 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem) mm_add_delaylist(heap, mem); return; } - else if (mm_trysemaphore(heap) == 0) + else if ((ret = mm_trysemaphore(heap)) == 0) { /* Got the sem, do free immediately */ } - else if (sched_idletask()) + else if (ret == -ESRCH || sched_idletask()) { - /* We are in IDLE task & can't get sem, add to mm_delaylist */ + /* We are in IDLE task & can't get sem, or meet -ESRCH return, + * which means we are in situations during context switching(See + * mm_trysemaphore() & getpid()). Then add to mm_delaylist. + */ mm_add_delaylist(heap, mem); return; diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c index 4b07fde3cd9..d96b7b16b9f 100644 --- a/mm/mm_heap/mm_initialize.c +++ b/mm/mm_heap/mm_initialize.c @@ -175,10 +175,10 @@ void mm_initialize(FAR struct mm_heap_s *heap, FAR void *heapstart, heap->mm_nregions = 0; #endif -#ifdef __KERNEL__ +#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) /* Initialize mm_delaylist */ - heap->mm_delaylist.flink = NULL; + heap->mm_delaylist = NULL; #endif /* Initialize the node array */ diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c index 6310c989521..e83bff84c99 100644 --- a/mm/mm_heap/mm_malloc.c +++ b/mm/mm_heap/mm_malloc.c @@ -59,7 +59,7 @@ * Private Functions ****************************************************************************/ -#ifdef __KERNEL__ +#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) static void mm_free_delaylist(FAR struct mm_heap_s *heap) { FAR struct mm_delaynode_s *tmp; @@ -69,8 +69,8 @@ static void mm_free_delaylist(FAR struct mm_heap_s *heap) flags = enter_critical_section(); - tmp = heap->mm_delaylist.flink; - heap->mm_delaylist.flink = NULL; + tmp = heap->mm_delaylist; + heap->mm_delaylist = NULL; leave_critical_section(flags); @@ -116,7 +116,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size) void *ret = NULL; int ndx; -#ifdef __KERNEL__ +#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) /* Firstly, free mm_delaylist */ mm_free_delaylist(heap);