aboutsummaryrefslogtreecommitdiff
path: root/opcontrol
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commit48ae5fc270ea3bbb965b4bd07cb1691a5c115642 (patch)
tree639ac5dd123a7fd28dfe4c86743b37c23b199b46 /opcontrol
parentcc2ee177dbb3befca43e36cfc56778b006c3d050 (diff)
downloadoprofile-48ae5fc270ea3bbb965b4bd07cb1691a5c115642.tar.gz
Initial Contributionandroid-1.0release-1.0
Diffstat (limited to 'opcontrol')
-rw-r--r--opcontrol/Android.mk18
-rw-r--r--opcontrol/opcontrol.cpp183
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);
+}
+