1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* this code is used to generate a boot sequence profile that can be used 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * with the 'bootchart' graphics generation tool. see www.bootchart.org 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * note that unlike the original bootchartd, this is not a Bash script but 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * some C code that is run right from the init script. 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <time.h> 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <dirent.h> 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "bootchart.h" 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define VERSION "0.8" 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SAMPLE_PERIOD 0.2 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_ROOT "/data/bootchart" 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_STAT LOG_ROOT"/proc_stat.log" 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_PROCS LOG_ROOT"/proc_ps.log" 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_DISK LOG_ROOT"/proc_diskstats.log" 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_HEADER LOG_ROOT"/header" 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_ACCT LOG_ROOT"/kernel_pacct" 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_STARTFILE "/data/bootchart-start" 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_STOPFILE "/data/bootchart-stop" 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunix_read(int fd, void* buff, int len) 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { ret = read(fd, buff, len); } while (ret < 0 && errno == EINTR); 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ret; 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunix_write(int fd, const void* buff, int len) 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { ret = write(fd, buff, len); } while (ret < 0 && errno == EINTR); 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ret; 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectproc_read(const char* filename, char* buff, size_t buffsize) 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = 0; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd = open(filename, O_RDONLY); 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = unix_read(fd, buff, buffsize-1); 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff[len > 0 ? len : 0] = 0; 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return len; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FILE_BUFF_SIZE 65536 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct { 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int count; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char data[FILE_BUFF_SIZE]; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} FileBuffRec, *FileBuff; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfile_buff_open( FileBuff buff, const char* path ) 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff->count = 0; 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff->fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0755); 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfile_buff_write( FileBuff buff, const void* src, int len ) 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (len > 0) { 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int avail = sizeof(buff->data) - buff->count; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (avail > len) 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project avail = len; 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy( buff->data + buff->count, src, avail ); 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= avail; 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project src = (char*)src + avail; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff->count += avail; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (buff->count == FILE_BUFF_SIZE) { 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unix_write( buff->fd, buff->data, buff->count ); 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff->count = 0; 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfile_buff_done( FileBuff buff ) 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (buff->count > 0) { 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unix_write( buff->fd, buff->data, buff->count ); 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff->count = 0; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlog_header(void) 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FILE* out; 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char cmdline[1024]; 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char uname[128]; 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char cpuinfo[128]; 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* cpu; 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char date[32]; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_t now_t = time(NULL); 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tm now = *localtime(&now_t); 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strftime(date, sizeof(date), "%x %X", &now); 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out = fopen( LOG_HEADER, "w" ); 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (out == NULL) 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_read("/proc/cmdline", cmdline, sizeof(cmdline)); 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_read("/proc/version", uname, sizeof(uname)); 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_read("/proc/cpuinfo", cpuinfo, sizeof(cpuinfo)); 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cpu = strchr( cpuinfo, ':' ); 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cpu) { 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = strchr(cpu, '\n'); 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cpu += 2; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (p) 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *p = 0; 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(out, "version = %s\n", VERSION); 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(out, "title = Boot chart for Android ( %s )\n", date); 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(out, "system.uname = %s\n", uname); 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(out, "system.release = 0.0\n"); 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(out, "system.cpu = %s\n", cpu); 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(out, "system.kernel.options = %s\n", cmdline); 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fclose(out); 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectclose_on_exec(int fd) 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fcntl(fd, F_SETFD, FD_CLOEXEC); 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectopen_log_file(int* plogfd, const char* logfile) 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int logfd = *plogfd; 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* create log file if needed */ 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (logfd < 0) 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project logfd = open(logfile,O_WRONLY|O_CREAT|O_TRUNC,0755); 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (logfd < 0) { 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *plogfd = -2; 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_on_exec(logfd); 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *plogfd = logfd; 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdo_log_uptime(FileBuff log) 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buff[65]; 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd, ret, len; 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open("/proc/uptime",O_RDONLY); 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = unix_read(fd, buff, 64); 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff[64] = 0; 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret >= 0) { 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project long long jiffies = 100LL*strtod(buff,NULL); 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(buff,sizeof(buff),"%lld\n",jiffies); 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(buff); 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_write(log, buff, len); 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdo_log_ln(FileBuff log) 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_write(log, "\n", 1); 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdo_log_file(FileBuff log, const char* procfile) 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buff[1024]; 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do_log_uptime(log); 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* append file content */ 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open(procfile,O_RDONLY); 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_on_exec(fd); 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;;) { 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = unix_read(fd, buff, sizeof(buff)); 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret <= 0) 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_write(log, buff, ret); 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret < (int)sizeof(buff)) 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do_log_ln(log); 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdo_log_procs(FileBuff log) 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DIR* dir = opendir("/proc"); 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct dirent* entry; 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do_log_uptime(log); 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((entry = readdir(dir)) != NULL) { 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* only match numeric values */ 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* end; 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pid = strtol( entry->d_name, &end, 10); 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (end != NULL && end > entry->d_name && *end == 0) { 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char filename[32]; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buff[1024]; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char cmdline[1024]; 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* read command line and extract program name */ 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(filename,sizeof(filename),"/proc/%d/cmdline",pid); 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_read(filename, cmdline, sizeof(cmdline)); 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* read process stat line */ 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(filename,sizeof(filename),"/proc/%d/stat",pid); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open(filename,O_RDONLY); 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = unix_read(fd, buff, sizeof(buff)-1); 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len > 0) { 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len2 = strlen(cmdline); 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len2 > 0) { 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we want to substitute the process name with its real name */ 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char* p1; 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char* p2; 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff[len] = 0; 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p1 = strchr(buff, '('); 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p2 = strchr(p1, ')'); 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_write(log, buff, p1+1-buff); 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_write(log, cmdline, strlen(cmdline)); 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_write(log, p2, strlen(p2)); 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* no substitution */ 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_write(log,buff,len); 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project closedir(dir); 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do_log_ln(log); 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic FileBuffRec log_stat[1]; 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic FileBuffRec log_procs[1]; 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic FileBuffRec log_disks[1]; 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* called to setup bootcharting */ 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint bootchart_init( void ) 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buff[4]; 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int timeout = 0, count = 0; 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff[0] = 0; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_read( LOG_STARTFILE, buff, sizeof(buff) ); 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (buff[0] != 0) { 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project timeout = atoi(buff); 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else { 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* when running with emulator, androidboot.bootchart=<timeout> 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * might be passed by as kernel parameters to specify the bootchart 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * timeout. this is useful when using -wipe-data since the /data 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * partition is fresh 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char cmdline[1024]; 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* s; 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define KERNEL_OPTION "androidboot.bootchart=" 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project proc_read( "/proc/cmdline", cmdline, sizeof(cmdline) ); 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s = strstr(cmdline, KERNEL_OPTION); 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (s) { 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s += sizeof(KERNEL_OPTION)-1; 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project timeout = atoi(s); 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (timeout == 0) 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (timeout > BOOTCHART_MAX_TIME_SEC) 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project timeout = BOOTCHART_MAX_TIME_SEC; 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = (timeout*1000 + BOOTCHART_POLLING_MS-1)/BOOTCHART_POLLING_MS; 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do {ret=mkdir(LOG_ROOT,0755);}while (ret < 0 && errno == EINTR); 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_open(log_stat, LOG_STAT); 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_open(log_procs, LOG_PROCS); 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_open(log_disks, LOG_DISK); 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* create kernel process accounting file */ 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd = open( LOG_ACCT, O_WRONLY|O_CREAT|O_TRUNC,0644); 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project acct( LOG_ACCT ); 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project log_header(); 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return count; 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* called each time you want to perform a bootchart sampling op */ 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint bootchart_step( void ) 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do_log_file(log_stat, "/proc/stat"); 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do_log_file(log_disks, "/proc/diskstats"); 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do_log_procs(log_procs); 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we stop when /data/bootchart-stop contains 1 */ 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buff[2]; 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (proc_read(LOG_STOPFILE,buff,sizeof(buff)) > 0 && buff[0] == '1') { 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid bootchart_finish( void ) 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unlink( LOG_STOPFILE ); 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_done(log_stat); 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_done(log_disks); 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_buff_done(log_procs); 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project acct(NULL); 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 379