Merge pull request #1267 from vjpai/timers
Infrastructure for timer insertion, logging, and testingpull/1277/head
commit
5fa5042850
20 changed files with 525 additions and 6 deletions
@ -0,0 +1,138 @@ |
||||
/*
|
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifdef GRPC_LATENCY_PROFILER |
||||
|
||||
#include "src/core/profiling/timers.h" |
||||
#include "src/core/profiling/timers_preciseclock.h" |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/time.h> |
||||
#include <grpc/support/sync.h> |
||||
#include <stdio.h> |
||||
|
||||
typedef struct grpc_timer_entry { |
||||
grpc_precise_clock tm; |
||||
const char* tag; |
||||
int seq; |
||||
const char* file; |
||||
int line; |
||||
} grpc_timer_entry; |
||||
|
||||
struct grpc_timers_log { |
||||
gpr_mu mu; |
||||
grpc_timer_entry* log; |
||||
int num_entries; |
||||
int capacity; |
||||
int capacity_limit; |
||||
FILE* fp; |
||||
}; |
||||
|
||||
grpc_timers_log* grpc_timers_log_global = NULL; |
||||
|
||||
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 */ |
||||
log->log = gpr_malloc(capacity_limit * sizeof(*log->log)); |
||||
|
||||
/* TODO (vpai): Improve concurrency, do per-thread logging? */ |
||||
gpr_mu_init(&log->mu); |
||||
|
||||
log->num_entries = 0; |
||||
log->capacity = log->capacity_limit = capacity_limit; |
||||
|
||||
log->fp = dump; |
||||
|
||||
return log; |
||||
} |
||||
|
||||
static void log_report_locked(grpc_timers_log* log) { |
||||
FILE* fp = log->fp; |
||||
int i; |
||||
for (i = 0; i < log->num_entries; i++) { |
||||
grpc_timer_entry* entry = &(log->log[i]); |
||||
fprintf(fp, "GRPC_LAT_PROF "); |
||||
grpc_precise_clock_print(&entry->tm, fp); |
||||
fprintf(fp, " %s#%d,%s:%d\n", entry->tag, entry->seq, entry->file, |
||||
entry->line); |
||||
} |
||||
|
||||
/* Now clear out the log */ |
||||
log->num_entries = 0; |
||||
} |
||||
|
||||
void grpc_timers_log_destroy(grpc_timers_log* log) { |
||||
gpr_mu_lock(&log->mu); |
||||
log_report_locked(log); |
||||
gpr_mu_unlock(&log->mu); |
||||
|
||||
gpr_free(log->log); |
||||
gpr_mu_destroy(&log->mu); |
||||
|
||||
gpr_free(log); |
||||
} |
||||
|
||||
void grpc_timers_log_add(grpc_timers_log* log, const char* tag, int seq, |
||||
const char* file, int line) { |
||||
grpc_timer_entry* entry; |
||||
|
||||
/* TODO (vpai) : Improve concurrency */ |
||||
gpr_mu_lock(&log->mu); |
||||
if (log->num_entries == log->capacity_limit) { |
||||
log_report_locked(log); |
||||
} |
||||
|
||||
entry = &log->log[log->num_entries++]; |
||||
|
||||
grpc_precise_clock_now(&entry->tm); |
||||
entry->tag = tag; |
||||
entry->seq = seq; |
||||
entry->file = file; |
||||
entry->line = line; |
||||
|
||||
gpr_mu_unlock(&log->mu); |
||||
} |
||||
|
||||
void grpc_timers_log_global_init(void) { |
||||
grpc_timers_log_global = grpc_timers_log_create(100000, stdout); |
||||
} |
||||
|
||||
void grpc_timers_log_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 */ |
@ -0,0 +1,70 @@ |
||||
/*
|
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_PROFILING_TIMERS_H |
||||
#define GRPC_CORE_PROFILING_TIMERS_H |
||||
|
||||
#include <stdio.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#ifdef GRPC_LATENCY_PROFILER |
||||
|
||||
typedef struct grpc_timers_log grpc_timers_log; |
||||
|
||||
grpc_timers_log *grpc_timers_log_create(int capacity_limit, FILE *dump); |
||||
void grpc_timers_log_add(grpc_timers_log *, const char *tag, int seq, |
||||
const char *file, int line); |
||||
void grpc_timers_log_destroy(grpc_timers_log *); |
||||
|
||||
extern grpc_timers_log *grpc_timers_log_global; |
||||
|
||||
#define GRPC_TIMER_MARK(x, s) \ |
||||
grpc_timers_log_add(grpc_timers_log_global, #x, s, __FILE__, __LINE__) |
||||
|
||||
#else /* !GRPC_LATENCY_PROFILER */ |
||||
#define GRPC_TIMER_MARK(x, s) \ |
||||
do { \
|
||||
} while (0) |
||||
#endif /* GRPC_LATENCY_PROFILER */ |
||||
|
||||
void grpc_timers_log_global_init(void); |
||||
void grpc_timers_log_global_destroy(void); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* GRPC_CORE_PROFILING_TIMERS_H */ |
@ -0,0 +1,56 @@ |
||||
/*
|
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_PROFILING_TIMERS_PRECISECLOCK_H |
||||
#define GRPC_CORE_PROFILING_TIMERS_PRECISECLOCK_H |
||||
|
||||
#include <grpc/support/time.h> |
||||
#include <stdio.h> |
||||
|
||||
typedef struct grpc_precise_clock grpc_precise_clock; |
||||
|
||||
#ifdef GRPC_TIMERS_RDTSC |
||||
#error RDTSC timers not currently supported |
||||
#else |
||||
struct grpc_precise_clock { |
||||
gpr_timespec clock; |
||||
}; |
||||
static void grpc_precise_clock_now(grpc_precise_clock* clk) { |
||||
clk->clock = gpr_now(); |
||||
} |
||||
static void grpc_precise_clock_print(const grpc_precise_clock* clk, FILE* fp) { |
||||
fprintf(fp, "%ld.%09d", clk->clock.tv_sec, clk->clock.tv_nsec); |
||||
} |
||||
#endif /* GRPC_TIMERS_RDTSC */ |
||||
|
||||
#endif /* GRPC_CORE_PROFILING_TIMERS_PRECISECLOCK_H */ |
@ -0,0 +1,83 @@ |
||||
/*
|
||||
* |
||||
* 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 "src/core/profiling/timers.h" |
||||
#include <stdlib.h> |
||||
#include "test/core/util/test_config.h" |
||||
|
||||
void test_log_events(int num_seqs) { |
||||
int start = 0; |
||||
int *state; |
||||
state = calloc(num_seqs, sizeof(state[0])); |
||||
while (start < num_seqs) { |
||||
int i; |
||||
int row; |
||||
if (state[start] == 3) { /* Already done with this posn */ |
||||
start++; |
||||
continue; |
||||
} |
||||
|
||||
row = rand() % 10; /* how many in a row */ |
||||
for (i = start; (i < start + row) && (i < num_seqs); i++) { |
||||
int j; |
||||
int advance = 1 + rand() % 3; /* how many to advance by */ |
||||
for (j = 0; j < advance; j++) { |
||||
switch (state[i]) { |
||||
case 0: |
||||
GRPC_TIMER_MARK(STATE_0, i); |
||||
state[i]++; |
||||
break; |
||||
case 1: |
||||
GRPC_TIMER_MARK(STATE_1, i); |
||||
state[i]++; |
||||
break; |
||||
case 2: |
||||
GRPC_TIMER_MARK(STATE_2, i); |
||||
state[i]++; |
||||
break; |
||||
case 3: |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
free(state); |
||||
} |
||||
|
||||
int main(int argc, char **argv) { |
||||
grpc_test_init(argc, argv); |
||||
grpc_timers_log_global_init(); |
||||
test_log_events(1000000); |
||||
grpc_timers_log_global_destroy(); |
||||
return 0; |
||||
} |
Loading…
Reference in new issue