Skip to contentSkip to conversation

Perf on Android

PATCH New Bernhard Rosenkraenzer 1 participant 1 message Nov 26, 2012 perf events

lore
Share & tools
lore
#0 lore raw

PATCH v3 1/1 Perf on Android

This is another attempt at getting perf ot work on Android - it's rebased to 3.7-rc6 and cleaned up from the earlier version. Also adds support for Android 4.2.

---
 tools/perf/Makefile                 |  17 +++++-
 tools/perf/builtin-record.c         |  33 +++++++++++
 tools/perf/builtin-test.c           |   7 +++
 tools/perf/compat-android.h         | 106 
++++++++++++++++++++++++++++++++++++
 tools/perf/config/feature-tests.mak |  13 +++++
 tools/perf/util/util.h              |   2 +
 6 files changed, 175 insertions(+), 3 deletions(-)
 create mode 100644 tools/perf/compat-android.h
tools/perf/Makefile +0 -0
index 00deed4d..f74ea4b 100644
@@ -104,7 +104,7 @@ ifdef PARSER_DEBUG
 endif
 
 CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra -

std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS)
-EXTLIBS = -lpthread -lrt -lelf -lm
+EXTLIBS = -lpthread -lelf -lm
ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -
D_GNU_SOURCE
ALL_LDFLAGS = $(LDFLAGS)
STRIP ?= strip
@@ -471,7 +471,14 @@ FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y)
FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
ifneq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y)
- msg := $(error No gnu/libc-version.h found, please install glibc-
dev[el]/glibc-static);
+ ifeq ($(call try-cc,$(SOURCE_BIONIC),$(FLAGS_GLIBC)),y)
+ # Found Bionic instead of glibc...
+ # That works too, but needs a bit of special treatment
+ BASIC_CFLAGS += -DANDROID -DHAVE_STRLCPY -include $(CURDIR)/compat-
android.h
+ ANDROID := 1
+ else
+ msg := $(error No gnu/libc-version.h found, please install glibc-
dev[el]/glibc-static);
+ endif
else
NO_LIBELF := 1
NO_DWARF := 1
@@ -486,6 +493,10 @@ else
endif # SOURCE_LIBELF
endif # NO_LIBELF

+ifneq ($(ANDROID),1)
+EXTLIBS += -lrt
+endif
+
ifndef NO_LIBUNWIND

 # for linking with debug library, run like:
 # make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
@@ -920,7 +931,7 @@ $(LIB_FILE): $(LIB_OBJS)
 # libtraceevent.a
 $(LIBTRACEEVENT):
-	$(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) 
libtraceevent.a
+	$(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) CFLAGS="$(ALL_CFLAGS)" 
O=$(OUTPUT) libtraceevent.a

$(LIBTRACEEVENT)-clean:
$(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean

tools/perf/builtin-record.c +33 -0
index e9231659..451db23 100644
@@ -27,10 +27,43 @@
 #include "util/cpumap.h"
 #include "util/thread_map.h"
 
+#include <stdlib.h>
 #include <unistd.h>
 #include <sched.h>
 #include <sys/mman.h>
 
+#ifdef ANDROID
+/* While stdlib.h has a prototype for it,
+   Bionic doesn't actually implement on_exit() */
+#ifndef ATEXIT_MAX
+#define ATEXIT_MAX 32
+#endif
+static int __on_exit_count = 0;
+typedef void (*on_exit_func_t)(int, void*);
+static on_exit_func_t __on_exit_funcs[ATEXIT_MAX];
+static void *__on_exit_args[ATEXIT_MAX];
+static int __exitcode = 0;
+static void __handle_on_exit_funcs();
+static int on_exit(on_exit_func_t function, void *arg);
+#define exit(x) (exit)(__exitcode = (x))
+
+static int on_exit(on_exit_func_t function, void *arg) {
+	if(__on_exit_count == ATEXIT_MAX)
+		return ENOMEM;
+	else if(__on_exit_count == 0)
+		atexit(__handle_on_exit_funcs);
+	__on_exit_funcs[__on_exit_count] = function;
+	__on_exit_args[__on_exit_count++] = arg;
+	return 0;
+}
+
+static void __handle_on_exit_funcs() {
+	for(int i=0; i<__on_exit_count; i++) {
+		__on_exit_funcs[i](__exitcode, __on_exit_args[i]);
+	}
+}
+#endif
+
 enum write_mode_t {
 	WRITE_FORCE,
 	WRITE_APPEND
tools/perf/builtin-test.c +7 -0
index 484f26c..70a9cd6 100644
@@ -471,10 +471,17 @@ static int test__basic_mmap(void)
 		.watermark	= 0,
 	};
 	cpu_set_t cpu_set;
+#ifndef ANDROID
 	const char *syscall_names[] = { "getsid", "getppid", "getpgrp",
 					"getpgid", };
 	pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp,
 				      (void*)getpgid };
+#else
+	/* No getsid() on Android */
+	const char *syscall_names[] = { "getppid", "getpgrp",
+					"getpgid", };
+	pid_t (*syscalls[])(void) = { getppid, getpgrp, (void*)getpgid };
+#endif
 #define nsyscalls ARRAY_SIZE(syscall_names)
 	int ids[nsyscalls];
 	unsigned int nr_events[nsyscalls],
tools/perf/compat-android.h new file +106 -0

106 lines not on this page · raw message

tools/perf/config/feature- renamed from tools/perf/config/feature-tests.mak +0 -0

tests.mak
index 4add41b..76ec8bf 100644

tools/perf/config/feature-tests.mak +13 -0
@@ -43,6 +43,19 @@ int main(void)
 }
 endef
 
+define SOURCE_BIONIC
+#include <android/api-level.h>
+
+int main(void)
+{
+#ifndef __ANDROID_API__
+	error out
+#else
+	return 0;
+#endif
+}
+endef
+
 define SOURCE_ELF_MMAP
 #include <libelf.h>
 int main(void)
tools/perf/util/util.h +2 -0
index 70fa70b..10e8a47 100644
@@ -72,7 +72,9 @@
 #include <inttypes.h>
 #include <linux/magic.h>
 #include "types.h"
+#ifndef ANDROID
 #include <sys/ttydefaults.h>
+#endif
 
 extern const char *graph_line;
 extern const char *graph_dotted_line;
Signature · 1 line
1.7.11.3