perf tools: Separate out GTK codes to libperf-gtk.so

Separate out GTK codes to a shared object called libperf-gtk.so.  This
time only GTK codes are built with -fPIC and libperf remains as is.  Now
run GTK hist and annotation browser using libdl.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Reviewed-by: Pekka Enberg <penberg@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1379053663-13706-1-git-send-email-namhyung@kernel.org
[ Fix it up wrt Ingo's tools/perf build speedups ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Namhyung Kim 2013-09-13 15:27:43 +09:00 committed by Arnaldo Carvalho de Melo
parent fc2be6968e
commit fc67297b16
11 changed files with 165 additions and 74 deletions

View File

@ -114,6 +114,7 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
BUILTIN_OBJS = BUILTIN_OBJS =
LIB_H = LIB_H =
LIB_OBJS = LIB_OBJS =
GTK_OBJS =
PYRF_OBJS = PYRF_OBJS =
SCRIPT_SH = SCRIPT_SH =
@ -490,13 +491,19 @@ ifndef NO_SLANG
endif endif
ifndef NO_GTK2 ifndef NO_GTK2
LIB_OBJS += $(OUTPUT)ui/gtk/browser.o ALL_PROGRAMS += $(OUTPUT)libperf-gtk.so
LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
LIB_OBJS += $(OUTPUT)ui/gtk/setup.o GTK_OBJS += $(OUTPUT)ui/gtk/browser.o
LIB_OBJS += $(OUTPUT)ui/gtk/util.o GTK_OBJS += $(OUTPUT)ui/gtk/hists.o
LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o GTK_OBJS += $(OUTPUT)ui/gtk/setup.o
LIB_OBJS += $(OUTPUT)ui/gtk/progress.o GTK_OBJS += $(OUTPUT)ui/gtk/util.o
LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o GTK_OBJS += $(OUTPUT)ui/gtk/helpline.o
GTK_OBJS += $(OUTPUT)ui/gtk/progress.o
GTK_OBJS += $(OUTPUT)ui/gtk/annotate.o
install-gtk: $(OUTPUT)libperf-gtk.so
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)'
$(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)'
endif endif
ifndef NO_LIBPERL ifndef NO_LIBPERL
@ -550,6 +557,12 @@ $(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \ $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \
$(BUILTIN_OBJS) $(LIBS) -o $@ $(BUILTIN_OBJS) $(LIBS) -o $@
$(GTK_OBJS): $(OUTPUT)%.o: %.c $(LIB_H)
$(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $<
$(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS)
$(QUIET_LINK)$(CC) -o $@ -shared $(ALL_LDFLAGS) $(filter %.o,$^) $(GTK_LIBS)
$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
'-DPERF_HTML_PATH="$(htmldir_SQ)"' \ '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
@ -632,6 +645,9 @@ $(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS
$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
$(OUTPUT)ui/setup.o: ui/setup.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DLIBDIR='"$(libdir_SQ)"' $<
$(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
@ -673,7 +689,8 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
# we compile into subdirectories. if the target directory is not the source directory, they might not exists. So # we compile into subdirectories. if the target directory is not the source directory, they might not exists. So
# we depend the various files onto their directories. # we depend the various files onto their directories.
DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(GTK_OBJS)
DIRECTORY_DEPS += $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h
$(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS))) $(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS)))
# In the second step, we make a rule to actually create these directories # In the second step, we make a rule to actually create these directories
$(sort $(dir $(DIRECTORY_DEPS))): $(sort $(dir $(DIRECTORY_DEPS))):
@ -786,7 +803,9 @@ check: $(OUTPUT)common-cmds.h
### Installation rules ### Installation rules
install-bin: all install-gtk:
install-bin: all install-gtk
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
@ -831,7 +850,8 @@ config-clean:
@$(MAKE) -C config/feature-checks clean @$(MAKE) -C config/feature-checks clean
clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-clean clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-clean
$(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(GTK_OBJS)
$(RM) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS)
$(RM) $(ALL_PROGRAMS) perf $(RM) $(ALL_PROGRAMS) perf
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
@ -850,7 +870,7 @@ else
GIT-HEAD-PHONY = GIT-HEAD-PHONY =
endif endif
.PHONY: all install clean config-clean strip .PHONY: all install clean config-clean strip install-gtk
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS

View File

@ -30,6 +30,7 @@
#include "util/tool.h" #include "util/tool.h"
#include "arch/common.h" #include "arch/common.h"
#include <dlfcn.h>
#include <linux/bitmap.h> #include <linux/bitmap.h>
struct perf_annotate { struct perf_annotate {
@ -142,8 +143,18 @@ find_next:
if (use_browser == 2) { if (use_browser == 2) {
int ret; int ret;
int (*annotate)(struct hist_entry *he,
struct perf_evsel *evsel,
struct hist_browser_timer *hbt);
ret = hist_entry__gtk_annotate(he, evsel, NULL); annotate = dlsym(perf_gtk_handle,
"hist_entry__gtk_annotate");
if (annotate == NULL) {
ui__error("GTK browser not found!\n");
return;
}
ret = annotate(he, evsel, NULL);
if (!ret || !ann->skip_missing) if (!ret || !ann->skip_missing)
return; return;
@ -247,8 +258,17 @@ static int __cmd_annotate(struct perf_annotate *ann)
goto out_delete; goto out_delete;
} }
if (use_browser == 2) if (use_browser == 2) {
perf_gtk__show_annotations(); void (*show_annotations)(void);
show_annotations = dlsym(perf_gtk_handle,
"perf_gtk__show_annotations");
if (show_annotations == NULL) {
ui__error("GTK browser not found!\n");
goto out_delete;
}
show_annotations();
}
out_delete: out_delete:
/* /*

View File

@ -35,6 +35,7 @@
#include "util/hist.h" #include "util/hist.h"
#include "arch/common.h" #include "arch/common.h"
#include <dlfcn.h>
#include <linux/bitmap.h> #include <linux/bitmap.h>
struct perf_report { struct perf_report {
@ -591,8 +592,19 @@ static int __cmd_report(struct perf_report *rep)
ret = 0; ret = 0;
} else if (use_browser == 2) { } else if (use_browser == 2) {
perf_evlist__gtk_browse_hists(session->evlist, help, int (*hist_browser)(struct perf_evlist *,
NULL, rep->min_percent); const char *,
struct hist_browser_timer *,
float min_pcnt);
hist_browser = dlsym(perf_gtk_handle,
"perf_evlist__gtk_browse_hists");
if (hist_browser == NULL) {
ui__error("GTK browser not found!\n");
return ret;
}
hist_browser(session->evlist, help, NULL,
rep->min_percent);
} }
} else } else
perf_evlist__tty_browse_hists(session->evlist, rep, help); perf_evlist__tty_browse_hists(session->evlist, rep, help);

View File

@ -377,11 +377,11 @@ ifndef NO_GTK2
NO_GTK2 := 1 NO_GTK2 := 1
else else
ifeq ($(feature-gtk2-infobar), 1) ifeq ($(feature-gtk2-infobar), 1)
CFLAGS += -DHAVE_GTK_INFO_BAR_SUPPORT GTK_CFLAGS := -DHAVE_GTK_INFO_BAR_SUPPORT
endif endif
CFLAGS += -DHAVE_GTK2_SUPPORT CFLAGS += -DHAVE_GTK2_SUPPORT
CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null) GTK_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null) GTK_LIBS := $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
endif endif
endif endif
@ -554,7 +554,12 @@ else
sysconfdir = $(prefix)/etc sysconfdir = $(prefix)/etc
ETC_PERFCONFIG = etc/perfconfig ETC_PERFCONFIG = etc/perfconfig
endif endif
ifeq ($(IS_X86_64),1)
lib = lib64
else
lib = lib lib = lib
endif
libdir = $(prefix)/$(lib)
# Shell quote (do not use $(call) to accommodate ancient setups); # Shell quote (do not use $(call) to accommodate ancient setups);
ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG)) ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
@ -567,6 +572,7 @@ template_dir_SQ = $(subst ','\'',$(template_dir))
htmldir_SQ = $(subst ','\'',$(htmldir)) htmldir_SQ = $(subst ','\'',$(htmldir))
prefix_SQ = $(subst ','\'',$(prefix)) prefix_SQ = $(subst ','\'',$(prefix))
sysconfdir_SQ = $(subst ','\'',$(sysconfdir)) sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
libdir_SQ = $(subst ','\'',$(libdir))
ifneq ($(filter /%,$(firstword $(perfexecdir))),) ifneq ($(filter /%,$(firstword $(perfexecdir))),)
perfexec_instdir = $(perfexecdir) perfexec_instdir = $(perfexecdir)

View File

@ -154,9 +154,9 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
return 0; return 0;
} }
int symbol__gtk_annotate(struct symbol *sym, struct map *map, static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
struct perf_evsel *evsel, struct perf_evsel *evsel,
struct hist_browser_timer *hbt) struct hist_browser_timer *hbt)
{ {
GtkWidget *window; GtkWidget *window;
GtkWidget *notebook; GtkWidget *notebook;
@ -226,6 +226,13 @@ int symbol__gtk_annotate(struct symbol *sym, struct map *map,
return 0; return 0;
} }
int hist_entry__gtk_annotate(struct hist_entry *he,
struct perf_evsel *evsel,
struct hist_browser_timer *hbt)
{
return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
}
void perf_gtk__show_annotations(void) void perf_gtk__show_annotations(void)
{ {
GtkWidget *window; GtkWidget *window;

View File

@ -20,6 +20,9 @@ struct perf_gtk_context {
guint statbar_ctx_id; guint statbar_ctx_id;
}; };
int perf_gtk__init(void);
void perf_gtk__exit(bool wait_for_ok);
extern struct perf_gtk_context *pgctx; extern struct perf_gtk_context *pgctx;
static inline bool perf_gtk__is_active_context(struct perf_gtk_context *ctx) static inline bool perf_gtk__is_active_context(struct perf_gtk_context *ctx)
@ -48,4 +51,17 @@ static inline GtkWidget *perf_gtk__setup_info_bar(void)
} }
#endif #endif
struct perf_evsel;
struct perf_evlist;
struct hist_entry;
struct hist_browser_timer;
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
struct hist_browser_timer *hbt,
float min_pcnt);
int hist_entry__gtk_annotate(struct hist_entry *he,
struct perf_evsel *evsel,
struct hist_browser_timer *hbt);
void perf_gtk__show_annotations(void);
#endif /* _PERF_GTK_H_ */ #endif /* _PERF_GTK_H_ */

View File

@ -1,10 +1,64 @@
#include <pthread.h> #include <pthread.h>
#include <dlfcn.h>
#include "../util/cache.h" #include "../util/cache.h"
#include "../util/debug.h" #include "../util/debug.h"
#include "../util/hist.h" #include "../util/hist.h"
pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
void *perf_gtk_handle;
#ifdef HAVE_GTK2_SUPPORT
static int setup_gtk_browser(void)
{
int (*perf_ui_init)(void);
if (perf_gtk_handle)
return 0;
perf_gtk_handle = dlopen(PERF_GTK_DSO, RTLD_LAZY);
if (perf_gtk_handle == NULL) {
char buf[PATH_MAX];
scnprintf(buf, sizeof(buf), "%s/%s", LIBDIR, PERF_GTK_DSO);
perf_gtk_handle = dlopen(buf, RTLD_LAZY);
}
if (perf_gtk_handle == NULL)
return -1;
perf_ui_init = dlsym(perf_gtk_handle, "perf_gtk__init");
if (perf_ui_init == NULL)
goto out_close;
if (perf_ui_init() == 0)
return 0;
out_close:
dlclose(perf_gtk_handle);
return -1;
}
static void exit_gtk_browser(bool wait_for_ok)
{
void (*perf_ui_exit)(bool);
if (perf_gtk_handle == NULL)
return;
perf_ui_exit = dlsym(perf_gtk_handle, "perf_gtk__exit");
if (perf_ui_exit == NULL)
goto out_close;
perf_ui_exit(wait_for_ok);
out_close:
dlclose(perf_gtk_handle);
perf_gtk_handle = NULL;
}
#else
static inline int setup_gtk_browser(void) { return -1; }
static inline void exit_gtk_browser(bool wait_for_ok __maybe_unused) {}
#endif
void setup_browser(bool fallback_to_pager) void setup_browser(bool fallback_to_pager)
{ {
@ -17,8 +71,11 @@ void setup_browser(bool fallback_to_pager)
switch (use_browser) { switch (use_browser) {
case 2: case 2:
if (perf_gtk__init() == 0) if (setup_gtk_browser() == 0)
break; break;
printf("GTK browser requested but could not find %s\n",
PERF_GTK_DSO);
sleep(1);
/* fall through */ /* fall through */
case 1: case 1:
use_browser = 1; use_browser = 1;
@ -39,7 +96,7 @@ void exit_browser(bool wait_for_ok)
{ {
switch (use_browser) { switch (use_browser) {
case 2: case 2:
perf_gtk__exit(wait_for_ok); exit_gtk_browser(wait_for_ok);
break; break;
case 1: case 1:

View File

@ -6,6 +6,7 @@
#include <linux/compiler.h> #include <linux/compiler.h>
extern pthread_mutex_t ui__lock; extern pthread_mutex_t ui__lock;
extern void *perf_gtk_handle;
extern int use_browser; extern int use_browser;
@ -23,17 +24,6 @@ static inline int ui__init(void)
static inline void ui__exit(bool wait_for_ok __maybe_unused) {} static inline void ui__exit(bool wait_for_ok __maybe_unused) {}
#endif #endif
#ifdef HAVE_GTK2_SUPPORT
int perf_gtk__init(void);
void perf_gtk__exit(bool wait_for_ok);
#else
static inline int perf_gtk__init(void)
{
return -1;
}
static inline void perf_gtk__exit(bool wait_for_ok __maybe_unused) {}
#endif
void ui__refresh_dimensions(bool force); void ui__refresh_dimensions(bool force);
#endif /* _PERF_UI_H_ */ #endif /* _PERF_UI_H_ */

View File

@ -165,30 +165,6 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
} }
#endif #endif
#ifdef HAVE_GTK2_SUPPORT
int symbol__gtk_annotate(struct symbol *sym, struct map *map,
struct perf_evsel *evsel,
struct hist_browser_timer *hbt);
static inline int hist_entry__gtk_annotate(struct hist_entry *he,
struct perf_evsel *evsel,
struct hist_browser_timer *hbt)
{
return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
}
void perf_gtk__show_annotations(void);
#else
static inline int hist_entry__gtk_annotate(struct hist_entry *he __maybe_unused,
struct perf_evsel *evsel __maybe_unused,
struct hist_browser_timer *hbt __maybe_unused)
{
return 0;
}
static inline void perf_gtk__show_annotations(void) {}
#endif
extern const char *disassembler_style; extern const char *disassembler_style;
#endif /* __PERF_ANNOTATE_H */ #endif /* __PERF_ANNOTATE_H */

View File

@ -228,20 +228,5 @@ static inline int script_browse(const char *script_opt __maybe_unused)
#define K_SWITCH_INPUT_DATA -3000 #define K_SWITCH_INPUT_DATA -3000
#endif #endif
#ifdef HAVE_GTK2_SUPPORT
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
struct hist_browser_timer *hbt __maybe_unused,
float min_pcnt);
#else
static inline
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
const char *help __maybe_unused,
struct hist_browser_timer *hbt __maybe_unused,
float min_pcnt __maybe_unused)
{
return 0;
}
#endif
unsigned int hists__sort_list_width(struct hists *self); unsigned int hists__sort_list_width(struct hists *self);
#endif /* __PERF_HIST_H */ #endif /* __PERF_HIST_H */

View File

@ -128,6 +128,8 @@ void put_tracing_file(char *file);
#endif #endif
#endif #endif
#define PERF_GTK_DSO "libperf-gtk.so"
/* General helper functions */ /* General helper functions */
extern void usage(const char *err) NORETURN; extern void usage(const char *err) NORETURN;
extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));