1/* 2 * Copyright 2013 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11// A simple wall-clock profiler for instrumented code. 12// Example: 13// void MyLongFunction() { 14// PROFILE_F(); // Time the execution of this function. 15// // Do something 16// { // Time just what is in this scope. 17// PROFILE("My event"); 18// // Do something else 19// } 20// } 21// Another example: 22// void StartAsyncProcess() { 23// PROFILE_START("My async event"); 24// DoSomethingAsyncAndThenCall(&Callback); 25// } 26// void Callback() { 27// PROFILE_STOP("My async event"); 28// // Handle callback. 29// } 30 31#ifndef WEBRTC_BASE_PROFILER_H_ 32#define WEBRTC_BASE_PROFILER_H_ 33 34#include <map> 35#include <string> 36 37#include "webrtc/base/basictypes.h" 38#include "webrtc/base/common.h" 39#include "webrtc/base/logging.h" 40#include "webrtc/base/sharedexclusivelock.h" 41 42// Profiling could be switched via a build flag, but for now, it's always on. 43#ifndef ENABLE_PROFILING 44#define ENABLE_PROFILING 45#endif 46 47#ifdef ENABLE_PROFILING 48 49#define UV_HELPER2(x) _uv_ ## x 50#define UV_HELPER(x) UV_HELPER2(x) 51#define UNIQUE_VAR UV_HELPER(__LINE__) 52 53// Profiles the current scope. 54#define PROFILE(msg) rtc::ProfilerScope UNIQUE_VAR(msg) 55// When placed at the start of a function, profiles the current function. 56#define PROFILE_F() PROFILE(__FUNCTION__) 57// Reports current timings to the log at severity |sev|. 58#define PROFILE_DUMP_ALL(sev) \ 59 rtc::Profiler::Instance()->ReportAllToLog(__FILE__, __LINE__, sev) 60// Reports current timings for all events whose names are prefixed by |prefix| 61// to the log at severity |sev|. Using a unique event name as |prefix| will 62// report only that event. 63#define PROFILE_DUMP(sev, prefix) \ 64 rtc::Profiler::Instance()->ReportToLog(__FILE__, __LINE__, sev, prefix) 65// Starts and stops a profile event. Useful when an event is not easily 66// captured within a scope (eg, an async call with a callback when done). 67#define PROFILE_START(msg) rtc::Profiler::Instance()->StartEvent(msg) 68#define PROFILE_STOP(msg) rtc::Profiler::Instance()->StopEvent(msg) 69// TODO(ryanpetrie): Consider adding PROFILE_DUMP_EVERY(sev, iterations) 70 71#undef UV_HELPER2 72#undef UV_HELPER 73#undef UNIQUE_VAR 74 75#else // ENABLE_PROFILING 76 77#define PROFILE(msg) (void)0 78#define PROFILE_F() (void)0 79#define PROFILE_DUMP_ALL(sev) (void)0 80#define PROFILE_DUMP(sev, prefix) (void)0 81#define PROFILE_START(msg) (void)0 82#define PROFILE_STOP(msg) (void)0 83 84#endif // ENABLE_PROFILING 85 86namespace rtc { 87 88// Tracks information for one profiler event. 89class ProfilerEvent { 90 public: 91 ProfilerEvent(); 92 void Start(); 93 void Stop(); 94 void Stop(uint64_t stop_time); 95 double standard_deviation() const; 96 double total_time() const { return total_time_; } 97 double mean() const { return mean_; } 98 double minimum() const { return minimum_; } 99 double maximum() const { return maximum_; } 100 int event_count() const { return event_count_; } 101 bool is_started() const { return start_count_ > 0; } 102 103 private: 104 uint64_t current_start_time_; 105 double total_time_; 106 double mean_; 107 double sum_of_squared_differences_; 108 double minimum_; 109 double maximum_; 110 int start_count_; 111 int event_count_; 112}; 113 114// Singleton that owns ProfilerEvents and reports results. Prefer to use 115// macros, defined above, rather than directly calling Profiler methods. 116class Profiler { 117 public: 118 ~Profiler(); 119 void StartEvent(const std::string& event_name); 120 void StopEvent(const std::string& event_name); 121 void ReportToLog(const char* file, int line, LoggingSeverity severity_to_use, 122 const std::string& event_prefix); 123 void ReportAllToLog(const char* file, int line, 124 LoggingSeverity severity_to_use); 125 const ProfilerEvent* GetEvent(const std::string& event_name) const; 126 // Clears all _stopped_ events. Returns true if _all_ events were cleared. 127 bool Clear(); 128 129 static Profiler* Instance(); 130 private: 131 Profiler(); 132 133 typedef std::map<std::string, ProfilerEvent> EventMap; 134 EventMap events_; 135 mutable SharedExclusiveLock lock_; 136 137 RTC_DISALLOW_COPY_AND_ASSIGN(Profiler); 138}; 139 140// Starts an event on construction and stops it on destruction. 141// Used by PROFILE macro. 142class ProfilerScope { 143 public: 144 explicit ProfilerScope(const std::string& event_name) 145 : event_name_(event_name) { 146 Profiler::Instance()->StartEvent(event_name_); 147 } 148 ~ProfilerScope() { 149 Profiler::Instance()->StopEvent(event_name_); 150 } 151 private: 152 std::string event_name_; 153 154 RTC_DISALLOW_COPY_AND_ASSIGN(ProfilerScope); 155}; 156 157std::ostream& operator<<(std::ostream& stream, 158 const ProfilerEvent& profiler_event); 159 160} // namespace rtc 161 162#endif // WEBRTC_BASE_PROFILER_H_ 163