aboutsummaryrefslogtreecommitdiff
path: root/include/perfetto/tracing/data_source.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/perfetto/tracing/data_source.h')
-rw-r--r--include/perfetto/tracing/data_source.h126
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_