| Index: base/debug/trace_event_impl.cc
|
| diff --git a/base/debug/trace_event_impl.cc b/base/debug/trace_event_impl.cc
|
| index f17990e4fe7586f39315852e5d6aa1266675b1d5..b3e0cb8fa41adb6f1b4c092721cbaf36ccc5e374 100644
|
| --- a/base/debug/trace_event_impl.cc
|
| +++ b/base/debug/trace_event_impl.cc
|
| @@ -11,6 +11,7 @@
|
| #include "base/command_line.h"
|
| #include "base/debug/leak_annotations.h"
|
| #include "base/debug/trace_event.h"
|
| +#include "base/debug/trace_event_synthetic_delay.h"
|
| #include "base/format_macros.h"
|
| #include "base/json/string_escape.h"
|
| #include "base/lazy_instance.h"
|
| @@ -72,6 +73,8 @@ const int kThreadFlushTimeoutMs = 3000;
|
| // These categories will cause deadlock when ECHO_TO_CONSOLE. crbug.com/325575.
|
| const char kEchoToConsoleCategoryFilter[] = "-ipc,-task";
|
|
|
| +const char kSyntheticDelayCategoryFilterPrefix[] = "DELAY(";
|
| +
|
| #define MAX_CATEGORY_GROUPS 100
|
|
|
| // Parallel arrays g_category_groups and g_category_group_enabled are separate
|
| @@ -1209,6 +1212,31 @@ void TraceLog::UpdateCategoryGroupEnabledFlags() {
|
| UpdateCategoryGroupEnabledFlag(i);
|
| }
|
|
|
| +void TraceLog::UpdateSyntheticDelaysFromCategoryFilter() {
|
| + ResetTraceEventSyntheticDelays();
|
| + const CategoryFilter::DelayValueList& delays =
|
| + category_filter_.GetSyntheticDelayValues();
|
| + CategoryFilter::DelayValueList::const_iterator ci;
|
| + for (ci = delays.begin(); ci != delays.end(); ++ci) {
|
| + TraceEventSyntheticDelay* delay =
|
| + TraceEventSyntheticDelay::Lookup(ci->first);
|
| + StringTokenizer tokens(ci->second, ";");
|
| + while (tokens.GetNext()) {
|
| + double target_duration;
|
| + if (StringToDouble(tokens.token(), &target_duration)) {
|
| + delay->SetTargetDuration(
|
| + TimeDelta::FromMicroseconds(target_duration * 1e6));
|
| + } else if (tokens.token() == "static") {
|
| + delay->SetMode(TraceEventSyntheticDelay::STATIC);
|
| + } else if (tokens.token() == "oneshot") {
|
| + delay->SetMode(TraceEventSyntheticDelay::ONE_SHOT);
|
| + } else if (tokens.token() == "alternating") {
|
| + delay->SetMode(TraceEventSyntheticDelay::ALTERNATING);
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| const unsigned char* TraceLog::GetCategoryGroupEnabledInternal(
|
| const char* category_group) {
|
| DCHECK(!strchr(category_group, '"')) <<
|
| @@ -1303,6 +1331,7 @@ void TraceLog::SetEnabled(const CategoryFilter& category_filter,
|
|
|
| category_filter_ = CategoryFilter(category_filter);
|
| UpdateCategoryGroupEnabledFlags();
|
| + UpdateSyntheticDelaysFromCategoryFilter();
|
|
|
| if (options & ENABLE_SAMPLING) {
|
| sampling_thread_.reset(new TraceSamplingThread);
|
| @@ -2176,7 +2205,8 @@ CategoryFilter::CategoryFilter(const std::string& filter_string) {
|
| CategoryFilter::CategoryFilter(const CategoryFilter& cf)
|
| : included_(cf.included_),
|
| disabled_(cf.disabled_),
|
| - excluded_(cf.excluded_) {
|
| + excluded_(cf.excluded_),
|
| + delays_(cf.delays_) {
|
| }
|
|
|
| CategoryFilter::~CategoryFilter() {
|
| @@ -2189,6 +2219,7 @@ CategoryFilter& CategoryFilter::operator=(const CategoryFilter& rhs) {
|
| included_ = rhs.included_;
|
| disabled_ = rhs.disabled_;
|
| excluded_ = rhs.excluded_;
|
| + delays_ = rhs.delays_;
|
| return *this;
|
| }
|
|
|
| @@ -2201,8 +2232,20 @@ void CategoryFilter::Initialize(const std::string& filter_string) {
|
| // Ignore empty categories.
|
| if (category.empty())
|
| continue;
|
| - // Excluded categories start with '-'.
|
| - if (category.at(0) == '-') {
|
| + // Synthetic delays are of the form 'DELAY(delay;option;option;...)'.
|
| + if (category.find(kSyntheticDelayCategoryFilterPrefix) == 0 &&
|
| + category.at(category.size() - 1) == ')') {
|
| + category = category.substr(
|
| + strlen(kSyntheticDelayCategoryFilterPrefix),
|
| + category.size() - strlen(kSyntheticDelayCategoryFilterPrefix) - 1);
|
| + size_t name_length = category.find(';');
|
| + if (name_length != std::string::npos && name_length > 0 &&
|
| + name_length != category.size() - 1) {
|
| + delays_.push_back(DelayValue(category.substr(0, name_length),
|
| + category.substr(name_length + 1)));
|
| + }
|
| + } else if (category.at(0) == '-') {
|
| + // Excluded categories start with '-'.
|
| // Remove '-' from category string.
|
| category = category.substr(1);
|
| excluded_.push_back(category);
|
| @@ -2229,11 +2272,26 @@ void CategoryFilter::WriteString(const StringList& values,
|
| }
|
| }
|
|
|
| +void CategoryFilter::WriteString(const DelayValueList& delays,
|
| + std::string* out) const {
|
| + bool prepend_comma = !out->empty();
|
| + int token_cnt = 0;
|
| + for (DelayValueList::const_iterator ci = delays.begin();
|
| + ci != delays.end(); ++ci) {
|
| + if (token_cnt > 0 || prepend_comma)
|
| + StringAppendF(out, ",");
|
| + StringAppendF(out, "%s%s;%s)", kSyntheticDelayCategoryFilterPrefix,
|
| + ci->first.c_str(), ci->second.c_str());
|
| + ++token_cnt;
|
| + }
|
| +}
|
| +
|
| std::string CategoryFilter::ToString() const {
|
| std::string filter_string;
|
| WriteString(included_, &filter_string, true);
|
| WriteString(disabled_, &filter_string, true);
|
| WriteString(excluded_, &filter_string, false);
|
| + WriteString(delays_, &filter_string);
|
| return filter_string;
|
| }
|
|
|
| @@ -2289,6 +2347,9 @@ void CategoryFilter::Merge(const CategoryFilter& nested_filter) {
|
| excluded_.insert(excluded_.end(),
|
| nested_filter.excluded_.begin(),
|
| nested_filter.excluded_.end());
|
| + delays_.insert(delays_.end(),
|
| + nested_filter.delays_.begin(),
|
| + nested_filter.delays_.end());
|
| }
|
|
|
| void CategoryFilter::Clear() {
|
| @@ -2297,6 +2358,11 @@ void CategoryFilter::Clear() {
|
| excluded_.clear();
|
| }
|
|
|
| +const CategoryFilter::DelayValueList&
|
| + CategoryFilter::GetSyntheticDelayValues() const {
|
| + return delays_;
|
| +}
|
| +
|
| } // namespace debug
|
| } // namespace base
|
|
|
|
|