aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/profiling
diff options
context:
space:
mode:
authorGravatar Craig Tiller <craig.tiller@gmail.com>2015-04-30 13:05:56 -0700
committerGravatar Craig Tiller <craig.tiller@gmail.com>2015-04-30 13:05:56 -0700
commitf2791ab02b0100c890fce8a2dbcd322d84595936 (patch)
treebfb416546a96d4b5e402d0f0745bb8054ea0868c /src/core/profiling
parentd30457a34875fe0ddaeb533ecc566916d88255f9 (diff)
parent34c396325a207bbacebb3cd67e108a5f36a2b5cc (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.d6
-rw-r--r--src/core/profiling/stap_timers.c57
-rw-r--r--src/core/profiling/timers.h90
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
}