diff options
Diffstat (limited to 'include/perfetto/tracing/data_source.h')
-rw-r--r-- | include/perfetto/tracing/data_source.h | 126 |
1 files changed, 27 insertions, 99 deletions
diff --git a/include/perfetto/tracing/data_source.h b/include/perfetto/tracing/data_source.h index c4c668143..77804067d 100644 --- a/include/perfetto/tracing/data_source.h +++ b/include/perfetto/tracing/data_source.h @@ -31,7 +31,6 @@ #include <memory> #include <mutex> -#include "perfetto/base/build_config.h" #include "perfetto/base/compiler.h" #include "perfetto/base/export.h" #include "perfetto/protozero/message.h" @@ -173,12 +172,7 @@ class DataSource : public DataSourceBase { ::protozero::MessageHandle<::perfetto::protos::pbzero::TracePacket>; TraceContext(TraceContext&&) noexcept = default; - ~TraceContext() { - // If the data source is being intercepted, flush the trace writer after - // each trace point to make sure the interceptor sees the data right away. - if (PERFETTO_UNLIKELY(tls_inst_->is_intercepted)) - Flush(); - } + ~TraceContext() = default; TracePacketHandle NewTracePacket() { return tls_inst_->trace_writer->NewTracePacket(); @@ -224,13 +218,6 @@ class DataSource : public DataSourceBase { } typename DataSourceTraits::IncrementalStateType* GetIncrementalState() { - // Recreate incremental state data if it has been reset by the service. - if (tls_inst_->incremental_state_generation != - static_state_.incremental_state_generation.load( - std::memory_order_relaxed)) { - tls_inst_->incremental_state.reset(); - CreateIncrementalState(tls_inst_); - } return reinterpret_cast<typename DataSourceTraits::IncrementalStateType*>( tls_inst_->incremental_state.get()); } @@ -270,9 +257,7 @@ class DataSource : public DataSourceBase { // instances. It is given an instance state parameter, which should be passed // to TraceWithInstances() to actually record trace data. template <typename Traits = DefaultTracePointTraits, typename Callback> - static void CallIfEnabled(Callback callback, - typename Traits::TracePointData trace_point_data = - {}) PERFETTO_ALWAYS_INLINE { + static void CallIfEnabled(Callback callback) PERFETTO_ALWAYS_INLINE { // |instances| is a per-class bitmap that tells: // 1. If the data source is enabled at all. // 2. The index of the slot within |static_state_| that holds the instance @@ -282,8 +267,8 @@ class DataSource : public DataSourceBase { // - |instances| is re-read with an acquire barrier below if this succeeds. // - The code between this point and the acquire-load is based on static // storage which has indefinite lifetime. - uint32_t instances = Traits::GetActiveInstances(trace_point_data) - ->load(std::memory_order_relaxed); + uint32_t instances = + Traits::GetActiveInstances()->load(std::memory_order_relaxed); // This is the tracing fast-path. Bail out immediately if tracing is not // enabled (or tracing is enabled but not for this data source). @@ -298,19 +283,11 @@ class DataSource : public DataSourceBase { // CallIfEnabled(). // |tracing_fn| will be called to record trace data as in Trace(). // - // |trace_point_data| is an optional parameter given to |Traits:: - // GetActiveInstances| to make it possible to use custom storage for - // the data source enabled state. This is, for example, used by TrackEvent to - // implement per-tracing category enabled states. - // // TODO(primiano): all the stuff below should be outlined from the trace // point. Or at least we should have some compile-time traits like // kOptimizeBinarySize / kOptimizeTracingLatency. template <typename Traits = DefaultTracePointTraits, typename Lambda> - static void TraceWithInstances( - uint32_t instances, - Lambda tracing_fn, - typename Traits::TracePointData trace_point_data = {}) { + static void TraceWithInstances(uint32_t instances, Lambda tracing_fn) { PERFETTO_DCHECK(instances); constexpr auto kMaxDataSourceInstances = internal::kMaxDataSourceInstances; @@ -319,11 +296,6 @@ class DataSource : public DataSourceBase { if (PERFETTO_UNLIKELY(!tls_state_)) tls_state_ = GetOrCreateDataSourceTLS(&static_state_); - // Avoid re-entering the trace point recursively. - if (PERFETTO_UNLIKELY(tls_state_->root_tls->is_in_trace_point)) - return; - internal::ScopedReentrancyAnnotator scoped_annotator(*tls_state_->root_tls); - // TracingTLS::generation is a global monotonic counter that is incremented // every time a tracing session is stopped. We use that as a signal to force // a slow-path garbage collection of all the trace writers for the current @@ -382,21 +354,19 @@ class DataSource : public DataSourceBase { // Here we need an acquire barrier, which matches the release-store made // by TracingMuxerImpl::SetupDataSource(), to ensure that the backend_id // and buffer_id are consistent. - instances = Traits::GetActiveInstances(trace_point_data) - ->load(std::memory_order_acquire); + instances = + Traits::GetActiveInstances()->load(std::memory_order_acquire); instance_state = static_state_.TryGetCached(instances, i); if (!instance_state || !instance_state->trace_lambda_enabled) - continue; + return; tls_inst.backend_id = instance_state->backend_id; - tls_inst.backend_connection_id = instance_state->backend_connection_id; tls_inst.buffer_id = instance_state->buffer_id; - tls_inst.data_source_instance_id = - instance_state->data_source_instance_id; - tls_inst.is_intercepted = instance_state->interceptor_id != 0; tls_inst.trace_writer = tracing_impl->CreateTraceWriter( - &static_state_, i, instance_state, - DataSourceType::kBufferExhaustedPolicy); - CreateIncrementalState(&tls_inst); + instance_state, DataSourceType::kBufferExhaustedPolicy); + CreateIncrementalState( + &tls_inst, + static_cast<typename DataSourceTraits::IncrementalStateType*>( + nullptr)); // Even in the case of out-of-IDs, SharedMemoryArbiterImpl returns a // NullTraceWriter. The returned pointer should never be null. @@ -415,21 +385,18 @@ class DataSource : public DataSourceBase { // Can return false to signal failure if attemping to register more than // kMaxDataSources (32) data sources types or if tracing hasn't been // initialized. - // The optional |constructor_args| will be passed to the data source when it - // is constructed. - template <class... Args> - static bool Register(const DataSourceDescriptor& descriptor, - const Args&... constructor_args) { + static bool Register(const DataSourceDescriptor& descriptor) { // Silences -Wunused-variable warning in case the trace method is not used // by the translation unit that declares the data source. (void)static_state_; (void)tls_state_; - auto factory = [constructor_args...]() { - return std::unique_ptr<DataSourceBase>( - new DataSourceType(constructor_args...)); + auto factory = [] { + return std::unique_ptr<DataSourceBase>(new DataSourceType()); }; auto* tracing_impl = internal::TracingMuxer::Get(); + if (!tracing_impl) + return false; return tracing_impl->RegisterDataSource(descriptor, factory, &static_state_); } @@ -444,13 +411,7 @@ class DataSource : public DataSourceBase { // // DANGER: when doing this, the data source must use the appropriate memory // fences when changing the state of the bitmap. - // - // |TraceWithInstances| may be optionally given an additional parameter for - // looking up the enable flags. That parameter is passed as |TracePointData| - // to |GetActiveInstances|. This is, for example, used by TrackEvent to - // implement per-category enabled states. - struct TracePointData {}; - static constexpr std::atomic<uint32_t>* GetActiveInstances(TracePointData) { + static constexpr std::atomic<uint32_t>* GetActiveInstances() { return &static_state_.valid_instances; } }; @@ -459,37 +420,23 @@ class DataSource : public DataSourceBase { // storage. Note: The second parameter here is used to specialize the case // where there is no incremental state type. template <typename T> - static void CreateIncrementalStateImpl( + static void CreateIncrementalState( internal::DataSourceInstanceThreadLocalState* tls_inst, const T*) { PERFETTO_DCHECK(!tls_inst->incremental_state); - tls_inst->incremental_state_generation = - static_state_.incremental_state_generation.load( - std::memory_order_relaxed); tls_inst->incremental_state = internal::DataSourceInstanceThreadLocalState::IncrementalStatePointer( reinterpret_cast<void*>(new T()), [](void* p) { delete reinterpret_cast<T*>(p); }); } - - static void CreateIncrementalStateImpl( + static void CreateIncrementalState( internal::DataSourceInstanceThreadLocalState*, const void*) {} - static void CreateIncrementalState( - internal::DataSourceInstanceThreadLocalState* tls_inst) { - CreateIncrementalStateImpl( - tls_inst, - static_cast<typename DataSourceTraits::IncrementalStateType*>(nullptr)); - } - // Note that the returned object is one per-thread per-data-source-type, NOT // per data-source *instance*. static internal::DataSourceThreadLocalState* GetOrCreateDataSourceTLS( internal::DataSourceStaticState* static_state) { -#if PERFETTO_BUILDFLAG(PERFETTO_OS_IOS) - PERFETTO_FATAL("Data source TLS not supported on iOS, see b/158814068"); -#endif auto* tracing_impl = internal::TracingMuxer::Get(); internal::TracingTLS* root_tls = tracing_impl->GetOrCreateTracingTLS(); internal::DataSourceThreadLocalState* ds_tls = @@ -512,16 +459,13 @@ class DataSource : public DataSourceBase { // destructors) that we need to defer to the embedder. In chromium's platform // implementation, for instance, the tls slot is implemented using // chromium's base::ThreadLocalStorage. - static PERFETTO_THREAD_LOCAL internal::DataSourceThreadLocalState* tls_state_; + static thread_local internal::DataSourceThreadLocalState* tls_state_; }; -// static template <typename T, typename D> internal::DataSourceStaticState DataSource<T, D>::static_state_; -// static template <typename T, typename D> -PERFETTO_THREAD_LOCAL internal::DataSourceThreadLocalState* - DataSource<T, D>::tls_state_; +thread_local internal::DataSourceThreadLocalState* DataSource<T, D>::tls_state_; } // namespace perfetto @@ -538,35 +482,19 @@ PERFETTO_THREAD_LOCAL internal::DataSourceThreadLocalState* PERFETTO_COMPONENT_EXPORT perfetto::internal::DataSourceStaticState \ perfetto::DataSource<__VA_ARGS__>::static_state_; \ template <> \ - PERFETTO_COMPONENT_EXPORT PERFETTO_THREAD_LOCAL \ - perfetto::internal::DataSourceThreadLocalState* \ + PERFETTO_COMPONENT_EXPORT thread_local perfetto::internal:: \ + DataSourceThreadLocalState* \ perfetto::DataSource<__VA_ARGS__>::tls_state_ -// MSVC has a bug where explicit template member specialization declarations -// can't have thread_local as the storage class specifier. The generated code -// seems correct without the specifier, so drop it until the bug gets fixed. -// See https://developercommunity2.visualstudio.com/t/Unable-to-specialize- -// static-thread_local/1302689. -#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC) -#define PERFETTO_TEMPLATE_THREAD_LOCAL -#else -#define PERFETTO_TEMPLATE_THREAD_LOCAL PERFETTO_THREAD_LOCAL -#endif - // This macro must be used once for each data source in one source file to // allocate static storage for the data source's static state. -// -// Note: if MSVC fails with a C2086 (redefinition) error here, use the -// permissive- flag to enable standards-compliant mode. See -// https://developercommunity.visualstudio.com/content/problem/319447/ -// explicit-specialization-of-static-data-member-inco.html. #define PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(...) \ template <> \ PERFETTO_COMPONENT_EXPORT perfetto::internal::DataSourceStaticState \ perfetto::DataSource<__VA_ARGS__>::static_state_{}; \ template <> \ - PERFETTO_COMPONENT_EXPORT PERFETTO_TEMPLATE_THREAD_LOCAL \ - perfetto::internal::DataSourceThreadLocalState* \ + PERFETTO_COMPONENT_EXPORT thread_local perfetto::internal:: \ + DataSourceThreadLocalState* \ perfetto::DataSource<__VA_ARGS__>::tls_state_ = nullptr #endif // INCLUDE_PERFETTO_TRACING_DATA_SOURCE_H_ |