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
{
#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
* Public Types
****************************************************************************/
+#define HEAPINFO_TRACE 0
+#define HEAPINFO_NORMAL 1
+
/* Determines the size of the chunk size/offset type */
#ifdef CONFIG_MM_SMALL
#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
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
/****************************************************************************
* 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 */
*/
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");
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;
}
* 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++;
* 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;
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);
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);
#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
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;
/* 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;
}
* 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;
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);
/* 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
}
#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
/* 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