|  | // Copyright 2016 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef BASE_TRACE_EVENT_CATEGORY_REGISTRY_H_ | 
|  | #define BASE_TRACE_EVENT_CATEGORY_REGISTRY_H_ | 
|  |  | 
|  | #include <stddef.h> | 
|  | #include <stdint.h> | 
|  |  | 
|  | #include "base/base_export.h" | 
|  | #include "base/logging.h" | 
|  |  | 
|  | namespace base { | 
|  | namespace trace_event { | 
|  |  | 
|  | struct TraceCategory; | 
|  | class TraceCategoryTest; | 
|  | class TraceLog; | 
|  |  | 
|  | // Allows fast and thread-safe acces to the state of all tracing categories. | 
|  | // All the methods in this class can be concurrently called on multiple threads, | 
|  | // unless otherwise noted (e.g., GetOrCreateCategoryLocked). | 
|  | // The reason why this is a fully static class with global state is to allow to | 
|  | // statically define known categories as global linker-initialized structs, | 
|  | // without requiring static initializers. | 
|  | class BASE_EXPORT CategoryRegistry { | 
|  | public: | 
|  | // Allows for-each iterations over a slice of the categories array. | 
|  | class Range { | 
|  | public: | 
|  | Range(TraceCategory* begin, TraceCategory* end) : begin_(begin), end_(end) { | 
|  | DCHECK_LE(begin, end); | 
|  | } | 
|  | TraceCategory* begin() const { return begin_; } | 
|  | TraceCategory* end() const { return end_; } | 
|  |  | 
|  | private: | 
|  | TraceCategory* const begin_; | 
|  | TraceCategory* const end_; | 
|  | }; | 
|  |  | 
|  | // Known categories. | 
|  | static TraceCategory* const kCategoryExhausted; | 
|  | static TraceCategory* const kCategoryMetadata; | 
|  | static TraceCategory* const kCategoryAlreadyShutdown; | 
|  |  | 
|  | // Returns a category entry from the Category.state_ptr() pointer. | 
|  | // TODO(primiano): trace macros should just keep a pointer to the entire | 
|  | // TraceCategory, not just the enabled state pointer. That would remove the | 
|  | // need for this function and make everything cleaner at no extra cost (as | 
|  | // long as the |state_| is the first field of the struct, which can be | 
|  | // guaranteed via static_assert, see TraceCategory ctor). | 
|  | static const TraceCategory* GetCategoryByStatePtr( | 
|  | const uint8_t* category_state); | 
|  |  | 
|  | // Returns a category from its name or nullptr if not found. | 
|  | // The output |category| argument is an undefinitely lived pointer to the | 
|  | // TraceCategory owned by the registry. TRACE_EVENTx macros will cache this | 
|  | // pointer and use it for checks in their fast-paths. | 
|  | static TraceCategory* GetCategoryByName(const char* category_name); | 
|  |  | 
|  | static bool IsBuiltinCategory(const TraceCategory*); | 
|  |  | 
|  | private: | 
|  | friend class TraceCategoryTest; | 
|  | friend class TraceLog; | 
|  | using CategoryInitializerFn = void (*)(TraceCategory*); | 
|  |  | 
|  | // Only for debugging/testing purposes, is a no-op on release builds. | 
|  | static void Initialize(); | 
|  |  | 
|  | // Resets the state of all categories, to clear up the state between tests. | 
|  | static void ResetForTesting(); | 
|  |  | 
|  | // Used to get/create a category in the slow-path. If the category exists | 
|  | // already, this has the same effect of GetCategoryByName and returns false. | 
|  | // If not, a new category is created and the CategoryInitializerFn is invoked | 
|  | // before retuning true. The caller must guarantee serialization: either call | 
|  | // this method from a single thread or hold a lock when calling this. | 
|  | static bool GetOrCreateCategoryLocked(const char* category_name, | 
|  | CategoryInitializerFn, | 
|  | TraceCategory**); | 
|  |  | 
|  | // Allows to iterate over the valid categories in a for-each loop. | 
|  | // This includes builtin categories such as __metadata. | 
|  | static Range GetAllCategories(); | 
|  | }; | 
|  |  | 
|  | }  // namespace trace_event | 
|  | }  // namespace base | 
|  |  | 
|  | #endif  // BASE_TRACE_EVENT_CATEGORY_REGISTRY_H_ |