diff --git a/mm/mm_heap/Make.defs b/mm/mm_heap/Make.defs index 8381c89b38..2b7e248023 100644 --- a/mm/mm_heap/Make.defs +++ b/mm/mm_heap/Make.defs @@ -24,7 +24,7 @@ ifeq ($(CONFIG_MM_DEFAULT_MANAGER),y) CSRCS += mm_initialize.c mm_sem.c mm_addfreechunk.c mm_size2ndx.c CSRCS += mm_malloc_size.c mm_shrinkchunk.c mm_brkaddr.c mm_calloc.c -CSRCS += mm_extend.c mm_free.c mm_mallinfo.c mm_malloc.c +CSRCS += mm_extend.c mm_free.c mm_mallinfo.c mm_malloc.c mm_foreach.c CSRCS += mm_memalign.c mm_realloc.c mm_zalloc.c mm_heapmember.c ifeq ($(CONFIG_DEBUG_MM),y) diff --git a/mm/mm_heap/mm.h b/mm/mm_heap/mm.h index 5c7d727522..4726acb29b 100644 --- a/mm/mm_heap/mm.h +++ b/mm/mm_heap/mm.h @@ -209,6 +209,15 @@ struct mm_heap_s #endif }; +/* This describes the callback for mm_foreach */ + +typedef CODE void (*mmchunk_handler_t)(FAR struct mm_allocnode_s *node, + FAR void *arg); + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + /* Functions contained in mm_sem.c ******************************************/ void mm_seminitialize(FAR struct mm_heap_s *heap); @@ -225,8 +234,13 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap, void mm_addfreechunk(FAR struct mm_heap_s *heap, FAR struct mm_freenode_s *node); -/* Functions contained in mm_size2ndx.c.c ***********************************/ +/* Functions contained in mm_size2ndx.c *************************************/ int mm_size2ndx(size_t size); +/* Functions contained in mm_foreach.c **************************************/ + +void mm_foreach(FAR struct mm_heap_s *heap, mmchunk_handler_t handler, + FAR void *arg); + #endif /* __MM_MM_HEAP_MM_H */ diff --git a/mm/mm_heap/mm_foreach.c b/mm/mm_heap/mm_foreach.c new file mode 100644 index 0000000000..25cec561f1 --- /dev/null +++ b/mm/mm_heap/mm_foreach.c @@ -0,0 +1,97 @@ +/**************************************************************************** + * mm/mm_heap/mm_foreach.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "mm_heap/mm.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mm_foreach + * + * Description: + * Visit each node to run handler in heap. + * + ****************************************************************************/ + +void mm_foreach(FAR struct mm_heap_s *heap, mmchunk_handler_t handler, + FAR void *arg) +{ + FAR struct mm_allocnode_s *node; + FAR struct mm_allocnode_s *prev; +#if CONFIG_MM_REGIONS > 1 + int region; +#else +# define region 0 +#endif + + DEBUGASSERT(handler); + + /* Visit each region */ + +#if CONFIG_MM_REGIONS > 1 + for (region = 0; region < heap->mm_nregions; region++) +#endif + { + prev = NULL; + + /* Visit each node in the region + * Retake the semaphore for each region to reduce latencies + */ + + DEBUGVERIFY(mm_takesemaphore(heap)); + + for (node = heap->mm_heapstart[region]; + node < heap->mm_heapend[region]; + node = (FAR struct mm_allocnode_s *) + ((FAR char *)node + node->size)) + { + minfo("region=%d node=%p size=%u preceding=%u (%c)\n", + region, node, (unsigned int)node->size, + (unsigned int)(node->preceding & ~MM_ALLOC_BIT), + (node->preceding & MM_ALLOC_BIT) ? 'A' : 'F'); + + handler(node, arg); + + DEBUGASSERT(prev == NULL || + prev->size == (node->preceding & ~MM_ALLOC_BIT)); + prev = node; + } + + minfo("region=%d node=%p heapend=%p\n", + region, node, heap->mm_heapend[region]); + DEBUGASSERT(node == heap->mm_heapend[region]); + + mm_givesemaphore(heap); + } +#undef region +}