Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / tools / android / ps_ext / ps_ext.c
blob06cf7bcff98cec8a35f3642f5629f59f29e25f12
1 /*
2 * Copyright 2014 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
7 #include <ctype.h>
8 #include <dirent.h>
9 #include <stdbool.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <time.h>
14 #include <unistd.h>
17 * This tool is essentially an extended version of ps with JSON output.
18 * Its output is meant consumed by scripts / tools for gathering OS/ps stats.
19 * Output units:
20 * All times are expressed in ticks.
21 * All memory counters are expressed in Kb.
24 static void dump_time(void) {
25 float uptime_secs = 0.0F;
26 const long rate = sysconf(_SC_CLK_TCK);
27 FILE *f = fopen("/proc/uptime", "r");
28 if (!f)
29 return;
30 fscanf(f, "%f", &uptime_secs);
31 fclose(f);
32 const long ticks = (long) (rate * uptime_secs);
33 printf(" \"time\": { \"ticks\": %ld, \"rate\": %ld}", ticks, rate);
36 static void dump_cpu_stats(void) {
37 FILE *f = fopen("/proc/stat", "r");
38 if (!f)
39 return;
40 printf(" \"cpu\":\n [\n");
42 bool terminate_prev_line = false;
43 while (!feof(f)) {
44 char line[256];
45 char cpu[8];
46 long unsigned t_usr = 0;
47 long unsigned t_nice = 0;
48 long unsigned t_sys = 0;
49 long unsigned t_idle = 0;
50 fgets(line, sizeof(line), f);
52 /* Skip the total 'cpu ' line and the other irrelevant ones. */
53 if (strncmp(line, "cpu", 3) != 0 || line[3] == ' ')
54 continue;
55 if (sscanf(line, "%s %lu %lu %lu %lu",
56 cpu, &t_usr, &t_nice, &t_sys, &t_idle) != 5) {
57 continue;
60 if (terminate_prev_line)
61 printf(",\n");
62 terminate_prev_line = true;
63 printf(" {\"usr\": %lu, \"sys\": %lu, \"idle\": %lu}",
64 t_usr + t_nice, t_sys, t_idle);
66 fclose(f);
67 printf("\n ]");
70 static void dump_mem_stats(void) {
71 FILE *f = fopen("/proc/meminfo", "r");
72 if (!f)
73 return;
74 printf(" \"mem\":\n {\n");
76 bool terminate_prev_line = false;
77 while (!feof(f)) {
78 char line[256];
79 char key[32];
80 long value = 0;
82 fgets(line, sizeof(line), f);
83 if (sscanf(line, "%s %lu %*s", key, &value) < 2)
84 continue;
86 if (terminate_prev_line)
87 printf(",\n");
88 terminate_prev_line = true;
89 printf(" \"%s\": %lu", key, value);
91 fclose(f);
92 printf("\n }");
95 static void dump_proc_stats(void) {
96 struct dirent *de;
97 DIR *d = opendir("/proc");
98 if (!d)
99 return;
101 const long kb_per_page = sysconf(_SC_PAGESIZE) / 1024;
102 bool terminate_prev_line = false;
103 printf(" \"processes\":\n {\n");
104 while ((de = readdir(d))) {
105 if (!isdigit(de->d_name[0]))
106 continue;
107 const int pid = atoi(de->d_name);
109 /* Don't print out ourselves (how civilized). */
110 if (pid == getpid())
111 continue;
113 char cmdline[64];
114 char fpath[32];
115 FILE *f;
117 /* Read full process path / package from cmdline. */
118 sprintf(fpath, "/proc/%d/cmdline", pid);
119 f = fopen(fpath, "r");
120 if (!f)
121 continue;
122 cmdline[0] = '\0';
123 fgets(cmdline, sizeof(cmdline), f);
124 fclose(f);
126 /* Read cpu/io/mem stats. */
127 char proc_name[256];
128 long num_threads = 0;
129 long unsigned min_faults = 0;
130 long unsigned maj_faults = 0;
131 long unsigned utime = 0;
132 long unsigned ktime = 0;
133 long unsigned vm_rss = 0;
134 long long unsigned start_time = 0;
136 sprintf(fpath, "/proc/%d/stat", pid);
137 f = fopen(fpath, "r");
138 if (!f)
139 continue;
140 fscanf(f, "%*d %s %*c %*d %*d %*d %*d %*d %*u %lu %*u %lu %*u %lu %lu "
141 "%*d %*d %*d %*d %ld %*d %llu %*u %ld", proc_name, &min_faults,
142 &maj_faults, &utime, &ktime, &num_threads, &start_time, &vm_rss);
143 fclose(f);
145 /* Prefer the cmdline when available, since it contains the package name. */
146 char const * const cmd = (strlen(cmdline) > 0) ? cmdline : proc_name;
148 if (terminate_prev_line)
149 printf(",\n");
150 terminate_prev_line = true;
151 printf(" \"%d\": {"
152 "\"name\": \"%s\", "
153 "\"n_threads\": %ld, "
154 "\"start_time\": %llu, "
155 "\"user_time\": %lu, "
156 "\"sys_time\": %lu, "
157 "\"min_faults\": %lu, "
158 "\"maj_faults\": %lu, "
159 "\"vm_rss\": %lu"
160 "}",
161 pid,
162 cmd,
163 num_threads,
164 start_time,
165 utime,
166 ktime,
167 min_faults,
168 maj_faults,
169 vm_rss * kb_per_page);
171 closedir(d);
172 printf("\n }");
175 int main()
177 printf("{\n");
179 dump_time();
180 printf(",\n");
182 dump_mem_stats();
183 printf(",\n");
185 dump_cpu_stats();
186 printf(",\n");
188 dump_proc_stats();
189 printf("\n}\n");
191 return 0;