Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Side by Side Diff: base/debug/trace_event_impl.cc

Issue 98953002: Configure synthetic delays through TraceLog (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Only use category=value syntax for delays. Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/debug/trace_event_impl.h ('k') | base/debug/trace_event_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/debug/trace_event_impl.h" 5 #include "base/debug/trace_event_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/base_switches.h" 9 #include "base/base_switches.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/debug/leak_annotations.h" 12 #include "base/debug/leak_annotations.h"
13 #include "base/debug/trace_event.h" 13 #include "base/debug/trace_event.h"
14 #include "base/debug/trace_event_synthetic_delay.h"
14 #include "base/format_macros.h" 15 #include "base/format_macros.h"
15 #include "base/json/string_escape.h" 16 #include "base/json/string_escape.h"
16 #include "base/lazy_instance.h" 17 #include "base/lazy_instance.h"
17 #include "base/memory/singleton.h" 18 #include "base/memory/singleton.h"
18 #include "base/message_loop/message_loop.h" 19 #include "base/message_loop/message_loop.h"
19 #include "base/process/process_metrics.h" 20 #include "base/process/process_metrics.h"
20 #include "base/stl_util.h" 21 #include "base/stl_util.h"
21 #include "base/strings/string_number_conversions.h" 22 #include "base/strings/string_number_conversions.h"
22 #include "base/strings/string_split.h" 23 #include "base/strings/string_split.h"
23 #include "base/strings/string_tokenizer.h" 24 #include "base/strings/string_tokenizer.h"
(...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 event_callback_category_filter_.IsCategoryGroupEnabled(category_group)) 1194 event_callback_category_filter_.IsCategoryGroupEnabled(category_group))
1194 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; 1195 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK;
1195 g_category_group_enabled[category_index] = enabled_flag; 1196 g_category_group_enabled[category_index] = enabled_flag;
1196 } 1197 }
1197 1198
1198 void TraceLog::UpdateCategoryGroupEnabledFlags() { 1199 void TraceLog::UpdateCategoryGroupEnabledFlags() {
1199 for (int i = 0; i < g_category_index; i++) 1200 for (int i = 0; i < g_category_index; i++)
1200 UpdateCategoryGroupEnabledFlag(i); 1201 UpdateCategoryGroupEnabledFlag(i);
1201 } 1202 }
1202 1203
1204 void TraceLog::UpdateSyntheticDelaysFromCategoryFilter() {
1205 ResetTraceEventSyntheticDelays();
1206 const CategoryFilter::DelayValueList& delays =
1207 category_filter_.GetSyntheticDelayValues();
1208 CategoryFilter::DelayValueList::const_iterator ci;
1209 for (ci = delays.begin(); ci != delays.end(); ++ci) {
1210 TraceEventSyntheticDelay* delay =
1211 TraceEventSyntheticDelay::Lookup(ci->first);
1212 StringTokenizer tokens(ci->second, ";");
1213 while (tokens.GetNext()) {
1214 double target_duration;
1215 if (StringToDouble(tokens.token(), &target_duration)) {
1216 delay->SetTargetDuration(
1217 TimeDelta::FromMicroseconds(target_duration * 1e6));
1218 } else if (tokens.token() == "static") {
1219 delay->SetMode(TraceEventSyntheticDelay::STATIC);
1220 } else if (tokens.token() == "oneshot") {
1221 delay->SetMode(TraceEventSyntheticDelay::ONE_SHOT);
1222 } else if (tokens.token() == "alternating") {
1223 delay->SetMode(TraceEventSyntheticDelay::ALTERNATING);
1224 }
1225 }
1226 }
1227 }
1228
1203 const unsigned char* TraceLog::GetCategoryGroupEnabledInternal( 1229 const unsigned char* TraceLog::GetCategoryGroupEnabledInternal(
1204 const char* category_group) { 1230 const char* category_group) {
1205 DCHECK(!strchr(category_group, '"')) << 1231 DCHECK(!strchr(category_group, '"')) <<
1206 "Category groups may not contain double quote"; 1232 "Category groups may not contain double quote";
1207 AutoLock lock(lock_); 1233 AutoLock lock(lock_);
1208 1234
1209 unsigned char* category_group_enabled = NULL; 1235 unsigned char* category_group_enabled = NULL;
1210 // Search for pre-existing category group. 1236 // Search for pre-existing category group.
1211 for (int i = 0; i < g_category_index; i++) { 1237 for (int i = 0; i < g_category_index; i++) {
1212 if (strcmp(g_category_groups[i], category_group) == 0) { 1238 if (strcmp(g_category_groups[i], category_group) == 0) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 if (options != old_options) { 1309 if (options != old_options) {
1284 subtle::NoBarrier_Store(&trace_options_, options); 1310 subtle::NoBarrier_Store(&trace_options_, options);
1285 logged_events_.reset(CreateTraceBuffer()); 1311 logged_events_.reset(CreateTraceBuffer());
1286 NextGeneration(); 1312 NextGeneration();
1287 } 1313 }
1288 1314
1289 num_traces_recorded_++; 1315 num_traces_recorded_++;
1290 1316
1291 category_filter_ = CategoryFilter(category_filter); 1317 category_filter_ = CategoryFilter(category_filter);
1292 UpdateCategoryGroupEnabledFlags(); 1318 UpdateCategoryGroupEnabledFlags();
1319 UpdateSyntheticDelaysFromCategoryFilter();
1293 1320
1294 if ((options & ENABLE_SAMPLING) || (options & MONITOR_SAMPLING)) { 1321 if ((options & ENABLE_SAMPLING) || (options & MONITOR_SAMPLING)) {
1295 sampling_thread_.reset(new TraceSamplingThread); 1322 sampling_thread_.reset(new TraceSamplingThread);
1296 sampling_thread_->RegisterSampleBucket( 1323 sampling_thread_->RegisterSampleBucket(
1297 &g_trace_state[0], 1324 &g_trace_state[0],
1298 "bucket0", 1325 "bucket0",
1299 Bind(&TraceSamplingThread::DefaultSamplingCallback)); 1326 Bind(&TraceSamplingThread::DefaultSamplingCallback));
1300 sampling_thread_->RegisterSampleBucket( 1327 sampling_thread_->RegisterSampleBucket(
1301 &g_trace_state[1], 1328 &g_trace_state[1],
1302 "bucket1", 1329 "bucket1",
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after
2149 CategoryFilter::CategoryFilter(const std::string& filter_string) { 2176 CategoryFilter::CategoryFilter(const std::string& filter_string) {
2150 if (!filter_string.empty()) 2177 if (!filter_string.empty())
2151 Initialize(filter_string); 2178 Initialize(filter_string);
2152 else 2179 else
2153 Initialize(CategoryFilter::kDefaultCategoryFilterString); 2180 Initialize(CategoryFilter::kDefaultCategoryFilterString);
2154 } 2181 }
2155 2182
2156 CategoryFilter::CategoryFilter(const CategoryFilter& cf) 2183 CategoryFilter::CategoryFilter(const CategoryFilter& cf)
2157 : included_(cf.included_), 2184 : included_(cf.included_),
2158 disabled_(cf.disabled_), 2185 disabled_(cf.disabled_),
2159 excluded_(cf.excluded_) { 2186 excluded_(cf.excluded_),
2187 delays_(cf.delays_) {
2160 } 2188 }
2161 2189
2162 CategoryFilter::~CategoryFilter() { 2190 CategoryFilter::~CategoryFilter() {
2163 } 2191 }
2164 2192
2165 CategoryFilter& CategoryFilter::operator=(const CategoryFilter& rhs) { 2193 CategoryFilter& CategoryFilter::operator=(const CategoryFilter& rhs) {
2166 if (this == &rhs) 2194 if (this == &rhs)
2167 return *this; 2195 return *this;
2168 2196
2169 included_ = rhs.included_; 2197 included_ = rhs.included_;
2170 disabled_ = rhs.disabled_; 2198 disabled_ = rhs.disabled_;
2171 excluded_ = rhs.excluded_; 2199 excluded_ = rhs.excluded_;
2200 delays_ = rhs.delays_;
2172 return *this; 2201 return *this;
2173 } 2202 }
2174 2203
2175 void CategoryFilter::Initialize(const std::string& filter_string) { 2204 void CategoryFilter::Initialize(const std::string& filter_string) {
2176 // Tokenize list of categories, delimited by ','. 2205 // Tokenize list of categories, delimited by ','.
2177 StringTokenizer tokens(filter_string, ","); 2206 StringTokenizer tokens(filter_string, ",");
2178 // Add each token to the appropriate list (included_,excluded_). 2207 // Add each token to the appropriate list (included_,excluded_).
2179 while (tokens.GetNext()) { 2208 while (tokens.GetNext()) {
2180 std::string category = tokens.token(); 2209 std::string category = tokens.token();
2181 // Ignore empty categories. 2210 // Ignore empty categories.
2182 if (category.empty()) 2211 if (category.empty())
2183 continue; 2212 continue;
2184 // Excluded categories start with '-'. 2213 std::vector<std::string> parts;
2185 if (category.at(0) == '-') { 2214 SplitString(category, '=', &parts);
2215 if (parts.size() == 2) {
2216 // Synthetic delays are of the form 'delay=options'.
2217 delays_.push_back(DelayValue(parts[0], parts[1]));
2218 } else if (category.at(0) == '-') {
2219 // Excluded categories start with '-'.
2186 // Remove '-' from category string. 2220 // Remove '-' from category string.
2187 category = category.substr(1); 2221 category = category.substr(1);
2188 excluded_.push_back(category); 2222 excluded_.push_back(category);
2189 } else if (category.compare(0, strlen(TRACE_DISABLED_BY_DEFAULT("")), 2223 } else if (category.compare(0, strlen(TRACE_DISABLED_BY_DEFAULT("")),
2190 TRACE_DISABLED_BY_DEFAULT("")) == 0) { 2224 TRACE_DISABLED_BY_DEFAULT("")) == 0) {
2191 disabled_.push_back(category); 2225 disabled_.push_back(category);
2192 } else { 2226 } else {
2193 included_.push_back(category); 2227 included_.push_back(category);
2194 } 2228 }
2195 } 2229 }
2196 } 2230 }
2197 2231
2198 void CategoryFilter::WriteString(const StringList& values, 2232 void CategoryFilter::WriteString(const StringList& values,
2199 std::string* out, 2233 std::string* out,
2200 bool included) const { 2234 bool included) const {
2201 bool prepend_comma = !out->empty(); 2235 bool prepend_comma = !out->empty();
2202 int token_cnt = 0; 2236 int token_cnt = 0;
2203 for (StringList::const_iterator ci = values.begin(); 2237 for (StringList::const_iterator ci = values.begin();
2204 ci != values.end(); ++ci) { 2238 ci != values.end(); ++ci) {
2205 if (token_cnt > 0 || prepend_comma) 2239 if (token_cnt > 0 || prepend_comma)
2206 StringAppendF(out, ","); 2240 StringAppendF(out, ",");
2207 StringAppendF(out, "%s%s", (included ? "" : "-"), ci->c_str()); 2241 StringAppendF(out, "%s%s", (included ? "" : "-"), ci->c_str());
2208 ++token_cnt; 2242 ++token_cnt;
2209 } 2243 }
2210 } 2244 }
2211 2245
2246 void CategoryFilter::WriteString(const DelayValueList& delays,
2247 std::string* out) const {
2248 bool prepend_comma = !out->empty();
2249 int token_cnt = 0;
2250 for (DelayValueList::const_iterator ci = delays.begin();
2251 ci != delays.end(); ++ci) {
2252 if (token_cnt > 0 || prepend_comma)
2253 StringAppendF(out, ",");
2254 StringAppendF(out, "%s=%s", ci->first.c_str(), ci->second.c_str());
2255 ++token_cnt;
2256 }
2257 }
2258
2212 std::string CategoryFilter::ToString() const { 2259 std::string CategoryFilter::ToString() const {
2213 std::string filter_string; 2260 std::string filter_string;
2214 WriteString(included_, &filter_string, true); 2261 WriteString(included_, &filter_string, true);
2215 WriteString(disabled_, &filter_string, true); 2262 WriteString(disabled_, &filter_string, true);
2216 WriteString(excluded_, &filter_string, false); 2263 WriteString(excluded_, &filter_string, false);
2264 WriteString(delays_, &filter_string);
2217 return filter_string; 2265 return filter_string;
2218 } 2266 }
2219 2267
2220 bool CategoryFilter::IsCategoryGroupEnabled( 2268 bool CategoryFilter::IsCategoryGroupEnabled(
2221 const char* category_group_name) const { 2269 const char* category_group_name) const {
2222 // TraceLog should call this method only as part of enabling/disabling 2270 // TraceLog should call this method only as part of enabling/disabling
2223 // categories. 2271 // categories.
2224 StringList::const_iterator ci; 2272 StringList::const_iterator ci;
2225 2273
2226 // Check the disabled- filters and the disabled-* wildcard first so that a 2274 // Check the disabled- filters and the disabled-* wildcard first so that a
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2262 } else { 2310 } else {
2263 included_.clear(); 2311 included_.clear();
2264 } 2312 }
2265 2313
2266 disabled_.insert(disabled_.end(), 2314 disabled_.insert(disabled_.end(),
2267 nested_filter.disabled_.begin(), 2315 nested_filter.disabled_.begin(),
2268 nested_filter.disabled_.end()); 2316 nested_filter.disabled_.end());
2269 excluded_.insert(excluded_.end(), 2317 excluded_.insert(excluded_.end(),
2270 nested_filter.excluded_.begin(), 2318 nested_filter.excluded_.begin(),
2271 nested_filter.excluded_.end()); 2319 nested_filter.excluded_.end());
2272 } 2320 }
dsinclair1 2014/01/07 19:52:40 Do we need to merge the delay lists as well?
2273 2321
2274 void CategoryFilter::Clear() { 2322 void CategoryFilter::Clear() {
2275 included_.clear(); 2323 included_.clear();
2276 disabled_.clear(); 2324 disabled_.clear();
2277 excluded_.clear(); 2325 excluded_.clear();
2278 } 2326 }
2279 2327
2328 const CategoryFilter::DelayValueList&
2329 CategoryFilter::GetSyntheticDelayValues() const {
2330 return delays_;
2331 }
2332
2280 } // namespace debug 2333 } // namespace debug
2281 } // namespace base 2334 } // namespace base
2282 2335
2283 namespace trace_event_internal { 2336 namespace trace_event_internal {
2284 2337
2285 ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient( 2338 ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient(
2286 const char* category_group, const char* name) { 2339 const char* category_group, const char* name) {
2287 // The single atom works because for now the category_group can only be "gpu". 2340 // The single atom works because for now the category_group can only be "gpu".
2288 DCHECK(strcmp(category_group, "gpu") == 0); 2341 DCHECK(strcmp(category_group, "gpu") == 0);
2289 static TRACE_EVENT_API_ATOMIC_WORD atomic = 0; 2342 static TRACE_EVENT_API_ATOMIC_WORD atomic = 0;
(...skipping 12 matching lines...) Expand all
2302 } 2355 }
2303 2356
2304 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 2357 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
2305 if (*category_group_enabled_) { 2358 if (*category_group_enabled_) {
2306 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, 2359 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_,
2307 name_, event_handle_); 2360 name_, event_handle_);
2308 } 2361 }
2309 } 2362 }
2310 2363
2311 } // namespace trace_event_internal 2364 } // namespace trace_event_internal
OLDNEW
« no previous file with comments | « base/debug/trace_event_impl.h ('k') | base/debug/trace_event_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698