1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h> 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 5b93e5812faffd3b6c5fb349072413aace31918d8Olivier Bailly#include <unistd.h> 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7b93e5812faffd3b6c5fb349072413aace31918d8Olivier Bailly#include <stdint.h> 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <dirent.h> 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <signal.h> 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <pwd.h> 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct thread_info { 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pid; 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int tid; 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char name[64]; 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint64_t exec_time; 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint64_t delay_time; 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t run_count; 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct thread_table { 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t allocated; 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t active; 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct thread_info *data; 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectenum { 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FLAG_BATCH = 1U << 0, 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FLAG_HIDE_IDLE = 1U << 1, 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FLAG_SHOW_THREADS = 1U << 2, 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FLAG_USE_ALTERNATE_SCREEN = 1U << 3, 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int time_dp = 9; 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int time_div = 1; 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define NS_TO_S_D(ns) \ 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (uint32_t)((ns) / 1000000000), time_dp, ((uint32_t)((ns) % 1000000000) / time_div) 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct thread_table processes; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct thread_table last_processes; 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct thread_table threads; 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct thread_table last_threads; 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void grow_table(struct thread_table *table) 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t size = table->allocated; 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct thread_info *new_table; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (size < 128) 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size = 128; 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size *= 2; 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project new_table = realloc(table->data, size * sizeof(*table->data)); 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (new_table == NULL) { 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "out of memory\n"); 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project table->data = new_table; 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project table->allocated = size; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct thread_info *get_item(struct thread_table *table) 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (table->active >= table->allocated) 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project grow_table(table); 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return table->data + table->active; 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void commit_item(struct thread_table *table) 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project table->active++; 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int read_line(char *line, size_t line_size) 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open(line, O_RDONLY); 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd == 0) 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = read(fd, line, line_size - 1); 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len <= 0) 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project line[len] = '\0'; 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void add_thread(int pid, int tid, struct thread_info *proc_info) 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char line[1024]; 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *name, *name_end; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t name_len; 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct thread_info *info; 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(tid == 0) 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info = get_item(&processes); 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info = get_item(&threads); 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info->pid = pid; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info->tid = tid; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(tid) 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(line, "/proc/%d/task/%d/schedstat", pid, tid); 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(line, "/proc/%d/schedstat", pid); 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (read_line(line, sizeof(line))) 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(sscanf(line, "%llu %llu %u", &info->exec_time, &info->delay_time, &info->run_count) != 3) 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (proc_info) { 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_info->exec_time += info->exec_time; 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_info->delay_time += info->delay_time; 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_info->run_count += info->run_count; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name = NULL; 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!tid) { 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(line, "/proc/%d/cmdline", pid); 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (read_line(line, sizeof(line)) == 0 && line[0]) { 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name = line; 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name_len = strlen(name); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!name) { 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tid) 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(line, "/proc/%d/task/%d/stat", pid, tid); 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(line, "/proc/%d/stat", pid); 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (read_line(line, sizeof(line))) 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name = strchr(line, '('); 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (name == NULL) 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name_end = strchr(name, ')'); 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (name_end == NULL) 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name++; 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name_len = name_end - name; 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (name_len >= sizeof(info->name)) 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name_len = sizeof(info->name) - 1; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(info->name, name, name_len); 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info->name[name_len] = '\0'; 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(tid == 0) 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project commit_item(&processes); 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project commit_item(&threads); 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void add_threads(int pid, struct thread_info *proc_info) 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char path[1024]; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DIR *d; 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct dirent *de; 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(path, "/proc/%d/task", pid); 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d = opendir(path); 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(d == 0) return; 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while((de = readdir(d)) != 0){ 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(isdigit(de->d_name[0])){ 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int tid = atoi(de->d_name); 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project add_thread(pid, tid, proc_info); 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project closedir(d); 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void print_threads(int pid, uint32_t flags) 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t i, j; 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < last_threads.active; i++) { 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int epid = last_threads.data[i].pid; 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int tid = last_threads.data[i].tid; 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (epid != pid) 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (j = 0; j < threads.active; j++) 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tid == threads.data[j].tid) 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (j == threads.active) 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf(" %5u died\n", tid); 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (!(flags & FLAG_HIDE_IDLE) || threads.data[j].run_count - last_threads.data[i].run_count) 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf(" %5u %2u.%0*u %2u.%0*u %5u %5u.%0*u %5u.%0*u %7u %s\n", tid, 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NS_TO_S_D(threads.data[j].exec_time - last_threads.data[i].exec_time), 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NS_TO_S_D(threads.data[j].delay_time - last_threads.data[i].delay_time), 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project threads.data[j].run_count - last_threads.data[i].run_count, 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NS_TO_S_D(threads.data[j].exec_time), NS_TO_S_D(threads.data[j].delay_time), 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project threads.data[j].run_count, threads.data[j].name); 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void update_table(DIR *d, uint32_t flags) 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t i, j; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct dirent *de; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rewinddir(d); 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while((de = readdir(d)) != 0){ 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(isdigit(de->d_name[0])){ 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pid = atoi(de->d_name); 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct thread_info *proc_info; 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project add_thread(pid, 0, NULL); 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_info = &processes.data[processes.active - 1]; 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_info->exec_time = 0; 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_info->delay_time = 0; 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_info->run_count = 0; 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project add_threads(pid, proc_info); 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!(flags & FLAG_BATCH)) 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("\e[H\e[0J"); 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("Processes: %d, Threads %d\n", processes.active, threads.active); 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (time_dp) { 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 3: 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf(" TID --- SINCE LAST ---- ---------- TOTAL ----------\n"); 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf(" PID EXEC_T DELAY SCHED EXEC_TIME DELAY_TIM SCHED NAME\n"); 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 6: 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf(" TID ------ SINCE LAST ------- ------------ TOTAL -----------\n"); 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf(" PID EXEC_TIME DELAY_TIM SCHED EXEC_TIME DELAY_TIME SCHED NAME\n"); 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf(" TID -------- SINCE LAST -------- ------------- TOTAL -------------\n"); 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf(" PID EXEC_TIME DELAY_TIME SCHED EXEC_TIME DELAY_TIME SCHED NAME\n"); 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < last_processes.active; i++) { 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pid = last_processes.data[i].pid; 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int tid = last_processes.data[i].tid; 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (j = 0; j < processes.active; j++) 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pid == processes.data[j].pid) 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (j == processes.active) 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("%5u died\n", pid); 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (!(flags & FLAG_HIDE_IDLE) || processes.data[j].run_count - last_processes.data[i].run_count) { 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("%5u %2u.%0*u %2u.%0*u %5u %5u.%0*u %5u.%0*u %7u %s\n", pid, 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NS_TO_S_D(processes.data[j].exec_time - last_processes.data[i].exec_time), 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NS_TO_S_D(processes.data[j].delay_time - last_processes.data[i].delay_time), 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project processes.data[j].run_count - last_processes.data[i].run_count, 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NS_TO_S_D(processes.data[j].exec_time), NS_TO_S_D(processes.data[j].delay_time), 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project processes.data[j].run_count, processes.data[j].name); 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (flags & FLAG_SHOW_THREADS) 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project print_threads(pid, flags); 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct thread_table tmp; 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp = last_processes; 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project last_processes = processes; 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project processes = tmp; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project processes.active = 0; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp = last_threads; 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project last_threads = threads; 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project threads = tmp; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project threads.active = 0; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsig_abort(int signum) 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("\e[?47l"); 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint schedtop_main(int argc, char **argv) 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int c; 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DIR *d; 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct dirent *de; 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *namefilter = 0; 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pidfilter = 0; 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t flags = 0; 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int delay = 3000000; 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project float delay_f; 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(1) { 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = getopt(argc, argv, "d:ibtamun"); 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (c == EOF) 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (c) { 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'd': 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project delay_f = atof(optarg); 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project delay = delay_f * 1000000; 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'b': 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flags |= FLAG_BATCH; 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'i': 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flags |= FLAG_HIDE_IDLE; 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 't': 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flags |= FLAG_SHOW_THREADS; 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'a': 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flags |= FLAG_USE_ALTERNATE_SCREEN; 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'm': 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_dp = 3; 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_div = 1000000; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'u': 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_dp = 6; 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_div = 1000; 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'n': 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_dp = 9; 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_div = 1; 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d = opendir("/proc"); 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(d == 0) return -1; 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!(flags & FLAG_BATCH)) { 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(flags & FLAG_USE_ALTERNATE_SCREEN) { 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project signal(SIGINT, sig_abort); 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project signal(SIGPIPE, sig_abort); 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project signal(SIGTERM, sig_abort); 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("\e7\e[?47h"); 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("\e[2J"); 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (1) { 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_table(d, flags); 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usleep(delay); 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project closedir(d); 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 337