1e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/* 2e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * 4e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * you may not use this file except in compliance with the License. 6e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * You may obtain a copy of the License at 7e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * 8e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * 10e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * See the License for the specific language governing permissions and 14e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * limitations under the License. 15e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project */ 16e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 17e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <assert.h> 18e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <dirent.h> 19e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <errno.h> 20eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross#include <getopt.h> 21122c7191dbac60e0a79c24551c142c98597354cdColin Cross#include <stdbool.h> 22e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdlib.h> 23e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <string.h> 24e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/types.h> 25e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <unistd.h> 26e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 27e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <pagemap/pagemap.h> 28e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 29e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define MAX_CMDLINE 256 30e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 31e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstruct process_info { 32e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pid_t pid; 33e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char cmdline[MAX_CMDLINE]; 34e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}; 35e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 36e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstruct mapping_info { 37e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project struct process_info *proc; 38e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_memusage_t usage; 391154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn}; 40e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 41e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstruct library_info { 42e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project struct library_info *next; 43e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char *name; 44e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project struct mapping_info **mappings; 451154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn size_t mappings_count; 461154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn size_t mappings_size; 47e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_memusage_t total_usage; 48e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}; 49e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 50e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic void usage(char *myname); 51e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int getprocname(pid_t pid, char *buf, size_t len); 52e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int numcmp(long long a, long long b); 53e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int licmp(const void *a, const void *b); 54e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 55e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectchar *library_name_blacklist[] = { "[heap]", "[stack]", "", NULL }; 56e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 57e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define declare_sort(field) \ 58e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project static int sort_by_ ## field (const void *a, const void *b) 59e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 60e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectdeclare_sort(vss); 61e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectdeclare_sort(rss); 62e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectdeclare_sort(pss); 63e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectdeclare_sort(uss); 64d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Crossdeclare_sort(swap); 65e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 66e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define INIT_LIBRARIES 16 67e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define INIT_MAPPINGS 4 68e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 69e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int order; 70e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 71e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstruct library_info **libraries; 721154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzynsize_t libraries_count; 731154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzynsize_t libraries_size; 74e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 75122c7191dbac60e0a79c24551c142c98597354cdColin Crossstruct library_info *get_library(const char *name, bool all) { 761154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn size_t i; 77e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project struct library_info *library; 78e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 79122c7191dbac60e0a79c24551c142c98597354cdColin Cross if (!all) { 80122c7191dbac60e0a79c24551c142c98597354cdColin Cross for (i = 0; library_name_blacklist[i]; i++) 81122c7191dbac60e0a79c24551c142c98597354cdColin Cross if (!strcmp(name, library_name_blacklist[i])) 82122c7191dbac60e0a79c24551c142c98597354cdColin Cross return NULL; 83122c7191dbac60e0a79c24551c142c98597354cdColin Cross } else { 84122c7191dbac60e0a79c24551c142c98597354cdColin Cross if (name[0] == 0) { 85122c7191dbac60e0a79c24551c142c98597354cdColin Cross name = "[anon]"; 86122c7191dbac60e0a79c24551c142c98597354cdColin Cross } 87122c7191dbac60e0a79c24551c142c98597354cdColin Cross } 88e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 89e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project for (i = 0; i < libraries_count; i++) { 90e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (!strcmp(libraries[i]->name, name)) 91e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return libraries[i]; 92e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 93e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 94e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (libraries_count >= libraries_size) { 95e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project libraries = realloc(libraries, 2 * libraries_size * sizeof(struct library_info *)); 96e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (!libraries) { 97e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Couldn't resize libraries array: %s\n", strerror(errno)); 98e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 99e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 100e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project libraries_size = 2 * libraries_size; 101e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 102e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 103e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project library = calloc(1, sizeof(*library)); 104e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (!library) { 105e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Couldn't allocate space for library struct: %s\n", strerror(errno)); 106e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 107e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 108e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project library->name = malloc(strlen(name) + 1); 109e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (!library->name) { 110e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Couldn't allocate space for library name: %s\n", strerror(errno)); 111e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 112e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 113e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project strcpy(library->name, name); 114e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project library->mappings = malloc(INIT_MAPPINGS * sizeof(struct mapping_info *)); 115e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (!library->mappings) { 116e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Couldn't allocate space for library mappings array: %s\n", strerror(errno)); 117e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 118e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 119e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project library->mappings_count = 0; library->mappings_size = INIT_MAPPINGS; 120e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_memusage_zero(&library->total_usage); 121e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 122e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project libraries[libraries_count++] = library; 123e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 124e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return library; 125e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 126e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 127e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstruct mapping_info *get_mapping(struct library_info *library, struct process_info *proc) { 128e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project struct mapping_info *mapping; 1291154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn size_t i; 130e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 131e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project for (i = 0; i < library->mappings_count; i++) { 132e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (library->mappings[i]->proc == proc) 133e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return library->mappings[i]; 134e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 135e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 136e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (library->mappings_count >= library->mappings_size) { 137e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project library->mappings = realloc(library->mappings, 138e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 2 * library->mappings_size * sizeof(struct mapping*)); 139e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (!library->mappings) { 140e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Couldn't resize mappings array: %s\n", strerror(errno)); 141e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 142e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 143e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project library->mappings_size = 2 * library->mappings_size; 144e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 145e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 146e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mapping = calloc(1, sizeof(*mapping)); 147e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (!mapping) { 148e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Couldn't allocate space for mapping struct: %s\n", strerror(errno)); 149e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 150e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 151e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mapping->proc = proc; 152e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_memusage_zero(&mapping->usage); 153e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 154e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project library->mappings[library->mappings_count++] = mapping; 155e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 156e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return mapping; 157e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 158e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 159e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstruct process_info *get_process(pid_t pid) { 160e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project struct process_info *process; 161e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 162e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project process = calloc(1, sizeof(*process)); 163e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (!process) { 164e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Couldn't allocate space for process struct: %s\n", strerror(errno)); 165e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 166e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 1671154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn 168e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project process->pid = pid; 169e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project getprocname(pid, process->cmdline, sizeof(process->cmdline)); 170e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 171e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return process; 172e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 173e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 17472f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Crossstatic int parse_perm(const char *perm) 17572f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross{ 17672f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross int ret = 0; 17772f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross 17872f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross while (*perm) { 17972f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross switch(*perm) { 18072f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross case 'r': 18172f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross ret |= PM_MAP_READ; 18272f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross break; 18372f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross case 'w': 18472f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross ret |= PM_MAP_WRITE; 18572f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross break; 18672f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross case 'x': 18772f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross ret |= PM_MAP_EXEC; 18872f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross break; 18972f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross default: 19072f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross fprintf(stderr, "Unknown permission '%c'\n", *perm); 19172f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross exit(EXIT_FAILURE); 19272f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross } 19372f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross perm++; 19472f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross } 19572f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross return ret; 19672f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross} 19772f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross 198e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint main(int argc, char *argv[]) { 199e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char cmdline[256]; 200e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char *prefix; 201e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project size_t prefix_len; 202e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project int (*compfn)(const void *a, const void *b); 203e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 204e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_kernel_t *ker; 205e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_process_t *proc; 206e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 207e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pid_t *pids; 208e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project size_t num_procs; 209e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 210e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_map_t **maps; 211e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project size_t num_maps; 212e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_memusage_t map_usage; 213e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 214e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project struct library_info *li, **lis; 215e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project struct mapping_info *mi, **mis; 216e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project struct process_info *pi; 217e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 2181154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn size_t i, j; 2191154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn int error; 22072f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross int perm; 221122c7191dbac60e0a79c24551c142c98597354cdColin Cross bool all; 222bd86b3b10f8c57788177b5132e7078236683f185Colin Cross uint64_t required_flags; 223bd86b3b10f8c57788177b5132e7078236683f185Colin Cross uint64_t flags_mask; 224e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 225d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross bool has_swap = false; 226d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross 22780cb15504324667c9934ff350afff48881613393JP Abgrall signal(SIGPIPE, SIG_IGN); 228e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project compfn = &sort_by_pss; 229e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project order = -1; 230e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project prefix = NULL; 231e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project prefix_len = 0; 232eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross opterr = 0; 23372f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross perm = 0; 234122c7191dbac60e0a79c24551c142c98597354cdColin Cross all = false; 235bd86b3b10f8c57788177b5132e7078236683f185Colin Cross required_flags = 0; 236bd86b3b10f8c57788177b5132e7078236683f185Colin Cross flags_mask = 0; 237eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross 238eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross while (1) { 239eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross int c; 240eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross const struct option longopts[] = { 241122c7191dbac60e0a79c24551c142c98597354cdColin Cross {"all", 0, 0, 'a'}, 242bd86b3b10f8c57788177b5132e7078236683f185Colin Cross {"cached", 0, 0, 'c'}, 243bd86b3b10f8c57788177b5132e7078236683f185Colin Cross {"nocached", 0, 0, 'C'}, 244479747be63f3c8c33220d3c2690cac6b674746eaColin Cross {"ksm", 0, 0, 'k'}, 245eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross {"help", 0, 0, 'h'}, 246eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross {"pss", 0, 0, 'p'}, 247eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross {"uss", 0, 0, 'u'}, 248eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross {"vss", 0, 0, 'v'}, 249eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross {"rss", 0, 0, 'r'}, 250d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross {"swap", 0, 0, 's'}, 251eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross {"reverse", 0, 0, 'R'}, 252eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross {"path", required_argument, 0, 'P'}, 25372f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross {"perm", required_argument, 0, 'm'}, 254eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross {0, 0, 0, 0} 255eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross }; 256479747be63f3c8c33220d3c2690cac6b674746eaColin Cross c = getopt_long(argc, argv, "acChkm:pP:uvrsR", longopts, NULL); 257eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross if (c < 0) { 258eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross break; 259eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross } 260eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross /* Alphabetical cases */ 261eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross switch (c) { 262122c7191dbac60e0a79c24551c142c98597354cdColin Cross case 'a': 263122c7191dbac60e0a79c24551c142c98597354cdColin Cross all = true; 264122c7191dbac60e0a79c24551c142c98597354cdColin Cross break; 265bd86b3b10f8c57788177b5132e7078236683f185Colin Cross case 'c': 266bd86b3b10f8c57788177b5132e7078236683f185Colin Cross required_flags = 0; 267bd86b3b10f8c57788177b5132e7078236683f185Colin Cross flags_mask = PM_PAGE_SWAPBACKED; 268bd86b3b10f8c57788177b5132e7078236683f185Colin Cross break; 269bd86b3b10f8c57788177b5132e7078236683f185Colin Cross case 'C': 270bd86b3b10f8c57788177b5132e7078236683f185Colin Cross required_flags = PM_PAGE_SWAPBACKED; 271bd86b3b10f8c57788177b5132e7078236683f185Colin Cross flags_mask = PM_PAGE_SWAPBACKED; 272bd86b3b10f8c57788177b5132e7078236683f185Colin Cross break; 273479747be63f3c8c33220d3c2690cac6b674746eaColin Cross case 'k': 274479747be63f3c8c33220d3c2690cac6b674746eaColin Cross required_flags = PM_PAGE_KSM; 275479747be63f3c8c33220d3c2690cac6b674746eaColin Cross flags_mask = PM_PAGE_KSM; 276479747be63f3c8c33220d3c2690cac6b674746eaColin Cross break; 277eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross case 'h': 278eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross usage(argv[0]); 279eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross exit(EXIT_SUCCESS); 28072f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross case 'm': 28172f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross perm = parse_perm(optarg); 28272f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross break; 283eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross case 'p': 284eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross compfn = &sort_by_pss; 285eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross break; 286eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross case 'P': 287eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross prefix = optarg; 288e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project prefix_len = strlen(prefix); 289eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross break; 290eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross case 'u': 291eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross compfn = &sort_by_uss; 292eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross break; 293eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross case 'v': 294eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross compfn = &sort_by_vss; 295eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross break; 296eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross case 'r': 297eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross compfn = &sort_by_rss; 298eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross break; 299d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross case 's': 300d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross compfn = &sort_by_swap; 301d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross break; 302eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross case 'R': 303eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross order *= -1; 304eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross break; 305eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross case '?': 306eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross fprintf(stderr, "Invalid argument \"%s\".\n", argv[optind - 1]); 307eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross usage(argv[0]); 308eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross exit(EXIT_FAILURE); 309eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross default: 310eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross abort(); 311e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 312e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 313e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 314eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross argc -= optind; 315eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross argv += optind; 316eff57afe53f2cbdf48f988b692036a7c470c41faColin Cross 317e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project libraries = malloc(INIT_LIBRARIES * sizeof(struct library_info *)); 318e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project libraries_count = 0; libraries_size = INIT_LIBRARIES; 319e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 320e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project error = pm_kernel_create(&ker); 321e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (error) { 322e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Error initializing kernel interface -- " 323e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project "does this kernel have pagemap?\n"); 324e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 325e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 326e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 327e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project error = pm_kernel_pids(ker, &pids, &num_procs); 328e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (error) { 329e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Error listing processes.\n"); 330e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 331e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 332e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 333e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project for (i = 0; i < num_procs; i++) { 334e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project error = pm_process_create(ker, pids[i], &proc); 335e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (error) { 336e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "warning: could not create process interface for %d\n", pids[i]); 337e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project continue; 338e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 3391154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn 340e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pi = get_process(pids[i]); 341e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 342e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project error = pm_process_maps(proc, &maps, &num_maps); 343e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (error) { 344e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Error listing maps for process %d.\n", proc->pid); 345e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 346e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 347e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 348e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project for (j = 0; j < num_maps; j++) { 349e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (prefix && (strncmp(pm_map_name(maps[j]), prefix, prefix_len))) 350e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project continue; 351e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 35272f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross if (perm && (pm_map_flags(maps[j]) & PM_MAP_PERMISSIONS) != perm) 35372f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross continue; 35472f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross 355122c7191dbac60e0a79c24551c142c98597354cdColin Cross li = get_library(pm_map_name(maps[j]), all); 356e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (!li) 357e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project continue; 358e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 359e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mi = get_mapping(li, pi); 3601154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn 361bd86b3b10f8c57788177b5132e7078236683f185Colin Cross error = pm_map_usage_flags(maps[j], &map_usage, flags_mask, 362bd86b3b10f8c57788177b5132e7078236683f185Colin Cross required_flags); 363e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (error) { 364e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Error getting map memory usage of " 365e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project "map %s in process %d.\n", 366e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_map_name(maps[j]), proc->pid); 367e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 368e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 369d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross 370d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross if (map_usage.swap) { 371d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross has_swap = true; 372d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross } 373d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross 374e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_memusage_add(&mi->usage, &map_usage); 375e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_memusage_add(&li->total_usage, &map_usage); 376e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 377e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 378e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 379d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross printf(" %6s %6s %6s %6s %6s ", "RSStot", "VSS", "RSS", "PSS", "USS"); 380d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross 381d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross if (has_swap) { 382d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross printf(" %6s ", "Swap"); 383d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross } 384d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross 385d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross printf("Name/PID\n"); 386e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fflush(stdout); 387e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 388e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project qsort(libraries, libraries_count, sizeof(libraries[0]), &licmp); 389e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 390e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project for (i = 0; i < libraries_count; i++) { 391e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project li = libraries[i]; 392e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 3931154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn printf("%6zdK %6s %6s %6s %6s ", li->total_usage.pss / 1024, "", "", "", ""); 394d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross if (has_swap) { 395d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross printf(" %6s ", ""); 396d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross } 397d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross printf("%s\n", li->name); 398e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fflush(stdout); 399e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 400e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project qsort(li->mappings, li->mappings_count, sizeof(li->mappings[0]), compfn); 401e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 402e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project for (j = 0; j < li->mappings_count; j++) { 403e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mi = li->mappings[j]; 404e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pi = mi->proc; 4051154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn printf( " %6s %6zdK %6zdK %6zdK %6zdK ", "", 406e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mi->usage.vss / 1024, 407e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mi->usage.rss / 1024, 408e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mi->usage.pss / 1024, 409d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross mi->usage.uss / 1024); 410d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross if (has_swap) { 4111154fe3bd09d22a39b657726e019d8644069ea94Mark Salyzyn printf("%6zdK ", mi->usage.swap / 1024); 412d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross } 413d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross printf(" %s [%d]\n", 414e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pi->cmdline, 415e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pi->pid); 416e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 417e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project printf("\n"); 418e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fflush(stdout); 419e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 420e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 421e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 0; 422e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 423e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 424e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic void usage(char *myname) { 425d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross fprintf(stderr, "Usage: %s [ -P | -L ] [ -v | -r | -p | -u | -s | -h ]\n" 426e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project "\n" 427e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project "Sort options:\n" 428e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -v Sort processes by VSS.\n" 429e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -r Sort processes by RSS.\n" 430e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -p Sort processes by PSS.\n" 431e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -u Sort processes by USS.\n" 432d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Cross " -s Sort processes by swap.\n" 433e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " (Default sort order is PSS.)\n" 434122c7191dbac60e0a79c24551c142c98597354cdColin Cross " -a Show all mappings, including stack, heap and anon.\n" 435e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -P /path Limit libraries displayed to those in path.\n" 436e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -R Reverse sort order (default is descending).\n" 43772f75f0b12ca23cf91ecfcb945ee42a0e1da9fd4Colin Cross " -m [r][w][x] Only list pages that exactly match permissions\n" 438bd86b3b10f8c57788177b5132e7078236683f185Colin Cross " -c Only show cached (storage backed) pages\n" 439bd86b3b10f8c57788177b5132e7078236683f185Colin Cross " -C Only show non-cached (ram/swap backed) pages\n" 440479747be63f3c8c33220d3c2690cac6b674746eaColin Cross " -k Only show pages collapsed by KSM\n" 441e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -h Display this help screen.\n", 442e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project myname); 443e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 444e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 445e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int getprocname(pid_t pid, char *buf, size_t len) { 446e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char filename[20]; 447e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project FILE *f; 448e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 449e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project sprintf(filename, "/proc/%d/cmdline", pid); 450e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project f = fopen(filename, "r"); 451e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (!f) { *buf = '\0'; return 1; } 452e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (!fgets(buf, len, f)) { *buf = '\0'; return 2; } 453e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fclose(f); 454e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 0; 455e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 456e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 457e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int numcmp(long long a, long long b) { 458e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (a < b) return -1; 459e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (a > b) return 1; 460e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 0; 461e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 462e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 463e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int licmp(const void *a, const void *b) { 464e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return order * numcmp( 465e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project (*((struct library_info**)a))->total_usage.pss, 466e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project (*((struct library_info**)b))->total_usage.pss 467e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project ); 468e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 469e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 470e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define create_sort(field, compfn) \ 471e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project static int sort_by_ ## field (const void *a, const void *b) { \ 472e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return order * compfn( \ 473e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project (*((struct mapping_info**)a))->usage.field, \ 474e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project (*((struct mapping_info**)b))->usage.field \ 475e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project ); \ 476e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 477e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 478e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectcreate_sort(vss, numcmp) 479e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectcreate_sort(rss, numcmp) 480e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectcreate_sort(pss, numcmp) 481e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectcreate_sort(uss, numcmp) 482d2b8656ce47ee08aba7cb95499deeb29254eb655Colin Crosscreate_sort(swap, numcmp) 483