]> granicus.if.org Git - sysstat/commitdiff
Pidstat outputs values > 100% for %CPU
authorPeter Schiffer <pschiffe@redhat.com>
Thu, 27 Aug 2015 15:52:53 +0000 (17:52 +0200)
committerPeter Schiffer <pschiffe@redhat.com>
Thu, 27 Aug 2015 15:52:53 +0000 (17:52 +0200)
On systems with many short living processes pidstat could run out of
pre-allocated space for PIDs. This patch increases NR_PID_PREALLOC constant so
more space for PIDs is pre-allocated, but also adds possibility to re-allocate
this space if needed.

pidstat.c
pidstat.h

index d24ae02166f7552079f25a38a4eae2d006862458..a8bf57142de9e3f1aea8bc2f85a6fe4c9f25475a 100644 (file)
--- a/pidstat.c
+++ b/pidstat.c
@@ -157,17 +157,37 @@ void salloc_pid_array(unsigned int len)
  */
 void salloc_pid(unsigned int len)
 {
-       int i;
+       short i;
 
        for (i = 0; i < 3; i++) {
-               if ((st_pid_list[i] = (struct pid_stats *) malloc(PID_STATS_SIZE * len)) == NULL) {
-                       perror("malloc");
+               if ((st_pid_list[i] = (struct pid_stats *) calloc(len, PID_STATS_SIZE)) == NULL) {
+                       perror("calloc");
                        exit(4);
                }
-               memset(st_pid_list[i], 0, PID_STATS_SIZE * len);
        }
 }
 
+/*
+ ***************************************************************************
+ * Reallocate structures for PIDs to read.
+ ***************************************************************************
+ */
+void realloc_pid(void)
+{
+       short i;
+       unsigned int new_size = 2 * pid_nr;
+
+       for (i = 0; i < 3; i++) {
+               if ((st_pid_list[i] = (struct pid_stats *) realloc(st_pid_list[i], PID_STATS_SIZE * new_size)) == NULL) {
+                       perror("realloc");
+                       exit(4);
+               }
+               memset(st_pid_list[i] + pid_nr, 0, PID_STATS_SIZE * (new_size - pid_nr));
+       }
+
+       pid_nr = new_size;
+}
+
 /*
  ***************************************************************************
  * Free PID list structures.
@@ -917,36 +937,33 @@ void read_stats(int curr)
                        exit(4);
                }
 
-               while (p < pid_nr) {
-
-                       /* Get directory entries */
-                       while ((drp = readdir(dir)) != NULL) {
-                               if (isdigit(drp->d_name[0]))
-                                       break;
+               /* Get directory entries */
+               while ((drp = readdir(dir)) != NULL) {
+                       if (!isdigit(drp->d_name[0])) {
+                               continue;
                        }
-                       if (drp) {
-                               pst = st_pid_list[curr] + p++;
-                               pid = atoi(drp->d_name);
 
-                               if (read_pid_stats(pid, pst, &thr_nr, 0)) {
-                                       /* Process has terminated */
-                                       pst->pid = 0;
-                               }
+                       pst = st_pid_list[curr] + p++;
+                       pid = atoi(drp->d_name);
 
-                               else if (DISPLAY_TID(pidflag)) {
-                                       /* Read stats for threads in task subdirectory */
-                                       read_task_stats(curr, pid, &p);
-                               }
+                       if (read_pid_stats(pid, pst, &thr_nr, 0)) {
+                               /* Process has terminated */
+                               pst->pid = 0;
+                       } else if (DISPLAY_TID(pidflag)) {
+                               /* Read stats for threads in task subdirectory */
+                               read_task_stats(curr, pid, &p);
                        }
-                       else {
-                               for (q = p; q < pid_nr; q++) {
-                                       pst = st_pid_list[curr] + q;
-                                       pst->pid = 0;
-                               }
-                               break;
+
+                       if (p >= pid_nr) {
+                               realloc_pid();
                        }
                }
 
+               for (q = p; q < pid_nr; q++) {
+                       pst = st_pid_list[curr] + q;
+                       pst->pid = 0;
+               }
+
                /* Close /proc directory */
                closedir(dir);
        }
index 0a7246867792f71abb406bad705c890c79e23d82..2fd5980164ce23473cc37e5ed7695fcc74fede74 100644 (file)
--- a/pidstat.h
+++ b/pidstat.h
@@ -13,7 +13,7 @@
 #define K_P_CHILD      "CHILD"
 #define K_P_ALL                "ALL"
 
-#define NR_PID_PREALLOC        10
+#define NR_PID_PREALLOC        100
 
 #define MAX_COMM_LEN   128
 #define MAX_CMDLINE_LEN        128