Change to using tcb info and Add Non-scheduled resource info in Heapinfo 59/111059/2
authorjc_.kim <jc_.kim@samsung.com>
Thu, 19 Jan 2017 08:43:56 +0000 (17:43 +0900)
committerjc_.kim <jc_.kim@samsung.com>
Thu, 19 Jan 2017 08:49:47 +0000 (17:49 +0900)
- Add Non-scheduled info:group res, child task's res and leaks
Parent res will not be released before all child tasks are terminated
- Modify calculation in mm_realloc and mm_memalign
- Display ppid instead of gid in kdbg_heapinfo

Change-Id: Ifc2b9b7c4f31561b39184e92e4c4164d38ca4e94

apps/system/utils/kdbg_heapinfo.c
os/include/tinyara/mm/mm.h
os/mm/mm_heap/mm_free.c
os/mm/mm_heap/mm_heapinfo.c
os/mm/mm_heap/mm_malloc.c
os/mm/mm_heap/mm_memalign.c
os/mm/mm_heap/mm_realloc.c

index ba2e193..5593a52 100644 (file)
@@ -36,7 +36,11 @@ static void kdbg_heapinfo_task(FAR struct tcb_s *tcb, FAR void *arg)
        if (tcb->pid == 0) {
                tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
        }
-       printf("%3d | %5d |     %5d  %5d | ", tcb->pid, tcb->adj_stack_size, tcb->curr_alloc_size, tcb->peak_alloc_size);
+       printf("%3d  ", tcb->pid);
+#if defined(CONFIG_SCHED_HAVE_PARENT) && !defined(HAVE_GROUP_MEMBERS)
+       printf("%4d  ", tcb->ppid);
+#endif
+       printf("%5d      %5d  %5d  ", tcb->adj_stack_size, tcb->curr_alloc_size, tcb->peak_alloc_size);
 
        /* Show task name and arguments */
 #if CONFIG_TASK_NAME_SIZE > 0
@@ -51,16 +55,23 @@ int kdbg_heapinfo(int argc, char **args)
 {
 #ifdef CONFIG_DEBUG_MM_HEAPINFO
        struct mm_heap_s *user_heap = mm_get_heap_info();
-       if (argc > 1 && strcmp(args[1], "init") == 0) {
-               sched_foreach(kdbg_heapinfo_init, NULL);
-
-               printf("Peak allocated memory size is cleared\n");
-               return OK;
+       if (argc > 1) {
+               if (strcmp(args[1], "init") == 0) {
+                       sched_foreach(kdbg_heapinfo_init, NULL);
+                       printf("Peak allocated memory size is cleared\n");
+                       return OK;
+               } else if (strcmp(args[1], "-v") == 0) {
+                       heapinfo_parse(user_heap, HEAPINFO_TRACE);
+               }
+       } else {
+               heapinfo_parse(user_heap, HEAPINFO_NORMAL);
        }
-
-       heapinfo_parse(user_heap);
-
-       printf("PID | STACK | HEAP Curr | Peak | NAME\n");
+       printf("\nPID  ");
+#if defined(CONFIG_SCHED_HAVE_PARENT) && !defined(HAVE_GROUP_MEMBERS)
+       printf("PPID  ");
+#endif
+       printf("STACK  HEAP Curr  Peak  NAME\n");
+       printf("------------------------------------\n");
 
        sched_foreach(kdbg_heapinfo_task, NULL);
 #endif
index ce1ffba..696156b 100644 (file)
  * Public Types
  ****************************************************************************/
 
+#define HEAPINFO_TRACE 0
+#define HEAPINFO_NORMAL 1
+
 /* Determines the size of the chunk size/offset type */
 
 #ifdef CONFIG_MM_SMALL
@@ -586,12 +589,12 @@ int mm_size2ndx(size_t size);
 
 #ifdef CONFIG_DEBUG_MM_HEAPINFO
 /* Functions contained in kmm_mallinfo.c . Used to display memory allocation details */
-void heapinfo_parse(FAR struct mm_heap_s *heap);
+void heapinfo_parse(FAR struct mm_heap_s *heap, int mode);
 /* Funciton to add memory allocation info */
 void heapinfo_update_node(FAR struct mm_allocnode_s *node, mmaddress_t caller_retaddr);
 
-void heapinfo_add_size(size_t size);
-void heapinfo_subtract_size(struct mm_allocnode_s *node, size_t size);
+void heapinfo_add_size(int16_t pid, size_t size);
+void heapinfo_subtract_size(int16_t pid, size_t size);
 void heapinfo_update_total_size(struct mm_heap_s *heap, int size);
 #endif
 
index 6dbdc34..7f8a6dc 100644 (file)
@@ -114,7 +114,7 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
        alloc_node = (struct mm_allocnode_s *)node;
 
        if ((alloc_node->preceding & MM_ALLOC_BIT) != 0) {
-               heapinfo_subtract_size(alloc_node, alloc_node->size);
+               heapinfo_subtract_size(alloc_node->pid, alloc_node->size);
                heapinfo_update_total_size(heap, ((-1) * alloc_node->size));
        }
 #endif
index a9f59e5..2b33632 100644 (file)
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
+#define MM_PIDHASH(pid) ((pid) & (CONFIG_MAX_TASKS - 1))
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 #ifdef CONFIG_DEBUG_MM_HEAPINFO
-
 /****************************************************************************
- * Name: mm_heapinfo_parse
+ * Name: heapinfo_parse
  *
  * Description:
  *   This function walk through heap and displays alloc info.
  ****************************************************************************/
-void heapinfo_parse(FAR struct mm_heap_s *heap)
+void heapinfo_parse(FAR struct mm_heap_s *heap, int mode)
 {
        struct mm_allocnode_s *node;
        size_t mxordblk = 0;
        int    ordblks  = 0;            /* Number of non-inuse chunks */
        size_t fordblks = 0;            /* Total non-inuse space */
-       FAR struct tcb_s *tcb;
+       int nonsched_resource;
+       int nonsched_idx;
+
+       /* This nonsched can be 3 types : group resources, freed when child task finished, leak */
+       pid_t nonsched_list[CONFIG_MAX_TASKS];
+       int nonsched_size[CONFIG_MAX_TASKS];
+
 #if CONFIG_MM_REGIONS > 1
        int region;
 #else
 #define region 0
 #endif
-       printf("****************************************************************\n");
-       printf("Heap Walker Output for Heap =0x%p\n", heap);
-       printf("****************************************************************\n");
+       /* initialize the nonsched */
+       nonsched_resource = 0;
+       for (nonsched_idx = 0; nonsched_idx < CONFIG_MAX_TASKS; nonsched_idx++) {
+               nonsched_list[nonsched_idx] = -1;
+               nonsched_size[nonsched_idx] = 0;
+       }
+
+       if (mode == HEAPINFO_TRACE) {
+               printf("****************************************************************\n");
+               printf("Heap Walker Output for Heap =0x%p\n", heap);
+               printf("****************************************************************\n");
+       }
 
        /* Visit each region */
 
@@ -102,28 +117,29 @@ void heapinfo_parse(FAR struct mm_heap_s *heap)
                 */
                mm_takesemaphore(heap);
 
-               printf("HeapReg#%d Heap StartAddr=0x%p, EndAddr=0x%p\n\n", region, heap->mm_heapstart[region], heap->mm_heapend[region]);
-               printf("****************************************************************\n");
-               printf("Heap Alloation Info- (Size in Bytes)\n");
-               printf("****************************************************************\n");
+               if (mode == HEAPINFO_TRACE) {
+                       printf("HeapReg#%d Heap StartAddr=0x%p, EndAddr=0x%p\n\n", region, heap->mm_heapstart[region], heap->mm_heapend[region]);
+                       printf("****************************************************************\n");
+                       printf("Heap Alloation Info- (Size in Bytes)\n");
+                       printf("****************************************************************\n");
+               }
 
                for (node = heap->mm_heapstart[region]; node < heap->mm_heapend[region]; node = (struct mm_allocnode_s *)((char *)node + node->size)) {
 
                        /* Check if the node corresponds to an allocated memory chunk */
 
                        if ((node->preceding & MM_ALLOC_BIT) != 0) {
-                               printf("MemAddr=0x%x Size=%5d (%c) Owner=0x%x Pid=%3d ", node, node->size, 'A', node->alloc_call_addr, node->pid);
+                               if (mode == HEAPINFO_TRACE) {
+                                       printf("MemAddr=0x%x Size=%6d (%c) Owner=0x%x Pid=%3d \n", node, node->size, 'A', node->alloc_call_addr, node->pid);
+                               }
 
 #if CONFIG_TASK_NAME_SIZE > 0
-                               if (node->pid == -1) {
+                               if (node->pid == -1 && mode == HEAPINFO_TRACE) {
                                        printf("INT Context\n");
-                               } else {
-                                       tcb = sched_gettcb(node->pid);
-                                       if (tcb != NULL) {
-                                               printf("%s\n", tcb->name);
-                                       } else {
-                                               printf("Unknown Context\n");
-                                       }
+                               } else if (sched_gettcb(node->pid) == NULL) {
+                                       nonsched_list[MM_PIDHASH(node->pid)] = node->pid;
+                                       nonsched_size[MM_PIDHASH(node->pid)] += node->size;
+                                       nonsched_resource += node->size;
                                }
 #else
                                printf("\n");
@@ -134,21 +150,37 @@ void heapinfo_parse(FAR struct mm_heap_s *heap)
                                if (node->size > mxordblk) {
                                        mxordblk = node->size;
                                }
-                               printf("MemAddr=0x%x Size=%5d (%c)\n", node, node->size, 'F');
+                               if (mode == HEAPINFO_TRACE) {
+                                       printf("MemAddr=0x%x Size=%6d (%c)\n", node, node->size, 'F');
+                               }
                        }
                }
 
                mm_givesemaphore(heap);
-               printf("HeapReg#=%d End node=0x%p Size=%5d (%c)\n", region, node, node->size, 'A');
+               if (mode == HEAPINFO_TRACE) {
+                       printf("HeapReg#=%d End node=0x%p Size=%5d (%c)\n", region, node, node->size, 'A');
+               }
        }
 #undef region
-       printf("\nHeap Alloation Summary(Size in Bytes)\n");
+       printf("\nHeap Alloation Summary(Bytes)\n");
        printf("Heap Size                      : %d\n", heap->mm_heapsize);
        printf("Current Allocated Node Size    : %d\n", heap->total_alloc_size + SIZEOF_MM_ALLOCNODE * 2);
        printf("Peak Allocated Node Size       : %d\n", heap->peak_alloc_size);
        printf("Free Size                      : %d\n", fordblks);
-       printf("Largest Free Chunk Size        : %d\n", mxordblk);
-       printf("Allocated not used(free)Chunks : %d\n", ordblks);
+       printf("Largest Free Node Size         : %d\n", mxordblk);
+       printf("Number of Free Node            : %d\n", ordblks);
+
+       printf("\nNon Scheduled Task Resources   : %d\n", nonsched_resource);
+       if (mode == HEAPINFO_TRACE) {
+               printf("PID  SIZE\n");
+               printf("----------\n");
+               for (nonsched_idx = 0; nonsched_idx < CONFIG_MAX_TASKS; nonsched_idx++) {
+                       if (nonsched_list[nonsched_idx] != -1) {
+                               printf("%4d %5d\n", nonsched_list[nonsched_idx], nonsched_size[nonsched_idx]);
+                       }
+               }
+       }
+
        return;
 }
 
@@ -158,9 +190,9 @@ void heapinfo_parse(FAR struct mm_heap_s *heap)
  * Description:
  * Add the allocated size in tcb
  ****************************************************************************/
-void heapinfo_add_size(size_t size)
+void heapinfo_add_size(int16_t pid, size_t size)
 {
-       struct tcb_s *rtcb = sched_self();
+       struct tcb_s *rtcb = sched_gettcb(pid);
        if (rtcb) {
                rtcb->curr_alloc_size += size;
                rtcb->num_alloc_free++;
@@ -176,9 +208,9 @@ void heapinfo_add_size(size_t size)
  * Description:
  * Subtract the allocated size in tcb
  ****************************************************************************/
-void heapinfo_subtract_size(struct mm_allocnode_s *node, size_t size)
+void heapinfo_subtract_size(int16_t pid, size_t size)
 {
-       struct tcb_s *rtcb = sched_gettcb(node->pid);
+       struct tcb_s *rtcb = sched_gettcb(pid);
 
        if (rtcb) {
                rtcb->curr_alloc_size -= size;
index 4a811c4..6dbf10a 100644 (file)
@@ -205,22 +205,13 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
 
                node->preceding |= MM_ALLOC_BIT;
 
-               /* Add memory allocation info for heap issue debug */
-
 #ifdef CONFIG_DEBUG_MM_HEAPINFO
-               if (0 != caller_retaddr) {
-                       heapinfo_update_node((struct mm_allocnode_s *)node, caller_retaddr);
-               }
+               heapinfo_update_node((struct mm_allocnode_s *)node, caller_retaddr);
+               heapinfo_add_size(((struct mm_allocnode_s *)node)->pid, node->size);
+               heapinfo_update_total_size(heap, node->size);
 #endif
-
                ret = (void *)((char *)node + SIZEOF_MM_ALLOCNODE);
        }
-#ifdef CONFIG_DEBUG_MM_HEAPINFO
-       if (ret) {
-               heapinfo_add_size(node->size);
-               heapinfo_update_total_size(heap, node->size);
-       }
-#endif
 
        mm_givesemaphore(heap);
 
@@ -232,7 +223,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
        if (!ret) {
                mdbg("Allocation failed, size %d\n", size);
 #ifdef CONFIG_DEBUG_MM_HEAPINFO
-               heapinfo_parse(heap);
+               heapinfo_parse(heap, HEAPINFO_NORMAL);
 #endif
        } else {
                mvdbg("Allocated %p, size %d\n", ret, size);
index 8b8efed..523d76c 100644 (file)
@@ -127,7 +127,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, size_t size)
 #ifdef CONFIG_DEBUG_MM_HEAPINFO
        /*Passing Zero as caller addr to avoid adding memalloc info in malloc function,
           alloc info will be added in this functiona after memory aligment . */
-       rawchunk = (size_t)mm_malloc(heap, allocsize, 0x0);
+       rawchunk = (size_t)mm_malloc(heap, allocsize, caller_retaddr);
 #else
        rawchunk = (size_t)mm_malloc(heap, allocsize);
 #endif
@@ -147,6 +147,10 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, size_t size)
 
        node = (FAR struct mm_allocnode_s *)(rawchunk - SIZEOF_MM_ALLOCNODE);
 
+#ifdef CONFIG_DEBUG_MM_HEAPINFO
+               heapinfo_subtract_size(node->pid, node->size);
+               heapinfo_update_total_size(heap, ((-1) * (node->size)));
+#endif
        /* Find the aligned subregion */
 
        alignedchunk = (rawchunk + mask) & ~mask;
@@ -212,16 +216,11 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, size_t size)
 
                /* Add the original, newly freed node to the free nodelist */
 
-#ifdef CONFIG_DEBUG_MM_HEAPINFO
-               heapinfo_subtract_size(node, node->size);
-               heapinfo_update_total_size(heap, ((-1) * (node->size)));
-#endif
                mm_addfreechunk(heap, (FAR struct mm_freenode_s *)node);
 
                /* Replace the original node with the newlay realloaced,
                 * aligned node
                 */
-
                node = newnode;
        }
 
@@ -232,15 +231,13 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, size_t size)
                 * internal chunk sizes that include SIZEOF_MM_ALLOCNODE, and not the
                 * malloc-compatible sizes that we have.
                 */
-#ifdef CONFIG_DEBUG_MM_HEAPINFO
-               heapinfo_subtract_size(node, (node->size - (size + SIZEOF_MM_ALLOCNODE)));
-               heapinfo_update_total_size(heap, (size + SIZEOF_MM_ALLOCNODE - node->size));
-
-#endif
                mm_shrinkchunk(heap, node, size + SIZEOF_MM_ALLOCNODE);
        }
 #ifdef CONFIG_DEBUG_MM_HEAPINFO
-       heapinfo_update_node((struct mm_allocnode_s *)((char *)alignedchunk - SIZEOF_MM_ALLOCNODE), caller_retaddr);
+       heapinfo_update_node(node, caller_retaddr);
+
+       heapinfo_add_size(node->pid, node->size);
+       heapinfo_update_total_size(heap, node->size);
 #endif
        mm_givesemaphore(heap);
        return (FAR void *)alignedchunk;
index 3603f01..002dcb8 100644 (file)
@@ -158,7 +158,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, size_t size)
                if (size < oldsize) {
 #ifdef CONFIG_DEBUG_MM_HEAPINFO
                        /* modify the current allocated size of old node */
-                       heapinfo_subtract_size(oldnode, oldsize);
+                       heapinfo_subtract_size(oldnode->pid, oldsize);
+                       heapinfo_update_total_size(heap, (-1) * oldsize);
 #endif
 
                        mm_shrinkchunk(heap, oldnode, size);
@@ -166,8 +167,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, size_t size)
                        /* update the chunk to realloc task information */
                        heapinfo_update_node(oldnode, caller_retaddr);
 
-                       heapinfo_add_size(size);
-                       heapinfo_update_total_size(heap, (size - oldsize));
+                       heapinfo_add_size(oldnode->pid, oldnode->size);
+                       heapinfo_update_total_size(heap, oldnode->size);
 #endif
                }
 
@@ -201,7 +202,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, size_t size)
 
 #ifdef CONFIG_DEBUG_MM_HEAPINFO
                /* modify the current allocated size of old node */
-               heapinfo_subtract_size(oldnode, oldsize);
+               heapinfo_subtract_size(oldnode->pid, oldsize);
                heapinfo_update_total_size(heap, (-1) * oldsize);
 #endif
 
@@ -352,7 +353,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, size_t size)
                /* update the chunk to realloc task information */
                heapinfo_update_node(oldnode, caller_retaddr);
 
-               heapinfo_add_size(oldnode->size);
+               heapinfo_add_size(oldnode->pid, oldnode->size);
                heapinfo_update_total_size(heap, oldnode->size);
 #endif