diff options
author | 2015-04-30 13:05:56 -0700 | |
---|---|---|
committer | 2015-04-30 13:05:56 -0700 | |
commit | f2791ab02b0100c890fce8a2dbcd322d84595936 (patch) | |
tree | bfb416546a96d4b5e402d0f0745bb8054ea0868c /src/core/profiling | |
parent | d30457a34875fe0ddaeb533ecc566916d88255f9 (diff) | |
parent | 34c396325a207bbacebb3cd67e108a5f36a2b5cc (diff) |
Merge pull request #1408 from dgquintas/stap
Integration of Systemtap as a profiling mechanism.
Diffstat (limited to 'src/core/profiling')
-rw-r--r-- | src/core/profiling/basic_timers.c (renamed from src/core/profiling/timers.c) | 41 | ||||
-rw-r--r-- | src/core/profiling/stap_probes.d | 6 | ||||
-rw-r--r-- | src/core/profiling/stap_timers.c | 57 | ||||
-rw-r--r-- | src/core/profiling/timers.h | 90 |
4 files changed, 161 insertions, 33 deletions
diff --git a/src/core/profiling/timers.c b/src/core/profiling/basic_timers.c index bd1700ffd8..d89bba7b87 100644 --- a/src/core/profiling/timers.c +++ b/src/core/profiling/basic_timers.c @@ -31,7 +31,9 @@ * */ -#ifdef GRPC_LATENCY_PROFILER +#include <grpc/support/port_platform.h> + +#ifdef GRPC_BASIC_PROFILER #include "src/core/profiling/timers.h" #include "src/core/profiling/timers_preciseclock.h" @@ -46,7 +48,7 @@ typedef struct grpc_timer_entry { grpc_precise_clock tm; gpr_thd_id thd; - const char* tag; + int tag; void* id; const char* file; int line; @@ -63,7 +65,7 @@ struct grpc_timers_log { grpc_timers_log* grpc_timers_log_global = NULL; -grpc_timers_log* grpc_timers_log_create(int capacity_limit, FILE* dump) { +static grpc_timers_log* grpc_timers_log_create(int capacity_limit, FILE* dump) { grpc_timers_log* log = gpr_malloc(sizeof(*log)); /* TODO (vpai): Allow allocation below limit */ @@ -87,15 +89,15 @@ static void log_report_locked(grpc_timers_log* log) { grpc_timer_entry* entry = &(log->log[i]); fprintf(fp, "GRPC_LAT_PROF "); grpc_precise_clock_print(&entry->tm, fp); - fprintf(fp, " %p %s %p %s %d\n", (void*)(gpr_intptr)entry->thd, entry->tag, entry->id, entry->file, - entry->line); + fprintf(fp, " %p %d %p %s %d\n", (void*)(gpr_intptr)entry->thd, entry->tag, + entry->id, entry->file, entry->line); } /* Now clear out the log */ log->num_entries = 0; } -void grpc_timers_log_destroy(grpc_timers_log* log) { +static void grpc_timers_log_destroy(grpc_timers_log* log) { gpr_mu_lock(&log->mu); log_report_locked(log); gpr_mu_unlock(&log->mu); @@ -106,8 +108,8 @@ void grpc_timers_log_destroy(grpc_timers_log* log) { gpr_free(log); } -void grpc_timers_log_add(grpc_timers_log* log, const char* tag, void* id, - const char* file, int line) { +static void grpc_timers_log_add(grpc_timers_log* log, int tag, void* id, + const char* file, int line) { grpc_timer_entry* entry; /* TODO (vpai) : Improve concurrency */ @@ -128,14 +130,25 @@ void grpc_timers_log_add(grpc_timers_log* log, const char* tag, void* id, gpr_mu_unlock(&log->mu); } -void grpc_timers_log_global_init(void) { +/* Latency profiler API implementation. */ +void grpc_timer_add_mark(int tag, void* id, const char* file, int line) { + grpc_timers_log_add(grpc_timers_log_global, tag, id, file, line); +} + +void grpc_timer_begin(int tag, void* id, const char *file, int line) {} +void grpc_timer_end(int tag, void* id, const char *file, int line) {} + +/* Basic profiler specific API functions. */ +void grpc_timers_global_init(void) { grpc_timers_log_global = grpc_timers_log_create(100000, stdout); } -void grpc_timers_log_global_destroy(void) { +void grpc_timers_global_destroy(void) { grpc_timers_log_destroy(grpc_timers_log_global); } -#else /* !GRPC_LATENCY_PROFILER */ -void grpc_timers_log_global_init(void) {} -void grpc_timers_log_global_destroy(void) {} -#endif /* GRPC_LATENCY_PROFILER */ + + +#else /* !GRPC_BASIC_PROFILER */ +void grpc_timers_global_init(void) {} +void grpc_timers_global_destroy(void) {} +#endif /* GRPC_BASIC_PROFILER */ diff --git a/src/core/profiling/stap_probes.d b/src/core/profiling/stap_probes.d new file mode 100644 index 0000000000..374eeedd6c --- /dev/null +++ b/src/core/profiling/stap_probes.d @@ -0,0 +1,6 @@ +provider _stap { + probe add_mark(int tag); + probe timing_ns_begin(int tag); + probe timing_ns_end(int tag); +}; + diff --git a/src/core/profiling/stap_timers.c b/src/core/profiling/stap_timers.c new file mode 100644 index 0000000000..52fb58a279 --- /dev/null +++ b/src/core/profiling/stap_timers.c @@ -0,0 +1,57 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <grpc/support/port_platform.h> + +#ifdef GRPC_STAP_PROFILER + +#include "src/core/profiling/timers.h" + +#include <sys/sdt.h> +/* Generated from src/core/profiling/stap_probes.d */ +#include "src/core/profiling/stap_probes.h" + +/* Latency profiler API implementation. */ +void grpc_timer_add_mark(int tag, void* id, const char *file, int line) { + _STAP_ADD_MARK(tag); +} + +void grpc_timer_begin(int tag, void* id, const char *file, int line) { + _STAP_TIMING_NS_BEGIN(tag); +} + +void grpc_timer_end(int tag, void* id, const char *file, int line) { + _STAP_TIMING_NS_END(tag); +} + +#endif /* GRPC_STAP_PROFILER */ diff --git a/src/core/profiling/timers.h b/src/core/profiling/timers.h index 1a6b9ffac9..d0b8286c03 100644 --- a/src/core/profiling/timers.h +++ b/src/core/profiling/timers.h @@ -34,35 +34,87 @@ #ifndef GRPC_CORE_PROFILING_TIMERS_H #define GRPC_CORE_PROFILING_TIMERS_H -#include <stdio.h> - #ifdef __cplusplus extern "C" { #endif -#ifdef GRPC_LATENCY_PROFILER +void grpc_timers_global_init(void); +void grpc_timers_global_destroy(void); -typedef struct grpc_timers_log grpc_timers_log; +void grpc_timer_add_mark(int tag, void* id, const char *file, int line); +void grpc_timer_begin(int tag, void* id, const char *file, int line); +void grpc_timer_end(int tag, void* id, const char *file, int line); -grpc_timers_log* grpc_timers_log_create(int capacity_limit, FILE* dump); -void grpc_timers_log_add(grpc_timers_log*, const char* tag, void* id, - const char* file, int line); -void grpc_timers_log_destroy(grpc_timers_log *); +enum grpc_profiling_tags { + /* Any GRPC_PTAG_* >= than the threshold won't generate any profiling mark. */ + GRPC_PTAG_IGNORE_THRESHOLD = 1000000, -extern grpc_timers_log *grpc_timers_log_global; + /* Re. Protos. */ + GRPC_PTAG_PROTO_SERIALIZE = 100 + GRPC_PTAG_IGNORE_THRESHOLD, + GRPC_PTAG_PROTO_DESERIALIZE = 101 + GRPC_PTAG_IGNORE_THRESHOLD, + + /* Re. sockets. */ + GRPC_PTAG_HANDLE_READ = 200 + GRPC_PTAG_IGNORE_THRESHOLD, + GRPC_PTAG_SENDMSG = 201 + GRPC_PTAG_IGNORE_THRESHOLD, + GRPC_PTAG_RECVMSG = 202 + GRPC_PTAG_IGNORE_THRESHOLD, + GRPC_PTAG_POLL_FINISHED = 203 + GRPC_PTAG_IGNORE_THRESHOLD, + GRPC_PTAG_TCP_CB_WRITE = 204 + GRPC_PTAG_IGNORE_THRESHOLD, + GRPC_PTAG_TCP_WRITE = 205 + GRPC_PTAG_IGNORE_THRESHOLD, + + /* C++ */ + GRPC_PTAG_CPP_CALL_CREATED = 300 + GRPC_PTAG_IGNORE_THRESHOLD, + GRPC_PTAG_CPP_PERFORM_OPS = 301 + GRPC_PTAG_IGNORE_THRESHOLD, -#define GRPC_TIMER_MARK(x, s) \ - grpc_timers_log_add(grpc_timers_log_global, #x, ((void *)(gpr_intptr)(s)), \ - __FILE__, __LINE__) + /* > 1024 Unassigned reserved. For any miscellaneous use. + * Use addition to generate tags from this base or take advantage of the 10 + * zero'd bits for OR-ing. */ + GRPC_PTAG_OTHER_BASE = 1024 +}; -#else /* !GRPC_LATENCY_PROFILER */ -#define GRPC_TIMER_MARK(x, s) \ - do { \ - } while (0) -#endif /* GRPC_LATENCY_PROFILER */ +#if !(defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER)) +/* No profiling. No-op all the things. */ +#define GRPC_TIMER_MARK(tag, id) \ + do {} while(0) + +#define GRPC_TIMER_BEGIN(tag, id) \ + do {} while(0) + +#define GRPC_TIMER_END(tag, id) \ + do {} while(0) + +#else /* at least one profiler requested... */ +/* ... hopefully only one. */ +#if defined(GRPC_STAP_PROFILER) && defined(GRPC_BASIC_PROFILER) +#error "GRPC_STAP_PROFILER and GRPC_BASIC_PROFILER are mutually exclusive." +#endif + +/* Generic profiling interface. */ +#define GRPC_TIMER_MARK(tag, id) \ + if (tag < GRPC_PTAG_IGNORE_THRESHOLD) { \ + grpc_timer_add_mark(tag, ((void *)(gpr_intptr)(id)), __FILE__, __LINE__); \ + } + +#define GRPC_TIMER_BEGIN(tag, id) \ + if (tag < GRPC_PTAG_IGNORE_THRESHOLD) { \ + grpc_timer_begin(tag, ((void *)(gpr_intptr)(id)), __FILE__, __LINE__); \ + } + +#define GRPC_TIMER_END(tag, id) \ + if (tag < GRPC_PTAG_IGNORE_THRESHOLD) { \ + grpc_timer_end(tag, ((void *)(gpr_intptr)(id)), __FILE__, __LINE__); \ + } + +#ifdef GRPC_STAP_PROFILER +/* Empty placeholder for now. */ +#endif /* GRPC_STAP_PROFILER */ + +#ifdef GRPC_BASIC_PROFILER +typedef struct grpc_timers_log grpc_timers_log; + +extern grpc_timers_log *grpc_timers_log_global; +#endif /* GRPC_BASIC_PROFILER */ -void grpc_timers_log_global_init(void); -void grpc_timers_log_global_destroy(void); +#endif /* at least one profiler requested. */ #ifdef __cplusplus } |