3535
3636#define RT_MEMHEAP_SIZE RT_ALIGN(sizeof(struct rt_memheap_item), RT_ALIGN_SIZE)
3737#define MEMITEM_SIZE (item ) ((rt_ubase_t)item->next - (rt_ubase_t)item - RT_MEMHEAP_SIZE)
38+ #define MEMITEM (ptr ) (struct rt_memheap_item*)((rt_uint8_t*)ptr - RT_MEMHEAP_SIZE)
39+
40+ #ifdef RT_USING_MEMTRACE
41+ rt_inline void rt_memheap_setname (struct rt_memheap_item * item , const char * name )
42+ {
43+ int index ;
44+ rt_uint8_t * ptr ;
45+
46+ ptr = (rt_uint8_t * )& (item -> next_free );
47+ for (index = 0 ; index < sizeof (void * ); index ++ )
48+ {
49+ if (name [index ] == '\0' ) break ;
50+ ptr [index ] = name [index ];
51+ }
52+ if (name [index ] == '\0' ) ptr [index ] = '\0' ;
53+ else
54+ {
55+ ptr = (rt_uint8_t * )& (item -> prev_free );
56+ for (index = 0 ; index < sizeof (void * ) && (index + sizeof (void * ))< RT_NAME_MAX ; index ++ )
57+ {
58+ if (name [sizeof (void * ) + index ] == '\0' ) break ;
59+ ptr [index ] = name [sizeof (void * ) + index ];
60+ }
61+
62+ if (name [sizeof (void * ) + index ] == '\0' ) ptr [index ] = '\0' ;
63+ }
64+ }
65+
66+ void rt_mem_set_tag (void * ptr , const char * name )
67+ {
68+ struct rt_memheap_item * item ;
69+
70+ if (ptr && name )
71+ {
72+ item = MEMITEM (ptr );
73+ rt_memheap_setname (item , name );
74+ }
75+ }
76+ #endif
3877
3978/*
4079 * The initialized memory pool will be:
@@ -66,7 +105,7 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap,
66105
67106 /* initialize the free list header */
68107 item = & (memheap -> free_header );
69- item -> magic = RT_MEMHEAP_MAGIC ;
108+ item -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED ) ;
70109 item -> pool_ptr = memheap ;
71110 item -> next = RT_NULL ;
72111 item -> prev = RT_NULL ;
@@ -78,7 +117,7 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap,
78117
79118 /* initialize the first big memory block */
80119 item = (struct rt_memheap_item * )start_addr ;
81- item -> magic = RT_MEMHEAP_MAGIC ;
120+ item -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED ) ;
82121 item -> pool_ptr = memheap ;
83122 item -> next = RT_NULL ;
84123 item -> prev = RT_NULL ;
@@ -103,7 +142,7 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap,
103142 */
104143 item = item -> next ;
105144 /* it's a used memory block */
106- item -> magic = RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED ;
145+ item -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED ) ;
107146 item -> pool_ptr = memheap ;
108147 item -> next = (struct rt_memheap_item * )start_addr ;
109148 item -> prev = (struct rt_memheap_item * )start_addr ;
@@ -201,7 +240,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_size_t size)
201240 new_ptr ));
202241
203242 /* mark the new block as a memory block and freed. */
204- new_ptr -> magic = RT_MEMHEAP_MAGIC ;
243+ new_ptr -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED ) ;
205244
206245 /* put the pool pointer into the new block. */
207246 new_ptr -> pool_ptr = heap ;
@@ -255,7 +294,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_size_t size)
255294 }
256295
257296 /* Mark the allocated block as not available. */
258- header_ptr -> magic |= RT_MEMHEAP_USED ;
297+ header_ptr -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED ) ;
259298
260299 /* release lock */
261300 rt_sem_release (& (heap -> lock ));
@@ -376,7 +415,7 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
376415 next_ptr -> prev ));
377416
378417 /* mark the new block as a memory block and freed. */
379- next_ptr -> magic = RT_MEMHEAP_MAGIC ;
418+ next_ptr -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED ) ;
380419
381420 /* put the pool pointer into the new block. */
382421 next_ptr -> pool_ptr = heap ;
@@ -441,7 +480,7 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
441480 new_ptr ));
442481
443482 /* mark the new block as a memory block and freed. */
444- new_ptr -> magic = RT_MEMHEAP_MAGIC ;
483+ new_ptr -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED ) ;
445484 /* put the pool pointer into the new block. */
446485 new_ptr -> pool_ptr = heap ;
447486
@@ -512,8 +551,11 @@ void rt_memheap_free(void *ptr)
512551 ptr , header_ptr ));
513552
514553 /* check magic */
515- RT_ASSERT ((header_ptr -> magic & RT_MEMHEAP_MASK ) == RT_MEMHEAP_MAGIC );
516- RT_ASSERT (header_ptr -> magic & RT_MEMHEAP_USED );
554+ if (header_ptr -> magic != (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED ))
555+ {
556+ RT_DEBUG_LOG ("bad magic:0x%08x @ memheap\n" , header_ptr -> magic );
557+ }
558+ RT_ASSERT (header_ptr -> magic == (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED ));
517559 /* check whether this block of memory has been over-written. */
518560 RT_ASSERT ((header_ptr -> next -> magic & RT_MEMHEAP_MASK ) == RT_MEMHEAP_MAGIC );
519561
@@ -533,9 +575,9 @@ void rt_memheap_free(void *ptr)
533575 }
534576
535577 /* Mark the memory as available. */
536- header_ptr -> magic &= ~ RT_MEMHEAP_USED ;
578+ header_ptr -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED ) ;
537579 /* Adjust the available number of bytes. */
538- heap -> available_size = heap -> available_size + MEMITEM_SIZE (header_ptr );
580+ heap -> available_size += MEMITEM_SIZE (header_ptr );
539581
540582 /* Determine if the block can be merged with the previous neighbor. */
541583 if (!RT_MEMHEAP_IS_USED (header_ptr -> prev ))
@@ -544,7 +586,7 @@ void rt_memheap_free(void *ptr)
544586 header_ptr -> prev ));
545587
546588 /* adjust the available number of bytes. */
547- heap -> available_size = heap -> available_size + RT_MEMHEAP_SIZE ;
589+ heap -> available_size += RT_MEMHEAP_SIZE ;
548590
549591 /* yes, merge block with previous neighbor. */
550592 (header_ptr -> prev )-> next = header_ptr -> next ;
@@ -560,7 +602,7 @@ void rt_memheap_free(void *ptr)
560602 if (!RT_MEMHEAP_IS_USED (header_ptr -> next ))
561603 {
562604 /* adjust the available number of bytes. */
563- heap -> available_size = heap -> available_size + RT_MEMHEAP_SIZE ;
605+ heap -> available_size += RT_MEMHEAP_SIZE ;
564606
565607 /* merge block with next neighbor. */
566608 new_ptr = header_ptr -> next ;
@@ -595,6 +637,91 @@ void rt_memheap_free(void *ptr)
595637}
596638RTM_EXPORT (rt_memheap_free );
597639
640+ #ifdef RT_USING_FINSH
641+ static void _memheap_dump_tag (struct rt_memheap_item * item )
642+ {
643+ rt_uint8_t name [2 * sizeof (void * )];
644+ rt_uint8_t * ptr ;
645+
646+ ptr = (rt_uint8_t * )& (item -> next_free );
647+ rt_memcpy (name , ptr , sizeof (void * ));
648+ ptr = (rt_uint8_t * )& (item -> prev_free );
649+ rt_memcpy (& name [sizeof (void * )], ptr , sizeof (void * ));
650+
651+ rt_kprintf ("%.*s" , 2 * sizeof (void * ), name );
652+ }
653+
654+ int rt_memheap_dump (struct rt_memheap * heap )
655+ {
656+ struct rt_memheap_item * item , * end ;
657+
658+ if (heap == RT_NULL ) return 0 ;
659+ RT_ASSERT (rt_object_get_type (& heap -> parent ) == RT_Object_Class_MemHeap );
660+
661+ rt_kprintf ("\n[%.*s] [0x%08x - 0x%08x]->\n" , RT_NAME_MAX , heap -> parent .name ,
662+ (rt_ubase_t )heap -> start_addr , (rt_ubase_t )heap -> start_addr + heap -> pool_size );
663+ rt_kprintf ("------------------------------\n" );
664+
665+ /* lock memheap */
666+ rt_sem_take (& (heap -> lock ), RT_WAITING_FOREVER );
667+ item = heap -> block_list ;
668+
669+ end = (struct rt_memheap_item * ) ((rt_uint8_t * )heap -> start_addr + heap -> pool_size - RT_MEMHEAP_SIZE );
670+
671+ /* for each memory block */
672+ while ((rt_ubase_t )item < ((rt_ubase_t )end ))
673+ {
674+ if (RT_MEMHEAP_IS_USED (item ) && ((item -> magic & RT_MEMHEAP_MASK ) != RT_MEMHEAP_MAGIC ))
675+ rt_kprintf ("0x%08x" , item + 1 );
676+
677+ if (item -> magic == (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED ))
678+ {
679+ rt_kprintf ("0x%08x: %-8d " , item + 1 , MEMITEM_SIZE (item ));
680+ _memheap_dump_tag (item );
681+ rt_kprintf ("\n" );
682+ }
683+ else
684+ {
685+ rt_kprintf ("0x%08x: %-8d <F>\n" , item + 1 , MEMITEM_SIZE (item ));
686+ }
687+
688+ item = item -> next ;
689+ }
690+ rt_sem_release (& (heap -> lock ));
691+
692+ return 0 ;
693+ }
694+
695+ int memtrace (void )
696+ {
697+ int count = rt_object_get_length (RT_Object_Class_MemHeap );
698+ struct rt_memheap * * heaps ;
699+
700+ if (count > 0 )
701+ {
702+ int index ;
703+ extern int list_memheap (void );
704+
705+ heaps = (struct rt_memheap * * )rt_malloc (sizeof (struct rt_memheap * ) * count );
706+ if (heaps == RT_NULL ) return 0 ;
707+
708+ list_memheap ();
709+
710+ rt_kprintf ("memheap header size: %d\n" , RT_MEMHEAP_SIZE );
711+ count = rt_object_get_pointers (RT_Object_Class_MemHeap , (rt_object_t * )heaps , count );
712+ for (index = 0 ; index < count ; index ++ )
713+ {
714+ rt_memheap_dump (heaps [index ]);
715+ }
716+
717+ rt_free (heaps );
718+ }
719+
720+ return 0 ;
721+ }
722+ MSH_CMD_EXPORT (memtrace , dump memory trace information );
723+ #endif
724+
598725#ifdef RT_USING_MEMHEAP_AS_HEAP
599726static struct rt_memheap _heap ;
600727
@@ -643,6 +770,24 @@ void *rt_malloc(rt_size_t size)
643770 }
644771 }
645772
773+
774+ #ifdef RT_USING_MEMTRACE
775+ if (ptr == RT_NULL )
776+ {
777+ RT_DEBUG_LOG ("malloc[%d] => NULL" , size );
778+ }
779+ else
780+ {
781+ struct rt_memheap_item * item = MEMITEM (ptr );
782+ if (rt_thread_self ())
783+ rt_memheap_setname (item , rt_thread_self ()-> name );
784+ else
785+ rt_memheap_setname (item , "<null>" );
786+
787+ RT_DEBUG_LOG ("malloc => 0x%08x : %d" , ptr , size );
788+ }
789+ #endif
790+
646791 return ptr ;
647792}
648793RTM_EXPORT (rt_malloc );
@@ -691,6 +836,23 @@ void *rt_realloc(void *rmem, rt_size_t newsize)
691836 }
692837 }
693838
839+ #ifdef RT_USING_MEMTRACE
840+ if (new_ptr == RT_NULL )
841+ {
842+ RT_DEBUG_LOG ("realloc[%d] => NULL" , newsize );
843+ }
844+ else
845+ {
846+ struct rt_memheap_item * item = MEMITEM (new_ptr );
847+ if (rt_thread_self ())
848+ rt_memheap_setname (item , rt_thread_self ()-> name );
849+ else
850+ rt_memheap_setname (item , "<null>" );
851+
852+ RT_DEBUG_LOG ("realloc => 0x%08x : %d" , new_ptr , newsize );
853+ }
854+ #endif
855+
694856 return new_ptr ;
695857}
696858RTM_EXPORT (rt_realloc );
@@ -708,6 +870,17 @@ void *rt_calloc(rt_size_t count, rt_size_t size)
708870 rt_memset (ptr , 0 , total_size );
709871 }
710872
873+ #ifdef RT_USING_MEMTRACE
874+ if (ptr == RT_NULL )
875+ {
876+ RT_DEBUG_LOG ("calloc[%d x %d] => NULL" , count , size );
877+ }
878+ else
879+ {
880+ RT_DEBUG_LOG ("calloc => 0x%08x : %d" , ptr , count * size );
881+ }
882+ #endif
883+
711884 return ptr ;
712885}
713886RTM_EXPORT (rt_calloc );
0 commit comments