diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 48ae5fc270ea3bbb965b4bd07cb1691a5c115642 (patch) | |
tree | 639ac5dd123a7fd28dfe4c86743b37c23b199b46 /opcontrol | |
parent | cc2ee177dbb3befca43e36cfc56778b006c3d050 (diff) | |
download | oprofile-48ae5fc270ea3bbb965b4bd07cb1691a5c115642.tar.gz |
Initial Contributionandroid-1.0release-1.0
Diffstat (limited to 'opcontrol')
-rw-r--r-- | opcontrol/Android.mk | 18 | ||||
-rw-r--r-- | opcontrol/opcontrol.cpp | 183 |
2 files changed, 201 insertions, 0 deletions
diff --git a/opcontrol/Android.mk b/opcontrol/Android.mk new file mode 100644 index 0000000..d238e9e --- /dev/null +++ b/opcontrol/Android.mk @@ -0,0 +1,18 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + opcontrol.cpp + +LOCAL_STATIC_LIBRARIES := \ + libpopt libutil libdb libabic libop + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/.. \ + $(LOCAL_PATH)/../libop + +LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) +LOCAL_MODULE_TAGS := debug +LOCAL_MODULE:= opcontrol + +include $(BUILD_EXECUTABLE) diff --git a/opcontrol/opcontrol.cpp b/opcontrol/opcontrol.cpp new file mode 100644 index 0000000..c0b29c7 --- /dev/null +++ b/opcontrol/opcontrol.cpp @@ -0,0 +1,183 @@ +/* + * opcontrol/opcontrol.cpp + */ + +#include "op_config.h" + +#include <stdlib.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <assert.h> +#include <dirent.h> +#include <sys/stat.h> + +static int usage(const char* name); +static int echo(const char* str, const char* file); +static int read_num(const char* file); + +static int start_profiler(int argc, char const * argv[]); +static int stop_profiler(); +static int reset_profiler(); +static int status_profiler(); + +int main(int argc, char const * argv[]) +{ + if (argc < 2) + return usage(argv[0]); + + const char* tool = argv[1]; + + int ret = 0; + if (!strcmp("start", tool)) ret = start_profiler(argc-2, argv+2); + else if (!strcmp("stop", tool)) ret = stop_profiler(); + else if (!strcmp("reset", tool)) ret = reset_profiler(); + else if (!strcmp("status", tool)) ret = status_profiler(); + + return ret ? usage(argv[0]) : 0; +} + +int usage(const char* name) +{ + printf("usage: %s [start [-e event][-p type][-c depth][-i names]" + " | stop | reset | status]\n", name); + return 0; +} + + +int start_profiler(int argc, char const * argv[]) +{ + char const* backtrace_depth = "0"; + if (argc&1) + return -1; + + while (argc>0) { + if (!strcmp("-c", argv[0])) + backtrace_depth = argv[1]; + else if (!strcmp("-p", argv[0])) + ; // type + else if (!strcmp("-e", argv[0])) + ; // event + else if (!strcmp("-i", argv[0])) + ; // images + argc-=2; + argv+=2; + } + + int err; + + err = echo(backtrace_depth, OP_DRIVER_BASE"/backtrace_depth"); + if (err) { + printf("couldn't set backtrace depth. backtraces disabled.\n"); + } + + err = echo("1", OP_DRIVER_BASE"/enable"); + if (err) { + printf("couldn't start profiling, is the oprofile driver installed?\n"); + return -1; + } + + // XXX: start daemon with all good options ... + + mkdir(OP_BASE_DIR, 644); + return 0; +} + +int stop_profiler() +{ + int dump, stop; + dump = echo("1", OP_DRIVER_BASE"/dump"); + // XXX: should wait for complete_dump + usleep(250000); + stop = echo("0", OP_DRIVER_BASE"/enable"); + if (dump || stop) { + printf("couldn't stop profiling, is the oprofile driver installed?\n"); + return -1; + } + int num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_received"); + printf("profiler stopped with %u samples received\n", num); + return 0; +} + +int rm_dir_content(const char* path) +{ + DIR* d = opendir(path); + if (d) { + struct dirent* de; + while ((de = readdir(d))) { + if(de->d_name[0] == '.') continue; + struct stat s; + char* tmp = (char*)malloc(strlen(path)+strlen(de->d_name)+2); + if (tmp) { + sprintf(tmp, "%s/%s", path, de->d_name); + if (lstat(tmp, &s) == 0) { + int mode = s.st_mode & S_IFMT; + if (mode == S_IFDIR) { + rm_dir_content(tmp); + rmdir(tmp); + } else if (mode == S_IFLNK) { + } else if (mode == S_IFSOCK) { + } else if (mode == S_IFREG) { + unlink(tmp); + } + } + free(tmp); + } + } + closedir(d); + } + return 0; +} + +int reset_profiler() +{ + echo("1", OP_DRIVER_BASE"/dump"); + usleep(250000); + // should erase all samples + rm_dir_content(OP_BASE_DIR); + return 0; +} + + +int status_profiler() +{ + int num = read_num(OP_DRIVER_BASE"/enable"); + if (num >= 0) { + printf("profiler %s\n", num ? "started" : "not started"); + num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_received"); + printf(" %9u samples received\n", num); + num = read_num(OP_DRIVER_BASE"/stats/cpu0/backtrace_aborted"); + printf(" %9u backtrace aborted\n", num); + num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_lost_overflow"); + printf(" %9u samples lost overflow\n", num); + num = read_num(OP_DRIVER_BASE"/backtrace_depth"); + printf(" %9u backtrace_depth\n", num); + return 0; + } + printf("couldn't get profiling status, is the oprofile driver installed?\n"); + return -1; + +} + +int echo(const char* str, const char* file) +{ + int fd = open(file, O_WRONLY); + if (fd<0) + return fd; + write(fd, str, strlen(str)); + close(fd); + return 0; +} + +int read_num(const char* file) +{ + char buffer[256]; + int fd = open(file, O_RDONLY); + if (fd<0) return -1; + int rd = read(fd, buffer, sizeof(buffer)-1); + buffer[rd] = 0; + return atoi(buffer); +} + |