opcontrol.cpp revision 48ae5fc270ea3bbb965b4bd07cb1691a5c115642
1/* 2 * opcontrol/opcontrol.cpp 3 */ 4 5#include "op_config.h" 6 7#include <stdlib.h> 8#include <fcntl.h> 9#include <stdio.h> 10#include <string.h> 11#include <unistd.h> 12#include <errno.h> 13#include <assert.h> 14#include <dirent.h> 15#include <sys/stat.h> 16 17static int usage(const char* name); 18static int echo(const char* str, const char* file); 19static int read_num(const char* file); 20 21static int start_profiler(int argc, char const * argv[]); 22static int stop_profiler(); 23static int reset_profiler(); 24static int status_profiler(); 25 26int main(int argc, char const * argv[]) 27{ 28 if (argc < 2) 29 return usage(argv[0]); 30 31 const char* tool = argv[1]; 32 33 int ret = 0; 34 if (!strcmp("start", tool)) ret = start_profiler(argc-2, argv+2); 35 else if (!strcmp("stop", tool)) ret = stop_profiler(); 36 else if (!strcmp("reset", tool)) ret = reset_profiler(); 37 else if (!strcmp("status", tool)) ret = status_profiler(); 38 39 return ret ? usage(argv[0]) : 0; 40} 41 42int usage(const char* name) 43{ 44 printf("usage: %s [start [-e event][-p type][-c depth][-i names]" 45 " | stop | reset | status]\n", name); 46 return 0; 47} 48 49 50int start_profiler(int argc, char const * argv[]) 51{ 52 char const* backtrace_depth = "0"; 53 if (argc&1) 54 return -1; 55 56 while (argc>0) { 57 if (!strcmp("-c", argv[0])) 58 backtrace_depth = argv[1]; 59 else if (!strcmp("-p", argv[0])) 60 ; // type 61 else if (!strcmp("-e", argv[0])) 62 ; // event 63 else if (!strcmp("-i", argv[0])) 64 ; // images 65 argc-=2; 66 argv+=2; 67 } 68 69 int err; 70 71 err = echo(backtrace_depth, OP_DRIVER_BASE"/backtrace_depth"); 72 if (err) { 73 printf("couldn't set backtrace depth. backtraces disabled.\n"); 74 } 75 76 err = echo("1", OP_DRIVER_BASE"/enable"); 77 if (err) { 78 printf("couldn't start profiling, is the oprofile driver installed?\n"); 79 return -1; 80 } 81 82 // XXX: start daemon with all good options ... 83 84 mkdir(OP_BASE_DIR, 644); 85 return 0; 86} 87 88int stop_profiler() 89{ 90 int dump, stop; 91 dump = echo("1", OP_DRIVER_BASE"/dump"); 92 // XXX: should wait for complete_dump 93 usleep(250000); 94 stop = echo("0", OP_DRIVER_BASE"/enable"); 95 if (dump || stop) { 96 printf("couldn't stop profiling, is the oprofile driver installed?\n"); 97 return -1; 98 } 99 int num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_received"); 100 printf("profiler stopped with %u samples received\n", num); 101 return 0; 102} 103 104int rm_dir_content(const char* path) 105{ 106 DIR* d = opendir(path); 107 if (d) { 108 struct dirent* de; 109 while ((de = readdir(d))) { 110 if(de->d_name[0] == '.') continue; 111 struct stat s; 112 char* tmp = (char*)malloc(strlen(path)+strlen(de->d_name)+2); 113 if (tmp) { 114 sprintf(tmp, "%s/%s", path, de->d_name); 115 if (lstat(tmp, &s) == 0) { 116 int mode = s.st_mode & S_IFMT; 117 if (mode == S_IFDIR) { 118 rm_dir_content(tmp); 119 rmdir(tmp); 120 } else if (mode == S_IFLNK) { 121 } else if (mode == S_IFSOCK) { 122 } else if (mode == S_IFREG) { 123 unlink(tmp); 124 } 125 } 126 free(tmp); 127 } 128 } 129 closedir(d); 130 } 131 return 0; 132} 133 134int reset_profiler() 135{ 136 echo("1", OP_DRIVER_BASE"/dump"); 137 usleep(250000); 138 // should erase all samples 139 rm_dir_content(OP_BASE_DIR); 140 return 0; 141} 142 143 144int status_profiler() 145{ 146 int num = read_num(OP_DRIVER_BASE"/enable"); 147 if (num >= 0) { 148 printf("profiler %s\n", num ? "started" : "not started"); 149 num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_received"); 150 printf(" %9u samples received\n", num); 151 num = read_num(OP_DRIVER_BASE"/stats/cpu0/backtrace_aborted"); 152 printf(" %9u backtrace aborted\n", num); 153 num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_lost_overflow"); 154 printf(" %9u samples lost overflow\n", num); 155 num = read_num(OP_DRIVER_BASE"/backtrace_depth"); 156 printf(" %9u backtrace_depth\n", num); 157 return 0; 158 } 159 printf("couldn't get profiling status, is the oprofile driver installed?\n"); 160 return -1; 161 162} 163 164int echo(const char* str, const char* file) 165{ 166 int fd = open(file, O_WRONLY); 167 if (fd<0) 168 return fd; 169 write(fd, str, strlen(str)); 170 close(fd); 171 return 0; 172} 173 174int read_num(const char* file) 175{ 176 char buffer[256]; 177 int fd = open(file, O_RDONLY); 178 if (fd<0) return -1; 179 int rd = read(fd, buffer, sizeof(buffer)-1); 180 buffer[rd] = 0; 181 return atoi(buffer); 182} 183 184