Merge remote-tracking branch 'github/pr/1036'
authorFlorian Forster <octo@collectd.org>
Sat, 6 Jun 2015 19:43:28 +0000 (21:43 +0200)
committerFlorian Forster <octo@collectd.org>
Sat, 6 Jun 2015 19:43:28 +0000 (21:43 +0200)
Conflicts:
src/processes.c

1  2 
src/processes.c

diff --cc src/processes.c
@@@ -778,8 -814,118 +814,118 @@@ static void ps_submit_fork_rate (derive
  
  /* ------- additional functions for KERNEL_LINUX/HAVE_THREAD_INFO ------- */
  #if KERNEL_LINUX
 -/* Read advanced virtual memory data from /proc/pid/status */
 -static procstat_t *ps_read_vmem (int pid, procstat_t *ps)
+ static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps)
+ {
+       char           dirname[64];
+       DIR           *dh;
+       char           filename[64];
+       FILE          *fh;
+       struct dirent *ent;
+       derive_t cswitch_vol = 0;
+       derive_t cswitch_invol = 0;
+       char buffer[1024];
+       char *fields[8];
+       int numfields;
+       ssnprintf (dirname, sizeof (dirname), "/proc/%i/task", pid);
+       if ((dh = opendir (dirname)) == NULL)
+       {
+               DEBUG ("Failed to open directory `%s'", dirname);
+               return (NULL);
+       }
+       while ((ent = readdir (dh)) != NULL)
+       {
+               char *tpid;
+               if (!isdigit ((int) ent->d_name[0]))
+                       continue;
+               tpid = ent->d_name;
+               ssnprintf (filename, sizeof (filename), "/proc/%i/task/%s/status", pid, tpid);
+               if ((fh = fopen (filename, "r")) == NULL)
+               {
+                       DEBUG ("Failed to open file `%s'", filename);
+                       continue;
+               }
+               while (fgets (buffer, sizeof(buffer), fh) != NULL)
+               {
+                       derive_t tmp;
+                       char *endptr;
+                       if (strncmp (buffer, "voluntary_ctxt_switches", 23) != 0
+                               && strncmp (buffer, "nonvoluntary_ctxt_switches", 26) != 0)
+                               continue;
+                       numfields = strsplit (buffer, fields,
+                               STATIC_ARRAY_SIZE (fields));
+                       if (numfields < 2)
+                               continue;
+                       errno = 0;
+                       endptr = NULL;
+                       tmp = (derive_t) strtoll (fields[1], &endptr, /* base = */ 10);
+                       if ((errno == 0) && (endptr != fields[1]))
+                       {
+                               if (strncmp (buffer, "voluntary_ctxt_switches", 23) == 0)
+                               {
+                                       cswitch_vol += tmp;
+                               }
+                               else if (strncmp (buffer, "nonvoluntary_ctxt_switches", 26) == 0)
+                               {
+                                       cswitch_invol += tmp;
+                               }
+                       }
+               } /* while (fgets) */
+               if (fclose (fh))
+               {
+                       char errbuf[1024];
+                               WARNING ("processes: fclose: %s",
+                                       sstrerror (errno, errbuf, sizeof (errbuf)));
+               }
+       }
+       closedir (dh);
+       ps->cswitch_vol = cswitch_vol;
+       ps->cswitch_invol = cswitch_invol;
+       return (ps);
+ } /* int *ps_read_tasks_status */
+ static int ps_read_tasks (int pid)
+ {
+       char           dirname[64];
+       DIR           *dh;
+       struct dirent *ent;
+       int count = 0;
+       ssnprintf (dirname, sizeof (dirname), "/proc/%i/task", pid);
+       if ((dh = opendir (dirname)) == NULL)
+       {
+               DEBUG ("Failed to open directory `%s'", dirname);
+               return (-1);
+       }
+       while ((ent = readdir (dh)) != NULL)
+       {
+               if (!isdigit ((int) ent->d_name[0]))
+                       continue;
+               else
+                       count++;
+       }
+       closedir (dh);
+       return ((count >= 1) ? count : 1);
+ } /* int *ps_read_tasks */
 +/* Read data from /proc/pid/status */
 +static procstat_t *ps_read_status (int pid, procstat_t *ps)
  {
        FILE *fh;
        char buffer[1024];