1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 2 // This source code is licensed under both the GPLv2 (found in the 3 // COPYING file in the root directory) and Apache 2.0 License 4 // (found in the LICENSE.Apache file in the root directory). 5 // 6 #pragma once 7 #include "monitoring/perf_step_timer.h" 8 #include "rocksdb/perf_context.h" 9 #include "util/stop_watch.h" 10 11 namespace ROCKSDB_NAMESPACE { 12 #if defined(NPERF_CONTEXT) || !defined(ROCKSDB_SUPPORT_THREAD_LOCAL) 13 extern PerfContext perf_context; 14 #else 15 #if defined(OS_SOLARIS) 16 extern __thread PerfContext perf_context_; 17 #define perf_context (*get_perf_context()) 18 #else 19 extern thread_local PerfContext perf_context; 20 #endif 21 #endif 22 23 #if defined(NPERF_CONTEXT) 24 25 #define PERF_TIMER_STOP(metric) 26 #define PERF_TIMER_START(metric) 27 #define PERF_TIMER_GUARD(metric) 28 #define PERF_TIMER_GUARD_WITH_ENV(metric, env) 29 #define PERF_CPU_TIMER_GUARD(metric, env) 30 #define PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(metric, condition, stats, \ 31 ticker_type) 32 #define PERF_TIMER_MEASURE(metric) 33 #define PERF_COUNTER_ADD(metric, value) 34 #define PERF_COUNTER_BY_LEVEL_ADD(metric, value, level) 35 36 #else 37 38 // Stop the timer and update the metric 39 #define PERF_TIMER_STOP(metric) perf_step_timer_##metric.Stop(); 40 41 #define PERF_TIMER_START(metric) perf_step_timer_##metric.Start(); 42 43 // Declare and set start time of the timer 44 #define PERF_TIMER_GUARD(metric) \ 45 PerfStepTimer perf_step_timer_##metric(&(perf_context.metric)); \ 46 perf_step_timer_##metric.Start(); 47 48 // Declare and set start time of the timer 49 #define PERF_TIMER_GUARD_WITH_ENV(metric, env) \ 50 PerfStepTimer perf_step_timer_##metric(&(perf_context.metric), env); \ 51 perf_step_timer_##metric.Start(); 52 53 // Declare and set start time of the timer 54 #define PERF_CPU_TIMER_GUARD(metric, env) \ 55 PerfStepTimer perf_step_timer_##metric( \ 56 &(perf_context.metric), env, true, \ 57 PerfLevel::kEnableTimeAndCPUTimeExceptForMutex); \ 58 perf_step_timer_##metric.Start(); 59 60 #define PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(metric, condition, stats, \ 61 ticker_type) \ 62 PerfStepTimer perf_step_timer_##metric(&(perf_context.metric), nullptr, \ 63 false, PerfLevel::kEnableTime, stats, \ 64 ticker_type); \ 65 if (condition) { \ 66 perf_step_timer_##metric.Start(); \ 67 } 68 69 // Update metric with time elapsed since last START. start time is reset 70 // to current timestamp. 71 #define PERF_TIMER_MEASURE(metric) perf_step_timer_##metric.Measure(); 72 73 // Increase metric value 74 #define PERF_COUNTER_ADD(metric, value) \ 75 if (perf_level >= PerfLevel::kEnableCount) { \ 76 perf_context.metric += value; \ 77 } 78 79 // Increase metric value 80 #define PERF_COUNTER_BY_LEVEL_ADD(metric, value, level) \ 81 if (perf_level >= PerfLevel::kEnableCount && \ 82 perf_context.per_level_perf_context_enabled && \ 83 perf_context.level_to_perf_context) { \ 84 if ((*(perf_context.level_to_perf_context)).find(level) != \ 85 (*(perf_context.level_to_perf_context)).end()) { \ 86 (*(perf_context.level_to_perf_context))[level].metric += value; \ 87 } \ 88 else { \ 89 PerfContextByLevel empty_context; \ 90 (*(perf_context.level_to_perf_context))[level] = empty_context; \ 91 (*(perf_context.level_to_perf_context))[level].metric += value; \ 92 } \ 93 } \ 94 95 #endif 96 97 } // namespace ROCKSDB_NAMESPACE 98