procfs: add heap info for every task
cat /proc/2/heap AllocSize: 512 AllocBlks: 10 Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
2dcc4a359d
commit
7ae3c572dc
|
@ -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>
|
||||
|
@ -86,6 +88,9 @@ enum proc_node_e
|
|||
#endif
|
||||
#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 */
|
||||
|
@ -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 */
|
||||
|
@ -307,6 +324,9 @@ static FAR const struct proc_node_s * const g_nodeinfo[] =
|
|||
#endif
|
||||
#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 */
|
||||
|
@ -330,6 +350,9 @@ static const struct proc_node_s * const g_level0info[] =
|
|||
#endif
|
||||
#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 */
|
||||
|
@ -876,6 +899,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
|
||||
****************************************************************************/
|
||||
|
@ -1483,6 +1558,11 @@ static ssize_t proc_read(FAR struct file *filep, FAR char *buffer,
|
|||
case PROC_CRITMON: /* Critical section monitor */
|
||||
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);
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 **************************************/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue