2 * pidstat: Report statistics for Linux tasks
3 * (C) 2007-2016 by Sebastien GODARD (sysstat <at> orange.fr)
5 ***************************************************************************
6 * This program is free software; you can redistribute it and/or modify it *
7 * under the terms of the GNU General Public License as published by the *
8 * Free Software Foundation; either version 2 of the License, or (at your *
9 * option) any later version. *
11 * This program is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY *
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
16 * You should have received a copy of the GNU General Public License along *
17 * with this program; if not, write to the Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA *
19 ***************************************************************************
30 #include <sys/types.h>
32 #include <sys/utsname.h>
34 #include <linux/sched.h>
45 #define _(string) gettext(string)
47 #define _(string) (string)
50 #define SCCSID "@(#)sysstat-" VERSION ": " __FILE__ " compiled " __DATE__ " " __TIME__
51 char *sccsid(void) { return (SCCSID); }
53 unsigned long long uptime[3] = {0, 0, 0};
54 unsigned long long uptime0[3] = {0, 0, 0};
55 struct pid_stats *st_pid_list[3] = {NULL, NULL, NULL};
56 unsigned int *pid_array = NULL;
57 struct pid_stats st_pid_null;
58 struct tm ps_tstamp[3];
59 char commstr[MAX_COMM_LEN];
60 char userstr[MAX_USER_LEN];
61 char procstr[MAX_COMM_LEN];
62 int show_threads = FALSE;
64 unsigned int pid_nr = 0; /* Nb of PID to display */
65 unsigned int pid_array_nr = 0;
66 int cpu_nr = 0; /* Nb of processors on the machine */
67 unsigned long tlmkb; /* Total memory in kB */
70 unsigned int pidflag = 0; /* General flags */
71 unsigned int tskflag = 0; /* TASK/CHILD stats */
72 unsigned int actflag = 0; /* Activity flag */
74 struct sigaction alrm_act, int_act;
75 int sigint_caught = 0;
78 ***************************************************************************
79 * Print usage and exit.
82 * @progname Name of sysstat command
83 ***************************************************************************
85 void usage(char *progname)
87 fprintf(stderr, _("Usage: %s [ options ] [ <interval> [ <count> ] ]\n"),
90 fprintf(stderr, _("Options are:\n"
91 "[ -d ] [ -h ] [ -I ] [ -l ] [ -R ] [ -r ] [ -s ] [ -t ] [ -U [ <username> ] ]\n"
92 "[ -u ] [ -V ] [ -v ] [ -w ] [ -C <command> ] [ -G <process_name> ]\n"
93 "[ -p { <pid> [,...] | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ]\n"));
98 ***************************************************************************
99 * SIGALRM signal handler. No need to resert the handler here.
102 * @sig Signal number.
103 ***************************************************************************
105 void alarm_handler(int sig)
111 ***************************************************************************
112 * SIGINT signal handler.
115 * @sig Signal number.
116 ***************************************************************************
118 void int_handler(int sig)
124 ***************************************************************************
125 * Initialize uptime variables.
126 ***************************************************************************
128 void init_stats(void)
130 memset(&st_pid_null, 0, PID_STATS_SIZE);
134 ***************************************************************************
135 * Allocate structures for PIDs entered on command line.
138 * @len Number of PIDs entered on the command line.
139 ***************************************************************************
141 void salloc_pid_array(unsigned int len)
143 if ((pid_array = (unsigned int *) malloc(sizeof(unsigned int) * len)) == NULL) {
147 memset(pid_array, 0, sizeof(int) * len);
151 ***************************************************************************
152 * Allocate structures for PIDs to read.
155 * @len Number of PIDs (and TIDs) on the system.
156 ***************************************************************************
158 void salloc_pid(unsigned int len)
162 for (i = 0; i < 3; i++) {
163 if ((st_pid_list[i] = (struct pid_stats *) calloc(len, PID_STATS_SIZE)) == NULL) {
171 ***************************************************************************
172 * Reallocate structures for PIDs to read.
173 ***************************************************************************
175 void realloc_pid(void)
178 unsigned int new_size = 2 * pid_nr;
180 for (i = 0; i < 3; i++) {
181 if ((st_pid_list[i] = (struct pid_stats *) realloc(st_pid_list[i], PID_STATS_SIZE * new_size)) == NULL) {
185 memset(st_pid_list[i] + pid_nr, 0, PID_STATS_SIZE * (new_size - pid_nr));
192 ***************************************************************************
193 * Free PID list structures.
194 ***************************************************************************
200 for (i = 0; i < 3; i++) {
201 free(st_pid_list[i]);
206 ***************************************************************************
207 * Check flags and set default values.
208 ***************************************************************************
210 void check_flags(void)
212 unsigned int act = 0;
214 /* Display CPU usage for active tasks by default */
219 if (!DISPLAY_PID(pidflag)) {
220 pidflag |= P_D_ACTIVE_PID + P_D_PID + P_D_ALL_PID;
227 /* Check that requested activities are available */
228 if (DISPLAY_TASK_STATS(tskflag)) {
229 act |= P_A_CPU + P_A_MEM + P_A_IO + P_A_CTXSW
230 + P_A_STACK + P_A_KTAB + P_A_RT;
232 if (DISPLAY_CHILD_STATS(tskflag)) {
233 act |= P_A_CPU + P_A_MEM;
239 fprintf(stderr, _("Requested activities not available\n"));
245 ***************************************************************************
246 * Look for the PID in the list of PIDs entered on the command line, and
247 * store it if necessary.
250 * @pid_array_nr Length of the PID list.
251 * @pid PID to search.
254 * @pid_array_nr New length of the PID list.
257 * Returns the position of the PID in the list.
258 ***************************************************************************
260 int update_pid_array(unsigned int *pid_array_nr, unsigned int pid)
264 for (i = 0; i < *pid_array_nr; i++) {
265 if (pid_array[i] == pid)
269 if (i == *pid_array_nr) {
270 /* PID not found: Store it */
279 ***************************************************************************
280 * Get pointer on task's command string.
283 * @pst Pointer on structure with process stats and command line.
284 ***************************************************************************
286 char *get_tcmd(struct pid_stats *pst)
288 if (DISPLAY_CMDLINE(pidflag) && strlen(pst->cmdline))
289 /* Option "-l" used */
296 ***************************************************************************
297 * Display process command name or command line.
300 * @pst Pointer on structure with process stats and command line.
301 ***************************************************************************
303 void print_comm(struct pid_stats *pst)
307 /* Get pointer on task's command string */
311 cprintf_s(IS_ZERO, " |__%s\n", p);
314 cprintf_s(IS_STR, " %s\n", p);
319 ***************************************************************************
320 * Read /proc/meminfo.
321 ***************************************************************************
323 void read_proc_meminfo(void)
325 struct stats_memory st_mem;
327 memset(&st_mem, 0, STATS_MEMORY_SIZE);
328 read_meminfo(&st_mem);
329 tlmkb = st_mem.tlmkb;
333 ***************************************************************************
334 * Read stats from /proc/#[/task/##]/stat.
337 * @pid Process whose stats are to be read.
338 * @pst Pointer on structure where stats will be saved.
339 * @tgid If !=0, thread whose stats are to be read.
342 * @pst Pointer on structure where stats have been saved.
343 * @thread_nr Number of threads of the process.
346 * 0 if stats have been successfully read, and 1 otherwise.
347 ***************************************************************************
349 int read_proc_pid_stat(unsigned int pid, struct pid_stats *pst,
350 unsigned int *thread_nr, unsigned int tgid)
352 int fd, sz, rc, commsz;
354 static char buffer[1024 + 1];
358 sprintf(filename, TASK_STAT, tgid, pid);
361 sprintf(filename, PID_STAT, pid);
364 if ((fd = open(filename, O_RDONLY)) < 0)
365 /* No such process */
368 sz = read(fd, buffer, 1024);
374 if ((start = strchr(buffer, '(')) == NULL)
377 if ((end = strrchr(start, ')')) == NULL)
379 commsz = end - start;
380 if (commsz >= MAX_COMM_LEN)
382 memcpy(pst->comm, start, commsz);
383 pst->comm[commsz] = '\0';
387 "%*s %*d %*d %*d %*d %*d %*u %llu %llu"
388 " %llu %llu %llu %llu %lld %lld %*d %*d %u %*u %*d %llu %llu"
389 " %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u"
390 " %*u %u %u %u %llu %llu %lld\n",
391 &pst->minflt, &pst->cminflt, &pst->majflt, &pst->cmajflt,
392 &pst->utime, &pst->stime, &pst->cutime, &pst->cstime,
393 thread_nr, &pst->vsz, &pst->rss, &pst->processor,
394 &pst->priority, &pst->policy,
395 &pst->blkio_swapin_delays, &pst->gtime, &pst->cgtime);
401 /* gtime and cgtime fields are unavailable in file */
402 pst->gtime = pst->cgtime = 0;
407 pst->rss = PG_TO_KB(pst->rss);
415 *****************************************************************************
416 * Read stats from /proc/#[/task/##]/status.
419 * @pid Process whose stats are to be read.
420 * @pst Pointer on structure where stats will be saved.
421 * @tgid If !=0, thread whose stats are to be read.
424 * @pst Pointer on structure where stats have been saved.
427 * 0 if stats have been successfully read, and 1 otherwise.
428 *****************************************************************************
430 int read_proc_pid_status(unsigned int pid, struct pid_stats *pst,
434 char filename[128], line[256];
437 sprintf(filename, TASK_STATUS, tgid, pid);
440 sprintf(filename, PID_STATUS, pid);
443 if ((fp = fopen(filename, "r")) == NULL)
444 /* No such process */
447 while (fgets(line, sizeof(line), fp) != NULL) {
449 if (!strncmp(line, "Uid:", 4)) {
450 sscanf(line + 5, "%u", &pst->uid);
452 else if (!strncmp(line, "Threads:", 8)) {
453 sscanf(line + 9, "%u", &pst->threads);
455 else if (!strncmp(line, "voluntary_ctxt_switches:", 24)) {
456 sscanf(line + 25, "%lu", &pst->nvcsw);
458 else if (!strncmp(line, "nonvoluntary_ctxt_switches:", 27)) {
459 sscanf(line + 28, "%lu", &pst->nivcsw);
471 *****************************************************************************
472 * Read information from /proc/#[/task/##}/smaps.
474 * @pid Process whose stats are to be read.
475 * @pst Pointer on structure where stats will be saved.
476 * @tgid If !=0, thread whose stats are to be read.
479 * @pst Pointer on structure where stats have been saved.
482 * 0 if stats have been successfully read, and 1 otherwise.
483 *****************************************************************************
485 int read_proc_pid_smap(unsigned int pid, struct pid_stats *pst, unsigned int tgid)
488 char filename[128], line[256];
492 sprintf(filename, TASK_SMAP, tgid, pid);
495 sprintf(filename, PID_SMAP, pid);
498 if ((fp = fopen(filename, "rt")) == NULL)
499 /* No such process */
502 while ((state < 3) && (fgets(line, sizeof(line), fp) != NULL)) {
505 if (strstr(line, "[stack]")) {
510 if (strstr(line, "Size:")) {
511 sscanf(line + sizeof("Size:"), "%lu", &pst->stack_size);
516 if (strstr(line, "Referenced:")) {
517 sscanf(line + sizeof("Referenced:"), "%lu", &pst->stack_ref);
532 *****************************************************************************
533 * Read process command line from /proc/#[/task/##]/cmdline.
536 * @pid Process whose command line is to be read.
537 * @pst Pointer on structure where command line will be saved.
538 * @tgid If !=0, thread whose command line is to be read.
541 * @pst Pointer on structure where command line has been saved.
544 * 0 if command line has been successfully read (even if the /proc/.../cmdline
545 * is just empty), and 1 otherwise (the process has terminated).
546 *****************************************************************************
548 int read_proc_pid_cmdline(unsigned int pid, struct pid_stats *pst,
552 char filename[128], line[MAX_CMDLINE_LEN];
557 sprintf(filename, TASK_CMDLINE, tgid, pid);
560 sprintf(filename, PID_CMDLINE, pid);
563 if ((fp = fopen(filename, "r")) == NULL)
564 /* No such process */
567 memset(line, 0, MAX_CMDLINE_LEN);
569 len = fread(line, 1, MAX_CMDLINE_LEN - 1, fp);
572 for (i = 0; i < len; i++) {
573 if (line[i] == '\0') {
579 strncpy(pst->cmdline, line, MAX_CMDLINE_LEN - 1);
580 pst->cmdline[MAX_CMDLINE_LEN - 1] = '\0';
583 /* proc/.../cmdline was empty */
584 pst->cmdline[0] = '\0';
590 ***************************************************************************
591 * Read stats from /proc/#[/task/##]/io.
594 * @pid Process whose stats are to be read.
595 * @pst Pointer on structure where stats will be saved.
596 * @tgid If !=0, thread whose stats are to be read.
599 * @pst Pointer on structure where stats have been saved.
602 * 0 if stats have been successfully read.
603 * Also returns 0 if current process has terminated or if its io file
604 * doesn't exist, but in this case, set process' F_NO_PID_IO flag to
605 * indicate that I/O stats should no longer be read for it.
606 ***************************************************************************
608 int read_proc_pid_io(unsigned int pid, struct pid_stats *pst,
612 char filename[128], line[256];
615 sprintf(filename, TASK_IO, tgid, pid);
618 sprintf(filename, PID_IO, pid);
621 if ((fp = fopen(filename, "r")) == NULL) {
622 /* No such process... or file non existent! */
623 pst->flags |= F_NO_PID_IO;
625 * Also returns 0 since io stats file doesn't necessarily exist,
626 * depending on the kernel version used.
631 while (fgets(line, sizeof(line), fp) != NULL) {
633 if (!strncmp(line, "read_bytes:", 11)) {
634 sscanf(line + 12, "%llu", &pst->read_bytes);
636 else if (!strncmp(line, "write_bytes:", 12)) {
637 sscanf(line + 13, "%llu", &pst->write_bytes);
639 else if (!strncmp(line, "cancelled_write_bytes:", 22)) {
640 sscanf(line + 23, "%llu", &pst->cancelled_write_bytes);
648 pst->flags &= ~F_NO_PID_IO;
653 ***************************************************************************
654 * Count number of file descriptors in /proc/#[/task/##]/fd directory.
657 * @pid Process whose stats are to be read.
658 * @pst Pointer on structure where stats will be saved.
659 * @tgid If !=0, thread whose stats are to be read.
662 * @pst Pointer on structure where stats have been saved.
665 * 0 if stats have been successfully read.
666 * Also returns 0 if current process has terminated or if we cannot read its
667 * fd directory, but in this case, set process' F_NO_PID_FD flag to
668 * indicate that fd directory couldn't be read.
669 ***************************************************************************
671 int read_proc_pid_fd(unsigned int pid, struct pid_stats *pst,
679 sprintf(filename, TASK_FD, tgid, pid);
682 sprintf(filename, PID_FD, pid);
685 if ((dir = opendir(filename)) == NULL) {
686 /* Cannot read fd directory */
687 pst->flags |= F_NO_PID_FD;
693 /* Count number of entries if fd directory */
694 while ((drp = readdir(dir)) != NULL) {
695 if (isdigit(drp->d_name[0])) {
704 pst->flags &= ~F_NO_PID_FD;
709 ***************************************************************************
710 * Read various stats for given PID.
713 * @pid Process whose stats are to be read.
714 * @pst Pointer on structure where stats will be saved.
715 * @tgid If !=0, thread whose stats are to be read.
718 * @pst Pointer on structure where stats have been saved.
719 * @thread_nr Number of threads of the process.
722 * 0 if stats have been successfully read, and 1 otherwise.
723 ***************************************************************************
725 int read_pid_stats(unsigned int pid, struct pid_stats *pst,
726 unsigned int *thread_nr, unsigned int tgid)
728 if (read_proc_pid_stat(pid, pst, thread_nr, tgid))
731 if (DISPLAY_CMDLINE(pidflag)) {
732 if (read_proc_pid_cmdline(pid, pst, tgid))
736 if (read_proc_pid_status(pid, pst, tgid))
739 if (DISPLAY_STACK(actflag)) {
740 if (read_proc_pid_smap(pid, pst, tgid))
744 if (DISPLAY_KTAB(actflag)) {
745 if (read_proc_pid_fd(pid, pst, tgid))
749 if (DISPLAY_IO(actflag))
750 /* Assume that /proc/#/task/#/io exists! */
751 return (read_proc_pid_io(pid, pst, tgid));
757 ***************************************************************************
758 * Count number of threads in /proc/#/task directory, including the leader
762 * @pid Process number for which the number of threads are to be counted.
765 * Number of threads for the given process (min value is 1).
766 * A value of 0 indicates that the process has terminated.
767 ***************************************************************************
769 unsigned int count_tid(unsigned int pid)
771 struct pid_stats pst;
772 unsigned int thread_nr;
774 if (read_proc_pid_stat(pid, &pst, &thread_nr, 0) != 0)
775 /* Task no longer exists */
782 ***************************************************************************
783 * Count number of processes (and threads).
786 * Number of processes (and threads if requested).
787 ***************************************************************************
789 unsigned int count_pid(void)
793 unsigned int pid = 0;
795 /* Open /proc directory */
796 if ((dir = opendir(PROC)) == NULL) {
801 /* Get directory entries */
802 while ((drp = readdir(dir)) != NULL) {
803 if (isdigit(drp->d_name[0])) {
804 /* There is at least the TGID */
806 if (DISPLAY_TID(pidflag)) {
807 pid += count_tid(atoi(drp->d_name));
812 /* Close /proc directory */
819 ***************************************************************************
820 * Count number of threads associated with the tasks entered on the command
824 * Number of threads (including the leading one) associated with every task
825 * entered on the command line.
826 ***************************************************************************
828 unsigned int count_tid_in_list(void)
830 unsigned int p, tid, pid = 0;
832 for (p = 0; p < pid_array_nr; p++) {
834 tid = count_tid(pid_array[p]);
837 /* PID no longer exists */
841 /* <tid_value> TIDs + 1 TGID */
850 ***************************************************************************
851 * Allocate and init structures according to system state.
852 ***************************************************************************
854 void pid_sys_init(void)
856 /* Init stat common counters */
859 /* Count nb of proc */
860 cpu_nr = get_cpu_nr(~0, FALSE);
862 if (DISPLAY_ALL_PID(pidflag)) {
863 /* Count PIDs and allocate structures */
864 pid_nr = count_pid() + NR_PID_PREALLOC;
867 else if (DISPLAY_TID(pidflag)) {
868 /* Count total number of threads associated with tasks in list */
869 pid_nr = count_tid_in_list() + NR_PID_PREALLOC;
873 pid_nr = pid_array_nr;
879 ***************************************************************************
880 * Read stats for threads in /proc/#/task directory.
883 * @curr Index in array for current sample statistics.
884 * @pid Process number whose threads stats are to be read.
885 * @index Index in process list where stats will be saved.
888 * @index Index in process list where next stats will be saved.
889 ***************************************************************************
891 void read_task_stats(int curr, unsigned int pid, unsigned int *index)
896 struct pid_stats *pst;
899 /* Open /proc/#/task directory */
900 sprintf(filename, PROC_TASK, pid);
901 if ((dir = opendir(filename)) == NULL)
904 while ((drp = readdir(dir)) != NULL) {
905 if (!isdigit(drp->d_name[0])) {
909 pst = st_pid_list[curr] + (*index)++;
910 if (read_pid_stats(atoi(drp->d_name), pst, &thr_nr, pid)) {
911 /* Thread no longer exists */
915 if (*index >= pid_nr) {
924 ***************************************************************************
925 * Read various stats.
928 * @curr Index in array for current sample statistics.
929 ***************************************************************************
931 void read_stats(int curr)
935 unsigned int p = 0, q, pid, thr_nr;
936 struct pid_stats *pst;
937 struct stats_cpu *st_cpu;
940 * Allocate two structures for CPU statistics.
941 * No need to init them (done by read_stat_cpu() function).
943 if ((st_cpu = (struct stats_cpu *) malloc(STATS_CPU_SIZE * 2)) == NULL) {
947 /* Read statistics for CPUs "all" and 0 */
948 read_stat_cpu(st_cpu, 2, &uptime[curr], &uptime0[curr]);
951 if (DISPLAY_ALL_PID(pidflag)) {
953 /* Open /proc directory */
954 if ((dir = opendir(PROC)) == NULL) {
959 /* Get directory entries */
960 while ((drp = readdir(dir)) != NULL) {
961 if (!isdigit(drp->d_name[0])) {
965 pst = st_pid_list[curr] + p++;
966 pid = atoi(drp->d_name);
968 if (read_pid_stats(pid, pst, &thr_nr, 0)) {
969 /* Process has terminated */
971 } else if (DISPLAY_TID(pidflag)) {
972 /* Read stats for threads in task subdirectory */
973 read_task_stats(curr, pid, &p);
981 for (q = p; q < pid_nr; q++) {
982 pst = st_pid_list[curr] + q;
986 /* Close /proc directory */
990 else if (DISPLAY_PID(pidflag)) {
993 /* Read stats for each PID in the list */
994 for (op = 0; op < pid_array_nr; op++) {
998 pst = st_pid_list[curr] + p++;
1000 if (pid_array[op]) {
1001 /* PID should still exist. So read its stats */
1002 if (read_pid_stats(pid_array[op], pst, &thr_nr, 0)) {
1003 /* PID has terminated */
1007 else if (DISPLAY_TID(pidflag)) {
1008 read_task_stats(curr, pid_array[op], &p);
1012 /* Reset remaining structures */
1013 for (q = p; q < pid_nr; q++) {
1014 pst = st_pid_list[curr] + q;
1019 /* else unknown command */
1023 ***************************************************************************
1024 * Get current PID to display.
1025 * First, check that PID exists. *Then* check that it's an active process
1026 * and/or that the string (entered on the command line with option -C)
1027 * is found in command name, or that the process string (entered on the
1028 * command line with option -G) is found either in its command name (in case
1029 * PID is a process) or in command name of its thread leader (in case
1033 * @prev Index in array where stats used as reference are.
1034 * @curr Index in array for current sample statistics.
1035 * @p Index in process list.
1036 * @activity Current activity to display (CPU, memory...).
1037 * Can be more than one if stats are displayed on one line.
1038 * @pflag Flag indicating whether stats are to be displayed for
1039 * individual tasks or for all their children.
1042 * @pstc Structure with PID statistics for current sample.
1043 * @pstp Structure with PID statistics for previous sample.
1046 * 0 if PID no longer exists.
1047 * -1 if PID exists but should not be displayed.
1048 * 1 if PID can be displayed.
1049 ***************************************************************************
1051 int get_pid_to_display(int prev, int curr, int p, unsigned int activity,
1053 struct pid_stats **pstc, struct pid_stats **pstp)
1057 struct passwd *pwdent;
1060 *pstc = st_pid_list[curr] + p;
1063 /* PID no longer exists */
1066 if (DISPLAY_ALL_PID(pidflag) || DISPLAY_TID(pidflag)) {
1068 /* Look for previous stats for same PID */
1072 *pstp = st_pid_list[prev] + q;
1073 if (((*pstp)->pid == (*pstc)->pid) &&
1074 ((*pstp)->tgid == (*pstc)->tgid))
1083 if (((*pstp)->pid != (*pstc)->pid) ||
1084 ((*pstp)->tgid != (*pstc)->tgid)) {
1085 /* PID not found (no data previously read) */
1086 *pstp = &st_pid_null;
1089 if (DISPLAY_ACTIVE_PID(pidflag)) {
1090 int isActive = FALSE;
1092 /* Check that it's an "active" process */
1093 if (DISPLAY_CPU(activity)) {
1094 /* User time already includes guest time */
1095 if (((*pstc)->utime != (*pstp)->utime) ||
1096 ((*pstc)->stime != (*pstp)->stime)) {
1101 * Process is not active but if we are showing
1102 * child stats then we need to look there.
1104 if (DISPLAY_CHILD_STATS(pflag)) {
1105 /* User time already includes guest time */
1106 if (((*pstc)->cutime != (*pstp)->cutime) ||
1107 ((*pstc)->cstime != (*pstp)->cstime)) {
1114 if (DISPLAY_MEM(activity) && (!isActive)) {
1115 if (((*pstc)->minflt != (*pstp)->minflt) ||
1116 ((*pstc)->majflt != (*pstp)->majflt)) {
1120 if (DISPLAY_TASK_STATS(pflag)) {
1121 if (((*pstc)->vsz != (*pstp)->vsz) ||
1122 ((*pstc)->rss != (*pstp)->rss)) {
1126 else if (DISPLAY_CHILD_STATS(pflag)) {
1127 if (((*pstc)->cminflt != (*pstp)->cminflt) ||
1128 ((*pstc)->cmajflt != (*pstp)->cmajflt)) {
1136 if (DISPLAY_STACK(activity) && (!isActive)) {
1137 if (((*pstc)->stack_size != (*pstp)->stack_size) ||
1138 ((*pstc)->stack_ref != (*pstp)->stack_ref)) {
1143 if (DISPLAY_IO(activity) && (!isActive)) {
1144 if ((*pstc)->blkio_swapin_delays !=
1145 (*pstp)->blkio_swapin_delays) {
1148 if (!(NO_PID_IO((*pstc)->flags)) && (!isActive)) {
1149 /* /proc/#/io file should exist to check I/O stats */
1150 if (((*pstc)->read_bytes != (*pstp)->read_bytes) ||
1151 ((*pstc)->write_bytes != (*pstp)->write_bytes) ||
1152 ((*pstc)->cancelled_write_bytes !=
1153 (*pstp)->cancelled_write_bytes)) {
1159 if (DISPLAY_CTXSW(activity) && (!isActive)) {
1160 if (((*pstc)->nvcsw != (*pstp)->nvcsw) ||
1161 ((*pstc)->nivcsw != (*pstp)->nivcsw)) {
1166 if (DISPLAY_RT(activity) && (!isActive)) {
1167 if (((*pstc)->priority != (*pstp)->priority) ||
1168 ((*pstc)->policy != (*pstp)->policy)) {
1173 if (DISPLAY_KTAB(activity) && (!isActive) &&
1174 /* /proc/#/fd directory should be readable */
1175 !(NO_PID_FD((*pstc)->flags))) {
1176 if (((*pstc)->threads != (*pstp)->threads) ||
1177 ((*pstc)->fd_nr != (*pstp)->fd_nr)) {
1182 /* If PID isn't active for any of the activities then return */
1188 else if (DISPLAY_PID(pidflag)) {
1189 *pstp = st_pid_list[prev] + p;
1190 if (!(*pstp)->pid) {
1192 /* PID no longer exists */
1196 * If interval is zero, then we are trying to
1197 * display stats for a given process since boot time.
1199 *pstp = &st_pid_null;
1204 if (COMMAND_STRING(pidflag)) {
1205 if (regcomp(®ex, commstr, REG_EXTENDED | REG_NOSUB) != 0)
1206 /* Error in preparing regex structure */
1209 pc = get_tcmd(*pstc); /* Get pointer on task's command string */
1210 rc = regexec(®ex, pc, 0, NULL, 0);
1214 /* regex pattern not found in command name */
1218 if (PROCESS_STRING(pidflag)) {
1219 if (!(*pstc)->tgid) {
1220 /* This PID is a process ("thread group leader") */
1221 if (regcomp(®ex, procstr, REG_EXTENDED | REG_NOSUB) != 0) {
1222 /* Error in preparing regex structure */
1223 show_threads = FALSE;
1227 pc = get_tcmd(*pstc); /* Get pointer on task's command string */
1228 rc = regexec(®ex, pc, 0, NULL, 0);
1232 /* regex pattern not found in command name */
1233 show_threads = FALSE;
1238 * This process and all its threads will be displayed.
1239 * No need to save PID value: For every process read by pidstat,
1240 * pidstat then immediately reads all its threads.
1242 show_threads = TRUE;
1244 else if (!show_threads) {
1245 /* This pid is a thread and is not part of a process to display */
1250 if (USER_STRING(pidflag)) {
1251 if ((pwdent = getpwuid((*pstc)->uid)) != NULL) {
1252 if (strcmp(pwdent->pw_name, userstr))
1253 /* This PID doesn't belong to user */
1262 ***************************************************************************
1263 * Display UID/username, PID and TID.
1266 * @pst Current process statistics.
1267 * @c No-op character.
1268 ***************************************************************************
1270 void __print_line_id(struct pid_stats *pst, char c)
1273 struct passwd *pwdent;
1275 if (DISPLAY_USERNAME(pidflag) && ((pwdent = getpwuid(pst->uid)) != NULL)) {
1276 cprintf_in(IS_STR, " %8s", pwdent->pw_name, 0);
1279 cprintf_in(IS_INT, " %5d", "", pst->uid);
1282 if (DISPLAY_TID(pidflag)) {
1286 sprintf(format, " %c %%9u", c);
1289 /* This is a PID (TGID) */
1290 sprintf(format, " %%9u %c", c);
1294 strcpy(format, " %9u");
1297 cprintf_in(IS_INT, format, "", pst->pid);
1301 ***************************************************************************
1302 * Display timestamp, PID and TID.
1305 * @timestamp Current timestamp.
1306 * @pst Current process statistics.
1307 ***************************************************************************
1309 void print_line_id(char *timestamp, struct pid_stats *pst)
1311 printf("%-11s", timestamp);
1313 __print_line_id(pst, '-');
1317 ***************************************************************************
1318 * Display all statistics for tasks in one line format.
1321 * @prev Index in array where stats used as reference are.
1322 * @curr Index in array for current sample statistics.
1323 * @dis TRUE if a header line must be printed.
1324 * @itv Interval of time in jiffies.
1325 * @g_itv Interval of time in jiffies multiplied by the number of
1329 * 0 if all the processes to display have terminated.
1330 * <> 0 if there are still some processes left to display.
1331 ***************************************************************************
1333 int write_pid_task_all_stats(int prev, int curr, int dis,
1334 unsigned long long itv,
1335 unsigned long long g_itv)
1337 struct pid_stats *pstc, *pstp;
1343 PRINT_ID_HDR("# Time", pidflag);
1344 if (DISPLAY_CPU(actflag)) {
1345 printf(" %%usr %%system %%guest %%CPU CPU");
1347 if (DISPLAY_MEM(actflag)) {
1348 printf(" minflt/s majflt/s VSZ RSS %%MEM");
1350 if (DISPLAY_STACK(actflag)) {
1351 printf(" StkSize StkRef");
1353 if (DISPLAY_IO(actflag)) {
1354 printf(" kB_rd/s kB_wr/s kB_ccwr/s iodelay");
1356 if (DISPLAY_CTXSW(actflag)) {
1357 printf(" cswch/s nvcswch/s");
1359 if (DISPLAY_KTAB(actflag)) {
1360 printf(" threads fd-nr");
1362 if (DISPLAY_RT(actflag)) {
1363 printf(" prio policy");
1365 printf(" Command\n");
1368 for (p = 0; p < pid_nr; p++) {
1370 if (get_pid_to_display(prev, curr, p, actflag, P_TASK,
1374 printf("%11ld", (long) time(NULL));
1375 __print_line_id(pstc, '0');
1377 if (DISPLAY_CPU(actflag)) {
1379 (pstc->utime - pstc->gtime) < (pstp->utime - pstp->gtime) ?
1381 SP_VALUE_100(pstp->utime - pstp->gtime,
1382 pstc->utime - pstc->gtime, itv),
1383 SP_VALUE_100(pstp->stime, pstc->stime, itv),
1384 SP_VALUE_100(pstp->gtime, pstc->gtime, itv),
1385 /* User time already includes guest time */
1386 IRIX_MODE_OFF(pidflag) ?
1387 SP_VALUE_100(pstp->utime + pstp->stime,
1388 pstc->utime + pstc->stime, g_itv) :
1389 SP_VALUE_100(pstp->utime + pstp->stime,
1390 pstc->utime + pstc->stime, itv));
1392 cprintf_in(IS_INT, " %3d", "", pstc->processor);
1395 if (DISPLAY_MEM(actflag)) {
1397 S_VALUE(pstp->minflt, pstc->minflt, itv),
1398 S_VALUE(pstp->majflt, pstc->majflt, itv));
1400 (unsigned long long) pstc->vsz,
1401 (unsigned long long) pstc->rss);
1403 tlmkb ? SP_VALUE(0, pstc->rss, tlmkb) : 0.0);
1406 if (DISPLAY_STACK(actflag)) {
1408 (unsigned long long) pstc->stack_size,
1409 (unsigned long long) pstc->stack_ref);
1412 if (DISPLAY_IO(actflag)) {
1413 if (!NO_PID_IO(pstc->flags))
1416 S_VALUE(pstp->read_bytes, pstc->read_bytes, itv) / 1024,
1417 S_VALUE(pstp->write_bytes, pstc->write_bytes, itv) / 1024,
1418 S_VALUE(pstp->cancelled_write_bytes,
1419 pstc->cancelled_write_bytes, itv) / 1024);
1423 * Keep the layout even though this task has no I/O
1424 * typically threads with no I/O measurements.
1426 sprintf(dstr, " %9.2f %9.2f %9.2f", -1.0, -1.0, -1.0);
1427 cprintf_s(IS_ZERO, "%s", dstr);
1429 /* I/O delays come from another file (/proc/#/stat) */
1431 (unsigned long long) (pstc->blkio_swapin_delays - pstp->blkio_swapin_delays));
1434 if (DISPLAY_CTXSW(actflag)) {
1436 S_VALUE(pstp->nvcsw, pstc->nvcsw, itv),
1437 S_VALUE(pstp->nivcsw, pstc->nivcsw, itv));
1440 if (DISPLAY_KTAB(actflag)) {
1442 (unsigned long long) pstc->threads);
1443 if (NO_PID_FD(pstc->flags)) {
1444 /* /proc/#/fd directory not readable */
1445 cprintf_s(IS_ZERO, " %7s", "-1");
1448 cprintf_u64(1, 7, (unsigned long long) pstc->fd_nr);
1452 if (DISPLAY_RT(actflag)) {
1454 (unsigned long long) pstc->priority);
1455 cprintf_s(IS_STR, " %6s",
1456 GET_POLICY(pstc->policy));
1467 ***************************************************************************
1468 * Display all statistics for tasks' children in one line format.
1471 * @prev Index in array where stats used as reference are.
1472 * @curr Index in array for current sample statistics.
1473 * @dis TRUE if a header line must be printed.
1474 * @itv Interval of time in jiffies.
1477 * 0 if all the processes to display have terminated.
1478 * <> 0 if there are still some processes left to display.
1479 ***************************************************************************
1481 int write_pid_child_all_stats(int prev, int curr, int dis,
1482 unsigned long long itv)
1484 struct pid_stats *pstc, *pstp;
1489 PRINT_ID_HDR("# Time", pidflag);
1490 if (DISPLAY_CPU(actflag))
1491 printf(" usr-ms system-ms guest-ms");
1492 if (DISPLAY_MEM(actflag))
1493 printf(" minflt-nr majflt-nr");
1494 printf(" Command\n");
1497 for (p = 0; p < pid_nr; p++) {
1499 if (get_pid_to_display(prev, curr, p, actflag, P_CHILD,
1503 printf("%11ld", (long) time(NULL));
1504 __print_line_id(pstc, '0');
1506 if (DISPLAY_CPU(actflag)) {
1508 (pstc->utime + pstc->cutime - pstc->gtime - pstc->cgtime) <
1509 (pstp->utime + pstp->cutime - pstp->gtime - pstp->cgtime) ?
1511 (double) ((pstc->utime + pstc->cutime - pstc->gtime - pstc->cgtime) -
1512 (pstp->utime + pstp->cutime - pstp->gtime - pstp->cgtime)) /
1514 (double) ((pstc->stime + pstc->cstime) -
1515 (pstp->stime + pstp->cstime)) / HZ * 1000,
1516 (double) ((pstc->gtime + pstc->cgtime) -
1517 (pstp->gtime + pstp->cgtime)) / HZ * 1000);
1520 if (DISPLAY_MEM(actflag)) {
1522 (unsigned long long) ((pstc->minflt + pstc->cminflt) - (pstp->minflt + pstp->cminflt)),
1523 (unsigned long long) ((pstc->majflt + pstc->cmajflt) - (pstp->majflt + pstp->cmajflt)));
1534 ***************************************************************************
1535 * Display CPU statistics for tasks.
1538 * @prev Index in array where stats used as reference are.
1539 * @curr Index in array for current sample statistics.
1540 * @dis TRUE if a header line must be printed.
1541 * @disp_avg TRUE if average stats are displayed.
1542 * @prev_string String displayed at the beginning of a header line. This is
1543 * the timestamp of the previous sample, or "Average" when
1544 * displaying average stats.
1545 * @curr_string String displayed at the beginning of current sample stats.
1546 * This is the timestamp of the current sample, or "Average"
1547 * when displaying average stats.
1548 * @itv Interval of time in jiffies.
1549 * @g_itv Interval of time in jiffies multiplied by the number of
1553 * 0 if all the processes to display have terminated.
1554 * <> 0 if there are still some processes left to display.
1555 ***************************************************************************
1557 int write_pid_task_cpu_stats(int prev, int curr, int dis, int disp_avg,
1558 char *prev_string, char *curr_string,
1559 unsigned long long itv,
1560 unsigned long long g_itv)
1562 struct pid_stats *pstc, *pstp;
1567 PRINT_ID_HDR(prev_string, pidflag);
1568 printf(" %%usr %%system %%guest %%CPU CPU Command\n");
1571 for (p = 0; p < pid_nr; p++) {
1573 if (get_pid_to_display(prev, curr, p, P_A_CPU, P_TASK,
1577 print_line_id(curr_string, pstc);
1579 (pstc->utime - pstc->gtime) < (pstp->utime - pstp->gtime) ?
1581 SP_VALUE_100(pstp->utime - pstp->gtime,
1582 pstc->utime - pstc->gtime, itv),
1583 SP_VALUE_100(pstp->stime, pstc->stime, itv),
1584 SP_VALUE_100(pstp->gtime, pstc->gtime, itv),
1585 /* User time already includes guest time */
1586 IRIX_MODE_OFF(pidflag) ?
1587 SP_VALUE_100(pstp->utime + pstp->stime,
1588 pstc->utime + pstc->stime, g_itv) :
1589 SP_VALUE_100(pstp->utime + pstp->stime,
1590 pstc->utime + pstc->stime, itv));
1593 cprintf_in(IS_INT, " %3d", "", pstc->processor);
1596 cprintf_in(IS_STR, "%s", " -", 0);
1606 ***************************************************************************
1607 * Display CPU statistics for tasks' children.
1610 * @prev Index in array where stats used as reference are.
1611 * @curr Index in array for current sample statistics.
1612 * @dis TRUE if a header line must be printed.
1613 * @disp_avg TRUE if average stats are displayed.
1614 * @prev_string String displayed at the beginning of a header line. This is
1615 * the timestamp of the previous sample, or "Average" when
1616 * displaying average stats.
1617 * @curr_string String displayed at the beginning of current sample stats.
1618 * This is the timestamp of the current sample, or "Average"
1619 * when displaying average stats.
1622 * 0 if all the processes to display have terminated.
1623 * <> 0 if there are still some processes left to display.
1624 ***************************************************************************
1626 int write_pid_child_cpu_stats(int prev, int curr, int dis, int disp_avg,
1627 char *prev_string, char *curr_string)
1629 struct pid_stats *pstc, *pstp;
1634 PRINT_ID_HDR(prev_string, pidflag);
1635 printf(" usr-ms system-ms guest-ms Command\n");
1638 for (p = 0; p < pid_nr; p++) {
1640 if ((rc = get_pid_to_display(prev, curr, p, P_A_CPU, P_CHILD,
1641 &pstc, &pstp)) == 0)
1642 /* PID no longer exists */
1645 /* This will be used to compute average */
1647 pstc->uc_asum_count = pstp->uc_asum_count + 1;
1651 /* PID should not be displayed */
1654 print_line_id(curr_string, pstc);
1657 (pstc->utime + pstc->cutime - pstc->gtime - pstc->cgtime) <
1658 (pstp->utime + pstp->cutime - pstp->gtime - pstp->cgtime) ?
1660 (double) ((pstc->utime + pstc->cutime - pstc->gtime - pstc->cgtime) -
1661 (pstp->utime + pstp->cutime - pstp->gtime - pstp->cgtime)) /
1662 (HZ * pstc->uc_asum_count) * 1000,
1663 (double) ((pstc->stime + pstc->cstime) -
1664 (pstp->stime + pstp->cstime)) /
1665 (HZ * pstc->uc_asum_count) * 1000,
1666 (double) ((pstc->gtime + pstc->cgtime) -
1667 (pstp->gtime + pstp->cgtime)) /
1668 (HZ * pstc->uc_asum_count) * 1000);
1672 (pstc->utime + pstc->cutime - pstc->gtime - pstc->cgtime) <
1673 (pstp->utime + pstp->cutime - pstp->gtime - pstp->cgtime) ?
1675 (double) ((pstc->utime + pstc->cutime - pstc->gtime - pstc->cgtime) -
1676 (pstp->utime + pstp->cutime - pstp->gtime - pstp->cgtime)) /
1678 (double) ((pstc->stime + pstc->cstime) -
1679 (pstp->stime + pstp->cstime)) / HZ * 1000,
1680 (double) ((pstc->gtime + pstc->cgtime) -
1681 (pstp->gtime + pstp->cgtime)) / HZ * 1000);
1691 ***************************************************************************
1692 * Display memory statistics for tasks.
1695 * @prev Index in array where stats used as reference are.
1696 * @curr Index in array for current sample statistics.
1697 * @dis TRUE if a header line must be printed.
1698 * @disp_avg TRUE if average stats are displayed.
1699 * @prev_string String displayed at the beginning of a header line. This is
1700 * the timestamp of the previous sample, or "Average" when
1701 * displaying average stats.
1702 * @curr_string String displayed at the beginning of current sample stats.
1703 * This is the timestamp of the current sample, or "Average"
1704 * when displaying average stats.
1705 * @itv Interval of time in jiffies.
1708 * 0 if all the processes to display have terminated.
1709 * <> 0 if there are still some processes left to display.
1710 ***************************************************************************
1712 int write_pid_task_memory_stats(int prev, int curr, int dis, int disp_avg,
1713 char *prev_string, char *curr_string,
1714 unsigned long long itv)
1716 struct pid_stats *pstc, *pstp;
1721 PRINT_ID_HDR(prev_string, pidflag);
1722 printf(" minflt/s majflt/s VSZ RSS %%MEM Command\n");
1725 for (p = 0; p < pid_nr; p++) {
1727 if ((rc = get_pid_to_display(prev, curr, p, P_A_MEM, P_TASK,
1728 &pstc, &pstp)) == 0)
1729 /* PID no longer exists */
1732 /* This will be used to compute average */
1734 pstc->total_vsz = pstp->total_vsz + pstc->vsz;
1735 pstc->total_rss = pstp->total_rss + pstc->rss;
1736 pstc->rt_asum_count = pstp->rt_asum_count + 1;
1740 /* PID should not be displayed */
1743 print_line_id(curr_string, pstc);
1746 S_VALUE(pstp->minflt, pstc->minflt, itv),
1747 S_VALUE(pstp->majflt, pstc->majflt, itv));
1751 (double) pstc->total_vsz / pstc->rt_asum_count,
1752 (double) pstc->total_rss / pstc->rt_asum_count);
1756 SP_VALUE(0, pstc->total_rss / pstc->rt_asum_count, tlmkb)
1761 (unsigned long long) pstc->vsz,
1762 (unsigned long long) pstc->rss);
1765 tlmkb ? SP_VALUE(0, pstc->rss, tlmkb) : 0.0);
1776 ***************************************************************************
1777 * Display memory statistics for tasks' children.
1780 * @prev Index in array where stats used as reference are.
1781 * @curr Index in array for current sample statistics.
1782 * @dis TRUE if a header line must be printed.
1783 * @disp_avg TRUE if average stats are displayed.
1784 * @prev_string String displayed at the beginning of a header line. This is
1785 * the timestamp of the previous sample, or "Average" when
1786 * displaying average stats.
1787 * @curr_string String displayed at the beginning of current sample stats.
1788 * This is the timestamp of the current sample, or "Average"
1789 * when displaying average stats.
1792 * 0 if all the processes to display have terminated.
1793 * <> 0 if there are still some processes left to display.
1794 ***************************************************************************
1796 int write_pid_child_memory_stats(int prev, int curr, int dis, int disp_avg,
1797 char *prev_string, char *curr_string)
1799 struct pid_stats *pstc, *pstp;
1804 PRINT_ID_HDR(prev_string, pidflag);
1805 printf(" minflt-nr majflt-nr Command\n");
1808 for (p = 0; p < pid_nr; p++) {
1810 if ((rc = get_pid_to_display(prev, curr, p, P_A_MEM, P_CHILD,
1811 &pstc, &pstp)) == 0)
1812 /* PID no longer exists */
1815 /* This will be used to compute average */
1817 pstc->rc_asum_count = pstp->rc_asum_count + 1;
1821 /* PID should not be displayed */
1824 print_line_id(curr_string, pstc);
1827 (double) ((pstc->minflt + pstc->cminflt) -
1828 (pstp->minflt + pstp->cminflt)) / pstc->rc_asum_count,
1829 (double) ((pstc->majflt + pstc->cmajflt) -
1830 (pstp->majflt + pstp->cmajflt)) / pstc->rc_asum_count);
1834 (unsigned long long) ((pstc->minflt + pstc->cminflt) - (pstp->minflt + pstp->cminflt)),
1835 (unsigned long long) ((pstc->majflt + pstc->cmajflt) - (pstp->majflt + pstp->cmajflt)));
1845 ***************************************************************************
1846 * Display stack size statistics for tasks.
1849 * @prev Index in array where stats used as reference are.
1850 * @curr Index in array for current sample statistics.
1851 * @dis TRUE if a header line must be printed.
1852 * @disp_avg TRUE if average stats are displayed.
1853 * @prev_string String displayed at the beginning of a header line. This is
1854 * the timestamp of the previous sample, or "Average" when
1855 * displaying average stats.
1856 * @curr_string String displayed at the beginning of current sample stats.
1857 * This is the timestamp of the current sample, or "Average"
1858 * when displaying average stats.
1859 * @itv Interval of time in jiffies.
1862 * 0 if all the processes to display have terminated.
1863 * <> 0 if there are still some processes left to display.
1864 ***************************************************************************
1866 int write_pid_stack_stats(int prev, int curr, int dis, int disp_avg,
1867 char *prev_string, char *curr_string,
1868 unsigned long long itv)
1870 struct pid_stats *pstc, *pstp;
1875 PRINT_ID_HDR(prev_string, pidflag);
1876 printf(" StkSize StkRef Command\n");
1879 for (p = 0; p < pid_nr; p++) {
1881 if ((rc = get_pid_to_display(prev, curr, p, P_A_STACK, P_NULL,
1882 &pstc, &pstp)) == 0)
1883 /* PID no longer exists */
1886 /* This will be used to compute average */
1888 pstc->total_stack_size = pstp->total_stack_size + pstc->stack_size;
1889 pstc->total_stack_ref = pstp->total_stack_ref + pstc->stack_ref;
1890 pstc->sk_asum_count = pstp->sk_asum_count + 1;
1894 /* PID should not be displayed */
1897 print_line_id(curr_string, pstc);
1901 (double) pstc->total_stack_size / pstc->sk_asum_count,
1902 (double) pstc->total_stack_ref / pstc->sk_asum_count);
1906 (unsigned long long) pstc->stack_size,
1907 (unsigned long long) pstc->stack_ref);
1918 ***************************************************************************
1919 * Display I/O statistics.
1922 * @prev Index in array where stats used as reference are.
1923 * @curr Index in array for current sample statistics.
1924 * @dis TRUE if a header line must be printed.
1925 * @disp_avg TRUE if average stats are displayed.
1926 * @prev_string String displayed at the beginning of a header line. This is
1927 * the timestamp of the previous sample, or "Average" when
1928 * displaying average stats.
1929 * @curr_string String displayed at the beginning of current sample stats.
1930 * This is the timestamp of the current sample, or "Average"
1931 * when displaying average stats.
1932 * @itv Interval of time in jiffies.
1935 * 0 if all the processes to display have terminated.
1936 * <> 0 if there are still some processes left to display.
1937 ***************************************************************************
1939 int write_pid_io_stats(int prev, int curr, int dis, int disp_avg,
1940 char *prev_string, char *curr_string,
1941 unsigned long long itv)
1943 struct pid_stats *pstc, *pstp;
1949 PRINT_ID_HDR(prev_string, pidflag);
1950 printf(" kB_rd/s kB_wr/s kB_ccwr/s iodelay Command\n");
1953 for (p = 0; p < pid_nr; p++) {
1955 if ((rc = get_pid_to_display(prev, curr, p, P_A_IO, P_NULL,
1956 &pstc, &pstp)) == 0)
1957 /* PID no longer exists */
1960 /* This will be used to compute average delays */
1962 pstc->delay_asum_count = pstp->delay_asum_count + 1;
1966 /* PID should not be displayed */
1969 print_line_id(curr_string, pstc);
1970 if (!NO_PID_IO(pstc->flags)) {
1972 S_VALUE(pstp->read_bytes, pstc->read_bytes, itv) / 1024,
1973 S_VALUE(pstp->write_bytes, pstc->write_bytes, itv) / 1024,
1974 S_VALUE(pstp->cancelled_write_bytes,
1975 pstc->cancelled_write_bytes, itv) / 1024);
1978 /* I/O file not readable (permission denied or file non existent) */
1979 sprintf(dstr, " %9.2f %9.2f %9.2f", -1.0, -1.0, -1.0);
1980 cprintf_s(IS_ZERO, "%s", dstr);
1982 /* I/O delays come from another file (/proc/#/stat) */
1985 (double) (pstc->blkio_swapin_delays - pstp->blkio_swapin_delays) /
1986 pstc->delay_asum_count);
1990 (unsigned long long) (pstc->blkio_swapin_delays - pstp->blkio_swapin_delays));
2001 ***************************************************************************
2002 * Display context switches statistics.
2005 * @prev Index in array where stats used as reference are.
2006 * @curr Index in array for current sample statistics.
2007 * @dis TRUE if a header line must be printed.
2008 * @prev_string String displayed at the beginning of a header line. This is
2009 * the timestamp of the previous sample, or "Average" when
2010 * displaying average stats.
2011 * @curr_string String displayed at the beginning of current sample stats.
2012 * This is the timestamp of the current sample, or "Average"
2013 * when displaying average stats.
2014 * @itv Interval of time in jiffies.
2017 * 0 if all the processes to display have terminated.
2018 * <> 0 if there are still some processes left to display.
2019 ***************************************************************************
2021 int write_pid_ctxswitch_stats(int prev, int curr, int dis,
2022 char *prev_string, char *curr_string,
2023 unsigned long long itv)
2025 struct pid_stats *pstc, *pstp;
2030 PRINT_ID_HDR(prev_string, pidflag);
2031 printf(" cswch/s nvcswch/s Command\n");
2034 for (p = 0; p < pid_nr; p++) {
2036 if (get_pid_to_display(prev, curr, p, P_A_CTXSW, P_NULL,
2040 print_line_id(curr_string, pstc);
2042 S_VALUE(pstp->nvcsw, pstc->nvcsw, itv),
2043 S_VALUE(pstp->nivcsw, pstc->nivcsw, itv));
2052 ***************************************************************************
2053 * Display scheduling priority and policy information.
2056 * @prev Index in array where stats used as reference are.
2057 * @curr Index in array for current sample statistics.
2058 * @dis TRUE if a header line must be printed.
2059 * @prev_string String displayed at the beginning of a header line. This is
2060 * the timestamp of the previous sample, or "Average" when
2061 * displaying average stats.
2062 * @curr_string String displayed at the beginning of current sample stats.
2063 * This is the timestamp of the current sample, or "Average"
2064 * when displaying average stats.
2065 * @itv Interval of time in jiffies.
2068 * 0 if all the processes to display have terminated.
2069 * <> 0 if there are still some processes left to display.
2070 ***************************************************************************
2072 int write_pid_rt_stats(int prev, int curr, int dis,
2073 char *prev_string, char *curr_string,
2074 unsigned long long itv)
2076 struct pid_stats *pstc, *pstp;
2081 PRINT_ID_HDR(prev_string, pidflag);
2082 printf(" prio policy Command\n");
2085 for (p = 0; p < pid_nr; p++) {
2087 if (get_pid_to_display(prev, curr, p, P_A_RT, P_NULL,
2091 print_line_id(curr_string, pstc);
2093 (unsigned long long) pstc->priority);
2094 cprintf_s(IS_STR, " %6s", GET_POLICY(pstc->policy));
2103 ***************************************************************************
2104 * Display some kernel tables values for tasks.
2107 * @prev Index in array where stats used as reference are.
2108 * @curr Index in array for current sample statistics.
2109 * @dis TRUE if a header line must be printed.
2110 * @disp_avg TRUE if average stats are displayed.
2111 * @prev_string String displayed at the beginning of a header line. This is
2112 * the timestamp of the previous sample, or "Average" when
2113 * displaying average stats.
2114 * @curr_string String displayed at the beginning of current sample stats.
2115 * This is the timestamp of the current sample, or "Average"
2116 * when displaying average stats.
2117 * @itv Interval of time in jiffies.
2120 * 0 if all the processes to display have terminated.
2121 * <> 0 if there are still some processes left to display.
2122 ***************************************************************************
2124 int write_pid_ktab_stats(int prev, int curr, int dis, int disp_avg,
2125 char *prev_string, char *curr_string,
2126 unsigned long long itv)
2128 struct pid_stats *pstc, *pstp;
2133 PRINT_ID_HDR(prev_string, pidflag);
2134 printf(" threads fd-nr");
2135 printf(" Command\n");
2138 for (p = 0; p < pid_nr; p++) {
2140 if ((rc = get_pid_to_display(prev, curr, p, P_A_KTAB, P_NULL,
2141 &pstc, &pstp)) == 0)
2142 /* PID no longer exists */
2145 /* This will be used to compute average */
2147 pstc->total_threads = pstp->total_threads + pstc->threads;
2148 pstc->total_fd_nr = pstp->total_fd_nr + pstc->fd_nr;
2149 pstc->tf_asum_count = pstp->tf_asum_count + 1;
2153 /* PID should not be displayed */
2156 print_line_id(curr_string, pstc);
2160 (double) pstc->total_threads / pstc->tf_asum_count,
2161 NO_PID_FD(pstc->flags) ?
2163 (double) pstc->total_fd_nr / pstc->tf_asum_count);
2167 (unsigned long long) pstc->threads);
2168 if (NO_PID_FD(pstc->flags)) {
2169 cprintf_s(IS_ZERO, " %7s", "-1");
2173 (unsigned long long) pstc->fd_nr);
2185 ***************************************************************************
2186 * Display statistics.
2189 * @prev Index in array where stats used as reference are.
2190 * @curr Index in array for current sample statistics.
2191 * @dis TRUE if a header line must be printed.
2192 * @disp_avg TRUE if average stats are displayed.
2193 * @prev_string String displayed at the beginning of a header line. This is
2194 * the timestamp of the previous sample, or "Average" when
2195 * displaying average stats.
2196 * @curr_string String displayed at the beginning of current sample stats.
2197 * This is the timestamp of the current sample, or "Average"
2198 * when displaying average stats.
2201 * 0 if all the processes to display have terminated.
2202 * <> 0 if there are still some processes left to display.
2203 ***************************************************************************
2205 int write_stats_core(int prev, int curr, int dis, int disp_avg,
2206 char *prev_string, char *curr_string)
2208 unsigned long long itv, g_itv;
2212 TEST_STDOUT(STDOUT_FILENO);
2214 /* g_itv is multiplied by the number of processors */
2215 g_itv = get_interval(uptime[prev], uptime[curr]);
2219 itv = get_interval(uptime0[prev], uptime0[curr]);
2226 if (PROCESS_STRING(pidflag)) {
2227 /* Reset "show threads" flag */
2228 show_threads = FALSE;
2231 if (DISPLAY_ONELINE(pidflag)) {
2232 if (DISPLAY_TASK_STATS(tskflag)) {
2233 again += write_pid_task_all_stats(prev, curr, dis,
2236 if (DISPLAY_CHILD_STATS(tskflag)) {
2237 again += write_pid_child_all_stats(prev, curr, dis, itv);
2241 /* Display CPU stats */
2242 if (DISPLAY_CPU(actflag)) {
2244 if (DISPLAY_TASK_STATS(tskflag)) {
2245 again += write_pid_task_cpu_stats(prev, curr, dis, disp_avg,
2246 prev_string, curr_string,
2249 if (DISPLAY_CHILD_STATS(tskflag)) {
2250 again += write_pid_child_cpu_stats(prev, curr, dis, disp_avg,
2251 prev_string, curr_string);
2255 /* Display memory stats */
2256 if (DISPLAY_MEM(actflag)) {
2258 if (DISPLAY_TASK_STATS(tskflag)) {
2259 again += write_pid_task_memory_stats(prev, curr, dis, disp_avg,
2260 prev_string, curr_string, itv);
2262 if (DISPLAY_CHILD_STATS(tskflag) && DISPLAY_MEM(actflag)) {
2263 again += write_pid_child_memory_stats(prev, curr, dis, disp_avg,
2264 prev_string, curr_string);
2268 /* Display stack stats */
2269 if (DISPLAY_STACK(actflag)) {
2270 again += write_pid_stack_stats(prev, curr, dis, disp_avg,
2271 prev_string, curr_string, itv);
2274 /* Display I/O stats */
2275 if (DISPLAY_IO(actflag)) {
2276 again += write_pid_io_stats(prev, curr, dis, disp_avg, prev_string,
2280 /* Display context switches stats */
2281 if (DISPLAY_CTXSW(actflag)) {
2282 again += write_pid_ctxswitch_stats(prev, curr, dis, prev_string,
2286 /* Display kernel table stats */
2287 if (DISPLAY_KTAB(actflag)) {
2288 again += write_pid_ktab_stats(prev, curr, dis, disp_avg,
2289 prev_string, curr_string, itv);
2292 /* Display scheduling priority and policy information */
2293 if (DISPLAY_RT(actflag)) {
2294 again += write_pid_rt_stats(prev, curr, dis, prev_string,
2299 if (DISPLAY_ALL_PID(pidflag)) {
2307 ***************************************************************************
2308 * Print statistics average.
2311 * @curr Index in array for current sample statistics.
2312 * @dis TRUE if a header line must be printed.
2313 ***************************************************************************
2315 void write_stats_avg(int curr, int dis)
2319 strncpy(string, _("Average:"), 16);
2321 write_stats_core(2, curr, dis, TRUE, string, string);
2325 ***************************************************************************
2326 * Get previous and current timestamps, then display statistics.
2329 * @curr Index in array for current sample statistics.
2330 * @dis TRUE if a header line must be printed.
2333 * 0 if all the processes to display have terminated.
2334 * <> 0 if there are still some processes left to display.
2335 ***************************************************************************
2337 int write_stats(int curr, int dis)
2339 char cur_time[2][TIMESTAMP_LEN];
2341 /* Get previous timestamp */
2342 if (is_iso_time_fmt()) {
2343 strftime(cur_time[!curr], sizeof(cur_time[!curr]), "%H:%M:%S", &ps_tstamp[!curr]);
2346 strftime(cur_time[!curr], sizeof(cur_time[!curr]), "%X", &ps_tstamp[!curr]);
2349 /* Get current timestamp */
2350 if (is_iso_time_fmt()) {
2351 strftime(cur_time[curr], sizeof(cur_time[curr]), "%H:%M:%S", &ps_tstamp[curr]);
2354 strftime(cur_time[curr], sizeof(cur_time[curr]), "%X", &ps_tstamp[curr]);
2357 return (write_stats_core(!curr, curr, dis, FALSE,
2358 cur_time[!curr], cur_time[curr]));
2362 ***************************************************************************
2363 * Main loop: Read and display PID stats.
2366 * @dis_hdr Set to TRUE if the header line must always be printed.
2367 * @rows Number of rows of screen.
2368 ***************************************************************************
2370 void rw_pidstat_loop(int dis_hdr, int rows)
2372 int curr = 1, dis = 1;
2374 unsigned long lines = rows;
2376 /* Don't buffer data if redirected to a pipe */
2377 setbuf(stdout, NULL);
2381 * Read system uptime (only for SMP machines).
2382 * Init uptime0. So if /proc/uptime cannot fill it, this will be
2383 * done by /proc/stat.
2386 read_uptime(&uptime0[0]);
2390 if (DISPLAY_MEM(actflag)) {
2391 /* Get total memory */
2392 read_proc_meminfo();
2396 /* Display since boot time */
2397 ps_tstamp[1] = ps_tstamp[0];
2398 memset(st_pid_list[1], 0, PID_STATS_SIZE * pid_nr);
2399 write_stats(0, DISP_HDR);
2403 /* Set a handler for SIGALRM */
2404 memset(&alrm_act, 0, sizeof(alrm_act));
2405 alrm_act.sa_handler = alarm_handler;
2406 sigaction(SIGALRM, &alrm_act, NULL);
2409 /* Save the first stats collected. Will be used to compute the average */
2410 ps_tstamp[2] = ps_tstamp[0];
2411 uptime[2] = uptime[0];
2412 uptime0[2] = uptime0[0];
2413 memcpy(st_pid_list[2], st_pid_list[0], PID_STATS_SIZE * pid_nr);
2415 /* Set a handler for SIGINT */
2416 memset(&int_act, 0, sizeof(int_act));
2417 int_act.sa_handler = int_handler;
2418 sigaction(SIGINT, &int_act, NULL);
2420 /* Wait for SIGALRM (or possibly SIGINT) signal */
2424 /* SIGINT signal caught during first interval: Exit immediately */
2429 get_localtime(&ps_tstamp[curr], 0);
2433 * Read system uptime (only for SMP machines).
2434 * Init uptime0. So if /proc/uptime cannot fill it, this will be
2435 * done by /proc/stat.
2438 read_uptime(&(uptime0[curr]));
2453 again = write_stats(curr, dis);
2466 if (sigint_caught) {
2467 /* SIGINT signal caught => Display average stats */
2469 printf("\n"); /* Skip "^C" displayed on screen */
2479 * The one line format uses a raw time value rather than time strings
2480 * so the average doesn't really fit.
2482 if (!DISPLAY_ONELINE(pidflag))
2484 /* Write stats average */
2485 write_stats_avg(curr, dis_hdr);
2490 ***************************************************************************
2491 * Main entry to the pidstat program.
2492 ***************************************************************************
2494 int main(int argc, char **argv)
2496 int opt = 1, dis_hdr = -1;
2499 struct utsname header;
2504 /* Init National Language Support */
2508 /* Init color strings */
2514 /* Compute page shift in kB */
2517 /* Allocate structures for device list */
2519 salloc_pid_array((argc / 2) + count_csvalues(argc, argv));
2522 /* Process args... */
2523 while (opt < argc) {
2525 if (!strcmp(argv[opt], "-p")) {
2529 for (t = strtok(argv[opt], ","); t; t = strtok(NULL, ",")) {
2530 if (!strcmp(t, K_ALL)) {
2531 pidflag |= P_D_ALL_PID;
2533 else if (!strcmp(t, K_SELF)) {
2534 update_pid_array(&pid_array_nr, getpid());
2537 if (strspn(t, DIGITS) != strlen(t)) {
2544 update_pid_array(&pid_array_nr, pid);
2554 else if (!strcmp(argv[opt], "-C")) {
2556 strncpy(commstr, argv[opt++], MAX_COMM_LEN);
2557 commstr[MAX_COMM_LEN - 1] = '\0';
2558 pidflag |= P_F_COMMSTR;
2559 if (!strlen(commstr)) {
2568 else if (!strcmp(argv[opt], "-G")) {
2570 strncpy(procstr, argv[opt++], MAX_COMM_LEN);
2571 procstr[MAX_COMM_LEN - 1] = '\0';
2572 pidflag |= P_F_PROCSTR;
2573 if (!strlen(procstr)) {
2582 else if (!strcmp(argv[opt], "-T")) {
2587 if (!strcmp(argv[opt], K_P_TASK)) {
2590 else if (!strcmp(argv[opt], K_P_CHILD)) {
2593 else if (!strcmp(argv[opt], K_P_ALL)) {
2594 tskflag |= P_TASK + P_CHILD;
2607 /* Option used individually. See below for grouped option */
2608 else if (!strcmp(argv[opt], "-U")) {
2609 /* Display username instead of UID */
2610 pidflag |= P_D_USERNAME;
2611 if (argv[++opt] && (argv[opt][0] != '-') &&
2612 (strspn(argv[opt], DIGITS) != strlen(argv[opt]))) {
2613 strncpy(userstr, argv[opt++], MAX_USER_LEN);
2614 userstr[MAX_USER_LEN - 1] = '\0';
2615 pidflag |= P_F_USERSTR;
2616 if (!strlen(userstr)) {
2622 else if (!strncmp(argv[opt], "-", 1)) {
2623 for (i = 1; *(argv[opt] + i); i++) {
2625 switch (*(argv[opt] + i)) {
2628 /* Display I/O usage */
2634 /* Display stats on one line */
2635 pidflag |= P_D_ONELINE;
2640 pidflag |= P_F_IRIX_MODE;
2644 /* Display whole command line */
2645 pidflag |= P_D_CMDLINE;
2649 /* Display priority and policy info */
2655 /* Display memory usage */
2661 /* Display stack sizes */
2662 actflag |= P_A_STACK;
2667 /* Display stats for threads */
2672 /* When option is grouped, it cannot take an arg */
2673 pidflag |= P_D_USERNAME;
2677 /* Display CPU usage */
2683 /* Print version number and exit */
2688 /* Display some kernel tables values */
2689 actflag |= P_A_KTAB;
2694 /* Display context switches */
2695 actflag |= P_A_CTXSW;
2706 else if (interval < 0) { /* Get interval */
2707 if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) {
2710 interval = atol(argv[opt++]);
2717 else if (count <= 0) { /* Get count value */
2718 if ((strspn(argv[opt], DIGITS) != strlen(argv[opt])) ||
2722 count = atol(argv[opt++]);
2733 /* Interval not set => display stats since boot time */
2737 /* Check flags and set default values */
2740 /* Init structures */
2751 rows = get_win_height();
2756 get_localtime(&(ps_tstamp[0]), 0);
2758 /* Get system name, release number and hostname */
2760 print_gal_header(&(ps_tstamp[0]), header.sysname, header.release,
2761 header.nodename, header.machine, cpu_nr,
2765 rw_pidstat_loop(dis_hdr, rows);
2767 /* Free structures */