diff options
Diffstat (limited to 'src/bootchart/log.c')
-rw-r--r-- | src/bootchart/log.c | 420 |
1 files changed, 0 insertions, 420 deletions
diff --git a/src/bootchart/log.c b/src/bootchart/log.c deleted file mode 100644 index 89c7b3523c..0000000000 --- a/src/bootchart/log.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * log.c - * - * Copyright (C) 2009-2012 Intel Coproration - * - * Authors: - * Auke Kok <auke-jan.h.kok@intel.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 - * of the License. - */ - -#define _GNU_SOURCE 1 -#include <unistd.h> -#include <stdlib.h> -#include <limits.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <stdio.h> -#include <string.h> -#include <dirent.h> -#include <fcntl.h> -#include <time.h> - - -#include "bootchart.h" - -/* - * Alloc a static 4k buffer for stdio - primarily used to increase - * PSS buffering from the default 1k stdin buffer to reduce - * read() overhead. - */ -static char smaps_buf[4096]; -DIR *proc; - - -double gettime_ns(void) -{ - struct timespec now; - - clock_gettime(CLOCK_MONOTONIC, &now); - - return (now.tv_sec + (now.tv_nsec / 1000000000.0)); -} - - -void log_uptime(void) -{ - FILE *f; - char str[32]; - double uptime; - - f = fopen("/proc/uptime", "r"); - if (!f) - return; - if (!fscanf(f, "%s %*s", str)) { - fclose(f); - return; - } - fclose(f); - uptime = strtod(str, NULL); - - log_start = gettime_ns(); - - /* start graph at kernel boot time */ - if (relative) - graph_start = log_start; - else - graph_start = log_start - uptime; -} - - -static char *bufgetline(char *buf) -{ - char *c; - - if (!buf) - return NULL; - - c = strchr(buf, '\n'); - if (c) - c++; - return c; -} - - -void log_sample(int sample) -{ - static int vmstat; - static int schedstat; - FILE *st; - char buf[4095]; - char key[256]; - char val[256]; - char rt[256]; - char wt[256]; - char *m; - int c; - int p; - int mod; - static int e_fd; - ssize_t s; - ssize_t n; - struct dirent *ent; - - if (!vmstat) { - /* block stuff */ - vmstat = open("/proc/vmstat", O_RDONLY); - if (vmstat == -1) { - perror("open /proc/vmstat"); - exit (EXIT_FAILURE); - } - } - - n = pread(vmstat, buf, sizeof(buf) - 1, 0); - if (n <= 0) { - close(vmstat); - return; - } - buf[n] = '\0'; - - m = buf; - while (m) { - if (sscanf(m, "%s %s", key, val) < 2) - goto vmstat_next; - if (!strcmp(key, "pgpgin")) - blockstat[sample].bi = atoi(val); - if (!strcmp(key, "pgpgout")) { - blockstat[sample].bo = atoi(val); - break; - } -vmstat_next: - m = bufgetline(m); - if (!m) - break; - } - - if (!schedstat) { - /* overall CPU utilization */ - schedstat = open("/proc/schedstat", O_RDONLY); - if (schedstat == -1) { - perror("open /proc/schedstat"); - exit (EXIT_FAILURE); - } - } - - n = pread(schedstat, buf, sizeof(buf) - 1, 0); - if (n <= 0) { - close(schedstat); - return; - } - buf[n] = '\0'; - - m = buf; - while (m) { - if (sscanf(m, "%s %*s %*s %*s %*s %*s %*s %s %s", key, rt, wt) < 3) - goto schedstat_next; - - if (strstr(key, "cpu")) { - c = atoi((const char*)(key+3)); - if (c > MAXCPUS) - /* Oops, we only have room for MAXCPUS data */ - break; - cpustat[c].sample[sample].runtime = atoll(rt); - cpustat[c].sample[sample].waittime = atoll(wt); - - if (c == cpus) - cpus = c + 1; - } -schedstat_next: - m = bufgetline(m); - if (!m) - break; - } - - if (entropy) { - if (!e_fd) { - e_fd = open("/proc/sys/kernel/random/entropy_avail", O_RDONLY); - } - - if (e_fd) { - n = pread(e_fd, buf, sizeof(buf) - 1, 0); - if (n > 0) - entropy_avail[sample] = atoi(buf); - } - } - - /* all the per-process stuff goes here */ - if (!proc) { - /* find all processes */ - proc = opendir("/proc"); - if (!proc) - return; - } else { - rewinddir(proc); - } - - while ((ent = readdir(proc)) != NULL) { - char filename[PATH_MAX]; - int pid; - struct ps_struct *ps; - - if ((ent->d_name[0] < '0') || (ent->d_name[0] > '9')) - continue; - - pid = atoi(ent->d_name); - - if (pid >= MAXPIDS) - continue; - - ps = ps_first; - while (ps->next_ps) { - ps = ps->next_ps; - if (ps->pid == pid) - break; - } - - /* end of our LL? then append a new record */ - if (ps->pid != pid) { - char t[32]; - struct ps_struct *parent; - - ps->next_ps = malloc(sizeof(struct ps_struct)); - if (!ps->next_ps) { - perror("malloc(ps_struct)"); - exit (EXIT_FAILURE); - } - memset(ps->next_ps, 0, sizeof(struct ps_struct)); - ps = ps->next_ps; - ps->pid = pid; - - ps->sample = malloc(sizeof(struct ps_sched_struct) * (len + 1)); - if (!ps->sample) { - perror("malloc(ps_struct)"); - exit (EXIT_FAILURE); - } - memset(ps->sample, 0, sizeof(struct ps_sched_struct) * (len + 1)); - - pscount++; - - /* mark our first sample */ - ps->first = sample; - - /* get name, start time */ - if (!ps->sched) { - sprintf(filename, "/proc/%d/sched", pid); - ps->sched = open(filename, O_RDONLY); - if (ps->sched == -1) - continue; - } - - s = pread(ps->sched, buf, sizeof(buf) - 1, 0); - if (s <= 0) { - close(ps->sched); - continue; - } - - if (!sscanf(buf, "%s %*s %*s", key)) - continue; - - strncpy(ps->name, key, 16); - /* discard line 2 */ - m = bufgetline(buf); - if (!m) - continue; - - m = bufgetline(m); - if (!m) - continue; - - if (!sscanf(m, "%*s %*s %s", t)) - continue; - - ps->starttime = strtod(t, NULL) / 1000.0; - - /* ppid */ - sprintf(filename, "/proc/%d/stat", pid); - st = fopen(filename, "r"); - if (!st) - continue; - if (!fscanf(st, "%*s %*s %*s %i", &p)) { - fclose(st); - continue; - } - fclose(st); - ps->ppid = p; - - /* - * setup child pointers - * - * these are used to paint the tree coherently later - * each parent has a LL of children, and a LL of siblings - */ - if (pid == 1) - continue; /* nothing to do for init atm */ - - /* kthreadd has ppid=0, which breaks our tree ordering */ - if (ps->ppid == 0) - ps->ppid = 1; - - parent = ps_first; - while ((parent->next_ps && parent->pid != ps->ppid)) - parent = parent->next_ps; - - if ((!parent) || (parent->pid != ps->ppid)) { - /* orphan */ - ps->ppid = 1; - parent = ps_first->next_ps; - } - - ps->parent = parent; - - if (!parent->children) { - /* it's the first child */ - parent->children = ps; - } else { - /* walk all children and append */ - struct ps_struct *children; - children = parent->children; - while (children->next) - children = children->next; - children->next = ps; - } - } - - /* else -> found pid, append data in ps */ - - /* below here is all continuous logging parts - we get here on every - * iteration */ - - /* rt, wt */ - if (!ps->schedstat) { - sprintf(filename, "/proc/%d/schedstat", pid); - ps->schedstat = open(filename, O_RDONLY); - if (ps->schedstat == -1) - continue; - } - - if (pread(ps->schedstat, buf, sizeof(buf) - 1, 0) <= 0) { - /* clean up our file descriptors - assume that the process exited */ - close(ps->schedstat); - if (ps->sched) - close(ps->sched); - //if (ps->smaps) - // fclose(ps->smaps); - continue; - } - if (!sscanf(buf, "%s %s %*s", rt, wt)) - continue; - - ps->last = sample; - ps->sample[sample].runtime = atoll(rt); - ps->sample[sample].waittime = atoll(wt); - - ps->total = (ps->sample[ps->last].runtime - - ps->sample[ps->first].runtime) - / 1000000000.0; - - if (!pss) - goto catch_rename; - /* Pss */ - if (!ps->smaps) { - sprintf(filename, "/proc/%d/smaps", pid); - ps->smaps = fopen(filename, "r"); - setvbuf(ps->smaps, smaps_buf, _IOFBF, sizeof(smaps_buf)); - if (!ps->smaps) - continue; - } else { - rewind(ps->smaps); - } - - while (1) { - int pss_kb; - - /* skip one line, this contains the object mapped */ - if (fgets(buf, sizeof(buf), ps->smaps) == NULL) - break; - /* then there's a 28 char 14 line block */ - if (fread(buf, 1, 28 * 14, ps->smaps) != 28 * 14) - break; - - pss_kb = atoi(&buf[61]); - ps->sample[sample].pss += pss_kb; - } - - if (ps->sample[sample].pss > ps->pss_max) - ps->pss_max = ps->sample[sample].pss; - -catch_rename: - /* catch process rename, try to randomize time */ - mod = (hz < 4.0) ? 4.0 : (hz / 4.0); - if (((samples - ps->first) + pid) % (int)(mod) == 0) { - - /* re-fetch name */ - /* get name, start time */ - if (!ps->sched) { - sprintf(filename, "/proc/%d/sched", pid); - ps->sched = open(filename, O_RDONLY); - if (ps->sched == -1) - continue; - } - if (pread(ps->sched, buf, sizeof(buf) - 1, 0) <= 0) { - /* clean up file descriptors */ - close(ps->sched); - if (ps->schedstat) - close(ps->schedstat); - //if (ps->smaps) - // fclose(ps->smaps); - continue; - } - - if (!sscanf(buf, "%s %*s %*s", key)) - continue; - - strncpy(ps->name, key, 16); - } - } -} |