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

Unified Diff: base/trace_event/trace_log.cc

Issue 2452063003: tracing: split out the CategoryRegistry from the TraceLog (Closed)
Patch Set: add tests, rebase Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/trace_event/trace_log.h ('k') | tools/gn/bootstrap/bootstrap.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/trace_event/trace_log.cc
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc
index a77197017f57bbadcec8ed3bc9581d05690038c2..f76393cf230a3e97772d3cee734ffac79b0ba5fc 100644
--- a/base/trace_event/trace_log.cc
+++ b/base/trace_event/trace_log.cc
@@ -26,12 +26,12 @@
#include "base/strings/string_tokenizer.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
-#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_id_name_manager.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/threading/worker_pool.h"
#include "base/time/time.h"
+#include "base/trace_event/category_registry.h"
#include "base/trace_event/heap_profiler.h"
#include "base/trace_event/heap_profiler_allocation_context_tracker.h"
#include "base/trace_event/memory_dump_manager.h"
@@ -84,23 +84,6 @@ const size_t kEchoToConsoleTraceEventBufferChunks = 256;
const size_t kTraceEventBufferSizeInBytes = 100 * 1024;
const int kThreadFlushTimeoutMs = 3000;
-#define MAX_CATEGORY_GROUPS 200
-
-// Parallel arrays g_category_groups and g_category_group_enabled are separate
-// so that a pointer to a member of g_category_group_enabled can be easily
-// converted to an index into g_category_groups. This allows macros to deal
-// only with char enabled pointers from g_category_group_enabled, and we can
-// convert internally to determine the category name from the char enabled
-// pointer.
-const char* g_category_groups[MAX_CATEGORY_GROUPS] = {
- "toplevel",
- "tracing already shutdown",
- "tracing categories exhausted; must increase MAX_CATEGORY_GROUPS",
- "__metadata"};
-
-// The enabled flag is char instead of bool so that the API can be used from C.
-unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = {0};
-
const char kEventNameWhitelist[] = "event_name_whitelist";
#define MAX_TRACE_EVENT_FILTERS 32
@@ -109,9 +92,6 @@ const char kEventNameWhitelist[] = "event_name_whitelist";
base::LazyInstance<std::vector<std::unique_ptr<TraceLog::TraceEventFilter>>>::
Leaky g_category_group_filters = LAZY_INSTANCE_INITIALIZER;
-// Stores a bitmap of filters enabled for each category group.
-uint32_t g_category_group_filters_enabled[MAX_CATEGORY_GROUPS] = {0};
-
class EventNameFilter : public TraceLog::TraceEventFilter {
public:
EventNameFilter(const base::DictionaryValue* filter_args) {
@@ -181,14 +161,6 @@ class HeapProfilerFilter : public TraceLog::TraceEventFilter {
TraceLog::TraceEventFilterConstructorForTesting
g_trace_event_filter_constructor_for_testing = nullptr;
-// Indexes here have to match the g_category_groups array indexes above.
-const int kCategoryAlreadyShutdown = 1;
-const int kCategoryCategoriesExhausted = 2;
-const int kCategoryMetadata = 3;
-const int kNumBuiltinCategories = 4;
-// Skip default categories.
-base::subtle::AtomicWord g_category_index = kNumBuiltinCategories;
-
// The name of the current thread. This is used to decide if the current
// thread name has changed. We combine all the seen thread names into the
// output name for the thread.
@@ -217,7 +189,7 @@ void InitializeMetadataEvent(TraceEvent* trace_event,
TimeTicks(),
ThreadTicks(),
TRACE_EVENT_PHASE_METADATA,
- &g_category_group_enabled[kCategoryMetadata],
+ CategoryRegistry::kCategoryMetadata->state_ptr(),
metadata_name,
trace_event_internal::kGlobalScope, // scope
trace_event_internal::kNoId, // id
@@ -259,27 +231,12 @@ void MakeHandle(uint32_t chunk_seq,
handle->event_index = static_cast<uint16_t>(event_index);
}
-uintptr_t GetCategoryIndex(const unsigned char* category_group_enabled) {
- // Calculate the index of the category group by finding
- // category_group_enabled in g_category_group_enabled array.
- uintptr_t category_begin =
- reinterpret_cast<uintptr_t>(g_category_group_enabled);
- uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_group_enabled);
- DCHECK(category_ptr >= category_begin);
- DCHECK(category_ptr < reinterpret_cast<uintptr_t>(g_category_group_enabled +
- MAX_CATEGORY_GROUPS))
- << "out of bounds category pointer";
- uintptr_t category_index =
- (category_ptr - category_begin) / sizeof(g_category_group_enabled[0]);
-
- return category_index;
-}
-
template <typename Function>
void ForEachCategoryGroupFilter(const unsigned char* category_group_enabled,
Function filter_fn) {
- uint32_t filter_bitmap = g_category_group_filters_enabled[GetCategoryIndex(
- category_group_enabled)];
+ const TraceCategory* category =
+ CategoryRegistry::GetCategoryByStatePtr(category_group_enabled);
+ uint32_t filter_bitmap = category->enabled_filters();
int index = 0;
while (filter_bitmap) {
if (filter_bitmap & 1 && g_category_group_filters.Get()[index])
@@ -473,18 +430,8 @@ TraceLog::TraceLog()
thread_shared_chunk_index_(0),
generation_(0),
use_worker_thread_(false) {
- // Trace is enabled or disabled on one thread while other threads are
- // accessing the enabled flag. We don't care whether edge-case events are
- // traced or not, so we allow races on the enabled flag to keep the trace
- // macros fast.
- // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots:
- // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled,
- // sizeof(g_category_group_enabled),
- // "trace_event category enabled");
- for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) {
- ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i],
- "trace_event category enabled");
- }
+ CategoryRegistry::Initialize();
+
#if defined(OS_NACL) // NaCl shouldn't expose the process id.
SetProcessID(0);
#else
@@ -543,43 +490,52 @@ const unsigned char* TraceLog::GetCategoryGroupEnabled(
const char* category_group) {
TraceLog* tracelog = GetInstance();
if (!tracelog) {
- DCHECK(!g_category_group_enabled[kCategoryAlreadyShutdown]);
- return &g_category_group_enabled[kCategoryAlreadyShutdown];
+ DCHECK(!CategoryRegistry::kCategoryAlreadyShutdown->is_enabled());
+ return CategoryRegistry::kCategoryAlreadyShutdown->state_ptr();
}
- return tracelog->GetCategoryGroupEnabledInternal(category_group);
+ TraceCategory* category = nullptr;
+ bool is_new_category =
+ CategoryRegistry::GetOrCreateCategoryByName(category_group, &category);
+ if (is_new_category)
+ tracelog->UpdateCategoryState(category);
+ DCHECK(category->state_ptr());
+ return category->state_ptr();
}
const char* TraceLog::GetCategoryGroupName(
const unsigned char* category_group_enabled) {
- return g_category_groups[GetCategoryIndex(category_group_enabled)];
+ return CategoryRegistry::GetCategoryByStatePtr(category_group_enabled)
+ ->name();
}
-void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) {
- unsigned char enabled_flag = 0;
- const char* category_group = g_category_groups[category_index];
+void TraceLog::UpdateCategoryState(TraceCategory* category) {
+ DCHECK(category->is_valid());
+ unsigned char state_flags = 0;
if (enabled_modes_ & RECORDING_MODE &&
- trace_config_.IsCategoryGroupEnabled(category_group)) {
- enabled_flag |= ENABLED_FOR_RECORDING;
+ trace_config_.IsCategoryGroupEnabled(category->name())) {
+ state_flags |= TraceCategory::ENABLED_FOR_RECORDING;
+ }
+
+ // TODO(primiano): this is a temporary workaround for catapult:#2341,
+ // to guarantee that metadata events are always added even if the category
+ // filter is "-*". See crbug.com/618054 for more details and long-term fix.
+ if (enabled_modes_ & RECORDING_MODE &&
+ category == CategoryRegistry::kCategoryMetadata) {
+ state_flags |= TraceCategory::ENABLED_FOR_RECORDING;
}
#if defined(OS_WIN)
if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled(
- category_group)) {
- enabled_flag |= ENABLED_FOR_ETW_EXPORT;
+ category->name())) {
+ state_flags |= TraceCategory::ENABLED_FOR_ETW_EXPORT;
}
#endif
- // TODO(primiano): this is a temporary workaround for catapult:#2341,
- // to guarantee that metadata events are always added even if the category
- // filter is "-*". See crbug.com/618054 for more details and long-term fix.
- if (enabled_modes_ & RECORDING_MODE && !strcmp(category_group, "__metadata"))
- enabled_flag |= ENABLED_FOR_RECORDING;
-
uint32_t enabled_filters_bitmap = 0;
int index = 0;
for (const auto& event_filter : enabled_event_filters_) {
- if (event_filter.IsCategoryGroupEnabled(category_group)) {
- enabled_flag |= ENABLED_FOR_FILTERING;
+ if (event_filter.IsCategoryGroupEnabled(category->name())) {
+ state_flags |= TraceCategory::ENABLED_FOR_FILTERING;
DCHECK(g_category_group_filters.Get()[index]);
enabled_filters_bitmap |= 1 << index;
}
@@ -588,16 +544,15 @@ void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) {
break;
}
}
- g_category_group_filters_enabled[category_index] = enabled_filters_bitmap;
-
- g_category_group_enabled[category_index] = enabled_flag;
+ category->set_enabled_filters(enabled_filters_bitmap);
+ category->set_state(state_flags);
}
-void TraceLog::UpdateCategoryGroupEnabledFlags() {
+void TraceLog::UpdateCategoryRegistry() {
CreateFiltersForTraceConfig();
- size_t category_index = base::subtle::NoBarrier_Load(&g_category_index);
- for (size_t i = 0; i < category_index; i++)
- UpdateCategoryGroupEnabledFlag(i);
+ for (TraceCategory& category : CategoryRegistry::GetAllCategories()) {
+ UpdateCategoryState(&category);
+ }
}
void TraceLog::CreateFiltersForTraceConfig() {
@@ -662,64 +617,12 @@ void TraceLog::UpdateSyntheticDelaysFromTraceConfig() {
}
}
-const unsigned char* TraceLog::GetCategoryGroupEnabledInternal(
- const char* category_group) {
- DCHECK(!strchr(category_group, '"'))
- << "Category groups may not contain double quote";
- // The g_category_groups is append only, avoid using a lock for the fast path.
- size_t current_category_index = base::subtle::Acquire_Load(&g_category_index);
-
- // Search for pre-existing category group.
- for (size_t i = 0; i < current_category_index; ++i) {
- if (strcmp(g_category_groups[i], category_group) == 0) {
- return &g_category_group_enabled[i];
- }
- }
-
- // This is the slow path: the lock is not held in the case above, so more
- // than one thread could have reached here trying to add the same category.
- // Only hold to lock when actually appending a new category, and
- // check the categories groups again.
- AutoLock lock(lock_);
- size_t category_index = base::subtle::Acquire_Load(&g_category_index);
- for (size_t i = 0; i < category_index; ++i) {
- if (strcmp(g_category_groups[i], category_group) == 0) {
- return &g_category_group_enabled[i];
- }
- }
-
- // Create a new category group.
- DCHECK(category_index < MAX_CATEGORY_GROUPS)
- << "must increase MAX_CATEGORY_GROUPS";
- unsigned char* category_group_enabled = nullptr;
- if (category_index < MAX_CATEGORY_GROUPS) {
- // Don't hold on to the category_group pointer, so that we can create
- // category groups with strings not known at compile time (this is
- // required by SetWatchEvent).
- const char* new_group = strdup(category_group);
- ANNOTATE_LEAKING_OBJECT_PTR(new_group);
- g_category_groups[category_index] = new_group;
- DCHECK(!g_category_group_enabled[category_index]);
- // Note that if both included and excluded patterns in the
- // TraceConfig are empty, we exclude nothing,
- // thereby enabling this category group.
- UpdateCategoryGroupEnabledFlag(category_index);
- category_group_enabled = &g_category_group_enabled[category_index];
- // Update the max index now.
- base::subtle::Release_Store(&g_category_index, category_index + 1);
- } else {
- category_group_enabled =
- &g_category_group_enabled[kCategoryCategoriesExhausted];
- }
- return category_group_enabled;
-}
-
void TraceLog::GetKnownCategoryGroups(
std::vector<std::string>* category_groups) {
- AutoLock lock(lock_);
- size_t category_index = base::subtle::NoBarrier_Load(&g_category_index);
- for (size_t i = kNumBuiltinCategories; i < category_index; i++)
- category_groups->push_back(g_category_groups[i]);
+ for (const auto& category : CategoryRegistry::GetAllCategories()) {
+ if (!CategoryRegistry::IsBuiltinCategory(&category))
+ category_groups->push_back(category.name());
+ }
}
void TraceLog::SetEnabled(const TraceConfig& trace_config,
@@ -783,7 +686,7 @@ void TraceLog::SetEnabled(const TraceConfig& trace_config,
trace_config_.SetEventFilters(enabled_event_filters_);
enabled_modes_ |= modes_to_enable;
- UpdateCategoryGroupEnabledFlags();
+ UpdateCategoryRegistry();
// Do not notify observers or create trace buffer if only enabled for
// filtering or if recording was already enabled.
@@ -797,7 +700,7 @@ void TraceLog::SetEnabled(const TraceConfig& trace_config,
num_traces_recorded_++;
- UpdateCategoryGroupEnabledFlags();
+ UpdateCategoryRegistry();
UpdateSyntheticDelaysFromTraceConfig();
dispatching_to_observer_list_ = true;
@@ -885,7 +788,7 @@ void TraceLog::SetDisabledWhileLocked(uint8_t modes_to_disable) {
trace_config_.Clear();
}
- UpdateCategoryGroupEnabledFlags();
+ UpdateCategoryRegistry();
// Add metadata events and notify observers only if recording mode was
// disabled now.
@@ -1411,7 +1314,7 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
#if defined(OS_WIN)
// This is done sooner rather than later, to avoid creating the event and
// acquiring the lock, which is not needed for ETW as it's already threadsafe.
- if (*category_group_enabled & ENABLED_FOR_ETW_EXPORT)
+ if (*category_group_enabled & TraceCategory::ENABLED_FOR_ETW_EXPORT)
TraceEventETWExport::AddEvent(phase, category_group_enabled, name, id,
num_args, arg_names, arg_types, arg_values,
convertable_values);
@@ -1420,7 +1323,7 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
std::string console_message;
std::unique_ptr<TraceEvent> filtered_trace_event;
bool disabled_by_filters = false;
- if (*category_group_enabled & ENABLED_FOR_FILTERING) {
+ if (*category_group_enabled & TraceCategory::ENABLED_FOR_FILTERING) {
std::unique_ptr<TraceEvent> new_trace_event(new TraceEvent);
new_trace_event->Initialize(thread_id, offset_event_timestamp, thread_now,
phase, category_group_enabled, name, scope, id,
@@ -1440,7 +1343,7 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
// If enabled for recording, the event should be added only if one of the
// filters indicates or category is not enabled for filtering.
- if ((*category_group_enabled & ENABLED_FOR_RECORDING) &&
+ if ((*category_group_enabled & TraceCategory::ENABLED_FOR_RECORDING) &&
!disabled_by_filters) {
OptionalAutoLock lock(&lock_);
@@ -1586,12 +1489,12 @@ void TraceLog::UpdateTraceEventDuration(
#if defined(OS_WIN)
// Generate an ETW event that marks the end of a complete event.
- if (category_group_enabled_local & ENABLED_FOR_ETW_EXPORT)
+ if (category_group_enabled_local & TraceCategory::ENABLED_FOR_ETW_EXPORT)
TraceEventETWExport::AddCompleteEndEvent(name);
#endif // OS_WIN
std::string console_message;
- if (category_group_enabled_local & ENABLED_FOR_RECORDING) {
+ if (category_group_enabled_local & TraceCategory::ENABLED_FOR_RECORDING) {
OptionalAutoLock lock(&lock_);
TraceEvent* trace_event = GetEventByHandleInternal(handle, &lock);
@@ -1624,7 +1527,7 @@ void TraceLog::UpdateTraceEventDuration(
if (!console_message.empty())
LOG(ERROR) << console_message;
- if (category_group_enabled_local & ENABLED_FOR_FILTERING)
+ if (category_group_enabled_local & TraceCategory::ENABLED_FOR_FILTERING)
EndFilteredEvent(category_group_enabled, name, handle);
}
@@ -1699,6 +1602,7 @@ void TraceLog::AddMetadataEventsWhileLocked() {
void TraceLog::DeleteForTesting() {
internal::DeleteTraceLogForTesting::Delete();
+ CategoryRegistry::ResetForTesting();
}
void TraceLog::SetTraceEventFilterConstructorForTesting(
@@ -1815,18 +1719,14 @@ TraceBuffer* TraceLog::CreateTraceBuffer() {
#if defined(OS_WIN)
void TraceLog::UpdateETWCategoryGroupEnabledFlags() {
- AutoLock lock(lock_);
- size_t category_index = base::subtle::NoBarrier_Load(&g_category_index);
// Go through each category and set/clear the ETW bit depending on whether the
// category is enabled.
- for (size_t i = 0; i < category_index; i++) {
- const char* category_group = g_category_groups[i];
- DCHECK(category_group);
+ for (TraceCategory& category : CategoryRegistry::GetAllCategories()) {
if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled(
- category_group)) {
- g_category_group_enabled[i] |= ENABLED_FOR_ETW_EXPORT;
+ category.name())) {
+ category.set_state_flag(TraceCategory::ENABLED_FOR_ETW_EXPORT);
} else {
- g_category_group_enabled[i] &= ~ENABLED_FOR_ETW_EXPORT;
+ category.clear_state_flag(TraceCategory::ENABLED_FOR_ETW_EXPORT);
}
}
}
« no previous file with comments | « base/trace_event/trace_log.h ('k') | tools/gn/bootstrap/bootstrap.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698