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 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 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 void StartEvent(const std::string& event_name); 119 void StopEvent(const std::string& event_name); 120 void ReportToLog(const char* file, int line, LoggingSeverity severity_to_use, 121 const std::string& event_prefix); 122 void ReportAllToLog(const char* file, int line, 123 LoggingSeverity severity_to_use); 124 const ProfilerEvent* GetEvent(const std::string& event_name) const; 125 // Clears all _stopped_ events. Returns true if _all_ events were cleared. 126 bool Clear(); 127 128 static Profiler* Instance(); 129 private: 130 Profiler() {} 131 132 typedef std::map<std::string, ProfilerEvent> EventMap; 133 EventMap events_; 134 mutable SharedExclusiveLock lock_; 135 136 DISALLOW_COPY_AND_ASSIGN(Profiler); 137}; 138 139// Starts an event on construction and stops it on destruction. 140// Used by PROFILE macro. 141class ProfilerScope { 142 public: 143 explicit ProfilerScope(const std::string& event_name) 144 : event_name_(event_name) { 145 Profiler::Instance()->StartEvent(event_name_); 146 } 147 ~ProfilerScope() { 148 Profiler::Instance()->StopEvent(event_name_); 149 } 150 private: 151 std::string event_name_; 152 153 DISALLOW_COPY_AND_ASSIGN(ProfilerScope); 154}; 155 156std::ostream& operator<<(std::ostream& stream, 157 const ProfilerEvent& profiler_event); 158 159} // namespace rtc 160 161#endif // WEBRTC_BASE_PROFILER_H_ 162