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

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

Issue 144423009: Trace event micro-optimization: use finer grained lock. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: off by one Created 6 years, 10 months 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 | « no previous file | no next file » | 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"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 "trace_event_overhead"}; 93 "trace_event_overhead"};
94 94
95 // The enabled flag is char instead of bool so that the API can be used from C. 95 // The enabled flag is char instead of bool so that the API can be used from C.
96 unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = { 0 }; 96 unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = { 0 };
97 // Indexes here have to match the g_category_groups array indexes above. 97 // Indexes here have to match the g_category_groups array indexes above.
98 const int g_category_already_shutdown = 1; 98 const int g_category_already_shutdown = 1;
99 const int g_category_categories_exhausted = 2; 99 const int g_category_categories_exhausted = 2;
100 const int g_category_metadata = 3; 100 const int g_category_metadata = 3;
101 const int g_category_trace_event_overhead = 4; 101 const int g_category_trace_event_overhead = 4;
102 const int g_num_builtin_categories = 5; 102 const int g_num_builtin_categories = 5;
103 int g_category_index = g_num_builtin_categories; // Skip default categories. 103 // Skip default categories.
104 base::subtle::AtomicWord g_category_index = g_num_builtin_categories;
104 105
105 // The name of the current thread. This is used to decide if the current 106 // The name of the current thread. This is used to decide if the current
106 // thread name has changed. We combine all the seen thread names into the 107 // thread name has changed. We combine all the seen thread names into the
107 // output name for the thread. 108 // output name for the thread.
108 LazyInstance<ThreadLocalPointer<const char> >::Leaky 109 LazyInstance<ThreadLocalPointer<const char> >::Leaky
109 g_current_thread_name = LAZY_INSTANCE_INITIALIZER; 110 g_current_thread_name = LAZY_INSTANCE_INITIALIZER;
110 111
111 TimeTicks ThreadNow() { 112 TimeTicks ThreadNow() {
112 return TimeTicks::IsThreadNowSupported() ? 113 return TimeTicks::IsThreadNowSupported() ?
113 TimeTicks::ThreadNow() : TimeTicks(); 114 TimeTicks::ThreadNow() : TimeTicks();
(...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1252 delay->SetMode(TraceEventSyntheticDelay::ALTERNATING); 1253 delay->SetMode(TraceEventSyntheticDelay::ALTERNATING);
1253 } 1254 }
1254 } 1255 }
1255 } 1256 }
1256 } 1257 }
1257 1258
1258 const unsigned char* TraceLog::GetCategoryGroupEnabledInternal( 1259 const unsigned char* TraceLog::GetCategoryGroupEnabledInternal(
1259 const char* category_group) { 1260 const char* category_group) {
1260 DCHECK(!strchr(category_group, '"')) << 1261 DCHECK(!strchr(category_group, '"')) <<
1261 "Category groups may not contain double quote"; 1262 "Category groups may not contain double quote";
1262 AutoLock lock(lock_); 1263 // The g_category_groups is append only, avoid using a lock for the fast path.
1264 int current_category_index = base::subtle::NoBarrier_Load(&g_category_index);
1263 1265
1264 unsigned char* category_group_enabled = NULL;
1265 // Search for pre-existing category group. 1266 // Search for pre-existing category group.
1266 for (int i = 0; i < g_category_index; i++) { 1267 for (int i = 0; i < current_category_index; ++i) {
1267 if (strcmp(g_category_groups[i], category_group) == 0) { 1268 if (strcmp(g_category_groups[i], category_group) == 0) {
1268 category_group_enabled = &g_category_group_enabled[i]; 1269 return &g_category_group_enabled[i];
1269 break;
1270 } 1270 }
1271 } 1271 }
1272 1272
1273 if (!category_group_enabled) { 1273 unsigned char* category_group_enabled = NULL;
1274 // Create a new category group 1274 // This is the slow path: the lock is not held in the case above, so more
1275 DCHECK(g_category_index < MAX_CATEGORY_GROUPS) << 1275 // than one thread could have reached here trying to add the same category.
1276 "must increase MAX_CATEGORY_GROUPS"; 1276 // Only hold to lock when actually appending a new category, and
1277 if (g_category_index < MAX_CATEGORY_GROUPS) { 1277 // check the categories groups again.
1278 int new_index = g_category_index++; 1278 AutoLock lock(lock_);
1279 // Don't hold on to the category_group pointer, so that we can create 1279 for (int i = 0; i < g_category_index; ++i) {
1280 // category groups with strings not known at compile time (this is 1280 if (strcmp(g_category_groups[i], category_group) == 0) {
1281 // required by SetWatchEvent). 1281 return &g_category_group_enabled[i];
1282 const char* new_group = strdup(category_group);
1283 ANNOTATE_LEAKING_OBJECT_PTR(new_group);
1284 g_category_groups[new_index] = new_group;
1285 DCHECK(!g_category_group_enabled[new_index]);
1286 // Note that if both included and excluded patterns in the
1287 // CategoryFilter are empty, we exclude nothing,
1288 // thereby enabling this category group.
1289 UpdateCategoryGroupEnabledFlag(new_index);
1290 category_group_enabled = &g_category_group_enabled[new_index];
1291 } else {
1292 category_group_enabled =
1293 &g_category_group_enabled[g_category_categories_exhausted];
1294 } 1282 }
1295 } 1283 }
1284
1285 // Create a new category group.
1286 DCHECK(g_category_index < MAX_CATEGORY_GROUPS) <<
1287 "must increase MAX_CATEGORY_GROUPS";
1288 if (g_category_index < MAX_CATEGORY_GROUPS) {
1289 int new_index = base::subtle::Acquire_Load(&g_category_index);
bulach 2014/02/13 17:55:37 the + 1 was here.. :(
1290 // Don't hold on to the category_group pointer, so that we can create
1291 // category groups with strings not known at compile time (this is
1292 // required by SetWatchEvent).
1293 const char* new_group = strdup(category_group);
1294 ANNOTATE_LEAKING_OBJECT_PTR(new_group);
1295 g_category_groups[new_index] = new_group;
1296 DCHECK(!g_category_group_enabled[new_index]);
1297 // Note that if both included and excluded patterns in the
1298 // CategoryFilter are empty, we exclude nothing,
1299 // thereby enabling this category group.
1300 UpdateCategoryGroupEnabledFlag(new_index);
1301 category_group_enabled = &g_category_group_enabled[new_index];
1302 // Update the max index now.
1303 base::subtle::Release_Store(&g_category_index, new_index + 1);
1304 } else {
1305 category_group_enabled =
1306 &g_category_group_enabled[g_category_categories_exhausted];
1307 }
1296 return category_group_enabled; 1308 return category_group_enabled;
1297 } 1309 }
1298 1310
1299 void TraceLog::GetKnownCategoryGroups( 1311 void TraceLog::GetKnownCategoryGroups(
1300 std::vector<std::string>* category_groups) { 1312 std::vector<std::string>* category_groups) {
1301 AutoLock lock(lock_); 1313 AutoLock lock(lock_);
1302 category_groups->push_back( 1314 category_groups->push_back(
1303 g_category_groups[g_category_trace_event_overhead]); 1315 g_category_groups[g_category_trace_event_overhead]);
1304 for (int i = g_num_builtin_categories; i < g_category_index; i++) 1316 for (int i = g_num_builtin_categories; i < g_category_index; i++)
1305 category_groups->push_back(g_category_groups[i]); 1317 category_groups->push_back(g_category_groups[i]);
(...skipping 1099 matching lines...) Expand 10 before | Expand all | Expand 10 after
2405 } 2417 }
2406 2418
2407 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 2419 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
2408 if (*category_group_enabled_) { 2420 if (*category_group_enabled_) {
2409 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, 2421 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_,
2410 name_, event_handle_); 2422 name_, event_handle_);
2411 } 2423 }
2412 } 2424 }
2413 2425
2414 } // namespace trace_event_internal 2426 } // namespace trace_event_internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698