Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
fc67297b fc2be696

+165 -74
+31 -11
tools/perf/Makefile.perf
··· 114 114 BUILTIN_OBJS = 115 115 LIB_H = 116 116 LIB_OBJS = 117 + GTK_OBJS = 117 118 PYRF_OBJS = 118 119 SCRIPT_SH = 119 120 ··· 491 490 endif 492 491 493 492 ifndef NO_GTK2 494 - LIB_OBJS += $(OUTPUT)ui/gtk/browser.o 495 - LIB_OBJS += $(OUTPUT)ui/gtk/hists.o 496 - LIB_OBJS += $(OUTPUT)ui/gtk/setup.o 497 - LIB_OBJS += $(OUTPUT)ui/gtk/util.o 498 - LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o 499 - LIB_OBJS += $(OUTPUT)ui/gtk/progress.o 500 - LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o 493 + ALL_PROGRAMS += $(OUTPUT)libperf-gtk.so 494 + 495 + GTK_OBJS += $(OUTPUT)ui/gtk/browser.o 496 + GTK_OBJS += $(OUTPUT)ui/gtk/hists.o 497 + GTK_OBJS += $(OUTPUT)ui/gtk/setup.o 498 + GTK_OBJS += $(OUTPUT)ui/gtk/util.o 499 + GTK_OBJS += $(OUTPUT)ui/gtk/helpline.o 500 + GTK_OBJS += $(OUTPUT)ui/gtk/progress.o 501 + GTK_OBJS += $(OUTPUT)ui/gtk/annotate.o 502 + 503 + install-gtk: $(OUTPUT)libperf-gtk.so 504 + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)' 505 + $(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)' 501 506 endif 502 507 503 508 ifndef NO_LIBPERL ··· 556 549 $(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS) 557 550 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \ 558 551 $(BUILTIN_OBJS) $(LIBS) -o $@ 552 + 553 + $(GTK_OBJS): $(OUTPUT)%.o: %.c $(LIB_H) 554 + $(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $< 555 + 556 + $(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS) 557 + $(QUIET_LINK)$(CC) -o $@ -shared $(ALL_LDFLAGS) $(filter %.o,$^) $(GTK_LIBS) 559 558 560 559 $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS 561 560 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \ ··· 645 632 $(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS 646 633 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 647 634 635 + $(OUTPUT)ui/setup.o: ui/setup.c $(OUTPUT)PERF-CFLAGS 636 + $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DLIBDIR='"$(libdir_SQ)"' $< 637 + 648 638 $(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS 649 639 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $< 650 640 ··· 689 673 690 674 # we compile into subdirectories. if the target directory is not the source directory, they might not exists. So 691 675 # we depend the various files onto their directories. 692 - DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h 676 + DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(GTK_OBJS) 677 + DIRECTORY_DEPS += $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h 693 678 $(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS))) 694 679 # In the second step, we make a rule to actually create these directories 695 680 $(sort $(dir $(DIRECTORY_DEPS))): ··· 803 786 804 787 ### Installation rules 805 788 806 - install-bin: all 789 + install-gtk: 790 + 791 + install-bin: all install-gtk 807 792 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' 808 793 $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' 809 794 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' ··· 850 831 @$(MAKE) -C config/feature-checks clean 851 832 852 833 clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-clean 853 - $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) 834 + $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(GTK_OBJS) 835 + $(RM) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) 854 836 $(RM) $(ALL_PROGRAMS) perf 855 837 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* 856 838 $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean ··· 870 850 GIT-HEAD-PHONY = 871 851 endif 872 852 873 - .PHONY: all install clean config-clean strip 853 + .PHONY: all install clean config-clean strip install-gtk 874 854 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell 875 855 .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS 876 856
+23 -3
tools/perf/builtin-annotate.c
··· 30 30 #include "util/tool.h" 31 31 #include "arch/common.h" 32 32 33 + #include <dlfcn.h> 33 34 #include <linux/bitmap.h> 34 35 35 36 struct perf_annotate { ··· 143 142 144 143 if (use_browser == 2) { 145 144 int ret; 145 + int (*annotate)(struct hist_entry *he, 146 + struct perf_evsel *evsel, 147 + struct hist_browser_timer *hbt); 146 148 147 - ret = hist_entry__gtk_annotate(he, evsel, NULL); 149 + annotate = dlsym(perf_gtk_handle, 150 + "hist_entry__gtk_annotate"); 151 + if (annotate == NULL) { 152 + ui__error("GTK browser not found!\n"); 153 + return; 154 + } 155 + 156 + ret = annotate(he, evsel, NULL); 148 157 if (!ret || !ann->skip_missing) 149 158 return; 150 159 ··· 258 247 goto out_delete; 259 248 } 260 249 261 - if (use_browser == 2) 262 - perf_gtk__show_annotations(); 250 + if (use_browser == 2) { 251 + void (*show_annotations)(void); 252 + 253 + show_annotations = dlsym(perf_gtk_handle, 254 + "perf_gtk__show_annotations"); 255 + if (show_annotations == NULL) { 256 + ui__error("GTK browser not found!\n"); 257 + goto out_delete; 258 + } 259 + show_annotations(); 260 + } 263 261 264 262 out_delete: 265 263 /*
+14 -2
tools/perf/builtin-report.c
··· 35 35 #include "util/hist.h" 36 36 #include "arch/common.h" 37 37 38 + #include <dlfcn.h> 38 39 #include <linux/bitmap.h> 39 40 40 41 struct perf_report { ··· 592 591 ret = 0; 593 592 594 593 } else if (use_browser == 2) { 595 - perf_evlist__gtk_browse_hists(session->evlist, help, 596 - NULL, rep->min_percent); 594 + int (*hist_browser)(struct perf_evlist *, 595 + const char *, 596 + struct hist_browser_timer *, 597 + float min_pcnt); 598 + 599 + hist_browser = dlsym(perf_gtk_handle, 600 + "perf_evlist__gtk_browse_hists"); 601 + if (hist_browser == NULL) { 602 + ui__error("GTK browser not found!\n"); 603 + return ret; 604 + } 605 + hist_browser(session->evlist, help, NULL, 606 + rep->min_percent); 597 607 } 598 608 } else 599 609 perf_evlist__tty_browse_hists(session->evlist, rep, help);
+9 -3
tools/perf/config/Makefile
··· 377 377 NO_GTK2 := 1 378 378 else 379 379 ifeq ($(feature-gtk2-infobar), 1) 380 - CFLAGS += -DHAVE_GTK_INFO_BAR_SUPPORT 380 + GTK_CFLAGS := -DHAVE_GTK_INFO_BAR_SUPPORT 381 381 endif 382 382 CFLAGS += -DHAVE_GTK2_SUPPORT 383 - CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null) 384 - EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null) 383 + GTK_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null) 384 + GTK_LIBS := $(shell pkg-config --libs gtk+-2.0 2>/dev/null) 385 385 endif 386 386 endif 387 387 ··· 554 554 sysconfdir = $(prefix)/etc 555 555 ETC_PERFCONFIG = etc/perfconfig 556 556 endif 557 + ifeq ($(IS_X86_64),1) 558 + lib = lib64 559 + else 557 560 lib = lib 561 + endif 562 + libdir = $(prefix)/$(lib) 558 563 559 564 # Shell quote (do not use $(call) to accommodate ancient setups); 560 565 ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG)) ··· 572 567 htmldir_SQ = $(subst ','\'',$(htmldir)) 573 568 prefix_SQ = $(subst ','\'',$(prefix)) 574 569 sysconfdir_SQ = $(subst ','\'',$(sysconfdir)) 570 + libdir_SQ = $(subst ','\'',$(libdir)) 575 571 576 572 ifneq ($(filter /%,$(firstword $(perfexecdir))),) 577 573 perfexec_instdir = $(perfexecdir)
+10 -3
tools/perf/ui/gtk/annotate.c
··· 154 154 return 0; 155 155 } 156 156 157 - int symbol__gtk_annotate(struct symbol *sym, struct map *map, 158 - struct perf_evsel *evsel, 159 - struct hist_browser_timer *hbt) 157 + static int symbol__gtk_annotate(struct symbol *sym, struct map *map, 158 + struct perf_evsel *evsel, 159 + struct hist_browser_timer *hbt) 160 160 { 161 161 GtkWidget *window; 162 162 GtkWidget *notebook; ··· 224 224 225 225 perf_gtk__annotate_symbol(scrolled_window, sym, map, evsel, hbt); 226 226 return 0; 227 + } 228 + 229 + int hist_entry__gtk_annotate(struct hist_entry *he, 230 + struct perf_evsel *evsel, 231 + struct hist_browser_timer *hbt) 232 + { 233 + return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt); 227 234 } 228 235 229 236 void perf_gtk__show_annotations(void)
+16
tools/perf/ui/gtk/gtk.h
··· 20 20 guint statbar_ctx_id; 21 21 }; 22 22 23 + int perf_gtk__init(void); 24 + void perf_gtk__exit(bool wait_for_ok); 25 + 23 26 extern struct perf_gtk_context *pgctx; 24 27 25 28 static inline bool perf_gtk__is_active_context(struct perf_gtk_context *ctx) ··· 50 47 return NULL; 51 48 } 52 49 #endif 50 + 51 + struct perf_evsel; 52 + struct perf_evlist; 53 + struct hist_entry; 54 + struct hist_browser_timer; 55 + 56 + int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help, 57 + struct hist_browser_timer *hbt, 58 + float min_pcnt); 59 + int hist_entry__gtk_annotate(struct hist_entry *he, 60 + struct perf_evsel *evsel, 61 + struct hist_browser_timer *hbt); 62 + void perf_gtk__show_annotations(void); 53 63 54 64 #endif /* _PERF_GTK_H_ */
+59 -2
tools/perf/ui/setup.c
··· 1 1 #include <pthread.h> 2 + #include <dlfcn.h> 2 3 3 4 #include "../util/cache.h" 4 5 #include "../util/debug.h" 5 6 #include "../util/hist.h" 6 7 7 8 pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; 9 + void *perf_gtk_handle; 10 + 11 + #ifdef HAVE_GTK2_SUPPORT 12 + static int setup_gtk_browser(void) 13 + { 14 + int (*perf_ui_init)(void); 15 + 16 + if (perf_gtk_handle) 17 + return 0; 18 + 19 + perf_gtk_handle = dlopen(PERF_GTK_DSO, RTLD_LAZY); 20 + if (perf_gtk_handle == NULL) { 21 + char buf[PATH_MAX]; 22 + scnprintf(buf, sizeof(buf), "%s/%s", LIBDIR, PERF_GTK_DSO); 23 + perf_gtk_handle = dlopen(buf, RTLD_LAZY); 24 + } 25 + if (perf_gtk_handle == NULL) 26 + return -1; 27 + 28 + perf_ui_init = dlsym(perf_gtk_handle, "perf_gtk__init"); 29 + if (perf_ui_init == NULL) 30 + goto out_close; 31 + 32 + if (perf_ui_init() == 0) 33 + return 0; 34 + 35 + out_close: 36 + dlclose(perf_gtk_handle); 37 + return -1; 38 + } 39 + 40 + static void exit_gtk_browser(bool wait_for_ok) 41 + { 42 + void (*perf_ui_exit)(bool); 43 + 44 + if (perf_gtk_handle == NULL) 45 + return; 46 + 47 + perf_ui_exit = dlsym(perf_gtk_handle, "perf_gtk__exit"); 48 + if (perf_ui_exit == NULL) 49 + goto out_close; 50 + 51 + perf_ui_exit(wait_for_ok); 52 + 53 + out_close: 54 + dlclose(perf_gtk_handle); 55 + 56 + perf_gtk_handle = NULL; 57 + } 58 + #else 59 + static inline int setup_gtk_browser(void) { return -1; } 60 + static inline void exit_gtk_browser(bool wait_for_ok __maybe_unused) {} 61 + #endif 8 62 9 63 void setup_browser(bool fallback_to_pager) 10 64 { ··· 71 17 72 18 switch (use_browser) { 73 19 case 2: 74 - if (perf_gtk__init() == 0) 20 + if (setup_gtk_browser() == 0) 75 21 break; 22 + printf("GTK browser requested but could not find %s\n", 23 + PERF_GTK_DSO); 24 + sleep(1); 76 25 /* fall through */ 77 26 case 1: 78 27 use_browser = 1; ··· 96 39 { 97 40 switch (use_browser) { 98 41 case 2: 99 - perf_gtk__exit(wait_for_ok); 42 + exit_gtk_browser(wait_for_ok); 100 43 break; 101 44 102 45 case 1:
+1 -11
tools/perf/ui/ui.h
··· 6 6 #include <linux/compiler.h> 7 7 8 8 extern pthread_mutex_t ui__lock; 9 + extern void *perf_gtk_handle; 9 10 10 11 extern int use_browser; 11 12 ··· 22 21 return -1; 23 22 } 24 23 static inline void ui__exit(bool wait_for_ok __maybe_unused) {} 25 - #endif 26 - 27 - #ifdef HAVE_GTK2_SUPPORT 28 - int perf_gtk__init(void); 29 - void perf_gtk__exit(bool wait_for_ok); 30 - #else 31 - static inline int perf_gtk__init(void) 32 - { 33 - return -1; 34 - } 35 - static inline void perf_gtk__exit(bool wait_for_ok __maybe_unused) {} 36 24 #endif 37 25 38 26 void ui__refresh_dimensions(bool force);
-24
tools/perf/util/annotate.h
··· 165 165 } 166 166 #endif 167 167 168 - #ifdef HAVE_GTK2_SUPPORT 169 - int symbol__gtk_annotate(struct symbol *sym, struct map *map, 170 - struct perf_evsel *evsel, 171 - struct hist_browser_timer *hbt); 172 - 173 - static inline int hist_entry__gtk_annotate(struct hist_entry *he, 174 - struct perf_evsel *evsel, 175 - struct hist_browser_timer *hbt) 176 - { 177 - return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt); 178 - } 179 - 180 - void perf_gtk__show_annotations(void); 181 - #else 182 - static inline int hist_entry__gtk_annotate(struct hist_entry *he __maybe_unused, 183 - struct perf_evsel *evsel __maybe_unused, 184 - struct hist_browser_timer *hbt __maybe_unused) 185 - { 186 - return 0; 187 - } 188 - 189 - static inline void perf_gtk__show_annotations(void) {} 190 - #endif 191 - 192 168 extern const char *disassembler_style; 193 169 194 170 #endif /* __PERF_ANNOTATE_H */
-15
tools/perf/util/hist.h
··· 228 228 #define K_SWITCH_INPUT_DATA -3000 229 229 #endif 230 230 231 - #ifdef HAVE_GTK2_SUPPORT 232 - int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help, 233 - struct hist_browser_timer *hbt __maybe_unused, 234 - float min_pcnt); 235 - #else 236 - static inline 237 - int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused, 238 - const char *help __maybe_unused, 239 - struct hist_browser_timer *hbt __maybe_unused, 240 - float min_pcnt __maybe_unused) 241 - { 242 - return 0; 243 - } 244 - #endif 245 - 246 231 unsigned int hists__sort_list_width(struct hists *self); 247 232 #endif /* __PERF_HIST_H */
+2
tools/perf/util/util.h
··· 128 128 #endif 129 129 #endif 130 130 131 + #define PERF_GTK_DSO "libperf-gtk.so" 132 + 131 133 /* General helper functions */ 132 134 extern void usage(const char *err) NORETURN; 133 135 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));