]> granicus.if.org Git - sysstat/commitdiff
Add %wait to pidstat
authorgeekben <bn0418@gmail.com>
Mon, 6 Feb 2017 07:11:13 +0000 (15:11 +0800)
committergeekben <bn0418@gmail.com>
Mon, 6 Feb 2017 07:34:17 +0000 (15:34 +0800)
%wait: percentage of CPU spent by the task while waiting to run

man/pidstat.1
pidstat.c
pidstat.h

index 756f88f065961f4aa86a6b39bcb9e2db9912d4e0..56920b0e0b20efd87b8d1bb56c8baaf72e737837 100644 (file)
@@ -400,6 +400,11 @@ Percentage of CPU spent by the task in virtual machine (running a virtual
 processor).
 .RE
 
+.B %wait
+.RS
+Percentage of CPU spent by the task while waiting to run.
+.RE
+
 .B %CPU
 .RS
 Total percentage of CPU time used by the task. In an SMP environment,
index 5412ddee5045411c720085a660341b2bc8e03510..6854fae8e9a3bfb9c9522c5265df339d1c3e9bed 100644 (file)
--- a/pidstat.c
+++ b/pidstat.c
@@ -411,6 +411,63 @@ int read_proc_pid_stat(unsigned int pid, struct pid_stats *pst,
        return 0;
 }
 
+/*
+ ***************************************************************************
+ * Read stats from /proc/#[/task/##]/schedstat.
+ *
+ * IN:
+ * @pid                Process whose stats are to be read.
+ * @pst                Pointer on structure where stats will be saved.
+ * @tgid       If !=0, thread whose stats are to be read.
+ *
+ * OUT:
+ * @pst                Pointer on structure where stats have been saved.
+ * @thread_nr  Number of threads of the process.
+ *
+ * RETURNS:
+ * 0 if stats have been successfully read, and 1 otherwise.
+ ***************************************************************************
+ */
+int read_proc_pid_sched(unsigned int pid, struct pid_stats *pst,
+                      unsigned int *thread_nr, unsigned int tgid)
+{
+       int fd, sz, rc;
+       char filename[128];
+       static char buffer[1024 + 1];
+       unsigned long long wtime;
+
+       if (tgid) {
+               sprintf(filename, TASK_SCHED, tgid, pid);
+       }
+       else {
+               sprintf(filename, PID_SCHED, pid);
+       }
+
+       if ((fd = open(filename, O_RDONLY)) < 0)
+               /* No such process */
+               return 1;
+
+       sz = read(fd, buffer, 1024);
+       close(fd);
+       if (sz <= 0)
+               return 1;
+       buffer[sz] = '\0';
+
+       rc = sscanf(buffer,
+                   "%*u %llu %*d\n",
+                   &wtime);
+
+       if (rc < 1)
+               return 1;
+
+       /* convert ns to jiffies */
+       pst->wtime = wtime * HZ / 1000000000;
+
+       pst->pid = pid;
+       pst->tgid = tgid;
+       return 0;
+}
+
 /*
  *****************************************************************************
  * Read stats from /proc/#[/task/##]/status.
@@ -728,6 +785,9 @@ int read_pid_stats(unsigned int pid, struct pid_stats *pst,
        if (read_proc_pid_stat(pid, pst, thread_nr, tgid))
                return 1;
 
+       if (read_proc_pid_sched(pid, pst, thread_nr, tgid))
+               return 1;
+
        if (DISPLAY_CMDLINE(pidflag)) {
                if (read_proc_pid_cmdline(pid, pst, tgid))
                        return 1;
@@ -1573,7 +1633,7 @@ int write_pid_task_cpu_stats(int prev, int curr, int dis, int disp_avg,
 
        if (dis) {
                PRINT_ID_HDR(prev_string, pidflag);
-               printf("    %%usr %%system  %%guest    %%CPU   CPU  Command\n");
+               printf("    %%usr %%system  %%guest   %%wait    %%CPU   CPU  Command\n");
        }
 
        for (p = 0; p < pid_nr; p++) {
@@ -1583,13 +1643,14 @@ int write_pid_task_cpu_stats(int prev, int curr, int dis, int disp_avg,
                        continue;
 
                print_line_id(curr_string, pstc);
-               cprintf_pc(4, 7, 2,
+               cprintf_pc(5, 7, 2,
                           (pstc->utime - pstc->gtime) < (pstp->utime - pstp->gtime) ?
                           0.0 :
                           SP_VALUE_100(pstp->utime - pstp->gtime,
                                    pstc->utime - pstc->gtime, itv),
                           SP_VALUE_100(pstp->stime, pstc->stime, itv),
                           SP_VALUE_100(pstp->gtime, pstc->gtime, itv),
+                          SP_VALUE_100(pstp->wtime, pstc->wtime, itv),
                           /* User time already includes guest time */
                           IRIX_MODE_OFF(pidflag) ?
                           SP_VALUE_100(pstp->utime + pstp->stime,
index f58ee0c0e9674423001834b22d9b27742e6b4203..61d46fb4c2e1d8a86fa7a0b527a9a7d0223cbe24 100644 (file)
--- a/pidstat.h
+++ b/pidstat.h
 #define PID_CMDLINE    "/proc/%u/cmdline"
 #define PID_SMAP       "/proc/%u/smaps"
 #define PID_FD         "/proc/%u/fd"
+#define PID_SCHED      "/proc/%u/schedstat"
 
 #define PROC_TASK      "/proc/%u/task"
 #define TASK_STAT      "/proc/%u/task/%u/stat"
+#define TASK_SCHED     "/proc/%u/task/%u/schedstat"
 #define TASK_STATUS    "/proc/%u/task/%u/status"
 #define TASK_IO                "/proc/%u/task/%u/io"
 #define TASK_CMDLINE   "/proc/%u/task/%u/cmdline"
@@ -176,6 +178,7 @@ struct pid_stats {
        long long          cstime                       __attribute__ ((packed));
        unsigned long long gtime                        __attribute__ ((packed));
        long long          cgtime                       __attribute__ ((packed));
+       unsigned long long wtime                        __attribute__ ((packed));
        unsigned long long vsz                          __attribute__ ((packed));
        unsigned long long rss                          __attribute__ ((packed));
        unsigned long      nvcsw                        __attribute__ ((packed));