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 ;
@@ -107,7 +146,7 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap,
107146 */
108147 item = item -> next ;
109148 /* it's a used memory block */
110- item -> magic = RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED ;
149+ item -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED ) ;
111150 item -> pool_ptr = memheap ;
112151 item -> next = (struct rt_memheap_item * )start_addr ;
113152 item -> prev = (struct rt_memheap_item * )start_addr ;
@@ -205,7 +244,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_size_t size)
205244 new_ptr ));
206245
207246 /* mark the new block as a memory block and freed. */
208- new_ptr -> magic = RT_MEMHEAP_MAGIC ;
247+ new_ptr -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED ) ;
209248
210249 /* put the pool pointer into the new block. */
211250 new_ptr -> pool_ptr = heap ;
@@ -263,7 +302,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_size_t size)
263302 }
264303
265304 /* Mark the allocated block as not available. */
266- header_ptr -> magic |= RT_MEMHEAP_USED ;
305+ header_ptr -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED ) ;
267306
268307#ifdef RT_USING_MEMTRACE
269308 if (rt_thread_self ())
@@ -391,7 +430,7 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
391430 next_ptr -> prev ));
392431
393432 /* mark the new block as a memory block and freed. */
394- next_ptr -> magic = RT_MEMHEAP_MAGIC ;
433+ next_ptr -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED ) ;
395434
396435 /* put the pool pointer into the new block. */
397436 next_ptr -> pool_ptr = heap ;
@@ -460,7 +499,7 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
460499 new_ptr ));
461500
462501 /* mark the new block as a memory block and freed. */
463- new_ptr -> magic = RT_MEMHEAP_MAGIC ;
502+ new_ptr -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED ) ;
464503 /* put the pool pointer into the new block. */
465504 new_ptr -> pool_ptr = heap ;
466505
@@ -535,8 +574,12 @@ void rt_memheap_free(void *ptr)
535574 ptr , header_ptr ));
536575
537576 /* check magic */
538- RT_ASSERT ((header_ptr -> magic & RT_MEMHEAP_MASK ) == RT_MEMHEAP_MAGIC );
539- RT_ASSERT (header_ptr -> magic & RT_MEMHEAP_USED );
577+ if (header_ptr -> magic != (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED ))
578+ {
579+ RT_DEBUG_LOG (RT_DEBUG_MEMHEAP , ("bad magic:0x%08x @ memheap\n" ,
580+ header_ptr -> magic ));
581+ }
582+ RT_ASSERT (header_ptr -> magic == (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED ));
540583 /* check whether this block of memory has been over-written. */
541584 RT_ASSERT ((header_ptr -> next -> magic & RT_MEMHEAP_MASK ) == RT_MEMHEAP_MAGIC );
542585
@@ -556,9 +599,9 @@ void rt_memheap_free(void *ptr)
556599 }
557600
558601 /* Mark the memory as available. */
559- header_ptr -> magic &= ~ RT_MEMHEAP_USED ;
602+ header_ptr -> magic = ( RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED ) ;
560603 /* Adjust the available number of bytes. */
561- heap -> available_size = heap -> available_size + MEMITEM_SIZE (header_ptr );
604+ heap -> available_size += MEMITEM_SIZE (header_ptr );
562605
563606 /* Determine if the block can be merged with the previous neighbor. */
564607 if (!RT_MEMHEAP_IS_USED (header_ptr -> prev ))
@@ -567,7 +610,7 @@ void rt_memheap_free(void *ptr)
567610 header_ptr -> prev ));
568611
569612 /* adjust the available number of bytes. */
570- heap -> available_size = heap -> available_size + RT_MEMHEAP_SIZE ;
613+ heap -> available_size += RT_MEMHEAP_SIZE ;
571614
572615 /* yes, merge block with previous neighbor. */
573616 (header_ptr -> prev )-> next = header_ptr -> next ;
@@ -583,7 +626,7 @@ void rt_memheap_free(void *ptr)
583626 if (!RT_MEMHEAP_IS_USED (header_ptr -> next ))
584627 {
585628 /* adjust the available number of bytes. */
586- heap -> available_size = heap -> available_size + RT_MEMHEAP_SIZE ;
629+ heap -> available_size += RT_MEMHEAP_SIZE ;
587630
588631 /* merge block with next neighbor. */
589632 new_ptr = header_ptr -> next ;
@@ -622,6 +665,91 @@ void rt_memheap_free(void *ptr)
622665}
623666RTM_EXPORT (rt_memheap_free );
624667
668+ #ifdef RT_USING_FINSH
669+ static void _memheap_dump_tag (struct rt_memheap_item * item )
670+ {
671+ rt_uint8_t name [2 * sizeof (void * )];
672+ rt_uint8_t * ptr ;
673+
674+ ptr = (rt_uint8_t * )& (item -> next_free );
675+ rt_memcpy (name , ptr , sizeof (void * ));
676+ ptr = (rt_uint8_t * )& (item -> prev_free );
677+ rt_memcpy (& name [sizeof (void * )], ptr , sizeof (void * ));
678+
679+ rt_kprintf ("%.*s" , 2 * sizeof (void * ), name );
680+ }
681+
682+ int rt_memheap_dump (struct rt_memheap * heap )
683+ {
684+ struct rt_memheap_item * item , * end ;
685+
686+ if (heap == RT_NULL ) return 0 ;
687+ RT_ASSERT (rt_object_get_type (& heap -> parent ) == RT_Object_Class_MemHeap );
688+
689+ rt_kprintf ("\n[%.*s] [0x%08x - 0x%08x]->\n" , RT_NAME_MAX , heap -> parent .name ,
690+ (rt_ubase_t )heap -> start_addr , (rt_ubase_t )heap -> start_addr + heap -> pool_size );
691+ rt_kprintf ("------------------------------\n" );
692+
693+ /* lock memheap */
694+ rt_sem_take (& (heap -> lock ), RT_WAITING_FOREVER );
695+ item = heap -> block_list ;
696+
697+ end = (struct rt_memheap_item * ) ((rt_uint8_t * )heap -> start_addr + heap -> pool_size - RT_MEMHEAP_SIZE );
698+
699+ /* for each memory block */
700+ while ((rt_ubase_t )item < ((rt_ubase_t )end ))
701+ {
702+ if (RT_MEMHEAP_IS_USED (item ) && ((item -> magic & RT_MEMHEAP_MASK ) != RT_MEMHEAP_MAGIC ))
703+ rt_kprintf ("0x%08x" , item + 1 );
704+
705+ if (item -> magic == (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED ))
706+ {
707+ rt_kprintf ("0x%08x: %-8d " , item + 1 , MEMITEM_SIZE (item ));
708+ _memheap_dump_tag (item );
709+ rt_kprintf ("\n" );
710+ }
711+ else
712+ {
713+ rt_kprintf ("0x%08x: %-8d <F>\n" , item + 1 , MEMITEM_SIZE (item ));
714+ }
715+
716+ item = item -> next ;
717+ }
718+ rt_sem_release (& (heap -> lock ));
719+
720+ return 0 ;
721+ }
722+
723+ int memheaptrace (void )
724+ {
725+ int count = rt_object_get_length (RT_Object_Class_MemHeap );
726+ struct rt_memheap * * heaps ;
727+
728+ if (count > 0 )
729+ {
730+ int index ;
731+ extern int list_memheap (void );
732+
733+ heaps = (struct rt_memheap * * )rt_malloc (sizeof (struct rt_memheap * ) * count );
734+ if (heaps == RT_NULL ) return 0 ;
735+
736+ list_memheap ();
737+
738+ rt_kprintf ("memheap header size: %d\n" , RT_MEMHEAP_SIZE );
739+ count = rt_object_get_pointers (RT_Object_Class_MemHeap , (rt_object_t * )heaps , count );
740+ for (index = 0 ; index < count ; index ++ )
741+ {
742+ rt_memheap_dump (heaps [index ]);
743+ }
744+
745+ rt_free (heaps );
746+ }
747+
748+ return 0 ;
749+ }
750+ MSH_CMD_EXPORT (memheaptrace , dump memory trace information );
751+ #endif
752+
625753#ifdef RT_USING_MEMHEAP_AS_HEAP
626754static struct rt_memheap _heap ;
627755
@@ -670,6 +798,24 @@ void *rt_malloc(rt_size_t size)
670798 }
671799 }
672800
801+
802+ #ifdef RT_USING_MEMTRACE
803+ if (ptr == RT_NULL )
804+ {
805+ RT_DEBUG_LOG (RT_DEBUG_MEMHEAP , ("malloc[%d] => NULL" , size ));
806+ }
807+ else
808+ {
809+ struct rt_memheap_item * item = MEMITEM (ptr );
810+ if (rt_thread_self ())
811+ rt_memheap_setname (item , rt_thread_self ()-> name );
812+ else
813+ rt_memheap_setname (item , "<null>" );
814+
815+ RT_DEBUG_LOG (RT_DEBUG_MEMHEAP , ("malloc => 0x%08x : %d" , ptr , size ));
816+ }
817+ #endif
818+
673819 return ptr ;
674820}
675821RTM_EXPORT (rt_malloc );
@@ -718,6 +864,24 @@ void *rt_realloc(void *rmem, rt_size_t newsize)
718864 }
719865 }
720866
867+ #ifdef RT_USING_MEMTRACE
868+ if (new_ptr == RT_NULL )
869+ {
870+ RT_DEBUG_LOG (RT_DEBUG_MEMHEAP , ("realloc[%d] => NULL" , newsize ));
871+ }
872+ else
873+ {
874+ struct rt_memheap_item * item = MEMITEM (new_ptr );
875+ if (rt_thread_self ())
876+ rt_memheap_setname (item , rt_thread_self ()-> name );
877+ else
878+ rt_memheap_setname (item , "<null>" );
879+
880+ RT_DEBUG_LOG (RT_DEBUG_MEMHEAP , ("realloc => 0x%08x : %d" ,
881+ new_ptr , newsize ));
882+ }
883+ #endif
884+
721885 return new_ptr ;
722886}
723887RTM_EXPORT (rt_realloc );
@@ -735,6 +899,19 @@ void *rt_calloc(rt_size_t count, rt_size_t size)
735899 rt_memset (ptr , 0 , total_size );
736900 }
737901
902+ #ifdef RT_USING_MEMTRACE
903+ if (ptr == RT_NULL )
904+ {
905+ RT_DEBUG_LOG (RT_DEBUG_MEMHEAP , ("calloc[%d x %d] => NULL" ,
906+ count , size ));
907+ }
908+ else
909+ {
910+ RT_DEBUG_LOG (RT_DEBUG_MEMHEAP , ("calloc => 0x%08x : %d" ,
911+ ptr , count * size ));
912+ }
913+ #endif
914+
738915 return ptr ;
739916}
740917RTM_EXPORT (rt_calloc );
0 commit comments