1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (c) 2008, The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * All rights reserved.
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redistribution and use in source and binary forms, with or without
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * modification, are permitted provided that the following conditions
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are met:
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *  * Redistributions of source code must retain the above copyright
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *  * Redistributions in binary form must reproduce the above copyright
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    notice, this list of conditions and the following disclaimer in
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    the documentation and/or other materials provided with the
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    distribution.
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *  * Neither the name of Google, Inc. nor the names of its contributors
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    may be used to endorse or promote products derived from this
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    software without specific prior written permission.
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * SUCH DAMAGE.
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h>
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <dirent.h>
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <grp.h>
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <pwd.h>
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h>
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
42392744175c4de67dc98e72da6745e6351118c985San Mehat#include <cutils/sched_policy.h>
43392744175c4de67dc98e72da6745e6351118c985San Mehat
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct cpu_info {
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long unsigned utime, ntime, stime, itime;
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long unsigned iowtime, irqtime, sirqtime;
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define PROC_NAME_LEN 64
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define THREAD_NAME_LEN 32
5186c7cc81891a69ace7044de667b0624c284ee82bGlenn Kasten#define POLICY_NAME_LEN 4
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct proc_info {
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct proc_info *next;
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pid_t pid;
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pid_t tid;
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uid_t uid;
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    gid_t gid;
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char name[PROC_NAME_LEN];
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char tname[THREAD_NAME_LEN];
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char state;
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long unsigned utime;
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long unsigned stime;
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long unsigned delta_utime;
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long unsigned delta_stime;
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long unsigned delta_time;
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long vss;
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long rss;
694358544a3ffde4ffd1e9434b99b2a7179f05cce4Dmitry Shmidt    int prs;
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int num_threads;
7186c7cc81891a69ace7044de667b0624c284ee82bGlenn Kasten    char policy[POLICY_NAME_LEN];
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct proc_list {
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct proc_info **array;
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int size;
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define die(...) { fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); }
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define INIT_PROCS 50
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define THREAD_MULT 8
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct proc_info **old_procs, **new_procs;
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int num_old_procs, num_new_procs;
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct proc_info *free_procs;
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int num_used_procs, num_free_procs;
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int max_procs, delay, iterations, threads;
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct cpu_info old_cpu, new_cpu;
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct proc_info *alloc_proc(void);
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void free_proc(struct proc_info *proc);
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void read_procs(void);
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int read_stat(char *filename, struct proc_info *proc);
96392744175c4de67dc98e72da6745e6351118c985San Mehatstatic void read_policy(int pid, struct proc_info *proc);
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void add_proc(int proc_num, struct proc_info *proc);
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int read_cmdline(char *filename, struct proc_info *proc);
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int read_status(char *filename, struct proc_info *proc);
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void print_procs(void);
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct proc_info *find_old_proc(pid_t pid, pid_t tid);
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void free_old_procs(void);
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int (*proc_cmp)(const void *a, const void *b);
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int proc_cpu_cmp(const void *a, const void *b);
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int proc_vss_cmp(const void *a, const void *b);
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int proc_rss_cmp(const void *a, const void *b);
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int proc_thr_cmp(const void *a, const void *b);
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int numcmp(long long a, long long b);
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void usage(char *cmd);
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint top_main(int argc, char *argv[]) {
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i;
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    num_used_procs = num_free_procs = 0;
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    max_procs = 0;
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    delay = 3;
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    iterations = -1;
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    proc_cmp = &proc_cpu_cmp;
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 1; i < argc; i++) {
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(argv[i], "-m")) {
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (i + 1 >= argc) {
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr, "Option -m expects an argument.\n");
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                usage(argv[0]);
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                exit(EXIT_FAILURE);
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            max_procs = atoi(argv[++i]);
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(argv[i], "-n")) {
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (i + 1 >= argc) {
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr, "Option -n expects an argument.\n");
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                usage(argv[0]);
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                exit(EXIT_FAILURE);
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            iterations = atoi(argv[++i]);
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(argv[i], "-d")) {
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (i + 1 >= argc) {
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr, "Option -d expects an argument.\n");
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                usage(argv[0]);
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                exit(EXIT_FAILURE);
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            delay = atoi(argv[++i]);
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(argv[i], "-s")) {
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (i + 1 >= argc) {
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr, "Option -s expects an argument.\n");
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                usage(argv[0]);
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                exit(EXIT_FAILURE);
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ++i;
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (!strcmp(argv[i], "cpu")) { proc_cmp = &proc_cpu_cmp; continue; }
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (!strcmp(argv[i], "vss")) { proc_cmp = &proc_vss_cmp; continue; }
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (!strcmp(argv[i], "rss")) { proc_cmp = &proc_rss_cmp; continue; }
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (!strcmp(argv[i], "thr")) { proc_cmp = &proc_thr_cmp; continue; }
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "Invalid argument \"%s\" for option -s.\n", argv[i]);
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            exit(EXIT_FAILURE);
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(argv[i], "-t")) { threads = 1; continue; }
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(argv[i], "-h")) {
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            usage(argv[0]);
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            exit(EXIT_SUCCESS);
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "Invalid argument \"%s\".\n", argv[i]);
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        usage(argv[0]);
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(EXIT_FAILURE);
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (threads && proc_cmp == &proc_thr_cmp) {
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "Sorting by threads per thread makes no sense!\n");
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(EXIT_FAILURE);
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free_procs = NULL;
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    num_new_procs = num_old_procs = 0;
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    new_procs = old_procs = NULL;
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    read_procs();
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while ((iterations == -1) || (iterations-- > 0)) {
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        old_procs = new_procs;
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        num_old_procs = num_new_procs;
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memcpy(&old_cpu, &new_cpu, sizeof(old_cpu));
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sleep(delay);
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        read_procs();
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        print_procs();
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free_old_procs();
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct proc_info *alloc_proc(void) {
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct proc_info *proc;
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (free_procs) {
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        proc = free_procs;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free_procs = free_procs->next;
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        num_free_procs--;
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        proc = malloc(sizeof(*proc));
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!proc) die("Could not allocate struct process_info.\n");
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    num_used_procs++;
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return proc;
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void free_proc(struct proc_info *proc) {
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    proc->next = free_procs;
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free_procs = proc;
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    num_used_procs--;
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    num_free_procs++;
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define MAX_LINE 256
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void read_procs(void) {
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DIR *proc_dir, *task_dir;
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct dirent *pid_dir, *tid_dir;
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char filename[64];
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FILE *file;
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int proc_num;
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct proc_info *proc;
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pid_t pid, tid;
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i;
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    proc_dir = opendir("/proc");
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!proc_dir) die("Could not open /proc.\n");
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    new_procs = calloc(INIT_PROCS * (threads ? THREAD_MULT : 1), sizeof(struct proc_info *));
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    num_new_procs = INIT_PROCS * (threads ? THREAD_MULT : 1);
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    file = fopen("/proc/stat", "r");
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!file) die("Could not open /proc/stat.\n");
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fscanf(file, "cpu  %lu %lu %lu %lu %lu %lu %lu", &new_cpu.utime, &new_cpu.ntime, &new_cpu.stime,
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            &new_cpu.itime, &new_cpu.iowtime, &new_cpu.irqtime, &new_cpu.sirqtime);
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fclose(file);
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    proc_num = 0;
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while ((pid_dir = readdir(proc_dir))) {
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!isdigit(pid_dir->d_name[0]))
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pid = atoi(pid_dir->d_name);
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        struct proc_info cur_proc;
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!threads) {
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            proc = alloc_proc();
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            proc->pid = proc->tid = pid;
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sprintf(filename, "/proc/%d/stat", pid);
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            read_stat(filename, proc);
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sprintf(filename, "/proc/%d/cmdline", pid);
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            read_cmdline(filename, proc);
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sprintf(filename, "/proc/%d/status", pid);
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            read_status(filename, proc);
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
269392744175c4de67dc98e72da6745e6351118c985San Mehat            read_policy(pid, proc);
270392744175c4de67dc98e72da6745e6351118c985San Mehat
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            proc->num_threads = 0;
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sprintf(filename, "/proc/%d/cmdline", pid);
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            read_cmdline(filename, &cur_proc);
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sprintf(filename, "/proc/%d/status", pid);
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            read_status(filename, &cur_proc);
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            proc = NULL;
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sprintf(filename, "/proc/%d/task", pid);
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        task_dir = opendir(filename);
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!task_dir) continue;
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        while ((tid_dir = readdir(task_dir))) {
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (!isdigit(tid_dir->d_name[0]))
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                continue;
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (threads) {
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                tid = atoi(tid_dir->d_name);
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                proc = alloc_proc();
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                proc->pid = pid; proc->tid = tid;
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                sprintf(filename, "/proc/%d/task/%d/stat", pid, tid);
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                read_stat(filename, proc);
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
300392744175c4de67dc98e72da6745e6351118c985San Mehat                read_policy(tid, proc);
301392744175c4de67dc98e72da6745e6351118c985San Mehat
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                strcpy(proc->name, cur_proc.name);
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                proc->uid = cur_proc.uid;
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                proc->gid = cur_proc.gid;
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                add_proc(proc_num++, proc);
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                proc->num_threads++;
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        closedir(task_dir);
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!threads)
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            add_proc(proc_num++, proc);
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = proc_num; i < num_new_procs; i++)
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        new_procs[i] = NULL;
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    closedir(proc_dir);
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int read_stat(char *filename, struct proc_info *proc) {
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FILE *file;
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[MAX_LINE], *open_paren, *close_paren;
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int res, idx;
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    file = fopen(filename, "r");
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!file) return 1;
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fgets(buf, MAX_LINE, file);
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fclose(file);
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Split at first '(' and last ')' to get process name. */
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    open_paren = strchr(buf, '(');
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    close_paren = strrchr(buf, ')');
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!open_paren || !close_paren) return 1;
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *open_paren = *close_paren = '\0';
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    strncpy(proc->tname, open_paren + 1, THREAD_NAME_LEN);
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    proc->tname[THREAD_NAME_LEN-1] = 0;
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Scan rest of string. */
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sscanf(close_paren + 1, " %c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
3454358544a3ffde4ffd1e9434b99b2a7179f05cce4Dmitry Shmidt                 "%lu %lu %*d %*d %*d %*d %*d %*d %*d %lu %ld "
3464358544a3ffde4ffd1e9434b99b2a7179f05cce4Dmitry Shmidt                 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d",
3474358544a3ffde4ffd1e9434b99b2a7179f05cce4Dmitry Shmidt                 &proc->state, &proc->utime, &proc->stime, &proc->vss, &proc->rss, &proc->prs);
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void add_proc(int proc_num, struct proc_info *proc) {
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i;
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (proc_num >= num_new_procs) {
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        new_procs = realloc(new_procs, 2 * num_new_procs * sizeof(struct proc_info *));
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!new_procs) die("Could not expand procs array.\n");
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (i = num_new_procs; i < 2 * num_new_procs; i++)
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            new_procs[i] = NULL;
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        num_new_procs = 2 * num_new_procs;
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    new_procs[proc_num] = proc;
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int read_cmdline(char *filename, struct proc_info *proc) {
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FILE *file;
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char line[MAX_LINE];
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    line[0] = '\0';
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    file = fopen(filename, "r");
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!file) return 1;
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fgets(line, MAX_LINE, file);
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fclose(file);
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (strlen(line) > 0) {
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strncpy(proc->name, line, PROC_NAME_LEN);
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        proc->name[PROC_NAME_LEN-1] = 0;
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        proc->name[0] = 0;
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
382392744175c4de67dc98e72da6745e6351118c985San Mehatstatic void read_policy(int pid, struct proc_info *proc) {
383392744175c4de67dc98e72da6745e6351118c985San Mehat    SchedPolicy p;
384392744175c4de67dc98e72da6745e6351118c985San Mehat    if (get_sched_policy(pid, &p) < 0)
38586c7cc81891a69ace7044de667b0624c284ee82bGlenn Kasten        strlcpy(proc->policy, "unk", POLICY_NAME_LEN);
386392744175c4de67dc98e72da6745e6351118c985San Mehat    else {
38786c7cc81891a69ace7044de667b0624c284ee82bGlenn Kasten        strlcpy(proc->policy, get_sched_policy_name(p), POLICY_NAME_LEN);
38886c7cc81891a69ace7044de667b0624c284ee82bGlenn Kasten        proc->policy[2] = '\0';
389392744175c4de67dc98e72da6745e6351118c985San Mehat    }
390392744175c4de67dc98e72da6745e6351118c985San Mehat}
391392744175c4de67dc98e72da6745e6351118c985San Mehat
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int read_status(char *filename, struct proc_info *proc) {
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FILE *file;
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char line[MAX_LINE];
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int uid, gid;
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    file = fopen(filename, "r");
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!file) return 1;
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (fgets(line, MAX_LINE, file)) {
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sscanf(line, "Uid: %u", &uid);
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sscanf(line, "Gid: %u", &gid);
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fclose(file);
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    proc->uid = uid; proc->gid = gid;
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void print_procs(void) {
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i;
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct proc_info *old_proc, *proc;
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long unsigned total_delta_time;
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct passwd *user;
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct group *group;
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *user_str, user_buf[20];
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *group_str, group_buf[20];
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 0; i < num_new_procs; i++) {
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (new_procs[i]) {
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            old_proc = find_old_proc(new_procs[i]->pid, new_procs[i]->tid);
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (old_proc) {
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                new_procs[i]->delta_utime = new_procs[i]->utime - old_proc->utime;
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                new_procs[i]->delta_stime = new_procs[i]->stime - old_proc->stime;
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                new_procs[i]->delta_utime = 0;
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                new_procs[i]->delta_stime = 0;
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            new_procs[i]->delta_time = new_procs[i]->delta_utime + new_procs[i]->delta_stime;
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    total_delta_time = (new_cpu.utime + new_cpu.ntime + new_cpu.stime + new_cpu.itime
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        + new_cpu.iowtime + new_cpu.irqtime + new_cpu.sirqtime)
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                     - (old_cpu.utime + old_cpu.ntime + old_cpu.stime + old_cpu.itime
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        + old_cpu.iowtime + old_cpu.irqtime + old_cpu.sirqtime);
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    qsort(new_procs, num_new_procs, sizeof(struct proc_info *), proc_cmp);
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("\n\n\n");
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("User %ld%%, System %ld%%, IOW %ld%%, IRQ %ld%%\n",
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ((new_cpu.utime + new_cpu.ntime) - (old_cpu.utime + old_cpu.ntime)) * 100  / total_delta_time,
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ((new_cpu.stime ) - (old_cpu.stime)) * 100 / total_delta_time,
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ((new_cpu.iowtime) - (old_cpu.iowtime)) * 100 / total_delta_time,
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ((new_cpu.irqtime + new_cpu.sirqtime)
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    - (old_cpu.irqtime + old_cpu.sirqtime)) * 100 / total_delta_time);
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("User %ld + Nice %ld + Sys %ld + Idle %ld + IOW %ld + IRQ %ld + SIRQ %ld = %ld\n",
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            new_cpu.utime - old_cpu.utime,
447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            new_cpu.ntime - old_cpu.ntime,
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            new_cpu.stime - old_cpu.stime,
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            new_cpu.itime - old_cpu.itime,
450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            new_cpu.iowtime - old_cpu.iowtime,
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            new_cpu.irqtime - old_cpu.irqtime,
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            new_cpu.sirqtime - old_cpu.sirqtime,
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            total_delta_time);
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("\n");
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!threads)
4564358544a3ffde4ffd1e9434b99b2a7179f05cce4Dmitry Shmidt        printf("%5s %2s %4s %1s %5s %7s %7s %3s %-8s %s\n", "PID", "PR", "CPU%", "S", "#THR", "VSS", "RSS", "PCY", "UID", "Name");
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else
4584358544a3ffde4ffd1e9434b99b2a7179f05cce4Dmitry Shmidt        printf("%5s %5s %2s %4s %1s %7s %7s %3s %-8s %-15s %s\n", "PID", "TID", "PR", "CPU%", "S", "VSS", "RSS", "PCY", "UID", "Thread", "Proc");
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 0; i < num_new_procs; i++) {
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        proc = new_procs[i];
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!proc || (max_procs && (i >= max_procs)))
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        user  = getpwuid(proc->uid);
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        group = getgrgid(proc->gid);
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (user && user->pw_name) {
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            user_str = user->pw_name;
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            snprintf(user_buf, 20, "%d", proc->uid);
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            user_str = user_buf;
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (group && group->gr_name) {
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            group_str = group->gr_name;
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            snprintf(group_buf, 20, "%d", proc->gid);
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            group_str = group_buf;
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!threads)
4804358544a3ffde4ffd1e9434b99b2a7179f05cce4Dmitry Shmidt            printf("%5d %2d %3ld%% %c %5d %6ldK %6ldK %3s %-8.8s %s\n", proc->pid, proc->prs, proc->delta_time * 100 / total_delta_time, proc->state, proc->num_threads,
481392744175c4de67dc98e72da6745e6351118c985San Mehat                proc->vss / 1024, proc->rss * getpagesize() / 1024, proc->policy, user_str, proc->name[0] != 0 ? proc->name : proc->tname);
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else
4834358544a3ffde4ffd1e9434b99b2a7179f05cce4Dmitry Shmidt            printf("%5d %5d %2d %3ld%% %c %6ldK %6ldK %3s %-8.8s %-15s %s\n", proc->pid, proc->tid, proc->prs, proc->delta_time * 100 / total_delta_time, proc->state,
484392744175c4de67dc98e72da6745e6351118c985San Mehat                proc->vss / 1024, proc->rss * getpagesize() / 1024, proc->policy, user_str, proc->tname, proc->name);
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct proc_info *find_old_proc(pid_t pid, pid_t tid) {
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i;
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 0; i < num_old_procs; i++)
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (old_procs[i] && (old_procs[i]->pid == pid) && (old_procs[i]->tid == tid))
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return old_procs[i];
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return NULL;
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void free_old_procs(void) {
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i;
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 0; i < num_old_procs; i++)
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (old_procs[i])
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            free_proc(old_procs[i]);
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free(old_procs);
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int proc_cpu_cmp(const void *a, const void *b) {
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct proc_info *pa, *pb;
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pa = *((struct proc_info **)a); pb = *((struct proc_info **)b);
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pa && !pb) return 0;
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pa) return 1;
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pb) return -1;
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -numcmp(pa->delta_time, pb->delta_time);
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int proc_vss_cmp(const void *a, const void *b) {
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct proc_info *pa, *pb;
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pa = *((struct proc_info **)a); pb = *((struct proc_info **)b);
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pa && !pb) return 0;
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pa) return 1;
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pb) return -1;
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -numcmp(pa->vss, pb->vss);
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int proc_rss_cmp(const void *a, const void *b) {
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct proc_info *pa, *pb;
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pa = *((struct proc_info **)a); pb = *((struct proc_info **)b);
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pa && !pb) return 0;
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pa) return 1;
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pb) return -1;
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -numcmp(pa->rss, pb->rss);
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int proc_thr_cmp(const void *a, const void *b) {
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct proc_info *pa, *pb;
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pa = *((struct proc_info **)a); pb = *((struct proc_info **)b);
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pa && !pb) return 0;
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pa) return 1;
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pb) return -1;
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -numcmp(pa->num_threads, pb->num_threads);
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int numcmp(long long a, long long b) {
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (a < b) return -1;
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (a > b) return 1;
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void usage(char *cmd) {
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "Usage: %s [ -m max_procs ] [ -n iterations ] [ -d delay ] [ -s sort_column ] [ -t ] [ -h ]\n"
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    "    -m num  Maximum number of processes to display.\n"
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    "    -n num  Updates to show before exiting.\n"
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    "    -d num  Seconds to wait between updates.\n"
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    "    -s col  Column to sort by (cpu,vss,rss,thr).\n"
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    "    -t      Show threads instead of processes.\n"
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    "    -h      Display this help screen.\n",
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cmd);
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
572