blob: 28e7105f0aec03327b8affb86bd67eed84a275f5 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/fml/trace_event.h"
#include <algorithm>
#include <atomic>
#include <utility>
#include "flutter/fml/ascii_trie.h"
#include "flutter/fml/build_config.h"
#include "flutter/fml/logging.h"
namespace fml {
namespace tracing {
#if FLUTTER_TIMELINE_ENABLED
namespace {
int64_t DefaultMicrosSource() {
return -1;
}
AsciiTrie gAllowlist;
std::atomic<TimelineEventHandler> gTimelineEventHandler;
std::atomic<TimelineMicrosSource> gTimelineMicrosSource = DefaultMicrosSource;
inline void FlutterTimelineEvent(const char* label,
int64_t timestamp0,
int64_t timestamp1_or_async_id,
intptr_t flow_id_count,
const int64_t* flow_ids,
Dart_Timeline_Event_Type type,
intptr_t argument_count,
const char** argument_names,
const char** argument_values) {
TimelineEventHandler handler =
gTimelineEventHandler.load(std::memory_order_relaxed);
if (handler && gAllowlist.Query(label)) {
handler(label, timestamp0, timestamp1_or_async_id, flow_id_count, flow_ids,
type, argument_count, argument_names, argument_values);
}
}
} // namespace
void TraceSetAllowlist(const std::vector<std::string>& allowlist) {
gAllowlist.Fill(allowlist);
}
void TraceSetTimelineEventHandler(TimelineEventHandler handler) {
gTimelineEventHandler = handler;
}
bool TraceHasTimelineEventHandler() {
return static_cast<bool>(
gTimelineEventHandler.load(std::memory_order_relaxed));
}
int64_t TraceGetTimelineMicros() {
return gTimelineMicrosSource.load()();
}
void TraceSetTimelineMicrosSource(TimelineMicrosSource source) {
gTimelineMicrosSource = source;
}
size_t TraceNonce() {
static std::atomic_size_t last_item;
return ++last_item;
}
void TraceTimelineEvent(TraceArg category_group,
TraceArg name,
int64_t timestamp_micros,
TraceIDArg identifier,
size_t flow_id_count,
const uint64_t* flow_ids,
Dart_Timeline_Event_Type type,
const std::vector<const char*>& c_names,
const std::vector<std::string>& values) {
const auto argument_count = std::min(c_names.size(), values.size());
std::vector<const char*> c_values;
c_values.resize(argument_count, nullptr);
for (size_t i = 0; i < argument_count; i++) {
c_values[i] = values[i].c_str();
}
FlutterTimelineEvent(
name, // label
timestamp_micros, // timestamp0
identifier, // timestamp1_or_async_id
flow_id_count, // flow_id_count
reinterpret_cast<const int64_t*>(flow_ids), // flow_ids
type, // event type
argument_count, // argument_count
const_cast<const char**>(c_names.data()), // argument_names
c_values.data() // argument_values
);
}
void TraceTimelineEvent(TraceArg category_group,
TraceArg name,
TraceIDArg identifier,
size_t flow_id_count,
const uint64_t* flow_ids,
Dart_Timeline_Event_Type type,
const std::vector<const char*>& c_names,
const std::vector<std::string>& values) {
TraceTimelineEvent(category_group, // group
name, // name
gTimelineMicrosSource.load()(), // timestamp_micros
identifier, // identifier
flow_id_count, // flow_id_count
flow_ids, // flow_ids
type, // type
c_names, // names
values // values
);
}
void TraceEvent0(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids) {
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
0, // timestamp1_or_async_id
flow_id_count, // flow_id_count
reinterpret_cast<const int64_t*>(flow_ids), // flow_ids
Dart_Timeline_Event_Begin, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEvent1(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val) {
const char* arg_names[] = {arg1_name};
const char* arg_values[] = {arg1_val};
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
0, // timestamp1_or_async_id
flow_id_count, // flow_id_count
reinterpret_cast<const int64_t*>(flow_ids), // flow_ids
Dart_Timeline_Event_Begin, // event type
1, // argument_count
arg_names, // argument_names
arg_values // argument_values
);
}
void TraceEvent2(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val,
TraceArg arg2_name,
TraceArg arg2_val) {
const char* arg_names[] = {arg1_name, arg2_name};
const char* arg_values[] = {arg1_val, arg2_val};
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
0, // timestamp1_or_async_id
flow_id_count, // flow_id_count
reinterpret_cast<const int64_t*>(flow_ids), // flow_ids
Dart_Timeline_Event_Begin, // event type
2, // argument_count
arg_names, // argument_names
arg_values // argument_values
);
}
void TraceEventEnd(TraceArg name) {
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
0, // timestamp1_or_async_id
0, // flow_id_count
nullptr, // flow_ids
Dart_Timeline_Event_End, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventAsyncBegin0(TraceArg category_group,
TraceArg name,
TraceIDArg id,
size_t flow_id_count,
const uint64_t* flow_ids) {
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
id, // timestamp1_or_async_id
flow_id_count, // flow_id_count
reinterpret_cast<const int64_t*>(flow_ids), // flow_ids
Dart_Timeline_Event_Async_Begin, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventAsyncEnd0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
id, // timestamp1_or_async_id
0, // flow_id_count
nullptr, // flow_ids
Dart_Timeline_Event_Async_End, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventAsyncBegin1(TraceArg category_group,
TraceArg name,
TraceIDArg id,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val) {
const char* arg_names[] = {arg1_name};
const char* arg_values[] = {arg1_val};
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
id, // timestamp1_or_async_id
flow_id_count, // flow_id_count
reinterpret_cast<const int64_t*>(flow_ids), // flow_ids
Dart_Timeline_Event_Async_Begin, // event type
1, // argument_count
arg_names, // argument_names
arg_values // argument_values
);
}
void TraceEventAsyncEnd1(TraceArg category_group,
TraceArg name,
TraceIDArg id,
TraceArg arg1_name,
TraceArg arg1_val) {
const char* arg_names[] = {arg1_name};
const char* arg_values[] = {arg1_val};
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
id, // timestamp1_or_async_id
0, // flow_id_count
nullptr, // flow_ids
Dart_Timeline_Event_Async_End, // event type
1, // argument_count
arg_names, // argument_names
arg_values // argument_values
);
}
void TraceEventInstant0(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids) {
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
0, // timestamp1_or_async_id
flow_id_count, // flow_id_count
reinterpret_cast<const int64_t*>(flow_ids), // flow_ids
Dart_Timeline_Event_Instant, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventInstant1(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val) {
const char* arg_names[] = {arg1_name};
const char* arg_values[] = {arg1_val};
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
0, // timestamp1_or_async_id
flow_id_count, // flow_id_count
reinterpret_cast<const int64_t*>(flow_ids), // flow_ids
Dart_Timeline_Event_Instant, // event type
1, // argument_count
arg_names, // argument_names
arg_values // argument_values
);
}
void TraceEventInstant2(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val,
TraceArg arg2_name,
TraceArg arg2_val) {
const char* arg_names[] = {arg1_name, arg2_name};
const char* arg_values[] = {arg1_val, arg2_val};
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
0, // timestamp1_or_async_id
flow_id_count, // flow_id_count
reinterpret_cast<const int64_t*>(flow_ids), // flow_ids
Dart_Timeline_Event_Instant, // event type
2, // argument_count
arg_names, // argument_names
arg_values // argument_values
);
}
void TraceEventFlowBegin0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
id, // timestamp1_or_async_id
0, // flow_id_count
nullptr, // flow_ids
Dart_Timeline_Event_Flow_Begin, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventFlowStep0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
id, // timestamp1_or_async_id
0, // flow_id_count
nullptr, // flow_ids
Dart_Timeline_Event_Flow_Step, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventFlowEnd0(TraceArg category_group, TraceArg name, TraceIDArg id) {
FlutterTimelineEvent(name, // label
gTimelineMicrosSource.load()(), // timestamp0
id, // timestamp1_or_async_id
0, // flow_id_count
nullptr, // flow_ids
Dart_Timeline_Event_Flow_End, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
#else // FLUTTER_TIMELINE_ENABLED
void TraceSetAllowlist(const std::vector<std::string>& allowlist) {}
void TraceSetTimelineEventHandler(TimelineEventHandler handler) {}
bool TraceHasTimelineEventHandler() {
return false;
}
int64_t TraceGetTimelineMicros() {
return -1;
}
void TraceSetTimelineMicrosSource(TimelineMicrosSource source) {}
size_t TraceNonce() {
return 0;
}
void TraceTimelineEvent(TraceArg category_group,
TraceArg name,
int64_t timestamp_micros,
TraceIDArg identifier,
size_t flow_id_count,
const uint64_t* flow_ids,
Dart_Timeline_Event_Type type,
const std::vector<const char*>& c_names,
const std::vector<std::string>& values) {}
void TraceTimelineEvent(TraceArg category_group,
TraceArg name,
TraceIDArg identifier,
size_t flow_id_count,
const uint64_t* flow_ids,
Dart_Timeline_Event_Type type,
const std::vector<const char*>& c_names,
const std::vector<std::string>& values) {}
void TraceEvent0(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids) {}
void TraceEvent1(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val) {}
void TraceEvent2(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val,
TraceArg arg2_name,
TraceArg arg2_val) {}
void TraceEventEnd(TraceArg name) {}
void TraceEventAsyncComplete(TraceArg category_group,
TraceArg name,
TimePoint begin,
TimePoint end) {}
void TraceEventAsyncBegin0(TraceArg category_group,
TraceArg name,
TraceIDArg id,
size_t flow_id_count,
const uint64_t* flow_ids) {}
void TraceEventAsyncEnd0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {}
void TraceEventAsyncBegin1(TraceArg category_group,
TraceArg name,
TraceIDArg id,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val) {}
void TraceEventAsyncEnd1(TraceArg category_group,
TraceArg name,
TraceIDArg id,
TraceArg arg1_name,
TraceArg arg1_val) {}
void TraceEventInstant0(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids) {}
void TraceEventInstant1(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val) {}
void TraceEventInstant2(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val,
TraceArg arg2_name,
TraceArg arg2_val) {}
void TraceEventFlowBegin0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {}
void TraceEventFlowStep0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {}
void TraceEventFlowEnd0(TraceArg category_group, TraceArg name, TraceIDArg id) {
}
#endif // FLUTTER_TIMELINE_ENABLED
} // namespace tracing
} // namespace fml