From 5baf1a81ea59231235144a3e9edbc4438f6965ce Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Fri, 16 Sep 2011 09:09:35 +0100 Subject: Print out the summary when SIGUSR1 is received --- mutrace.c | 52 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/mutrace.c b/mutrace.c index 83a25f2..e1106bb 100644 --- a/mutrace.c +++ b/mutrace.c @@ -37,6 +37,7 @@ #include #include #include +#include #if !defined (__linux__) || !defined(__GLIBC__) #error "This stuff only works on Linux!" @@ -52,7 +53,6 @@ #if defined(__i386__) || defined(__x86_64__) #define DEBUG_TRAP __asm__("int $3") #else -#include #define DEBUG_TRAP raise(SIGTRAP) #endif @@ -147,6 +147,8 @@ static void shutdown(void) __attribute ((destructor)); static char *stacktrace_to_string(struct stacktrace_info stacktrace); +static void sigusr1_cb(int sig); + static pid_t _gettid(void) { return (pid_t) syscall(SYS_gettid); } @@ -259,6 +261,7 @@ static void load_functions(void) { } static void setup(void) { + struct sigaction sigusr_action; pthread_mutex_t *m, *last; int r; unsigned t; @@ -350,6 +353,13 @@ static void setup(void) { assert(r == 0); } + /* Listen for SIGUSR1 and print out a summary of what's happened so far + * when we receive it. */ + sigusr_action.sa_handler = sigusr1_cb; + sigemptyset(&sigusr_action.sa_mask); + sigusr_action.sa_flags = 0; + sigaction(SIGUSR1, &sigusr_action, NULL); + nsec_timestamp_setup = nsec_now(); initialized = true; @@ -542,20 +552,12 @@ static bool mutex_info_stat(struct mutex_info *mi) { return true; } -static void show_summary(void) { - static pthread_mutex_t summary_mutex = PTHREAD_MUTEX_INITIALIZER; - static bool shown_summary = false; - +static void show_summary_internal(void) { struct mutex_info *mi, **table; unsigned n, u, i, m; uint64_t t; long n_cpus; - real_pthread_mutex_lock(&summary_mutex); - - if (shown_summary) - goto finish; - t = nsec_now() - nsec_timestamp_setup; fprintf(stderr, @@ -576,7 +578,7 @@ static void show_summary(void) { if (n <= 0) { fprintf(stderr, "mutrace: No mutexes used.\n"); - goto finish; + return; } fprintf(stderr, @@ -680,6 +682,19 @@ static void show_summary(void) { "\n" "mutrace: WARNING: %u internal mutex contention detected. Results might not be reliable as they could be.\n" "mutrace: Try to increase --hash-size=, which is currently at %u.\n", n_self_contended, hash_size); +} + +/* Print out the summary only the first time this is called. */ +static void show_summary(void) { + static pthread_mutex_t summary_mutex = PTHREAD_MUTEX_INITIALIZER; + static bool shown_summary = false; + + real_pthread_mutex_lock(&summary_mutex); + + if (shown_summary) + goto finish; + + show_summary_internal(); finish: shown_summary = true; @@ -687,6 +702,17 @@ finish: real_pthread_mutex_unlock(&summary_mutex); } +/* Print out the summary every time this is called. */ +static void show_summary_again(void) { + static pthread_mutex_t summary_mutex = PTHREAD_MUTEX_INITIALIZER; + + real_pthread_mutex_lock(&summary_mutex); + + show_summary_internal(); + + real_pthread_mutex_unlock(&summary_mutex); +} + static void shutdown(void) { show_summary(); } @@ -706,6 +732,10 @@ void _Exit(int status) { real__Exit(status); } +void sigusr1_cb(int sig) { + show_summary_again(); +} + static bool is_realtime(void) { int policy; -- cgit