This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 7ae3c572dc8475e9ef2d6b05e2dc62c99f5203ca
Author: Jiuzhu Dong <[email protected]>
AuthorDate: Sat Jan 22 20:21:51 2022 +0800

    procfs: add heap info for every task
    
    cat /proc/2/heap
    AllocSize:  512
    AllocBlks:  10
    
    Signed-off-by: Jiuzhu Dong <[email protected]>
---
 fs/procfs/fs_procfsproc.c  | 80 ++++++++++++++++++++++++++++++++++++++++++++++
 include/malloc.h           | 12 +++++++
 include/nuttx/mm/mm.h      |  8 +++++
 mm/kmm_heap/kmm_mallinfo.c | 19 +++++++++++
 mm/mm_heap/mm_mallinfo.c   | 42 ++++++++++++++++++++++++
 mm/umm_heap/umm_mallinfo.c | 20 ++++++++++++
 6 files changed, 181 insertions(+)

diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c
index 60ca146..fbf622f 100644
--- a/fs/procfs/fs_procfsproc.c
+++ b/fs/procfs/fs_procfsproc.c
@@ -37,6 +37,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <debug.h>
+#include <malloc.h>
 
 #ifdef CONFIG_SCHED_CRITMONITOR
 #  include <time.h>
@@ -50,6 +51,7 @@
 #include <nuttx/fs/fs.h>
 #include <nuttx/fs/procfs.h>
 #include <nuttx/fs/dirent.h>
+#include <nuttx/mm/mm.h>
 
 #if defined(CONFIG_SCHED_CPULOAD) || defined(CONFIG_SCHED_CRITMONITOR)
 #  include <nuttx/clock.h>
@@ -87,6 +89,9 @@ enum proc_node_e
 #ifdef CONFIG_SCHED_CRITMONITOR
   PROC_CRITMON,                       /* Critical section monitor */
 #endif
+#ifdef CONFIG_DEBUG_MM
+  PROC_HEAP,                          /* Task heap info */
+#endif
   PROC_STACK,                         /* Task stack info */
   PROC_GROUP,                         /* Group directory */
   PROC_GROUP_STATUS,                  /* Task group status */
@@ -172,6 +177,11 @@ static ssize_t proc_critmon(FAR struct proc_file_s 
*procfile,
                  FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen,
                  off_t offset);
 #endif
+#ifdef CONFIG_DEBUG_MM
+static ssize_t proc_heap(FAR struct proc_file_s *procfile,
+                         FAR struct tcb_s *tcb, FAR char *buffer,
+                         size_t buflen, off_t offset);
+#endif
 static ssize_t proc_stack(FAR struct proc_file_s *procfile,
                  FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen,
                  off_t offset);
@@ -268,6 +278,13 @@ static const struct proc_node_s g_critmon =
 };
 #endif
 
+#ifdef CONFIG_DEBUG_MM
+static const struct proc_node_s g_heap =
+{
+  "heap",         "heap",   (uint8_t)PROC_HEAP,          DTYPE_FILE        /* 
Task heap info */
+};
+#endif
+
 static const struct proc_node_s g_stack =
 {
   "stack",        "stack",   (uint8_t)PROC_STACK,        DTYPE_FILE        /* 
Task stack info */
@@ -308,6 +325,9 @@ static FAR const struct proc_node_s * const g_nodeinfo[] =
 #ifdef CONFIG_SCHED_CRITMONITOR
   &g_critmon,      /* Critical section Monitor */
 #endif
+#ifdef CONFIG_DEBUG_MM
+  &g_heap,         /* Task heap info */
+#endif
   &g_stack,        /* Task stack info */
   &g_group,        /* Group directory */
   &g_groupstatus,  /* Task group status */
@@ -331,6 +351,9 @@ static const struct proc_node_s * const g_level0info[] =
 #ifdef CONFIG_SCHED_CRITMONITOR
   &g_critmon,      /* Critical section monitor */
 #endif
+#ifdef CONFIG_DEBUG_MM
+  &g_heap,         /* Task heap info */
+#endif
   &g_stack,        /* Task stack info */
   &g_group,        /* Group directory */
 };
@@ -877,6 +900,58 @@ static ssize_t proc_critmon(FAR struct proc_file_s 
*procfile,
 #endif
 
 /****************************************************************************
+ * Name: proc_heap
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_MM
+static ssize_t proc_heap(FAR struct proc_file_s *procfile,
+                         FAR struct tcb_s *tcb, FAR char *buffer,
+                         size_t buflen, off_t offset)
+{
+  size_t remaining = buflen;
+  size_t linesize;
+  size_t copysize;
+  size_t totalsize = 0;
+  struct mallinfo_task info;
+
+#ifdef CONFIG_MM_KERNEL_HEAP
+  if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
+    {
+      info = kmm_mallinfo_task(tcb->pid);
+    }
+  else
+#endif
+    {
+      info = mallinfo_task(tcb->pid);
+    }
+
+  /* Show the heap alloc size */
+
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                               "%-12s%d\n", "AllocSize:", info.uordblks);
+  copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
+                             &offset);
+
+  totalsize += copysize;
+  buffer    += copysize;
+  remaining -= copysize;
+
+  if (totalsize >= buflen)
+    {
+      return totalsize;
+    }
+
+  /* Show the heap alloc block */
+
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                               "%-12s%d\n", "AllocBlks:", info.aordblks);
+  totalsize += procfs_memcpy(procfile->line, linesize, buffer, remaining,
+                             &offset);
+  return totalsize;
+}
+#endif
+
+/****************************************************************************
  * Name: proc_stack
  ****************************************************************************/
 
@@ -1484,6 +1559,11 @@ static ssize_t proc_read(FAR struct file *filep, FAR 
char *buffer,
       ret = proc_critmon(procfile, tcb, buffer, buflen, filep->f_pos);
       break;
 #endif
+#ifdef CONFIG_DEBUG_MM
+    case PROC_HEAP: /* Task heap info */
+      ret = proc_heap(procfile, tcb, buffer, buflen, filep->f_pos);
+      break;
+#endif
     case PROC_STACK: /* Task stack info */
       ret = proc_stack(procfile, tcb, buffer, buflen, filep->f_pos);
       break;
diff --git a/include/malloc.h b/include/malloc.h
index 0854174..50345c3 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -52,6 +52,15 @@ struct mallinfo
                  * by free (not in use) chunks. */
 };
 
+#ifdef CONFIG_DEBUG_MM
+struct mallinfo_task
+{
+  pid_t pid;    /* The pid of task */
+  int aordblks; /* This is the number of allocated (in use) chunks for task */
+  int uordblks; /* This is the total size of memory occupied for task */
+};
+#endif
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -63,6 +72,9 @@ extern "C"
 
 struct mallinfo mallinfo(void);
 size_t malloc_size(FAR void *ptr);
+#ifdef CONFIG_DEBUG_MM
+struct mallinfo_task mallinfo_task(pid_t pid);
+#endif
 
 #if defined(__cplusplus)
 }
diff --git a/include/nuttx/mm/mm.h b/include/nuttx/mm/mm.h
index aad4e6f..6f78a6a 100644
--- a/include/nuttx/mm/mm.h
+++ b/include/nuttx/mm/mm.h
@@ -296,11 +296,19 @@ void kmm_extend(FAR void *mem, size_t size, int region);
 
 struct mallinfo; /* Forward reference */
 int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info);
+#ifdef CONFIG_DEBUG_MM
+struct mallinfo_task; /* Forward reference */
+int mm_mallinfo_task(FAR struct mm_heap_s *heap,
+                     FAR struct mallinfo_task *info);
+#endif
 
 /* Functions contained in kmm_mallinfo.c ************************************/
 
 #ifdef CONFIG_MM_KERNEL_HEAP
 struct mallinfo kmm_mallinfo(void);
+#  ifdef CONFIG_DEBUG_MM
+struct mallinfo_task kmm_mallinfo_task(pid_t pid);
+#  endif
 #endif
 
 /* Functions contained in mm_memdump.c **************************************/
diff --git a/mm/kmm_heap/kmm_mallinfo.c b/mm/kmm_heap/kmm_mallinfo.c
index 1172ed4..33dd664 100644
--- a/mm/kmm_heap/kmm_mallinfo.c
+++ b/mm/kmm_heap/kmm_mallinfo.c
@@ -50,4 +50,23 @@ struct mallinfo kmm_mallinfo(void)
   return info;
 }
 
+/****************************************************************************
+ * Name: kmm_mallinfo_task
+ *
+ * Description:
+ *   kmm_mallinfo_task returns a copy of updated current heap information of
+ *   task with specified pid for the user heap.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_MM
+struct mallinfo_task kmm_mallinfo_task(pid_t pid)
+{
+  struct mallinfo_task info;
+
+  info.pid = pid;
+  mm_mallinfo_task(g_kmmheap, &info);
+  return info;
+}
+#endif
 #endif /* CONFIG_MM_KERNEL_HEAP */
diff --git a/mm/mm_heap/mm_mallinfo.c b/mm/mm_heap/mm_mallinfo.c
index e3fb94a..7ecdc03 100644
--- a/mm/mm_heap/mm_mallinfo.c
+++ b/mm/mm_heap/mm_mallinfo.c
@@ -75,6 +75,26 @@ static void mallinfo_handler(FAR struct mm_allocnode_s 
*node, FAR void *arg)
     }
 }
 
+#ifdef CONFIG_DEBUG_MM
+static void mallinfo_task_handler(FAR struct mm_allocnode_s *node,
+                                  FAR void *arg)
+{
+  FAR struct mallinfo_task *info = arg;
+
+  /* Check if the node corresponds to an allocated memory chunk */
+
+  if ((node->preceding & MM_ALLOC_BIT) != 0)
+    {
+      DEBUGASSERT(node->size >= SIZEOF_MM_ALLOCNODE);
+      if (node->pid == info->pid)
+        {
+          info->aordblks++;
+          info->uordblks += node->size;
+        }
+    }
+}
+#endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -107,3 +127,25 @@ int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct 
mallinfo *info)
 
   return OK;
 }
+
+/****************************************************************************
+ * Name: mm_mallinfo_task
+ *
+ * Description:
+ *   mallinfo returns a copy of updated current heap information for task
+ *   with pid.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_MM
+int mm_mallinfo_task(FAR struct mm_heap_s *heap,
+                     FAR struct mallinfo_task *info)
+{
+  DEBUGASSERT(info);
+
+  info->uordblks = 0;
+  info->aordblks = 0;
+  mm_foreach(heap, mallinfo_task_handler, info);
+  return OK;
+}
+#endif
diff --git a/mm/umm_heap/umm_mallinfo.c b/mm/umm_heap/umm_mallinfo.c
index 2176095..e59cfa8 100644
--- a/mm/umm_heap/umm_mallinfo.c
+++ b/mm/umm_heap/umm_mallinfo.c
@@ -49,3 +49,23 @@ struct mallinfo mallinfo(void)
   mm_mallinfo(USR_HEAP, &info);
   return info;
 }
+
+/****************************************************************************
+ * Name: mallinfo_task
+ *
+ * Description:
+ *   mallinfo_task returns a copy of updated current heap information of
+ *   task with specified pid for the user heap.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_MM
+struct mallinfo_task mallinfo_task(pid_t pid)
+{
+  struct mallinfo_task info;
+
+  info.pid = pid;
+  mm_mallinfo_task(USR_HEAP, &info);
+  return info;
+}
+#endif

Reply via email to