diff --git a/webrtc/BUILD.gn b/webrtc/BUILD.gn index 99310e0988..1e1ef00096 100644 --- a/webrtc/BUILD.gn +++ b/webrtc/BUILD.gn @@ -372,7 +372,6 @@ if (rtc_include_tests) { "base/optionsfile_unittest.cc", "base/pathutils_unittest.cc", "base/platform_thread_unittest.cc", - "base/profiler_unittest.cc", "base/proxy_unittest.cc", "base/proxydetect_unittest.cc", "base/random_unittest.cc", diff --git a/webrtc/base/BUILD.gn b/webrtc/base/BUILD.gn index 86d697aa09..880d897986 100644 --- a/webrtc/base/BUILD.gn +++ b/webrtc/base/BUILD.gn @@ -462,8 +462,6 @@ rtc_static_library("rtc_base") { "nattypes.h", "optionsfile.cc", "optionsfile.h", - "profiler.cc", - "profiler.h", "proxyserver.cc", "proxyserver.h", "rollingaccumulator.h", diff --git a/webrtc/base/base.gyp b/webrtc/base/base.gyp index 3dad3602e9..7ab73b5137 100644 --- a/webrtc/base/base.gyp +++ b/webrtc/base/base.gyp @@ -423,8 +423,6 @@ 'nattypes.h', 'optionsfile.cc', 'optionsfile.h', - 'profiler.cc', - 'profiler.h', 'proxyserver.cc', 'proxyserver.h', 'rollingaccumulator.h', diff --git a/webrtc/base/profiler.cc b/webrtc/base/profiler.cc deleted file mode 100644 index 873b1989f7..0000000000 --- a/webrtc/base/profiler.cc +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright 2013 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/profiler.h" - -#include -#include - -#include "webrtc/base/timeutils.h" - -namespace { - -// When written to an ostream, FormattedTime chooses an appropriate scale and -// suffix for a time value given in seconds. -class FormattedTime { - public: - explicit FormattedTime(double t) : time_(t) {} - double time() const { return time_; } - private: - double time_; -}; - -std::ostream& operator<<(std::ostream& stream, const FormattedTime& time) { - if (time.time() < 1.0) { - stream << (time.time() * 1000.0) << "ms"; - } else { - stream << time.time() << 's'; - } - return stream; -} - -} // namespace - -namespace rtc { - -ProfilerEvent::ProfilerEvent() - : total_time_(0.0), - mean_(0.0), - sum_of_squared_differences_(0.0), - start_count_(0), - event_count_(0) { -} - -void ProfilerEvent::Start() { - if (start_count_ == 0) { - current_start_time_ = TimeNanos(); - } - ++start_count_; -} - -void ProfilerEvent::Stop(uint64_t stop_time) { - --start_count_; - ASSERT(start_count_ >= 0); - if (start_count_ == 0) { - double elapsed = static_cast(stop_time - current_start_time_) / - kNumNanosecsPerSec; - total_time_ += elapsed; - if (event_count_ == 0) { - minimum_ = maximum_ = elapsed; - } else { - minimum_ = std::min(minimum_, elapsed); - maximum_ = std::max(maximum_, elapsed); - } - // Online variance and mean algorithm: http://en.wikipedia.org/wiki/ - // Algorithms_for_calculating_variance#Online_algorithm - ++event_count_; - double delta = elapsed - mean_; - mean_ = mean_ + delta / event_count_; - sum_of_squared_differences_ += delta * (elapsed - mean_); - } -} - -void ProfilerEvent::Stop() { - Stop(TimeNanos()); -} - -double ProfilerEvent::standard_deviation() const { - if (event_count_ <= 1) return 0.0; - return sqrt(sum_of_squared_differences_ / (event_count_ - 1.0)); -} - -Profiler::~Profiler() = default; - -Profiler* Profiler::Instance() { - RTC_DEFINE_STATIC_LOCAL(Profiler, instance, ()); - return &instance; -} - -Profiler::Profiler() { -} - -void Profiler::StartEvent(const std::string& event_name) { - lock_.LockShared(); - EventMap::iterator it = events_.find(event_name); - bool needs_insert = (it == events_.end()); - lock_.UnlockShared(); - - if (needs_insert) { - // Need an exclusive lock to modify the map. - ExclusiveScope scope(&lock_); - it = events_.insert( - EventMap::value_type(event_name, ProfilerEvent())).first; - } - - it->second.Start(); -} - -void Profiler::StopEvent(const std::string& event_name) { - // Get the time ASAP, then wait for the lock. - uint64_t stop_time = TimeNanos(); - SharedScope scope(&lock_); - EventMap::iterator it = events_.find(event_name); - if (it != events_.end()) { - it->second.Stop(stop_time); - } -} - -void Profiler::ReportToLog(const char* file, int line, - LoggingSeverity severity_to_use, - const std::string& event_prefix) { - if (!LogMessage::Loggable(severity_to_use)) { - return; - } - - SharedScope scope(&lock_); - - { // Output first line. - LogMessage msg(file, line, severity_to_use); - msg.stream() << "=== Profile report "; - if (event_prefix.empty()) { - msg.stream() << "(prefix: '" << event_prefix << "') "; - } - msg.stream() << "==="; - } - for (EventMap::const_iterator it = events_.begin(); - it != events_.end(); ++it) { - if (event_prefix.empty() || it->first.find(event_prefix) == 0) { - LogMessage(file, line, severity_to_use).stream() - << it->first << " " << it->second; - } - } - LogMessage(file, line, severity_to_use).stream() - << "=== End profile report ==="; -} - -void Profiler::ReportAllToLog(const char* file, int line, - LoggingSeverity severity_to_use) { - ReportToLog(file, line, severity_to_use, ""); -} - -const ProfilerEvent* Profiler::GetEvent(const std::string& event_name) const { - SharedScope scope(&lock_); - EventMap::const_iterator it = - events_.find(event_name); - return (it == events_.end()) ? NULL : &it->second; -} - -bool Profiler::Clear() { - ExclusiveScope scope(&lock_); - bool result = true; - // Clear all events that aren't started. - EventMap::iterator it = events_.begin(); - while (it != events_.end()) { - if (it->second.is_started()) { - ++it; // Can't clear started events. - result = false; - } else { - events_.erase(it++); - } - } - return result; -} - -std::ostream& operator<<(std::ostream& stream, - const ProfilerEvent& profiler_event) { - stream << "count=" << profiler_event.event_count() - << " total=" << FormattedTime(profiler_event.total_time()) - << " mean=" << FormattedTime(profiler_event.mean()) - << " min=" << FormattedTime(profiler_event.minimum()) - << " max=" << FormattedTime(profiler_event.maximum()) - << " sd=" << profiler_event.standard_deviation(); - return stream; -} - -} // namespace rtc diff --git a/webrtc/base/profiler.h b/webrtc/base/profiler.h deleted file mode 100644 index 4dd35f5bac..0000000000 --- a/webrtc/base/profiler.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2013 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// A simple wall-clock profiler for instrumented code. -// Example: -// void MyLongFunction() { -// PROFILE_F(); // Time the execution of this function. -// // Do something -// { // Time just what is in this scope. -// PROFILE("My event"); -// // Do something else -// } -// } -// Another example: -// void StartAsyncProcess() { -// PROFILE_START("My async event"); -// DoSomethingAsyncAndThenCall(&Callback); -// } -// void Callback() { -// PROFILE_STOP("My async event"); -// // Handle callback. -// } - -#ifndef WEBRTC_BASE_PROFILER_H_ -#define WEBRTC_BASE_PROFILER_H_ - -#include -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/common.h" -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/sharedexclusivelock.h" - -// Profiling could be switched via a build flag, but for now, it's always on. -#ifndef ENABLE_PROFILING -#define ENABLE_PROFILING -#endif - -#ifdef ENABLE_PROFILING - -#define UV_HELPER2(x) _uv_ ## x -#define UV_HELPER(x) UV_HELPER2(x) -#define UNIQUE_VAR UV_HELPER(__LINE__) - -// Profiles the current scope. -#define PROFILE(msg) rtc::ProfilerScope UNIQUE_VAR(msg) -// When placed at the start of a function, profiles the current function. -#define PROFILE_F() PROFILE(__FUNCTION__) -// Reports current timings to the log at severity |sev|. -#define PROFILE_DUMP_ALL(sev) \ - rtc::Profiler::Instance()->ReportAllToLog(__FILE__, __LINE__, sev) -// Reports current timings for all events whose names are prefixed by |prefix| -// to the log at severity |sev|. Using a unique event name as |prefix| will -// report only that event. -#define PROFILE_DUMP(sev, prefix) \ - rtc::Profiler::Instance()->ReportToLog(__FILE__, __LINE__, sev, prefix) -// Starts and stops a profile event. Useful when an event is not easily -// captured within a scope (eg, an async call with a callback when done). -#define PROFILE_START(msg) rtc::Profiler::Instance()->StartEvent(msg) -#define PROFILE_STOP(msg) rtc::Profiler::Instance()->StopEvent(msg) -// TODO(ryanpetrie): Consider adding PROFILE_DUMP_EVERY(sev, iterations) - -#undef UV_HELPER2 -#undef UV_HELPER -#undef UNIQUE_VAR - -#else // ENABLE_PROFILING - -#define PROFILE(msg) (void)0 -#define PROFILE_F() (void)0 -#define PROFILE_DUMP_ALL(sev) (void)0 -#define PROFILE_DUMP(sev, prefix) (void)0 -#define PROFILE_START(msg) (void)0 -#define PROFILE_STOP(msg) (void)0 - -#endif // ENABLE_PROFILING - -namespace rtc { - -// Tracks information for one profiler event. -class ProfilerEvent { - public: - ProfilerEvent(); - void Start(); - void Stop(); - void Stop(uint64_t stop_time); - double standard_deviation() const; - double total_time() const { return total_time_; } - double mean() const { return mean_; } - double minimum() const { return minimum_; } - double maximum() const { return maximum_; } - int event_count() const { return event_count_; } - bool is_started() const { return start_count_ > 0; } - - private: - uint64_t current_start_time_; - double total_time_; - double mean_; - double sum_of_squared_differences_; - double minimum_; - double maximum_; - int start_count_; - int event_count_; -}; - -// Singleton that owns ProfilerEvents and reports results. Prefer to use -// macros, defined above, rather than directly calling Profiler methods. -class Profiler { - public: - ~Profiler(); - void StartEvent(const std::string& event_name); - void StopEvent(const std::string& event_name); - void ReportToLog(const char* file, int line, LoggingSeverity severity_to_use, - const std::string& event_prefix); - void ReportAllToLog(const char* file, int line, - LoggingSeverity severity_to_use); - const ProfilerEvent* GetEvent(const std::string& event_name) const; - // Clears all _stopped_ events. Returns true if _all_ events were cleared. - bool Clear(); - - static Profiler* Instance(); - private: - Profiler(); - - typedef std::map EventMap; - EventMap events_; - mutable SharedExclusiveLock lock_; - - RTC_DISALLOW_COPY_AND_ASSIGN(Profiler); -}; - -// Starts an event on construction and stops it on destruction. -// Used by PROFILE macro. -class ProfilerScope { - public: - explicit ProfilerScope(const std::string& event_name) - : event_name_(event_name) { - Profiler::Instance()->StartEvent(event_name_); - } - ~ProfilerScope() { - Profiler::Instance()->StopEvent(event_name_); - } - private: - std::string event_name_; - - RTC_DISALLOW_COPY_AND_ASSIGN(ProfilerScope); -}; - -std::ostream& operator<<(std::ostream& stream, - const ProfilerEvent& profiler_event); - -} // namespace rtc - -#endif // WEBRTC_BASE_PROFILER_H_