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