diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-02-23 10:55:01 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-02-23 10:55:01 -0600 |
commit | 7c745cd460ea7361719b9fd18a35491beed92623 (patch) | |
tree | b35642399f2cbe11bbe6c9a57f6cf2d90fea3ffb /nuttx/fs | |
parent | 875b32e8389ac6e06bfb328e992c1865445d96c1 (diff) | |
download | nuttx-7c745cd460ea7361719b9fd18a35491beed92623.tar.gz nuttx-7c745cd460ea7361719b9fd18a35491beed92623.tar.bz2 nuttx-7c745cd460ea7361719b9fd18a35491beed92623.zip |
CPU load calculations now available for all threads. Available in /proc/pid/loadavg
Diffstat (limited to 'nuttx/fs')
-rw-r--r-- | nuttx/fs/procfs/fs_procfscpuload.c | 40 | ||||
-rw-r--r-- | nuttx/fs/procfs/fs_procfsproc.c | 83 |
2 files changed, 98 insertions, 25 deletions
diff --git a/nuttx/fs/procfs/fs_procfscpuload.c b/nuttx/fs/procfs/fs_procfscpuload.c index a1f8179bf..75572dee3 100644 --- a/nuttx/fs/procfs/fs_procfscpuload.c +++ b/nuttx/fs/procfs/fs_procfscpuload.c @@ -207,9 +207,6 @@ static ssize_t cpuload_read(FAR struct file *filep, FAR char *buffer, size_t buflen) { FAR struct cpuload_file_s *attr; - uint32_t cpuload; - uint32_t cpuload_int; - uint32_t cpuload_frac; size_t linesize; off_t offset; ssize_t ret; @@ -230,40 +227,37 @@ static ssize_t cpuload_read(FAR struct file *filep, FAR char *buffer, if (filep->f_pos == 0) { - uint32_t idle; - uint32_t busycnt; - uint32_t verify; + struct cpuload_s cpuload; + uint32_t intpart; + uint32_t fracpart; - /* Sample the counts, repeatedly if necessary to assure that they are - * in sync. + /* Sample the counts for the IDLE thread. clock_cpuload should only + * fail if the PID is not valid. This, however, should never happen + * for the IDLE thread. */ - do - { - busycnt = g_cpuload.cnt; - idle = g_cpuload.idle; - verify = g_cpuload.cnt; - } - while (busycnt != verify); + DEBUGVERIFY(clock_cpuload(0, &cpuload)); - /* On the simulator, you may hit busycnt == 0, but probably never on + /* On the simulator, you may hit cpuload.total == 0, but probably never on * real hardware. */ - if (busycnt > 0) + if (cpuload.total > 0) { - cpuload = 1000 - (1000 * idle) / busycnt; - cpuload_int = cpuload / 10; - cpuload_frac = cpuload - 10 * cpuload_int; + uint32_t tmp; + + tmp = 1000 - (1000 * cpuload.active) / cpuload.total; + intpart = tmp / 10; + fracpart = tmp - 10 * intpart; } else { - cpuload_int = 0; - cpuload_frac = 0; + intpart = 0; + fracpart = 0; } linesize = snprintf(attr->line, CPULOAD_LINELEN, "%3d.%01d%%\n", - cpuload_int, cpuload_frac); + intpart, fracpart); /* Save the linesize in case we are re-entered with f_pos > 0 */ diff --git a/nuttx/fs/procfs/fs_procfsproc.c b/nuttx/fs/procfs/fs_procfsproc.c index 1fc90b096..a1ec1b898 100644 --- a/nuttx/fs/procfs/fs_procfsproc.c +++ b/nuttx/fs/procfs/fs_procfsproc.c @@ -60,6 +60,10 @@ #include <nuttx/fs/procfs.h> #include <nuttx/fs/dirent.h> +#ifdef CONFIG_SCHED_CPULOAD +# include <nuttx/clock.h> +#endif + #include <arch/irq.h> #if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) @@ -86,6 +90,9 @@ enum proc_node_e PROC_LEVEL0 = 0, /* The top-level directory */ PROC_STATUS, /* Task/thread status */ PROC_CMDLINE, /* Task command line */ +#ifdef CONFIG_SCHED_CPULOAD + PROC_LOADAVG, /* Average CPU utilization */ +#endif PROC_STACK, /* Task stack info */ PROC_GROUP, /* Group directory */ PROC_GROUP_STATUS, /* Task group status */ @@ -136,6 +143,11 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile, static ssize_t proc_cmdline(FAR struct proc_file_s *procfile, FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen, off_t offset); +#ifdef CONFIG_SCHED_CPULOAD +static ssize_t proc_loadavg(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); @@ -211,6 +223,13 @@ static const struct proc_node_s g_cmdline = "cmdline", "cmdline", (uint8_t)PROC_CMDLINE, DTYPE_FILE /* Task command line */ }; +#ifdef CONFIG_SCHED_CPULOAD +static const struct proc_node_s g_loadavg = +{ + "loadavg", "loadavg", (uint8_t)PROC_LOADAVG, DTYPE_FILE /* Average CPU utilization */ +}; +#endif + static const struct proc_node_s g_stack = { "stack", "stack", (uint8_t)PROC_STACK, DTYPE_FILE /* Task stack info */ @@ -237,6 +256,9 @@ static FAR const struct proc_node_s * const g_nodeinfo[] = { &g_status, /* Task/thread status */ &g_cmdline, /* Task command line */ +#ifdef CONFIG_SCHED_CPULOAD + &g_loadavg, /* Average CPU utilization */ +#endif &g_stack, /* Task stack info */ &g_group, /* Group directory */ &g_groupstatus, /* Task group status */ @@ -250,6 +272,9 @@ static const struct proc_node_s * const g_level0info[] = { &g_status, /* Task/thread status */ &g_cmdline, /* Task command line */ +#ifdef CONFIG_SCHED_CPULOAD + &g_loadavg, /* Average CPU utilization */ +#endif &g_stack, /* Task stack info */ &g_group, /* Group directory */ }; @@ -518,12 +543,61 @@ static ssize_t proc_cmdline(FAR struct proc_file_s *procfile, } /**************************************************************************** + * Name: proc_loadavg + ****************************************************************************/ + +#ifdef CONFIG_SCHED_CPULOAD +static ssize_t proc_loadavg(FAR struct proc_file_s *procfile, + FAR struct tcb_s *tcb, FAR char *buffer, + size_t buflen, off_t offset) +{ + struct cpuload_s cpuload; + uint32_t intpart; + uint32_t fracpart; + size_t linesize; + size_t copysize; + ssize_t ret; + + /* Sample the counts for the thread. clock_cpuload should only fail if + * the PID is not valid. This could happen if the thread exited sometime + * after the procfs entry was opened. + */ + + ret = (ssize_t)clock_cpuload(procfile->pid, &cpuload); + + /* On the simulator, you may hit cpuload.total == 0, but probably never on + * real hardware. + */ + + if (cpuload.total > 0) + { + uint32_t tmp; + + tmp = 1000 - (1000 * cpuload.active) / cpuload.total; + intpart = tmp / 10; + fracpart = tmp - 10 * intpart; + } + else + { + intpart = 0; + fracpart = 0; + } + + linesize = snprintf(procfile->line, STATUS_LINELEN, "%3d.%01d%%\n", + intpart, fracpart); + copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen, &offset); + + return copysize; +} +#endif + +/**************************************************************************** * Name: proc_stack ****************************************************************************/ 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) + FAR struct tcb_s *tcb, FAR char *buffer, + size_t buflen, off_t offset) { size_t remaining; size_t linesize; @@ -986,6 +1060,11 @@ static ssize_t proc_read(FAR struct file *filep, FAR char *buffer, ret = proc_cmdline(procfile, tcb, buffer, buflen, filep->f_pos); break; +#ifdef CONFIG_SCHED_CPULOAD + case PROC_LOADAVG: /* Average CPU utilization */ + ret = proc_loadavg(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; |