Merge "TraceProcessor: introduce RefCounted<T>, remove std::shared_ptr"
diff --git a/Android.bp b/Android.bp
index 845d0c4..f3f47ef 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1753,7 +1753,7 @@
":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
":perfetto_src_trace_processor_lib",
":perfetto_src_trace_processor_metatrace",
- ":perfetto_src_trace_processor_metrics_lib",
+ ":perfetto_src_trace_processor_metrics_metrics",
":perfetto_src_trace_processor_sqlite_sqlite",
":perfetto_src_trace_processor_storage_full",
":perfetto_src_trace_processor_storage_minimal",
@@ -1885,7 +1885,7 @@
"perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
- "perfetto_src_trace_processor_metrics_gen_merged_sql_metrics",
+ "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
],
defaults: [
"perfetto_defaults",
@@ -6841,6 +6841,7 @@
name: "perfetto_src_base_base",
srcs: [
"src/base/android_utils.cc",
+ "src/base/base64.cc",
"src/base/crash_keys.cc",
"src/base/ctrl_c_handler.cc",
"src/base/event_fd.cc",
@@ -6887,6 +6888,7 @@
filegroup {
name: "perfetto_src_base_unittests",
srcs: [
+ "src/base/base64_unittest.cc",
"src/base/circular_queue_unittest.cc",
"src/base/flat_set_unittest.cc",
"src/base/getopt_compat_unittest.cc",
@@ -7965,7 +7967,7 @@
],
cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
out: [
- "src/trace_processor/metrics/chrome/all_chrome_metrics.descriptor.h",
+ "src/trace_processor/metrics/all_chrome_metrics.descriptor.h",
],
tool_files: [
"tools/gen_cc_proto_descriptor.py",
@@ -7987,113 +7989,113 @@
],
}
-// GN: //src/trace_processor/metrics:gen_merged_sql_metrics
-genrule {
- name: "perfetto_src_trace_processor_metrics_gen_merged_sql_metrics",
+// GN: //src/trace_processor/metrics:metrics
+filegroup {
+ name: "perfetto_src_trace_processor_metrics_metrics",
srcs: [
- "src/trace_processor/metrics/android/android_batt.sql",
- "src/trace_processor/metrics/android/android_camera.sql",
- "src/trace_processor/metrics/android/android_cpu.sql",
- "src/trace_processor/metrics/android/android_cpu_agg.sql",
- "src/trace_processor/metrics/android/android_cpu_raw_metrics_per_core.sql",
- "src/trace_processor/metrics/android/android_dma_heap.sql",
- "src/trace_processor/metrics/android/android_fastrpc.sql",
- "src/trace_processor/metrics/android/android_gpu.sql",
- "src/trace_processor/metrics/android/android_hwcomposer.sql",
- "src/trace_processor/metrics/android/android_hwui_metric.sql",
- "src/trace_processor/metrics/android/android_hwui_threads.sql",
- "src/trace_processor/metrics/android/android_ion.sql",
- "src/trace_processor/metrics/android/android_jank.sql",
- "src/trace_processor/metrics/android/android_lmk.sql",
- "src/trace_processor/metrics/android/android_lmk_reason.sql",
- "src/trace_processor/metrics/android/android_mem.sql",
- "src/trace_processor/metrics/android/android_mem_unagg.sql",
- "src/trace_processor/metrics/android/android_multiuser.sql",
- "src/trace_processor/metrics/android/android_multiuser_populator.sql",
- "src/trace_processor/metrics/android/android_package_list.sql",
- "src/trace_processor/metrics/android/android_powrails.sql",
- "src/trace_processor/metrics/android/android_proxy_power.sql",
- "src/trace_processor/metrics/android/android_simpleperf.sql",
- "src/trace_processor/metrics/android/android_startup.sql",
- "src/trace_processor/metrics/android/android_surfaceflinger.sql",
- "src/trace_processor/metrics/android/android_sysui_cuj.sql",
- "src/trace_processor/metrics/android/android_sysui_cuj_jank_query.sql",
- "src/trace_processor/metrics/android/android_task_names.sql",
- "src/trace_processor/metrics/android/android_thread_time_in_state.sql",
- "src/trace_processor/metrics/android/android_trace_quality.sql",
- "src/trace_processor/metrics/android/composer_execution.sql",
- "src/trace_processor/metrics/android/composition_layers.sql",
- "src/trace_processor/metrics/android/cpu_info.sql",
- "src/trace_processor/metrics/android/display_metrics.sql",
- "src/trace_processor/metrics/android/frame_missed.sql",
- "src/trace_processor/metrics/android/g2d.sql",
- "src/trace_processor/metrics/android/g2d_duration.sql",
- "src/trace_processor/metrics/android/global_counter_span_view.sql",
- "src/trace_processor/metrics/android/gpu_counter_span_view.sql",
- "src/trace_processor/metrics/android/java_heap_histogram.sql",
- "src/trace_processor/metrics/android/java_heap_stats.sql",
- "src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql",
- "src/trace_processor/metrics/android/power_drain_in_watts.sql",
- "src/trace_processor/metrics/android/power_profile_data.sql",
- "src/trace_processor/metrics/android/process_counter_span_view.sql",
- "src/trace_processor/metrics/android/process_mem.sql",
- "src/trace_processor/metrics/android/process_metadata.sql",
- "src/trace_processor/metrics/android/process_oom_score.sql",
- "src/trace_processor/metrics/android/process_unagg_mem_view.sql",
- "src/trace_processor/metrics/android/profiler_smaps.sql",
- "src/trace_processor/metrics/android/span_view_stats.sql",
- "src/trace_processor/metrics/android/startup/hsc.sql",
- "src/trace_processor/metrics/android/startup/launches.sql",
- "src/trace_processor/metrics/android/thread_counter_span_view.sql",
- "src/trace_processor/metrics/android/unsymbolized_frames.sql",
- "src/trace_processor/metrics/chrome/actual_power_by_category.sql",
- "src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql",
- "src/trace_processor/metrics/chrome/chrome_event_metadata.sql",
- "src/trace_processor/metrics/chrome/chrome_processes.sql",
- "src/trace_processor/metrics/chrome/chrome_thread_slice_with_cpu_time.sql",
- "src/trace_processor/metrics/chrome/cpu_time_by_category.sql",
- "src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql",
- "src/trace_processor/metrics/chrome/estimated_power_by_category.sql",
- "src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql",
- "src/trace_processor/metrics/chrome/gesture_flow_event.sql",
- "src/trace_processor/metrics/chrome/gesture_flow_event_queuing_delay.sql",
- "src/trace_processor/metrics/chrome/gesture_jank.sql",
- "src/trace_processor/metrics/chrome/rail_modes.sql",
- "src/trace_processor/metrics/chrome/scroll_flow_event.sql",
- "src/trace_processor/metrics/chrome/scroll_flow_event_queuing_delay.sql",
- "src/trace_processor/metrics/chrome/scroll_jank.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_task.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_touch_move.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql",
- "src/trace_processor/metrics/chrome/test_chrome_metric.sql",
- "src/trace_processor/metrics/chrome/touch_flow_event.sql",
- "src/trace_processor/metrics/chrome/touch_flow_event_queuing_delay.sql",
- "src/trace_processor/metrics/chrome/touch_jank.sql",
- "src/trace_processor/metrics/experimental/blink_gc_metric.sql",
- "src/trace_processor/metrics/experimental/chrome_dropped_frames.sql",
- "src/trace_processor/metrics/experimental/frame_times.sql",
- "src/trace_processor/metrics/experimental/media_metric.sql",
- "src/trace_processor/metrics/experimental/reported_by_page.sql",
- "src/trace_processor/metrics/trace_metadata.sql",
- "src/trace_processor/metrics/trace_stats.sql",
- "src/trace_processor/metrics/webview/webview_power_usage.sql",
- ],
- cmd: "$(location tools/gen_merged_sql_metrics.py) --cpp_out=$(out) $(in)",
- out: [
- "src/trace_processor/metrics/sql_metrics.h",
- ],
- tool_files: [
- "tools/gen_merged_sql_metrics.py",
+ "src/trace_processor/metrics/metrics.cc",
],
}
-// GN: //src/trace_processor/metrics:lib
-filegroup {
- name: "perfetto_src_trace_processor_metrics_lib",
+// GN: //src/trace_processor/metrics/sql:gen_amalgamated_sql_metrics
+genrule {
+ name: "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
srcs: [
- "src/trace_processor/metrics/metrics.cc",
+ "src/trace_processor/metrics/sql/android/android_batt.sql",
+ "src/trace_processor/metrics/sql/android/android_camera.sql",
+ "src/trace_processor/metrics/sql/android/android_cpu.sql",
+ "src/trace_processor/metrics/sql/android/android_cpu_agg.sql",
+ "src/trace_processor/metrics/sql/android/android_cpu_raw_metrics_per_core.sql",
+ "src/trace_processor/metrics/sql/android/android_dma_heap.sql",
+ "src/trace_processor/metrics/sql/android/android_fastrpc.sql",
+ "src/trace_processor/metrics/sql/android/android_gpu.sql",
+ "src/trace_processor/metrics/sql/android/android_hwcomposer.sql",
+ "src/trace_processor/metrics/sql/android/android_hwui_metric.sql",
+ "src/trace_processor/metrics/sql/android/android_hwui_threads.sql",
+ "src/trace_processor/metrics/sql/android/android_ion.sql",
+ "src/trace_processor/metrics/sql/android/android_jank.sql",
+ "src/trace_processor/metrics/sql/android/android_lmk.sql",
+ "src/trace_processor/metrics/sql/android/android_lmk_reason.sql",
+ "src/trace_processor/metrics/sql/android/android_mem.sql",
+ "src/trace_processor/metrics/sql/android/android_mem_unagg.sql",
+ "src/trace_processor/metrics/sql/android/android_multiuser.sql",
+ "src/trace_processor/metrics/sql/android/android_multiuser_populator.sql",
+ "src/trace_processor/metrics/sql/android/android_package_list.sql",
+ "src/trace_processor/metrics/sql/android/android_powrails.sql",
+ "src/trace_processor/metrics/sql/android/android_proxy_power.sql",
+ "src/trace_processor/metrics/sql/android/android_simpleperf.sql",
+ "src/trace_processor/metrics/sql/android/android_startup.sql",
+ "src/trace_processor/metrics/sql/android/android_surfaceflinger.sql",
+ "src/trace_processor/metrics/sql/android/android_sysui_cuj.sql",
+ "src/trace_processor/metrics/sql/android/android_sysui_cuj_jank_query.sql",
+ "src/trace_processor/metrics/sql/android/android_task_names.sql",
+ "src/trace_processor/metrics/sql/android/android_thread_time_in_state.sql",
+ "src/trace_processor/metrics/sql/android/android_trace_quality.sql",
+ "src/trace_processor/metrics/sql/android/composer_execution.sql",
+ "src/trace_processor/metrics/sql/android/composition_layers.sql",
+ "src/trace_processor/metrics/sql/android/cpu_info.sql",
+ "src/trace_processor/metrics/sql/android/display_metrics.sql",
+ "src/trace_processor/metrics/sql/android/frame_missed.sql",
+ "src/trace_processor/metrics/sql/android/g2d.sql",
+ "src/trace_processor/metrics/sql/android/g2d_duration.sql",
+ "src/trace_processor/metrics/sql/android/global_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/gpu_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/java_heap_histogram.sql",
+ "src/trace_processor/metrics/sql/android/java_heap_stats.sql",
+ "src/trace_processor/metrics/sql/android/mem_stats_priority_breakdown.sql",
+ "src/trace_processor/metrics/sql/android/power_drain_in_watts.sql",
+ "src/trace_processor/metrics/sql/android/power_profile_data.sql",
+ "src/trace_processor/metrics/sql/android/process_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/process_mem.sql",
+ "src/trace_processor/metrics/sql/android/process_metadata.sql",
+ "src/trace_processor/metrics/sql/android/process_oom_score.sql",
+ "src/trace_processor/metrics/sql/android/process_unagg_mem_view.sql",
+ "src/trace_processor/metrics/sql/android/profiler_smaps.sql",
+ "src/trace_processor/metrics/sql/android/span_view_stats.sql",
+ "src/trace_processor/metrics/sql/android/startup/hsc.sql",
+ "src/trace_processor/metrics/sql/android/startup/launches.sql",
+ "src/trace_processor/metrics/sql/android/thread_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/unsymbolized_frames.sql",
+ "src/trace_processor/metrics/sql/chrome/actual_power_by_category.sql",
+ "src/trace_processor/metrics/sql/chrome/actual_power_by_rail_mode.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_event_metadata.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_processes.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_thread_slice_with_cpu_time.sql",
+ "src/trace_processor/metrics/sql/chrome/cpu_time_by_category.sql",
+ "src/trace_processor/metrics/sql/chrome/cpu_time_by_rail_mode.sql",
+ "src/trace_processor/metrics/sql/chrome/estimated_power_by_category.sql",
+ "src/trace_processor/metrics/sql/chrome/estimated_power_by_rail_mode.sql",
+ "src/trace_processor/metrics/sql/chrome/gesture_flow_event.sql",
+ "src/trace_processor/metrics/sql/chrome/gesture_flow_event_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/gesture_jank.sql",
+ "src/trace_processor/metrics/sql/chrome/rail_modes.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_flow_event.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_flow_event_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_task.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_touch_move.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_get_bitmap.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/test_chrome_metric.sql",
+ "src/trace_processor/metrics/sql/chrome/touch_flow_event.sql",
+ "src/trace_processor/metrics/sql/chrome/touch_flow_event_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/touch_jank.sql",
+ "src/trace_processor/metrics/sql/experimental/blink_gc_metric.sql",
+ "src/trace_processor/metrics/sql/experimental/chrome_dropped_frames.sql",
+ "src/trace_processor/metrics/sql/experimental/frame_times.sql",
+ "src/trace_processor/metrics/sql/experimental/media_metric.sql",
+ "src/trace_processor/metrics/sql/experimental/reported_by_page.sql",
+ "src/trace_processor/metrics/sql/trace_metadata.sql",
+ "src/trace_processor/metrics/sql/trace_stats.sql",
+ "src/trace_processor/metrics/sql/webview/webview_power_usage.sql",
+ ],
+ cmd: "$(location tools/gen_amalgamated_sql_metrics.py) --cpp_out=$(out) $(in)",
+ out: [
+ "src/trace_processor/metrics/sql/amalgamated_sql_metrics.h",
+ ],
+ tool_files: [
+ "tools/gen_amalgamated_sql_metrics.py",
],
}
@@ -8134,6 +8136,7 @@
filegroup {
name: "perfetto_src_trace_processor_sqlite_sqlite",
srcs: [
+ "src/trace_processor/sqlite/create_function.cc",
"src/trace_processor/sqlite/db_sqlite_table.cc",
"src/trace_processor/sqlite/query_constraints.cc",
"src/trace_processor/sqlite/register_function.cc",
@@ -9343,7 +9346,7 @@
":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
":perfetto_src_trace_processor_lib",
":perfetto_src_trace_processor_metatrace",
- ":perfetto_src_trace_processor_metrics_lib",
+ ":perfetto_src_trace_processor_metrics_metrics",
":perfetto_src_trace_processor_metrics_unittests",
":perfetto_src_trace_processor_rpc_rpc",
":perfetto_src_trace_processor_rpc_unittests",
@@ -9535,7 +9538,7 @@
"perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
- "perfetto_src_trace_processor_metrics_gen_merged_sql_metrics",
+ "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
"perfetto_src_traced_probes_ftrace_test_messages_cpp_gen_headers",
"perfetto_src_traced_probes_ftrace_test_messages_lite_gen_headers",
"perfetto_src_traced_probes_ftrace_test_messages_zero_gen_headers",
@@ -9643,7 +9646,7 @@
":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
":perfetto_src_trace_processor_lib",
":perfetto_src_trace_processor_metatrace",
- ":perfetto_src_trace_processor_metrics_lib",
+ ":perfetto_src_trace_processor_metrics_metrics",
":perfetto_src_trace_processor_rpc_httpd",
":perfetto_src_trace_processor_rpc_rpc",
":perfetto_src_trace_processor_sqlite_sqlite",
@@ -9698,7 +9701,7 @@
"perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
- "perfetto_src_trace_processor_metrics_gen_merged_sql_metrics",
+ "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
],
defaults: [
"perfetto_defaults",
@@ -9797,7 +9800,7 @@
":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
":perfetto_src_trace_processor_lib",
":perfetto_src_trace_processor_metatrace",
- ":perfetto_src_trace_processor_metrics_lib",
+ ":perfetto_src_trace_processor_metrics_metrics",
":perfetto_src_trace_processor_sqlite_sqlite",
":perfetto_src_trace_processor_storage_full",
":perfetto_src_trace_processor_storage_minimal",
@@ -9857,7 +9860,7 @@
"perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
- "perfetto_src_trace_processor_metrics_gen_merged_sql_metrics",
+ "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
"perfetto_tools_trace_to_text_gen_cc_trace_descriptor",
],
defaults: [
diff --git a/BUILD b/BUILD
index a5ef32c..10d6905 100644
--- a/BUILD
+++ b/BUILD
@@ -335,6 +335,7 @@
name = "include_perfetto_ext_base_base",
srcs = [
"include/perfetto/ext/base/android_utils.h",
+ "include/perfetto/ext/base/base64.h",
"include/perfetto/ext/base/circular_queue.h",
"include/perfetto/ext/base/container_annotations.h",
"include/perfetto/ext/base/crash_keys.h",
@@ -643,6 +644,7 @@
name = "src_base_base",
srcs = [
"src/base/android_utils.cc",
+ "src/base/base64.cc",
"src/base/crash_keys.cc",
"src/base/ctrl_c_handler.cc",
"src/base/event_fd.cc",
@@ -998,13 +1000,114 @@
],
)
+perfetto_genrule(
+ name = "src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ srcs = [
+ "src/trace_processor/metrics/sql/android/android_batt.sql",
+ "src/trace_processor/metrics/sql/android/android_camera.sql",
+ "src/trace_processor/metrics/sql/android/android_cpu.sql",
+ "src/trace_processor/metrics/sql/android/android_cpu_agg.sql",
+ "src/trace_processor/metrics/sql/android/android_cpu_raw_metrics_per_core.sql",
+ "src/trace_processor/metrics/sql/android/android_dma_heap.sql",
+ "src/trace_processor/metrics/sql/android/android_fastrpc.sql",
+ "src/trace_processor/metrics/sql/android/android_gpu.sql",
+ "src/trace_processor/metrics/sql/android/android_hwcomposer.sql",
+ "src/trace_processor/metrics/sql/android/android_hwui_metric.sql",
+ "src/trace_processor/metrics/sql/android/android_hwui_threads.sql",
+ "src/trace_processor/metrics/sql/android/android_ion.sql",
+ "src/trace_processor/metrics/sql/android/android_jank.sql",
+ "src/trace_processor/metrics/sql/android/android_lmk.sql",
+ "src/trace_processor/metrics/sql/android/android_lmk_reason.sql",
+ "src/trace_processor/metrics/sql/android/android_mem.sql",
+ "src/trace_processor/metrics/sql/android/android_mem_unagg.sql",
+ "src/trace_processor/metrics/sql/android/android_multiuser.sql",
+ "src/trace_processor/metrics/sql/android/android_multiuser_populator.sql",
+ "src/trace_processor/metrics/sql/android/android_package_list.sql",
+ "src/trace_processor/metrics/sql/android/android_powrails.sql",
+ "src/trace_processor/metrics/sql/android/android_proxy_power.sql",
+ "src/trace_processor/metrics/sql/android/android_simpleperf.sql",
+ "src/trace_processor/metrics/sql/android/android_startup.sql",
+ "src/trace_processor/metrics/sql/android/android_surfaceflinger.sql",
+ "src/trace_processor/metrics/sql/android/android_sysui_cuj.sql",
+ "src/trace_processor/metrics/sql/android/android_sysui_cuj_jank_query.sql",
+ "src/trace_processor/metrics/sql/android/android_task_names.sql",
+ "src/trace_processor/metrics/sql/android/android_thread_time_in_state.sql",
+ "src/trace_processor/metrics/sql/android/android_trace_quality.sql",
+ "src/trace_processor/metrics/sql/android/composer_execution.sql",
+ "src/trace_processor/metrics/sql/android/composition_layers.sql",
+ "src/trace_processor/metrics/sql/android/cpu_info.sql",
+ "src/trace_processor/metrics/sql/android/display_metrics.sql",
+ "src/trace_processor/metrics/sql/android/frame_missed.sql",
+ "src/trace_processor/metrics/sql/android/g2d.sql",
+ "src/trace_processor/metrics/sql/android/g2d_duration.sql",
+ "src/trace_processor/metrics/sql/android/global_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/gpu_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/java_heap_histogram.sql",
+ "src/trace_processor/metrics/sql/android/java_heap_stats.sql",
+ "src/trace_processor/metrics/sql/android/mem_stats_priority_breakdown.sql",
+ "src/trace_processor/metrics/sql/android/power_drain_in_watts.sql",
+ "src/trace_processor/metrics/sql/android/power_profile_data.sql",
+ "src/trace_processor/metrics/sql/android/process_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/process_mem.sql",
+ "src/trace_processor/metrics/sql/android/process_metadata.sql",
+ "src/trace_processor/metrics/sql/android/process_oom_score.sql",
+ "src/trace_processor/metrics/sql/android/process_unagg_mem_view.sql",
+ "src/trace_processor/metrics/sql/android/profiler_smaps.sql",
+ "src/trace_processor/metrics/sql/android/span_view_stats.sql",
+ "src/trace_processor/metrics/sql/android/startup/hsc.sql",
+ "src/trace_processor/metrics/sql/android/startup/launches.sql",
+ "src/trace_processor/metrics/sql/android/thread_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/unsymbolized_frames.sql",
+ "src/trace_processor/metrics/sql/chrome/actual_power_by_category.sql",
+ "src/trace_processor/metrics/sql/chrome/actual_power_by_rail_mode.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_event_metadata.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_processes.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_thread_slice_with_cpu_time.sql",
+ "src/trace_processor/metrics/sql/chrome/cpu_time_by_category.sql",
+ "src/trace_processor/metrics/sql/chrome/cpu_time_by_rail_mode.sql",
+ "src/trace_processor/metrics/sql/chrome/estimated_power_by_category.sql",
+ "src/trace_processor/metrics/sql/chrome/estimated_power_by_rail_mode.sql",
+ "src/trace_processor/metrics/sql/chrome/gesture_flow_event.sql",
+ "src/trace_processor/metrics/sql/chrome/gesture_flow_event_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/gesture_jank.sql",
+ "src/trace_processor/metrics/sql/chrome/rail_modes.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_flow_event.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_flow_event_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_task.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_touch_move.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_get_bitmap.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/test_chrome_metric.sql",
+ "src/trace_processor/metrics/sql/chrome/touch_flow_event.sql",
+ "src/trace_processor/metrics/sql/chrome/touch_flow_event_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/touch_jank.sql",
+ "src/trace_processor/metrics/sql/experimental/blink_gc_metric.sql",
+ "src/trace_processor/metrics/sql/experimental/chrome_dropped_frames.sql",
+ "src/trace_processor/metrics/sql/experimental/frame_times.sql",
+ "src/trace_processor/metrics/sql/experimental/media_metric.sql",
+ "src/trace_processor/metrics/sql/experimental/reported_by_page.sql",
+ "src/trace_processor/metrics/sql/trace_metadata.sql",
+ "src/trace_processor/metrics/sql/trace_stats.sql",
+ "src/trace_processor/metrics/sql/webview/webview_power_usage.sql",
+ ],
+ outs = [
+ "src/trace_processor/metrics/sql/amalgamated_sql_metrics.h",
+ ],
+ cmd = "$(location gen_amalgamated_sql_metrics_py) --cpp_out=$@ $(SRCS)",
+ exec_tools = [
+ ":gen_amalgamated_sql_metrics_py",
+ ],
+)
+
perfetto_cc_proto_descriptor(
name = "src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
deps = [
":protos_perfetto_metrics_chrome_descriptor",
],
outs = [
- "src/trace_processor/metrics/chrome/all_chrome_metrics.descriptor.h",
+ "src/trace_processor/metrics/all_chrome_metrics.descriptor.h",
],
)
@@ -1018,110 +1121,9 @@
],
)
-perfetto_genrule(
- name = "src_trace_processor_metrics_gen_merged_sql_metrics",
- srcs = [
- "src/trace_processor/metrics/android/android_batt.sql",
- "src/trace_processor/metrics/android/android_camera.sql",
- "src/trace_processor/metrics/android/android_cpu.sql",
- "src/trace_processor/metrics/android/android_cpu_agg.sql",
- "src/trace_processor/metrics/android/android_cpu_raw_metrics_per_core.sql",
- "src/trace_processor/metrics/android/android_dma_heap.sql",
- "src/trace_processor/metrics/android/android_fastrpc.sql",
- "src/trace_processor/metrics/android/android_gpu.sql",
- "src/trace_processor/metrics/android/android_hwcomposer.sql",
- "src/trace_processor/metrics/android/android_hwui_metric.sql",
- "src/trace_processor/metrics/android/android_hwui_threads.sql",
- "src/trace_processor/metrics/android/android_ion.sql",
- "src/trace_processor/metrics/android/android_jank.sql",
- "src/trace_processor/metrics/android/android_lmk.sql",
- "src/trace_processor/metrics/android/android_lmk_reason.sql",
- "src/trace_processor/metrics/android/android_mem.sql",
- "src/trace_processor/metrics/android/android_mem_unagg.sql",
- "src/trace_processor/metrics/android/android_multiuser.sql",
- "src/trace_processor/metrics/android/android_multiuser_populator.sql",
- "src/trace_processor/metrics/android/android_package_list.sql",
- "src/trace_processor/metrics/android/android_powrails.sql",
- "src/trace_processor/metrics/android/android_proxy_power.sql",
- "src/trace_processor/metrics/android/android_simpleperf.sql",
- "src/trace_processor/metrics/android/android_startup.sql",
- "src/trace_processor/metrics/android/android_surfaceflinger.sql",
- "src/trace_processor/metrics/android/android_sysui_cuj.sql",
- "src/trace_processor/metrics/android/android_sysui_cuj_jank_query.sql",
- "src/trace_processor/metrics/android/android_task_names.sql",
- "src/trace_processor/metrics/android/android_thread_time_in_state.sql",
- "src/trace_processor/metrics/android/android_trace_quality.sql",
- "src/trace_processor/metrics/android/composer_execution.sql",
- "src/trace_processor/metrics/android/composition_layers.sql",
- "src/trace_processor/metrics/android/cpu_info.sql",
- "src/trace_processor/metrics/android/display_metrics.sql",
- "src/trace_processor/metrics/android/frame_missed.sql",
- "src/trace_processor/metrics/android/g2d.sql",
- "src/trace_processor/metrics/android/g2d_duration.sql",
- "src/trace_processor/metrics/android/global_counter_span_view.sql",
- "src/trace_processor/metrics/android/gpu_counter_span_view.sql",
- "src/trace_processor/metrics/android/java_heap_histogram.sql",
- "src/trace_processor/metrics/android/java_heap_stats.sql",
- "src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql",
- "src/trace_processor/metrics/android/power_drain_in_watts.sql",
- "src/trace_processor/metrics/android/power_profile_data.sql",
- "src/trace_processor/metrics/android/process_counter_span_view.sql",
- "src/trace_processor/metrics/android/process_mem.sql",
- "src/trace_processor/metrics/android/process_metadata.sql",
- "src/trace_processor/metrics/android/process_oom_score.sql",
- "src/trace_processor/metrics/android/process_unagg_mem_view.sql",
- "src/trace_processor/metrics/android/profiler_smaps.sql",
- "src/trace_processor/metrics/android/span_view_stats.sql",
- "src/trace_processor/metrics/android/startup/hsc.sql",
- "src/trace_processor/metrics/android/startup/launches.sql",
- "src/trace_processor/metrics/android/thread_counter_span_view.sql",
- "src/trace_processor/metrics/android/unsymbolized_frames.sql",
- "src/trace_processor/metrics/chrome/actual_power_by_category.sql",
- "src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql",
- "src/trace_processor/metrics/chrome/chrome_event_metadata.sql",
- "src/trace_processor/metrics/chrome/chrome_processes.sql",
- "src/trace_processor/metrics/chrome/chrome_thread_slice_with_cpu_time.sql",
- "src/trace_processor/metrics/chrome/cpu_time_by_category.sql",
- "src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql",
- "src/trace_processor/metrics/chrome/estimated_power_by_category.sql",
- "src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql",
- "src/trace_processor/metrics/chrome/gesture_flow_event.sql",
- "src/trace_processor/metrics/chrome/gesture_flow_event_queuing_delay.sql",
- "src/trace_processor/metrics/chrome/gesture_jank.sql",
- "src/trace_processor/metrics/chrome/rail_modes.sql",
- "src/trace_processor/metrics/chrome/scroll_flow_event.sql",
- "src/trace_processor/metrics/chrome/scroll_flow_event_queuing_delay.sql",
- "src/trace_processor/metrics/chrome/scroll_jank.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_task.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_touch_move.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql",
- "src/trace_processor/metrics/chrome/test_chrome_metric.sql",
- "src/trace_processor/metrics/chrome/touch_flow_event.sql",
- "src/trace_processor/metrics/chrome/touch_flow_event_queuing_delay.sql",
- "src/trace_processor/metrics/chrome/touch_jank.sql",
- "src/trace_processor/metrics/experimental/blink_gc_metric.sql",
- "src/trace_processor/metrics/experimental/chrome_dropped_frames.sql",
- "src/trace_processor/metrics/experimental/frame_times.sql",
- "src/trace_processor/metrics/experimental/media_metric.sql",
- "src/trace_processor/metrics/experimental/reported_by_page.sql",
- "src/trace_processor/metrics/trace_metadata.sql",
- "src/trace_processor/metrics/trace_stats.sql",
- "src/trace_processor/metrics/webview/webview_power_usage.sql",
- ],
- outs = [
- "src/trace_processor/metrics/sql_metrics.h",
- ],
- cmd = "$(location gen_merged_sql_metrics_py) --cpp_out=$@ $(SRCS)",
- exec_tools = [
- ":gen_merged_sql_metrics_py",
- ],
-)
-
-# GN target: //src/trace_processor/metrics:lib
+# GN target: //src/trace_processor/metrics:metrics
perfetto_filegroup(
- name = "src_trace_processor_metrics_lib",
+ name = "src_trace_processor_metrics_metrics",
srcs = [
"src/trace_processor/metrics/metrics.cc",
"src/trace_processor/metrics/metrics.h",
@@ -1152,6 +1154,8 @@
perfetto_filegroup(
name = "src_trace_processor_sqlite_sqlite",
srcs = [
+ "src/trace_processor/sqlite/create_function.cc",
+ "src/trace_processor/sqlite/create_function.h",
"src/trace_processor/sqlite/db_sqlite_table.cc",
"src/trace_processor/sqlite/db_sqlite_table.h",
"src/trace_processor/sqlite/query_cache.h",
@@ -3681,7 +3685,7 @@
":src_trace_processor_importers_memory_tracker_graph_processor",
":src_trace_processor_lib",
":src_trace_processor_metatrace",
- ":src_trace_processor_metrics_lib",
+ ":src_trace_processor_metrics_metrics",
":src_trace_processor_sqlite_sqlite",
":src_trace_processor_storage_full",
":src_trace_processor_storage_minimal",
@@ -3750,7 +3754,7 @@
PERFETTO_CONFIG.deps.sqlite +
PERFETTO_CONFIG.deps.sqlite_ext_percentile +
PERFETTO_CONFIG.deps.zlib + [
- ":cc_merged_sql_metrics",
+ ":cc_amalgamated_sql_metrics",
],
linkstatic = True,
)
@@ -3780,7 +3784,7 @@
":src_trace_processor_importers_memory_tracker_graph_processor",
":src_trace_processor_lib",
":src_trace_processor_metatrace",
- ":src_trace_processor_metrics_lib",
+ ":src_trace_processor_metrics_metrics",
":src_trace_processor_rpc_httpd",
":src_trace_processor_rpc_rpc",
":src_trace_processor_sqlite_sqlite",
@@ -3847,7 +3851,7 @@
PERFETTO_CONFIG.deps.sqlite +
PERFETTO_CONFIG.deps.sqlite_ext_percentile +
PERFETTO_CONFIG.deps.zlib + [
- ":cc_merged_sql_metrics",
+ ":cc_amalgamated_sql_metrics",
],
)
@@ -3964,7 +3968,7 @@
":src_trace_processor_importers_memory_tracker_graph_processor",
":src_trace_processor_lib",
":src_trace_processor_metatrace",
- ":src_trace_processor_metrics_lib",
+ ":src_trace_processor_metrics_metrics",
":src_trace_processor_sqlite_sqlite",
":src_trace_processor_storage_full",
":src_trace_processor_storage_minimal",
@@ -4030,7 +4034,7 @@
PERFETTO_CONFIG.deps.sqlite +
PERFETTO_CONFIG.deps.sqlite_ext_percentile +
PERFETTO_CONFIG.deps.zlib + [
- ":cc_merged_sql_metrics",
+ ":cc_amalgamated_sql_metrics",
],
)
@@ -4047,16 +4051,16 @@
)
perfetto_cc_library(
- name = "cc_merged_sql_metrics",
- hdrs = ["src/trace_processor/metrics/sql_metrics.h"],
+ name = "cc_amalgamated_sql_metrics",
+ hdrs = ["src/trace_processor/metrics/sql/amalgamated_sql_metrics.h"],
)
perfetto_py_binary(
- name = "gen_merged_sql_metrics_py",
+ name = "gen_amalgamated_sql_metrics_py",
srcs = [
- "tools/gen_merged_sql_metrics.py",
+ "tools/gen_amalgamated_sql_metrics.py",
],
- main = "tools/gen_merged_sql_metrics.py",
+ main = "tools/gen_amalgamated_sql_metrics.py",
python_version = "PY3",
)
diff --git a/BUILD.extras b/BUILD.extras
index e546216..28bec08 100644
--- a/BUILD.extras
+++ b/BUILD.extras
@@ -9,16 +9,16 @@
)
perfetto_cc_library(
- name = "cc_merged_sql_metrics",
- hdrs = ["src/trace_processor/metrics/sql_metrics.h"],
+ name = "cc_amalgamated_sql_metrics",
+ hdrs = ["src/trace_processor/metrics/sql/amalgamated_sql_metrics.h"],
)
perfetto_py_binary(
- name = "gen_merged_sql_metrics_py",
+ name = "gen_amalgamated_sql_metrics_py",
srcs = [
- "tools/gen_merged_sql_metrics.py",
+ "tools/gen_amalgamated_sql_metrics.py",
],
- main = "tools/gen_merged_sql_metrics.py",
+ main = "tools/gen_amalgamated_sql_metrics.py",
python_version = "PY3",
)
diff --git a/CHANGELOG b/CHANGELOG
index 8718f0c..e316684 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,8 @@
This behavior affects only standalone builds and can be changed by setting
enable_perfetto_x64_cpu_opt=false in the GN args.
Trace Processor:
+ * Changed LIKE comparisions to be case-senstive. This may break existing
+ queries but was a necessary from a performance perspective.
* Changed compiler flags, assume recent x64 CPUs (see above).
UI:
*
diff --git a/docs/analysis/metrics.md b/docs/analysis/metrics.md
index d5c181c..9e14b89 100644
--- a/docs/analysis/metrics.md
+++ b/docs/analysis/metrics.md
@@ -90,6 +90,55 @@
There are several useful helpers functions which are available when writing a metric.
+### CREATE_FUNCTION.
+`CREATE_FUNCTION` allows you to define a parameterized SQL statement which
+is executable as a function. The inspiration from this function is the
+`CREATE FUNCTION` syntax which is available in other SQL engines (e.g.
+[Postgres](https://www.postgresql.org/docs/current/sql-createfunction.html)).
+
+NOTE: CREATE_FUNCTION only supports returning *exactly* a single value (i.e.
+single row and single column). For returning multiple a single row with
+multiple columns or multiples rows, see `CREATE_VIEW_FUNCTION` instead.
+
+Usage of `CREATE_FUNCTION` is as follows:
+```sql
+-- First, we define the function we'll use in the following statement.
+SELECT CREATE_FUNCTION(
+ -- First argument: prototype of the function; this is very similar to
+ -- function definitions in other languages - you set the function name
+ -- (IS_TS_IN_RANGE in this example) and the arguments
+ -- (ts, begin_ts and end_ts) along with their types (LONG for all
+ -- arguments here).
+ 'IS_TS_IN_RANGE(ts LONG, begin_ts LONG, end_ts LONG)',
+ -- Second argument: the return type of the function. Only single values
+ -- can be returned in CREATE_FUNCTION. See CREATE_VIEW_FUNCTION for defining
+ -- a function returning multiple rows/columns.
+ 'BOOL',
+ -- Third argument: the SQL body of the function. This should always be a
+ -- SELECT statement (even if you're not selecting from a table as in this
+ -- example). Arguments can be accessed by prefixing argument names
+ -- with $ (e.g. $ts, $begin_ts, $end_ts).
+ 'SELECT $ts >= $begin_ts AND $ts <= $end_ts'
+);
+
+-- Now we can actually use the function in queries as if it was any other
+-- function.
+
+-- For example, it can appear in the SELECT to produce a column:
+SELECT ts, IS_TS_IN_RANGE(slice.ts, 100000, 200000) AS in_range
+FROM slice
+
+-- It can also appear in a where clause:
+SELECT ts
+FROM counter
+WHERE IS_TS_IN_RANGE(counter.ts, 100000, 200000) AS in_range
+
+-- It can even appear in a join on clause:
+SELECT slice.ts
+FROM launches
+JOIN slice ON IS_TS_IN_RANGE(slice.ts, launches.ts, launches.end_ts)
+```
+
### RUN_METRIC
`RUN_METRIC` allows you to run another metric file. This allows you to use views
or tables defined in that file without repeatition.
diff --git a/include/perfetto/ext/base/BUILD.gn b/include/perfetto/ext/base/BUILD.gn
index f3b9113..34e09de 100644
--- a/include/perfetto/ext/base/BUILD.gn
+++ b/include/perfetto/ext/base/BUILD.gn
@@ -17,6 +17,7 @@
source_set("base") {
sources = [
"android_utils.h",
+ "base64.h",
"circular_queue.h",
"container_annotations.h",
"crash_keys.h",
diff --git a/include/perfetto/ext/base/base64.h b/include/perfetto/ext/base/base64.h
new file mode 100644
index 0000000..030a83d
--- /dev/null
+++ b/include/perfetto/ext/base/base64.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
+#define INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
+
+#include <string>
+
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/utils.h" // For ssize_t.
+
+namespace perfetto {
+namespace base {
+
+// Returns the length of the destination string (included '=' padding).
+// Does NOT include the size of the string null terminator.
+inline size_t Base64EncSize(size_t src_size) {
+ return (src_size + 2) / 3 * 4;
+}
+
+// Returns the upper bound on the length of the destination buffer.
+// The actual decoded length might be <= the number returned here.
+inline size_t Base64DecSize(size_t src_size) {
+ return (src_size + 3) / 4 * 3;
+}
+
+// Does NOT null-terminate |dst|.
+ssize_t Base64Encode(const void* src,
+ size_t src_size,
+ char* dst,
+ size_t dst_size);
+
+std::string Base64Encode(const void* src, size_t src_size);
+
+inline std::string Base64Encode(StringView sv) {
+ return Base64Encode(sv.data(), sv.size());
+}
+
+// Returns -1 in case of failure.
+ssize_t Base64Decode(const char* src,
+ size_t src_size,
+ uint8_t* dst,
+ size_t dst_size);
+
+Optional<std::string> Base64Decode(const char* src, size_t src_size);
+
+inline Optional<std::string> Base64Decode(StringView sv) {
+ return Base64Decode(sv.data(), sv.size());
+}
+
+} // namespace base
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
diff --git a/include/perfetto/ext/base/circular_queue.h b/include/perfetto/ext/base/circular_queue.h
index 80574c2..82f4394 100644
--- a/include/perfetto/ext/base/circular_queue.h
+++ b/include/perfetto/ext/base/circular_queue.h
@@ -261,11 +261,7 @@
size_t malloc_size = new_capacity * sizeof(T);
PERFETTO_CHECK(malloc_size > new_capacity);
- void* new_mem = nullptr;
- // posix_memalign() wants at least void* alignment.
- static constexpr size_t alignment = AlignUp<sizeof(void*)>(alignof(T));
- PERFETTO_CHECK(posix_memalign(&new_mem, alignment, malloc_size) == 0);
- T* new_vec = static_cast<T*>(new_mem);
+ T* new_vec = static_cast<T*>(AlignedAlloc(alignof(T), malloc_size));
// Move all elements in the expanded array.
size_t new_size = 0;
diff --git a/include/perfetto/ext/base/string_utils.h b/include/perfetto/ext/base/string_utils.h
index 2508aec..58444a8 100644
--- a/include/perfetto/ext/base/string_utils.h
+++ b/include/perfetto/ext/base/string_utils.h
@@ -125,7 +125,6 @@
const std::string& to_replace,
const std::string& replacement);
std::string TrimLeading(const std::string& str);
-std::string Base64Encode(const void* raw, size_t size);
// A BSD-style strlcpy without the return value.
// Copies at most |dst_size|-1 characters. Unlike strncpy, it always \0
diff --git a/include/perfetto/ext/base/utils.h b/include/perfetto/ext/base/utils.h
index a0aa2aa..cedf0ec 100644
--- a/include/perfetto/ext/base/utils.h
+++ b/include/perfetto/ext/base/utils.h
@@ -109,6 +109,8 @@
return err == EAGAIN || err == EWOULDBLOCK;
}
+void* AlignedAlloc(size_t alignment, size_t size);
+
// setenv(2)-equivalent. Deals with Windows vs Posix discrepancies.
void SetEnv(const std::string& key, const std::string& value);
diff --git a/protos/perfetto/trace/perfetto/perfetto_metatrace.proto b/protos/perfetto/trace/perfetto/perfetto_metatrace.proto
index a7b966c..df33b13 100644
--- a/protos/perfetto/trace/perfetto/perfetto_metatrace.proto
+++ b/protos/perfetto/trace/perfetto/perfetto_metatrace.proto
@@ -35,7 +35,7 @@
}
// Only when using |event_id|.
- optional uint32 event_duration_ns = 3;
+ optional uint64 event_duration_ns = 3;
// Only when using |counter_id|.
optional int32 counter_value = 4;
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 36b2589..1c58fbc 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -7542,7 +7542,7 @@
}
// Only when using |event_id|.
- optional uint32 event_duration_ns = 3;
+ optional uint64 event_duration_ns = 3;
// Only when using |counter_id|.
optional int32 counter_value = 4;
diff --git a/src/base/BUILD.gn b/src/base/BUILD.gn
index 156c98b..f6d86b0 100644
--- a/src/base/BUILD.gn
+++ b/src/base/BUILD.gn
@@ -32,6 +32,7 @@
]
sources = [
"android_utils.cc",
+ "base64.cc",
"crash_keys.cc",
"ctrl_c_handler.cc",
"event_fd.cc",
@@ -159,6 +160,7 @@
]
sources = [
+ "base64_unittest.cc",
"circular_queue_unittest.cc",
"flat_set_unittest.cc",
"getopt_compat_unittest.cc",
diff --git a/src/base/base64.cc b/src/base/base64.cc
new file mode 100644
index 0000000..437ad67
--- /dev/null
+++ b/src/base/base64.cc
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/base64.h"
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+constexpr char kPadding = '=';
+
+constexpr char kEncTable[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static_assert(sizeof(kEncTable) == (1u << 6) + sizeof('\0'), "Bad table size");
+
+// Maps an ASCII character to its 6-bit value. It only contains translations
+// from '+' to 'z'. Supports the standard (+/) and URL-safe (-_) alphabets.
+constexpr uint8_t kX = 0xff; // Value used for invalid characters
+constexpr uint8_t kDecTable[] = {
+ 62, kX, 62, kX, 63, 52, 53, 54, 55, 56, // 00 - 09
+ 57, 58, 59, 60, 61, kX, kX, kX, 0, kX, // 10 - 19
+ kX, kX, 0, 1, 2, 3, 4, 5, 6, 7, // 20 - 29
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, // 30 - 39
+ 18, 19, 20, 21, 22, 23, 24, 25, kX, kX, // 40 - 49
+ kX, kX, 63, kX, 26, 27, 28, 29, 30, 31, // 50 - 59
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, // 60 - 69
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 70 - 79
+};
+constexpr char kMinDecChar = '+';
+constexpr char kMaxDecChar = 'z';
+static_assert(kMaxDecChar - kMinDecChar <= sizeof(kDecTable), "Bad table size");
+
+inline uint8_t DecodeChar(char c) {
+ if (c < kMinDecChar || c > kMaxDecChar)
+ return kX;
+ return kDecTable[c - kMinDecChar];
+}
+
+} // namespace
+
+ssize_t Base64Encode(const void* src,
+ size_t src_size,
+ char* dst,
+ size_t dst_size) {
+ const size_t padded_dst_size = Base64EncSize(src_size);
+ if (dst_size < padded_dst_size)
+ return -1; // Not enough space in output.
+
+ const uint8_t* rd = static_cast<const uint8_t*>(src);
+ const uint8_t* const end = rd + src_size;
+ size_t wr_size = 0;
+ while (rd < end) {
+ uint8_t s[3]{};
+ s[0] = *(rd++);
+ dst[wr_size++] = kEncTable[s[0] >> 2];
+
+ uint8_t carry0 = static_cast<uint8_t>((s[0] & 0x03) << 4);
+ if (PERFETTO_LIKELY(rd < end)) {
+ s[1] = *(rd++);
+ dst[wr_size++] = kEncTable[carry0 | (s[1] >> 4)];
+ } else {
+ dst[wr_size++] = kEncTable[carry0];
+ dst[wr_size++] = kPadding;
+ dst[wr_size++] = kPadding;
+ break;
+ }
+
+ uint8_t carry1 = static_cast<uint8_t>((s[1] & 0x0f) << 2);
+ if (PERFETTO_LIKELY(rd < end)) {
+ s[2] = *(rd++);
+ dst[wr_size++] = kEncTable[carry1 | (s[2] >> 6)];
+ } else {
+ dst[wr_size++] = kEncTable[carry1];
+ dst[wr_size++] = kPadding;
+ break;
+ }
+
+ dst[wr_size++] = kEncTable[s[2] & 0x3f];
+ }
+ PERFETTO_DCHECK(wr_size == padded_dst_size);
+ return static_cast<ssize_t>(padded_dst_size);
+}
+
+std::string Base64Encode(const void* src, size_t src_size) {
+ std::string dst;
+ dst.resize(Base64EncSize(src_size));
+ auto res = Base64Encode(src, src_size, &dst[0], dst.size());
+ PERFETTO_CHECK(res == static_cast<ssize_t>(dst.size()));
+ return dst;
+}
+
+ssize_t Base64Decode(const char* src,
+ size_t src_size,
+ uint8_t* dst,
+ size_t dst_size) {
+ const size_t min_dst_size = Base64DecSize(src_size);
+ if (dst_size < min_dst_size)
+ return -1;
+
+ const char* rd = src;
+ const char* const end = src + src_size;
+ size_t wr_size = 0;
+
+ char s[4]{};
+ while (rd < end) {
+ uint8_t d[4];
+ for (uint32_t j = 0; j < 4; j++) {
+ // Padding is only feasible for the last 2 chars of each group of 4.
+ s[j] = rd < end ? *(rd++) : (j < 2 ? '\0' : kPadding);
+ d[j] = DecodeChar(s[j]);
+ if (d[j] == kX)
+ return -1; // Invalid input char.
+ }
+ dst[wr_size] = static_cast<uint8_t>((d[0] << 2) | (d[1] >> 4));
+ dst[wr_size + 1] = static_cast<uint8_t>((d[1] << 4) | (d[2] >> 2));
+ dst[wr_size + 2] = static_cast<uint8_t>((d[2] << 6) | (d[3]));
+ wr_size += 3;
+ }
+
+ PERFETTO_CHECK(wr_size <= dst_size);
+ wr_size -= (s[3] == kPadding ? 1 : 0) + (s[2] == kPadding ? 1 : 0);
+ return static_cast<ssize_t>(wr_size);
+}
+
+Optional<std::string> Base64Decode(const char* src, size_t src_size) {
+ std::string dst;
+ dst.resize(Base64DecSize(src_size));
+ auto res = Base64Decode(src, src_size, reinterpret_cast<uint8_t*>(&dst[0]),
+ dst.size());
+ if (res < 0)
+ return nullopt; // Decoding error.
+
+ PERFETTO_CHECK(res <= static_cast<ssize_t>(dst.size()));
+ dst.resize(static_cast<size_t>(res));
+ return make_optional(dst);
+}
+
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/base64_unittest.cc b/src/base/base64_unittest.cc
new file mode 100644
index 0000000..fb131d9
--- /dev/null
+++ b/src/base/base64_unittest.cc
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/base64.h"
+
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/utils.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace base {
+namespace {
+
+struct TestPattern {
+ size_t decoded_len;
+ const char* decoded;
+ const char* encoded;
+};
+
+TestPattern kPatterns[] = {
+
+ // Basic bit patterns;
+ // values obtained with "echo -n '...' | uuencode -m test"
+
+ {1, "\000", "AA=="},
+ {1, "\001", "AQ=="},
+ {1, "\002", "Ag=="},
+ {1, "\004", "BA=="},
+ {1, "\010", "CA=="},
+ {1, "\020", "EA=="},
+ {1, "\040", "IA=="},
+ {1, "\100", "QA=="},
+ {1, "\200", "gA=="},
+
+ {1, "\377", "/w=="},
+ {1, "\376", "/g=="},
+ {1, "\375", "/Q=="},
+ {1, "\373", "+w=="},
+ {1, "\367", "9w=="},
+ {1, "\357", "7w=="},
+ {1, "\337", "3w=="},
+ {1, "\277", "vw=="},
+ {1, "\177", "fw=="},
+ {2, "\000\000", "AAA="},
+ {2, "\000\001", "AAE="},
+ {2, "\000\002", "AAI="},
+ {2, "\000\004", "AAQ="},
+ {2, "\000\010", "AAg="},
+ {2, "\000\020", "ABA="},
+ {2, "\000\040", "ACA="},
+ {2, "\000\100", "AEA="},
+ {2, "\000\200", "AIA="},
+ {2, "\001\000", "AQA="},
+ {2, "\002\000", "AgA="},
+ {2, "\004\000", "BAA="},
+ {2, "\010\000", "CAA="},
+ {2, "\020\000", "EAA="},
+ {2, "\040\000", "IAA="},
+ {2, "\100\000", "QAA="},
+ {2, "\200\000", "gAA="},
+
+ {2, "\377\377", "//8="},
+ {2, "\377\376", "//4="},
+ {2, "\377\375", "//0="},
+ {2, "\377\373", "//s="},
+ {2, "\377\367", "//c="},
+ {2, "\377\357", "/+8="},
+ {2, "\377\337", "/98="},
+ {2, "\377\277", "/78="},
+ {2, "\377\177", "/38="},
+ {2, "\376\377", "/v8="},
+ {2, "\375\377", "/f8="},
+ {2, "\373\377", "+/8="},
+ {2, "\367\377", "9/8="},
+ {2, "\357\377", "7/8="},
+ {2, "\337\377", "3/8="},
+ {2, "\277\377", "v/8="},
+ {2, "\177\377", "f/8="},
+
+ {3, "\000\000\000", "AAAA"},
+ {3, "\000\000\001", "AAAB"},
+ {3, "\000\000\002", "AAAC"},
+ {3, "\000\000\004", "AAAE"},
+ {3, "\000\000\010", "AAAI"},
+ {3, "\000\000\020", "AAAQ"},
+ {3, "\000\000\040", "AAAg"},
+ {3, "\000\000\100", "AABA"},
+ {3, "\000\000\200", "AACA"},
+ {3, "\000\001\000", "AAEA"},
+ {3, "\000\002\000", "AAIA"},
+ {3, "\000\004\000", "AAQA"},
+ {3, "\000\010\000", "AAgA"},
+ {3, "\000\020\000", "ABAA"},
+ {3, "\000\040\000", "ACAA"},
+ {3, "\000\100\000", "AEAA"},
+ {3, "\000\200\000", "AIAA"},
+ {3, "\001\000\000", "AQAA"},
+ {3, "\002\000\000", "AgAA"},
+ {3, "\004\000\000", "BAAA"},
+ {3, "\010\000\000", "CAAA"},
+ {3, "\020\000\000", "EAAA"},
+ {3, "\040\000\000", "IAAA"},
+ {3, "\100\000\000", "QAAA"},
+ {3, "\200\000\000", "gAAA"},
+
+ {3, "\377\377\377", "////"},
+ {3, "\377\377\376", "///+"},
+ {3, "\377\377\375", "///9"},
+ {3, "\377\377\373", "///7"},
+ {3, "\377\377\367", "///3"},
+ {3, "\377\377\357", "///v"},
+ {3, "\377\377\337", "///f"},
+ {3, "\377\377\277", "//+/"},
+ {3, "\377\377\177", "//9/"},
+ {3, "\377\376\377", "//7/"},
+ {3, "\377\375\377", "//3/"},
+ {3, "\377\373\377", "//v/"},
+ {3, "\377\367\377", "//f/"},
+ {3, "\377\357\377", "/+//"},
+ {3, "\377\337\377", "/9//"},
+ {3, "\377\277\377", "/7//"},
+ {3, "\377\177\377", "/3//"},
+ {3, "\376\377\377", "/v//"},
+ {3, "\375\377\377", "/f//"},
+ {3, "\373\377\377", "+///"},
+ {3, "\367\377\377", "9///"},
+ {3, "\357\377\377", "7///"},
+ {3, "\337\377\377", "3///"},
+ {3, "\277\377\377", "v///"},
+ {3, "\177\377\377", "f///"},
+
+ // Random numbers: values obtained with
+ //
+ // #! /bin/bash
+ // dd bs=$1 count=1 if=/dev/random of=/tmp/bar.random
+ // od -N $1 -t o1 /tmp/bar.random
+ // uuencode -m test < /tmp/bar.random
+ //
+ // where $1 is the number of bytes (2, 3)
+
+ {2, "\243\361", "o/E="},
+ {2, "\024\167", "FHc="},
+ {2, "\313\252", "y6o="},
+ {2, "\046\041", "JiE="},
+ {2, "\145\236", "ZZ4="},
+ {2, "\254\325", "rNU="},
+ {2, "\061\330", "Mdg="},
+ {2, "\245\032", "pRo="},
+ {2, "\006\000", "BgA="},
+ {2, "\375\131", "/Vk="},
+ {2, "\303\210", "w4g="},
+ {2, "\040\037", "IB8="},
+ {2, "\261\372", "sfo="},
+ {2, "\335\014", "3Qw="},
+ {2, "\233\217", "m48="},
+ {2, "\373\056", "+y4="},
+ {2, "\247\232", "p5o="},
+ {2, "\107\053", "Rys="},
+ {2, "\204\077", "hD8="},
+ {2, "\276\211", "vok="},
+ {2, "\313\110", "y0g="},
+ {2, "\363\376", "8/4="},
+ {2, "\251\234", "qZw="},
+ {2, "\103\262", "Q7I="},
+ {2, "\142\312", "Yso="},
+ {2, "\067\211", "N4k="},
+ {2, "\220\001", "kAE="},
+ {2, "\152\240", "aqA="},
+ {2, "\367\061", "9zE="},
+ {2, "\133\255", "W60="},
+ {2, "\176\035", "fh0="},
+ {2, "\032\231", "Gpk="},
+
+ {3, "\013\007\144", "Cwdk"},
+ {3, "\030\112\106", "GEpG"},
+ {3, "\047\325\046", "J9Um"},
+ {3, "\310\160\022", "yHAS"},
+ {3, "\131\100\237", "WUCf"},
+ {3, "\064\342\134", "NOJc"},
+ {3, "\010\177\004", "CH8E"},
+ {3, "\345\147\205", "5WeF"},
+ {3, "\300\343\360", "wOPw"},
+ {3, "\061\240\201", "MaCB"},
+ {3, "\225\333\044", "ldsk"},
+ {3, "\215\137\352", "jV/q"},
+ {3, "\371\147\160", "+Wdw"},
+ {3, "\030\320\051", "GNAp"},
+ {3, "\044\174\241", "JHyh"},
+ {3, "\260\127\037", "sFcf"},
+ {3, "\111\045\033", "SSUb"},
+ {3, "\202\114\107", "gkxH"},
+ {3, "\057\371\042", "L/ki"},
+ {3, "\223\247\244", "k6ek"},
+ {3, "\047\216\144", "J45k"},
+ {3, "\203\070\327", "gzjX"},
+ {3, "\247\140\072", "p2A6"},
+ {3, "\124\115\116", "VE1O"},
+ {3, "\157\162\050", "b3Io"},
+ {3, "\357\223\004", "75ME"},
+ {3, "\052\117\156", "Kk9u"},
+ {3, "\347\154\000", "52wA"},
+ {3, "\303\012\142", "wwpi"},
+ {3, "\060\035\362", "MB3y"},
+ {3, "\130\226\361", "WJbx"},
+ {3, "\173\013\071", "ews5"},
+ {3, "\336\004\027", "3gQX"},
+ {3, "\357\366\234", "7/ac"},
+ {3, "\353\304\111", "68RJ"},
+ {3, "\024\264\131", "FLRZ"},
+ {3, "\075\114\251", "PUyp"},
+ {3, "\315\031\225", "zRmV"},
+ {3, "\154\201\276", "bIG+"},
+ {3, "\200\066\072", "gDY6"},
+ {3, "\142\350\267", "Yui3"},
+ {3, "\033\000\166", "GwB2"},
+ {3, "\210\055\077", "iC0/"},
+ {3, "\341\037\124", "4R9U"},
+ {3, "\161\103\152", "cUNq"},
+ {3, "\270\142\131", "uGJZ"},
+ {3, "\337\076\074", "3z48"},
+ {3, "\375\106\362", "/Uby"},
+ {3, "\227\301\127", "l8FX"},
+ {3, "\340\002\234", "4AKc"},
+ {3, "\121\064\033", "UTQb"},
+ {3, "\157\134\143", "b1xj"},
+ {3, "\247\055\327", "py3X"},
+ {3, "\340\142\005", "4GIF"},
+ {3, "\060\260\143", "MLBj"},
+ {3, "\075\203\170", "PYN4"},
+ {3, "\143\160\016", "Y3AO"},
+ {3, "\313\013\063", "ywsz"},
+ {3, "\174\236\135", "fJ5d"},
+ {3, "\103\047\026", "QycW"},
+ {3, "\365\005\343", "9QXj"},
+ {3, "\271\160\223", "uXCT"},
+ {3, "\362\255\172", "8q16"},
+ {3, "\113\012\015", "SwoN"},
+
+ // various lengths, generated by this python script:
+ //
+ // from string import lowercase as lc
+ // for i in range(27):
+ // print '{ %2d, "%s",%s "%s" },' % (i, lc[:i], ' ' * (26-i),
+ // lc[:i].encode('base64').strip())
+
+ {0, "abcdefghijklmnopqrstuvwxyz", ""},
+ {1, "abcdefghijklmnopqrstuvwxyz", "YQ=="},
+ {2, "abcdefghijklmnopqrstuvwxyz", "YWI="},
+ {3, "abcdefghijklmnopqrstuvwxyz", "YWJj"},
+ {4, "abcdefghijklmnopqrstuvwxyz", "YWJjZA=="},
+ {5, "abcdefghijklmnopqrstuvwxyz", "YWJjZGU="},
+ {6, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVm"},
+ {7, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZw=="},
+ {8, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2g="},
+ {9, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hp"},
+ {10, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpag=="},
+ {11, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpams="},
+ {12, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamts"},
+ {13, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbQ=="},
+ {14, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW4="},
+ {15, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5v"},
+ {16, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcA=="},
+ {17, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHE="},
+ {18, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFy"},
+ {19, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFycw=="},
+ {20, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3Q="},
+ {21, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1"},
+ {22, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dg=="},
+ {23, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnc="},
+ {24, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4"},
+ {25, "abcdefghijklmnopqrstuvwxy", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eQ=="},
+ {26, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo="},
+};
+
+TEST(Base64Test, Encode) {
+ EXPECT_EQ(Base64Encode(""), "");
+ EXPECT_EQ(Base64Encode("f"), "Zg==");
+ EXPECT_EQ(Base64Encode("fo"), "Zm8=");
+ EXPECT_EQ(Base64Encode("foo"), "Zm9v");
+ EXPECT_EQ(Base64Encode("foob"), "Zm9vYg==");
+ EXPECT_EQ(Base64Encode("fooba"), "Zm9vYmE=");
+ EXPECT_EQ(Base64Encode("foobar"), "Zm9vYmFy");
+ EXPECT_EQ(Base64Encode("\xff"), "/w==");
+ EXPECT_EQ(Base64Encode("\xff\xfe"), "//4=");
+ EXPECT_EQ(Base64Encode("\xff\xfe\xfd"), "//79");
+ EXPECT_EQ(Base64Encode("\xff\xfe\xfd\xfc"), "//79/A==");
+
+ for (size_t i = 0; i < ArraySize(kPatterns); ++i) {
+ const auto& p = kPatterns[i];
+ std::string res = Base64Encode(StringView(p.decoded, p.decoded_len));
+ EXPECT_EQ(p.encoded, res);
+ }
+
+ // Error cases
+ char buf[4];
+ EXPECT_EQ(0, Base64Encode("", 0, buf, 0));
+ EXPECT_EQ(0, Base64Encode("", 0, buf, 1));
+ EXPECT_EQ(-1, Base64Encode("a", 1, buf, 0));
+ EXPECT_EQ(-1, Base64Encode("abc", 3, buf, 0));
+ EXPECT_EQ(-1, Base64Encode("abc", 3, buf, 1));
+ EXPECT_EQ(-1, Base64Encode("abc", 3, buf, 3));
+ EXPECT_EQ(4, Base64Encode("abc", 3, buf, 4));
+}
+
+TEST(Base64Test, Decode) {
+ EXPECT_EQ(Base64Decode(""), "");
+ EXPECT_EQ(Base64Decode("Zg=="), "f");
+ EXPECT_EQ(Base64Decode("Zg="), "f");
+ EXPECT_EQ(Base64Decode("Zg"), "f");
+ EXPECT_EQ(Base64Decode("Zm8="), "fo");
+ EXPECT_EQ(Base64Decode("Zm8"), "fo");
+ EXPECT_EQ(Base64Decode("Zm9v"), "foo");
+ EXPECT_EQ(Base64Decode("Zm9vYg=="), "foob");
+ EXPECT_EQ(Base64Decode("Zm9vYg="), "foob");
+ EXPECT_EQ(Base64Decode("Zm9vYg"), "foob");
+ EXPECT_EQ(Base64Decode("Zm9vYmE="), "fooba");
+ EXPECT_EQ(Base64Decode("Zm9vYmE"), "fooba");
+ EXPECT_EQ(Base64Decode("Zm9vYmFy"), "foobar");
+ EXPECT_EQ(Base64Decode("/w=="), "\xff");
+ EXPECT_EQ(Base64Decode("/w="), "\xff");
+ EXPECT_EQ(Base64Decode("/w"), "\xff");
+ EXPECT_EQ(Base64Decode("//4="), "\xff\xfe");
+ EXPECT_EQ(Base64Decode("//4"), "\xff\xfe");
+ EXPECT_EQ(Base64Decode("//79"), "\xff\xfe\xfd");
+ EXPECT_EQ(Base64Decode("//79/A=="), "\xff\xfe\xfd\xfc");
+ EXPECT_EQ(Base64Decode("//79/A="), "\xff\xfe\xfd\xfc");
+ EXPECT_EQ(Base64Decode("//79/A"), "\xff\xfe\xfd\xfc");
+
+ for (size_t i = 0; i < ArraySize(kPatterns); ++i) {
+ const auto& p = kPatterns[i];
+ Optional<std::string> dec = Base64Decode(StringView(p.encoded));
+ EXPECT_TRUE(dec.has_value());
+ EXPECT_EQ(dec.value(), StringView(p.decoded, p.decoded_len).ToStdString());
+ }
+
+ // Error cases:
+ EXPECT_EQ(Base64Decode("Z"), nullopt);
+ EXPECT_EQ(Base64Decode("Zm9vY"), nullopt);
+
+ uint8_t buf[4];
+ EXPECT_EQ(Base64Decode("", 0, buf, 2), 0); // Valid, 0 len.
+ EXPECT_EQ(Base64Decode("Z", 1, buf, 1), -1); // Invalid input.
+ EXPECT_EQ(Base64Decode("Zg==", 4, buf, 1), -1); // Not enough dst space.
+}
+
+} // namespace
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/getopt_compat_unittest.cc b/src/base/getopt_compat_unittest.cc
index aeeb2ed..0ae3721 100644
--- a/src/base/getopt_compat_unittest.cc
+++ b/src/base/getopt_compat_unittest.cc
@@ -113,7 +113,6 @@
sops = "h";
this->SetCmdline({"argv0", "-h"});
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'h');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), -1);
EXPECT_EQ(t.optind, 2);
@@ -137,7 +136,6 @@
sops = "abc";
this->SetCmdline({"argv0", "-c", "-a", "-b"});
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'c');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'a');
EXPECT_EQ(t.optind, 3);
@@ -149,25 +147,19 @@
sops = "abc";
this->SetCmdline({"argv0", "-c", "-a", "--", "nonopt"});
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'c');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'a');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 3);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), -1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 4);
sops = "abc";
this->SetCmdline({"argv0", "-cb"});
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'c');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 1);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'b');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), -1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
sops = "abc";
@@ -232,7 +224,6 @@
const char* sops = "";
this->SetCmdline({"argv0"});
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), -1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 1);
}
@@ -243,7 +234,6 @@
const char* sops = "";
this->SetCmdline({"argv0", "--unknown"});
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), '?');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
}
@@ -256,13 +246,10 @@
const char* sops = "";
this->SetCmdline({"argv0", "--two", "--one"});
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), 2);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), 1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 3);
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), -1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 3);
}
@@ -275,13 +262,10 @@
const char* sops = "";
this->SetCmdline({"argv0", "--two", "--one", "--not-an-opt"});
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), 2);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), 1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 3);
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), '?');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 4);
}
@@ -355,7 +339,6 @@
this->SetCmdline({"argv0"});
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), -1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 1);
this->SetCmdline({"argv0", "-13", "--two", "--three", "--", "--one"});
@@ -393,7 +376,6 @@
const char* sops = "ab:";
this->SetCmdline({"argv0", "-a", "-c", "-b"});
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'a');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), '?');
EXPECT_EQ(t.optopt, 'c');
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), '?');
diff --git a/src/base/string_utils.cc b/src/base/string_utils.cc
index af663b8..5efca77 100644
--- a/src/base/string_utils.cc
+++ b/src/base/string_utils.cc
@@ -33,11 +33,6 @@
namespace perfetto {
namespace base {
-namespace {
-constexpr char kBase64Table[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz0123456789+/";
-}
// Locale-independant as possible version of strtod.
double StrToD(const char* nptr, char** endptr) {
@@ -215,44 +210,6 @@
return idx == std::string::npos ? str : str.substr(idx);
}
-std::string Base64Encode(const void* raw, size_t size) {
- // The following three cases are based on the tables in the example
- // section in https://en.wikipedia.org/wiki/Base64. We process three
- // input bytes at a time, emitting 4 output bytes at a time.
- const uint8_t* ptr = static_cast<const uint8_t*>(raw);
- size_t ii = 0;
-
- std::string out;
- out.reserve((size + 2) * 4 / 3);
-
- // While possible, process three input bytes.
- for (; ii + 3 <= size; ii += 3) {
- uint32_t twentyfour_bits =
- (uint32_t(ptr[ii]) << 16) | (uint32_t(ptr[ii + 1]) << 8) | ptr[ii + 2];
- out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
- out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
- out.push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
- out.push_back(kBase64Table[twentyfour_bits & 0x3f]);
- }
- if (ii + 2 <= size) { // Process two input bytes.
- uint32_t twentyfour_bits =
- (uint32_t(ptr[ii]) << 16) | (uint32_t(ptr[ii + 1]) << 8);
- out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
- out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
- out.push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
- out.push_back('='); // Emit padding.
- return out;
- }
- if (ii + 1 <= size) { // Process a single input byte.
- uint32_t twentyfour_bits = (uint32_t(ptr[ii]) << 16);
- out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
- out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
- out.push_back('='); // Emit padding.
- out.push_back('='); // Emit padding.
- }
- return out;
-}
-
size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...) {
if (PERFETTO_UNLIKELY(dst_size) == 0)
return 0;
diff --git a/src/base/string_utils_unittest.cc b/src/base/string_utils_unittest.cc
index 0787802..39803ff 100644
--- a/src/base/string_utils_unittest.cc
+++ b/src/base/string_utils_unittest.cc
@@ -303,29 +303,6 @@
EXPECT_EQ(TrimLeading(" aaaaa "), "aaaaa ");
}
-TEST(StringUtilsTest, Base64Encode) {
- auto base64_encode = [](const std::string& str) {
- return Base64Encode(str.c_str(), str.size());
- };
-
- EXPECT_EQ(base64_encode(""), "");
- EXPECT_EQ(base64_encode("f"), "Zg==");
- EXPECT_EQ(base64_encode("fo"), "Zm8=");
- EXPECT_EQ(base64_encode("foo"), "Zm9v");
- EXPECT_EQ(base64_encode("foob"), "Zm9vYg==");
- EXPECT_EQ(base64_encode("fooba"), "Zm9vYmE=");
- EXPECT_EQ(base64_encode("foobar"), "Zm9vYmFy");
-
- EXPECT_EQ(Base64Encode("foo\0bar", 7), "Zm9vAGJhcg==");
-
- std::vector<uint8_t> buffer = {0x04, 0x53, 0x42, 0x35,
- 0x32, 0xFF, 0x00, 0xFE};
- EXPECT_EQ(Base64Encode(buffer.data(), buffer.size()), "BFNCNTL/AP4=");
-
- buffer = {0xfb, 0xf0, 0x3e, 0x07, 0xfc};
- EXPECT_EQ(Base64Encode(buffer.data(), buffer.size()), "+/A+B/w=");
-}
-
TEST(StringUtilsTest, StringCopy) {
// Nothing should be written when |dst_size| = 0.
{
diff --git a/src/base/utils.cc b/src/base/utils.cc
index 732117a..c080388 100644
--- a/src/base/utils.cc
+++ b/src/base/utils.cc
@@ -39,6 +39,7 @@
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#include <io.h>
+#include <malloc.h> // For _aligned_malloc().
#endif
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
@@ -241,5 +242,21 @@
return path;
}
+void* AlignedAlloc(size_t alignment, size_t size) {
+ void* res = nullptr;
+ alignment = AlignUp<sizeof(void*)>(alignment); // At least pointer size.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ // Window's _aligned_malloc() has a nearly identically signature to Unix's
+ // aligned_alloc() but its arguments are obviously swapped.
+ res = _aligned_malloc(size, alignment);
+#else
+ // aligned_alloc() has been introduced in Android only in API 28.
+ // Also NaCl and Fuchsia seems to have only posix_memalign().
+ ignore_result(posix_memalign(&res, alignment, size));
+#endif
+ PERFETTO_CHECK(res);
+ return res;
+}
+
} // namespace base
} // namespace perfetto
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 02231ce..65f84e6 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -337,7 +337,7 @@
"analysis",
"db",
"importers/common",
- "metrics:lib",
+ "metrics",
"sqlite",
"storage",
"tables",
@@ -365,7 +365,7 @@
"../../src/profiling/symbolizer",
"../../src/profiling/symbolizer:symbolize_database",
"../base",
- "metrics:lib",
+ "metrics",
"util",
]
if (enable_perfetto_trace_processor_linenoise) {
diff --git a/src/trace_processor/importers/proto/metadata_module.cc b/src/trace_processor/importers/proto/metadata_module.cc
index b811320..cfb644b 100644
--- a/src/trace_processor/importers/proto/metadata_module.cc
+++ b/src/trace_processor/importers/proto/metadata_module.cc
@@ -16,7 +16,7 @@
#include "src/trace_processor/importers/proto/metadata_module.h"
-#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/base64.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/proto/metadata_tracker.h"
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index f212645..0c3f315 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -372,8 +372,9 @@
name_id = context_->storage->InternString(event.event_name());
}
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
- context_->slice_tracker->Scoped(ts, track_id, cat_id, name_id,
- event.event_duration_ns(), args_fn);
+ context_->slice_tracker->Scoped(
+ ts, track_id, cat_id, name_id,
+ static_cast<int64_t>(event.event_duration_ns()), args_fn);
} else if (event.has_counter_id() || event.has_counter_name()) {
if (event.has_counter_id()) {
auto cid = event.counter_id();
diff --git a/src/trace_processor/metrics/BUILD.gn b/src/trace_processor/metrics/BUILD.gn
index d9106a1..8731f78 100644
--- a/src/trace_processor/metrics/BUILD.gn
+++ b/src/trace_processor/metrics/BUILD.gn
@@ -13,159 +13,21 @@
# limitations under the License.
import("../../../gn/perfetto.gni")
+import("../../../gn/perfetto_cc_proto_descriptor.gni")
import("../../../gn/test.gni")
-sql_files = [
- "trace_metadata.sql",
- "trace_stats.sql",
- "android/android_batt.sql",
- "android/android_camera.sql",
- "android/android_cpu.sql",
- "android/android_surfaceflinger.sql",
- "android/android_cpu_agg.sql",
- "android/android_cpu_raw_metrics_per_core.sql",
- "android/android_dma_heap.sql",
- "android/android_fastrpc.sql",
- "android/android_gpu.sql",
- "android/android_hwui_threads.sql",
- "android/android_mem.sql",
- "android/android_mem_unagg.sql",
- "android/android_ion.sql",
- "android/composer_execution.sql",
- "android/composition_layers.sql",
- "android/frame_missed.sql",
- "android/android_jank.sql",
- "android/android_lmk_reason.sql",
- "android/android_lmk.sql",
- "android/android_powrails.sql",
- "android/android_proxy_power.sql",
- "android/android_simpleperf.sql",
- "android/android_startup.sql",
- "android/android_package_list.sql",
- "android/android_task_names.sql",
- "android/android_thread_time_in_state.sql",
- "android/android_trace_quality.sql",
- "android/cpu_info.sql",
- "android/display_metrics.sql",
- "android/g2d.sql",
- "android/g2d_duration.sql",
- "android/android_hwcomposer.sql",
- "android/android_hwui_metric.sql",
- "android/java_heap_histogram.sql",
- "android/java_heap_stats.sql",
- "android/power_drain_in_watts.sql",
- "android/power_profile_data.sql",
- "android/process_unagg_mem_view.sql",
- "android/process_mem.sql",
- "android/process_metadata.sql",
- "android/process_oom_score.sql",
- "android/profiler_smaps.sql",
- "android/mem_stats_priority_breakdown.sql",
- "android/android_multiuser.sql",
- "android/android_multiuser_populator.sql",
- "android/span_view_stats.sql",
- "android/android_sysui_cuj.sql",
- "android/android_sysui_cuj_jank_query.sql",
- "android/process_counter_span_view.sql",
- "android/global_counter_span_view.sql",
- "android/gpu_counter_span_view.sql",
- "android/thread_counter_span_view.sql",
- "android/unsymbolized_frames.sql",
- "android/startup/launches.sql",
- "android/startup/hsc.sql",
- "chrome/actual_power_by_category.sql",
- "chrome/actual_power_by_rail_mode.sql",
- "chrome/chrome_event_metadata.sql",
- "chrome/chrome_processes.sql",
- "chrome/chrome_thread_slice_with_cpu_time.sql",
- "chrome/cpu_time_by_category.sql",
- "chrome/cpu_time_by_rail_mode.sql",
- "chrome/estimated_power_by_category.sql",
- "chrome/estimated_power_by_rail_mode.sql",
- "chrome/gesture_jank.sql",
- "chrome/gesture_flow_event.sql",
- "chrome/gesture_flow_event_queuing_delay.sql",
- "chrome/rail_modes.sql",
- "chrome/scroll_jank.sql",
- "chrome/scroll_jank_cause.sql",
- "chrome/scroll_jank_cause_blocking_task.sql",
- "chrome/scroll_jank_cause_blocking_touch_move.sql",
- "chrome/scroll_jank_cause_get_bitmap.sql",
- "chrome/scroll_jank_cause_queuing_delay.sql",
- "chrome/scroll_flow_event.sql",
- "chrome/scroll_flow_event_queuing_delay.sql",
- "chrome/test_chrome_metric.sql",
- "chrome/touch_flow_event.sql",
- "chrome/touch_flow_event_queuing_delay.sql",
- "chrome/touch_jank.sql",
- "experimental/blink_gc_metric.sql",
- "experimental/chrome_dropped_frames.sql",
- "experimental/frame_times.sql",
- "experimental/media_metric.sql",
- "experimental/reported_by_page.sql",
- "webview/webview_power_usage.sql",
-]
-
-config("gen_config") {
- include_dirs = [ "${root_gen_dir}/${perfetto_root_path}" ]
-}
-
-action("gen_merged_sql_metrics") {
- script = "../../../tools/gen_merged_sql_metrics.py"
- generated_header = "${target_gen_dir}/sql_metrics.h"
- args = rebase_path(sql_files, root_build_dir) + [
- "--cpp_out",
- rebase_path(generated_header, root_build_dir),
- ]
- inputs = sql_files
- outputs = [ generated_header ]
- public_configs = [ ":gen_config" ]
-}
-
-action("gen_cc_metrics_descriptor") {
+perfetto_cc_proto_descriptor("gen_cc_metrics_descriptor") {
+ descriptor_name = "metrics.descriptor"
descriptor_target = "../../../protos/perfetto/metrics:descriptor"
- generated_header = "${target_gen_dir}/metrics.descriptor.h"
-
- descriptor_file_path = get_label_info(descriptor_target, "target_gen_dir") +
- "/metrics.descriptor"
-
- script = "../../../tools/gen_cc_proto_descriptor.py"
- deps = [ descriptor_target ]
- args = [
- "--gen_dir",
- rebase_path(root_gen_dir, root_build_dir),
- "--cpp_out",
- rebase_path(generated_header, root_build_dir),
- rebase_path(descriptor_file_path, root_build_dir),
- ]
- inputs = [ descriptor_file_path ]
- outputs = [ generated_header ]
- public_configs = [ ":gen_config" ]
}
-action("gen_cc_all_chrome_metrics_descriptor") {
+perfetto_cc_proto_descriptor("gen_cc_all_chrome_metrics_descriptor") {
+ descriptor_name = "all_chrome_metrics.descriptor"
descriptor_target = "../../../protos/perfetto/metrics/chrome:descriptor"
- generated_header = "${target_gen_dir}/chrome/all_chrome_metrics.descriptor.h"
-
- descriptor_file_path = get_label_info(descriptor_target, "target_gen_dir") +
- "/all_chrome_metrics.descriptor"
-
- script = "../../../tools/gen_cc_proto_descriptor.py"
- deps = [ descriptor_target ]
- args = [
- "--gen_dir",
- rebase_path(root_gen_dir, root_build_dir),
- "--cpp_out",
- rebase_path(generated_header, root_build_dir),
- rebase_path(descriptor_file_path, root_build_dir),
- ]
- inputs = [ descriptor_file_path ]
- outputs = [ generated_header ]
- public_configs = [ ":gen_config" ]
}
if (enable_perfetto_trace_processor_sqlite) {
- source_set("lib") {
+ source_set("metrics") {
sources = [
"metrics.cc",
"metrics.h",
@@ -184,9 +46,9 @@
public_deps = [
":gen_cc_all_chrome_metrics_descriptor",
":gen_cc_metrics_descriptor",
- ":gen_merged_sql_metrics",
"../util",
"../util:descriptors",
+ "sql:gen_amalgamated_sql_metrics",
]
}
@@ -194,7 +56,7 @@
testonly = true
sources = [ "metrics_unittest.cc" ]
deps = [
- ":lib",
+ ":metrics",
"..:lib",
"../../../gn:default_deps",
"../../../gn:gtest_and_gmock",
diff --git a/src/trace_processor/metrics/metrics.cc b/src/trace_processor/metrics/metrics.cc
index 3bfff9b..6926cff 100644
--- a/src/trace_processor/metrics/metrics.cc
+++ b/src/trace_processor/metrics/metrics.cc
@@ -24,7 +24,6 @@
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
-#include "src/trace_processor/metrics/sql_metrics.h"
#include "src/trace_processor/sqlite/sqlite_utils.h"
#include "src/trace_processor/tp_metatrace.h"
#include "src/trace_processor/util/status_macros.h"
diff --git a/src/trace_processor/metrics/protos/README.md b/src/trace_processor/metrics/protos/README.md
new file mode 100644
index 0000000..8b6ab1a
--- /dev/null
+++ b/src/trace_processor/metrics/protos/README.md
@@ -0,0 +1,11 @@
+This empty folder exists to harmonize "built-in" metrics
+work with the "metric extension" functionality of trace processor.
+
+Essentially by adding a protos folder, we can pass
+src/trace_processor/metrics as an extension path to shell to
+override all built-in metrics. This means we can change the SQL
+files *without* needing to recompile trace processor.
+
+In the future, we might also move the protos here but that would
+be a bigger change which would need coordination across repos (
+e.g. Chrome because of the metrics autoroller for Chrome metrics).
diff --git a/src/trace_processor/metrics/sql/BUILD.gn b/src/trace_processor/metrics/sql/BUILD.gn
new file mode 100644
index 0000000..2759d24
--- /dev/null
+++ b/src/trace_processor/metrics/sql/BUILD.gn
@@ -0,0 +1,122 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../../../gn/perfetto.gni")
+
+sql_files = [
+ "trace_metadata.sql",
+ "trace_stats.sql",
+ "android/android_batt.sql",
+ "android/android_camera.sql",
+ "android/android_cpu.sql",
+ "android/android_surfaceflinger.sql",
+ "android/android_cpu_agg.sql",
+ "android/android_cpu_raw_metrics_per_core.sql",
+ "android/android_dma_heap.sql",
+ "android/android_fastrpc.sql",
+ "android/android_gpu.sql",
+ "android/android_hwui_threads.sql",
+ "android/android_mem.sql",
+ "android/android_mem_unagg.sql",
+ "android/android_ion.sql",
+ "android/composer_execution.sql",
+ "android/composition_layers.sql",
+ "android/frame_missed.sql",
+ "android/android_jank.sql",
+ "android/android_lmk_reason.sql",
+ "android/android_lmk.sql",
+ "android/android_powrails.sql",
+ "android/android_proxy_power.sql",
+ "android/android_simpleperf.sql",
+ "android/android_startup.sql",
+ "android/android_package_list.sql",
+ "android/android_task_names.sql",
+ "android/android_thread_time_in_state.sql",
+ "android/android_trace_quality.sql",
+ "android/cpu_info.sql",
+ "android/display_metrics.sql",
+ "android/g2d.sql",
+ "android/g2d_duration.sql",
+ "android/android_hwcomposer.sql",
+ "android/android_hwui_metric.sql",
+ "android/java_heap_histogram.sql",
+ "android/java_heap_stats.sql",
+ "android/power_drain_in_watts.sql",
+ "android/power_profile_data.sql",
+ "android/process_unagg_mem_view.sql",
+ "android/process_mem.sql",
+ "android/process_metadata.sql",
+ "android/process_oom_score.sql",
+ "android/profiler_smaps.sql",
+ "android/mem_stats_priority_breakdown.sql",
+ "android/android_multiuser.sql",
+ "android/android_multiuser_populator.sql",
+ "android/span_view_stats.sql",
+ "android/android_sysui_cuj.sql",
+ "android/android_sysui_cuj_jank_query.sql",
+ "android/process_counter_span_view.sql",
+ "android/global_counter_span_view.sql",
+ "android/gpu_counter_span_view.sql",
+ "android/thread_counter_span_view.sql",
+ "android/unsymbolized_frames.sql",
+ "android/startup/launches.sql",
+ "android/startup/hsc.sql",
+ "chrome/actual_power_by_category.sql",
+ "chrome/actual_power_by_rail_mode.sql",
+ "chrome/chrome_event_metadata.sql",
+ "chrome/chrome_processes.sql",
+ "chrome/chrome_thread_slice_with_cpu_time.sql",
+ "chrome/cpu_time_by_category.sql",
+ "chrome/cpu_time_by_rail_mode.sql",
+ "chrome/estimated_power_by_category.sql",
+ "chrome/estimated_power_by_rail_mode.sql",
+ "chrome/gesture_jank.sql",
+ "chrome/gesture_flow_event.sql",
+ "chrome/gesture_flow_event_queuing_delay.sql",
+ "chrome/rail_modes.sql",
+ "chrome/scroll_jank.sql",
+ "chrome/scroll_jank_cause.sql",
+ "chrome/scroll_jank_cause_blocking_task.sql",
+ "chrome/scroll_jank_cause_blocking_touch_move.sql",
+ "chrome/scroll_jank_cause_get_bitmap.sql",
+ "chrome/scroll_jank_cause_queuing_delay.sql",
+ "chrome/scroll_flow_event.sql",
+ "chrome/scroll_flow_event_queuing_delay.sql",
+ "chrome/test_chrome_metric.sql",
+ "chrome/touch_flow_event.sql",
+ "chrome/touch_flow_event_queuing_delay.sql",
+ "chrome/touch_jank.sql",
+ "experimental/blink_gc_metric.sql",
+ "experimental/chrome_dropped_frames.sql",
+ "experimental/frame_times.sql",
+ "experimental/media_metric.sql",
+ "experimental/reported_by_page.sql",
+ "webview/webview_power_usage.sql",
+]
+
+config("gen_config") {
+ include_dirs = [ "${root_gen_dir}/${perfetto_root_path}" ]
+}
+
+action("gen_amalgamated_sql_metrics") {
+ script = "../../../../tools/gen_amalgamated_sql_metrics.py"
+ generated_header = "${target_gen_dir}/amalgamated_sql_metrics.h"
+ args = rebase_path(sql_files, root_build_dir) + [
+ "--cpp_out",
+ rebase_path(generated_header, root_build_dir),
+ ]
+ inputs = sql_files
+ outputs = [ generated_header ]
+ public_configs = [ ":gen_config" ]
+}
diff --git a/src/trace_processor/metrics/android/OWNERS b/src/trace_processor/metrics/sql/android/OWNERS
similarity index 100%
rename from src/trace_processor/metrics/android/OWNERS
rename to src/trace_processor/metrics/sql/android/OWNERS
diff --git a/src/trace_processor/metrics/android/android_batt.sql b/src/trace_processor/metrics/sql/android/android_batt.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_batt.sql
rename to src/trace_processor/metrics/sql/android/android_batt.sql
diff --git a/src/trace_processor/metrics/android/android_camera.sql b/src/trace_processor/metrics/sql/android/android_camera.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_camera.sql
rename to src/trace_processor/metrics/sql/android/android_camera.sql
diff --git a/src/trace_processor/metrics/android/android_cpu.sql b/src/trace_processor/metrics/sql/android/android_cpu.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_cpu.sql
rename to src/trace_processor/metrics/sql/android/android_cpu.sql
diff --git a/src/trace_processor/metrics/android/android_cpu_agg.sql b/src/trace_processor/metrics/sql/android/android_cpu_agg.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_cpu_agg.sql
rename to src/trace_processor/metrics/sql/android/android_cpu_agg.sql
diff --git a/src/trace_processor/metrics/android/android_cpu_raw_metrics_per_core.sql b/src/trace_processor/metrics/sql/android/android_cpu_raw_metrics_per_core.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_cpu_raw_metrics_per_core.sql
rename to src/trace_processor/metrics/sql/android/android_cpu_raw_metrics_per_core.sql
diff --git a/src/trace_processor/metrics/android/android_dma_heap.sql b/src/trace_processor/metrics/sql/android/android_dma_heap.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_dma_heap.sql
rename to src/trace_processor/metrics/sql/android/android_dma_heap.sql
diff --git a/src/trace_processor/metrics/android/android_fastrpc.sql b/src/trace_processor/metrics/sql/android/android_fastrpc.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_fastrpc.sql
rename to src/trace_processor/metrics/sql/android/android_fastrpc.sql
diff --git a/src/trace_processor/metrics/android/android_gpu.sql b/src/trace_processor/metrics/sql/android/android_gpu.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_gpu.sql
rename to src/trace_processor/metrics/sql/android/android_gpu.sql
diff --git a/src/trace_processor/metrics/android/android_hwcomposer.sql b/src/trace_processor/metrics/sql/android/android_hwcomposer.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_hwcomposer.sql
rename to src/trace_processor/metrics/sql/android/android_hwcomposer.sql
diff --git a/src/trace_processor/metrics/android/android_hwui_metric.sql b/src/trace_processor/metrics/sql/android/android_hwui_metric.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_hwui_metric.sql
rename to src/trace_processor/metrics/sql/android/android_hwui_metric.sql
diff --git a/src/trace_processor/metrics/android/android_hwui_threads.sql b/src/trace_processor/metrics/sql/android/android_hwui_threads.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_hwui_threads.sql
rename to src/trace_processor/metrics/sql/android/android_hwui_threads.sql
diff --git a/src/trace_processor/metrics/android/android_ion.sql b/src/trace_processor/metrics/sql/android/android_ion.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_ion.sql
rename to src/trace_processor/metrics/sql/android/android_ion.sql
diff --git a/src/trace_processor/metrics/android/android_jank.sql b/src/trace_processor/metrics/sql/android/android_jank.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_jank.sql
rename to src/trace_processor/metrics/sql/android/android_jank.sql
diff --git a/src/trace_processor/metrics/android/android_lmk.sql b/src/trace_processor/metrics/sql/android/android_lmk.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_lmk.sql
rename to src/trace_processor/metrics/sql/android/android_lmk.sql
diff --git a/src/trace_processor/metrics/android/android_lmk_reason.sql b/src/trace_processor/metrics/sql/android/android_lmk_reason.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_lmk_reason.sql
rename to src/trace_processor/metrics/sql/android/android_lmk_reason.sql
diff --git a/src/trace_processor/metrics/android/android_mem.sql b/src/trace_processor/metrics/sql/android/android_mem.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_mem.sql
rename to src/trace_processor/metrics/sql/android/android_mem.sql
diff --git a/src/trace_processor/metrics/android/android_mem_unagg.sql b/src/trace_processor/metrics/sql/android/android_mem_unagg.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_mem_unagg.sql
rename to src/trace_processor/metrics/sql/android/android_mem_unagg.sql
diff --git a/src/trace_processor/metrics/android/android_multiuser.sql b/src/trace_processor/metrics/sql/android/android_multiuser.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_multiuser.sql
rename to src/trace_processor/metrics/sql/android/android_multiuser.sql
diff --git a/src/trace_processor/metrics/android/android_multiuser_populator.sql b/src/trace_processor/metrics/sql/android/android_multiuser_populator.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_multiuser_populator.sql
rename to src/trace_processor/metrics/sql/android/android_multiuser_populator.sql
diff --git a/src/trace_processor/metrics/android/android_package_list.sql b/src/trace_processor/metrics/sql/android/android_package_list.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_package_list.sql
rename to src/trace_processor/metrics/sql/android/android_package_list.sql
diff --git a/src/trace_processor/metrics/android/android_powrails.sql b/src/trace_processor/metrics/sql/android/android_powrails.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_powrails.sql
rename to src/trace_processor/metrics/sql/android/android_powrails.sql
diff --git a/src/trace_processor/metrics/android/android_proxy_power.sql b/src/trace_processor/metrics/sql/android/android_proxy_power.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_proxy_power.sql
rename to src/trace_processor/metrics/sql/android/android_proxy_power.sql
diff --git a/src/trace_processor/metrics/android/android_simpleperf.sql b/src/trace_processor/metrics/sql/android/android_simpleperf.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_simpleperf.sql
rename to src/trace_processor/metrics/sql/android/android_simpleperf.sql
diff --git a/src/trace_processor/metrics/android/android_startup.sql b/src/trace_processor/metrics/sql/android/android_startup.sql
similarity index 89%
rename from src/trace_processor/metrics/android/android_startup.sql
rename to src/trace_processor/metrics/sql/android/android_startup.sql
index f561d52..20eaefe 100644
--- a/src/trace_processor/metrics/android/android_startup.sql
+++ b/src/trace_processor/metrics/sql/android/android_startup.sql
@@ -301,6 +301,15 @@
FROM long_binder_transactions s
LEFT JOIN binder_to_destination_process bdp USING(slice_id);
+SELECT CREATE_FUNCTION(
+ 'MAIN_PROCESS_SLICE_PROTO(launch_id LONG, name STRING)',
+ 'PROTO', '
+ SELECT slice_proto
+ FROM main_process_slice s
+ WHERE s.launch_id = $launch_id AND name LIKE $name
+ LIMIT 1
+ ');
+
DROP VIEW IF EXISTS startup_view;
CREATE VIEW startup_view AS
SELECT
@@ -430,41 +439,18 @@
FROM launching_events l
WHERE l.ts BETWEEN launches.ts AND launches.ts + launches.dur
),
- 'time_post_fork', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'PostFork'
- ),
- 'time_activity_thread_main', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'ActivityThreadMain'
- ),
- 'time_bind_application', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'bindApplication'
- ),
- 'time_activity_start', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'activityStart'
- ),
- 'time_activity_resume', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'activityResume'
- ),
- 'time_activity_restart', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'activityRestart'
- ),
- 'time_choreographer', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name LIKE 'Choreographer#doFrame%'
- ),
+ 'time_post_fork', MAIN_PROCESS_SLICE_PROTO(launches.id, 'PostFork'),
+ 'time_activity_thread_main', MAIN_PROCESS_SLICE_PROTO(launches.id, 'ActivityThreadMain'),
+ 'time_bind_application', MAIN_PROCESS_SLICE_PROTO(launches.id, 'bindApplication'),
+ 'time_activity_start', MAIN_PROCESS_SLICE_PROTO(launches.id, 'activityStart'),
+ 'time_activity_resume', MAIN_PROCESS_SLICE_PROTO(launches.id, 'activityResume'),
+ 'time_activity_restart', MAIN_PROCESS_SLICE_PROTO(launches.id, 'activityRestart'),
+ 'time_choreographer', MAIN_PROCESS_SLICE_PROTO(launches.id, 'Choreographer#doFrame%'),
+ 'time_inflate', MAIN_PROCESS_SLICE_PROTO(launches.id, 'inflate'),
+ 'time_get_resources', MAIN_PROCESS_SLICE_PROTO(launches.id, 'ResourcesManager#getResources'),
+ 'time_dex_open', MAIN_PROCESS_SLICE_PROTO(launches.id, 'OpenDexFilesFromOat'),
+ 'time_verify_class', MAIN_PROCESS_SLICE_PROTO(launches.id, 'VerifyClass'),
+ 'time_gc_total', MAIN_PROCESS_SLICE_PROTO(launches.id, 'GC'),
'time_before_start_process', (
SELECT AndroidStartupMetric_Slice(
'dur_ns', ts - launches.ts,
@@ -481,27 +467,6 @@
FROM zygote_forks_by_id z
WHERE z.id = launches.id
),
- 'time_inflate', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'inflate'
- ),
- 'time_get_resources', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id
- AND name = 'ResourcesManager#getResources'
- ),
- 'time_dex_open', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'OpenDexFilesFromOat'
- ),
- 'time_verify_class', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'VerifyClass'
- ),
'jit_compiled_methods', (
SELECT count
FROM jit_compiled_methods_materialized s
@@ -516,11 +481,6 @@
FROM launch_threads_cpu_materialized
WHERE launch_id = launches.id
),
- 'time_gc_total', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'GC'
- ),
'time_gc_on_cpu', (
SELECT
NULL_IF_EMPTY(AndroidStartupMetric_Slice(
diff --git a/src/trace_processor/metrics/android/android_surfaceflinger.sql b/src/trace_processor/metrics/sql/android/android_surfaceflinger.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_surfaceflinger.sql
rename to src/trace_processor/metrics/sql/android/android_surfaceflinger.sql
diff --git a/src/trace_processor/metrics/android/android_sysui_cuj.sql b/src/trace_processor/metrics/sql/android/android_sysui_cuj.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_sysui_cuj.sql
rename to src/trace_processor/metrics/sql/android/android_sysui_cuj.sql
diff --git a/src/trace_processor/metrics/android/android_sysui_cuj_jank_query.sql b/src/trace_processor/metrics/sql/android/android_sysui_cuj_jank_query.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_sysui_cuj_jank_query.sql
rename to src/trace_processor/metrics/sql/android/android_sysui_cuj_jank_query.sql
diff --git a/src/trace_processor/metrics/android/android_task_names.sql b/src/trace_processor/metrics/sql/android/android_task_names.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_task_names.sql
rename to src/trace_processor/metrics/sql/android/android_task_names.sql
diff --git a/src/trace_processor/metrics/android/android_thread_time_in_state.sql b/src/trace_processor/metrics/sql/android/android_thread_time_in_state.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_thread_time_in_state.sql
rename to src/trace_processor/metrics/sql/android/android_thread_time_in_state.sql
diff --git a/src/trace_processor/metrics/android/android_trace_quality.sql b/src/trace_processor/metrics/sql/android/android_trace_quality.sql
similarity index 100%
rename from src/trace_processor/metrics/android/android_trace_quality.sql
rename to src/trace_processor/metrics/sql/android/android_trace_quality.sql
diff --git a/src/trace_processor/metrics/android/composer_execution.sql b/src/trace_processor/metrics/sql/android/composer_execution.sql
similarity index 100%
rename from src/trace_processor/metrics/android/composer_execution.sql
rename to src/trace_processor/metrics/sql/android/composer_execution.sql
diff --git a/src/trace_processor/metrics/android/composition_layers.sql b/src/trace_processor/metrics/sql/android/composition_layers.sql
similarity index 100%
rename from src/trace_processor/metrics/android/composition_layers.sql
rename to src/trace_processor/metrics/sql/android/composition_layers.sql
diff --git a/src/trace_processor/metrics/android/cpu_info.sql b/src/trace_processor/metrics/sql/android/cpu_info.sql
similarity index 100%
rename from src/trace_processor/metrics/android/cpu_info.sql
rename to src/trace_processor/metrics/sql/android/cpu_info.sql
diff --git a/src/trace_processor/metrics/android/display_metrics.sql b/src/trace_processor/metrics/sql/android/display_metrics.sql
similarity index 100%
rename from src/trace_processor/metrics/android/display_metrics.sql
rename to src/trace_processor/metrics/sql/android/display_metrics.sql
diff --git a/src/trace_processor/metrics/android/frame_missed.sql b/src/trace_processor/metrics/sql/android/frame_missed.sql
similarity index 100%
rename from src/trace_processor/metrics/android/frame_missed.sql
rename to src/trace_processor/metrics/sql/android/frame_missed.sql
diff --git a/src/trace_processor/metrics/android/g2d.sql b/src/trace_processor/metrics/sql/android/g2d.sql
similarity index 100%
rename from src/trace_processor/metrics/android/g2d.sql
rename to src/trace_processor/metrics/sql/android/g2d.sql
diff --git a/src/trace_processor/metrics/android/g2d_duration.sql b/src/trace_processor/metrics/sql/android/g2d_duration.sql
similarity index 100%
rename from src/trace_processor/metrics/android/g2d_duration.sql
rename to src/trace_processor/metrics/sql/android/g2d_duration.sql
diff --git a/src/trace_processor/metrics/android/global_counter_span_view.sql b/src/trace_processor/metrics/sql/android/global_counter_span_view.sql
similarity index 100%
rename from src/trace_processor/metrics/android/global_counter_span_view.sql
rename to src/trace_processor/metrics/sql/android/global_counter_span_view.sql
diff --git a/src/trace_processor/metrics/android/gpu_counter_span_view.sql b/src/trace_processor/metrics/sql/android/gpu_counter_span_view.sql
similarity index 100%
rename from src/trace_processor/metrics/android/gpu_counter_span_view.sql
rename to src/trace_processor/metrics/sql/android/gpu_counter_span_view.sql
diff --git a/src/trace_processor/metrics/android/java_heap_histogram.sql b/src/trace_processor/metrics/sql/android/java_heap_histogram.sql
similarity index 100%
rename from src/trace_processor/metrics/android/java_heap_histogram.sql
rename to src/trace_processor/metrics/sql/android/java_heap_histogram.sql
diff --git a/src/trace_processor/metrics/android/java_heap_stats.sql b/src/trace_processor/metrics/sql/android/java_heap_stats.sql
similarity index 100%
rename from src/trace_processor/metrics/android/java_heap_stats.sql
rename to src/trace_processor/metrics/sql/android/java_heap_stats.sql
diff --git a/src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql b/src/trace_processor/metrics/sql/android/mem_stats_priority_breakdown.sql
similarity index 100%
rename from src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql
rename to src/trace_processor/metrics/sql/android/mem_stats_priority_breakdown.sql
diff --git a/src/trace_processor/metrics/android/power_drain_in_watts.sql b/src/trace_processor/metrics/sql/android/power_drain_in_watts.sql
similarity index 100%
rename from src/trace_processor/metrics/android/power_drain_in_watts.sql
rename to src/trace_processor/metrics/sql/android/power_drain_in_watts.sql
diff --git a/src/trace_processor/metrics/android/power_profile_data.sql b/src/trace_processor/metrics/sql/android/power_profile_data.sql
similarity index 100%
rename from src/trace_processor/metrics/android/power_profile_data.sql
rename to src/trace_processor/metrics/sql/android/power_profile_data.sql
diff --git a/src/trace_processor/metrics/android/process_counter_span_view.sql b/src/trace_processor/metrics/sql/android/process_counter_span_view.sql
similarity index 100%
rename from src/trace_processor/metrics/android/process_counter_span_view.sql
rename to src/trace_processor/metrics/sql/android/process_counter_span_view.sql
diff --git a/src/trace_processor/metrics/android/process_mem.sql b/src/trace_processor/metrics/sql/android/process_mem.sql
similarity index 100%
rename from src/trace_processor/metrics/android/process_mem.sql
rename to src/trace_processor/metrics/sql/android/process_mem.sql
diff --git a/src/trace_processor/metrics/android/process_metadata.sql b/src/trace_processor/metrics/sql/android/process_metadata.sql
similarity index 100%
rename from src/trace_processor/metrics/android/process_metadata.sql
rename to src/trace_processor/metrics/sql/android/process_metadata.sql
diff --git a/src/trace_processor/metrics/android/process_oom_score.sql b/src/trace_processor/metrics/sql/android/process_oom_score.sql
similarity index 100%
rename from src/trace_processor/metrics/android/process_oom_score.sql
rename to src/trace_processor/metrics/sql/android/process_oom_score.sql
diff --git a/src/trace_processor/metrics/android/process_unagg_mem_view.sql b/src/trace_processor/metrics/sql/android/process_unagg_mem_view.sql
similarity index 100%
rename from src/trace_processor/metrics/android/process_unagg_mem_view.sql
rename to src/trace_processor/metrics/sql/android/process_unagg_mem_view.sql
diff --git a/src/trace_processor/metrics/android/profiler_smaps.sql b/src/trace_processor/metrics/sql/android/profiler_smaps.sql
similarity index 100%
rename from src/trace_processor/metrics/android/profiler_smaps.sql
rename to src/trace_processor/metrics/sql/android/profiler_smaps.sql
diff --git a/src/trace_processor/metrics/android/span_view_stats.sql b/src/trace_processor/metrics/sql/android/span_view_stats.sql
similarity index 100%
rename from src/trace_processor/metrics/android/span_view_stats.sql
rename to src/trace_processor/metrics/sql/android/span_view_stats.sql
diff --git a/src/trace_processor/metrics/android/startup/hsc.sql b/src/trace_processor/metrics/sql/android/startup/hsc.sql
similarity index 100%
rename from src/trace_processor/metrics/android/startup/hsc.sql
rename to src/trace_processor/metrics/sql/android/startup/hsc.sql
diff --git a/src/trace_processor/metrics/android/startup/launches.sql b/src/trace_processor/metrics/sql/android/startup/launches.sql
similarity index 100%
rename from src/trace_processor/metrics/android/startup/launches.sql
rename to src/trace_processor/metrics/sql/android/startup/launches.sql
diff --git a/src/trace_processor/metrics/android/thread_counter_span_view.sql b/src/trace_processor/metrics/sql/android/thread_counter_span_view.sql
similarity index 100%
rename from src/trace_processor/metrics/android/thread_counter_span_view.sql
rename to src/trace_processor/metrics/sql/android/thread_counter_span_view.sql
diff --git a/src/trace_processor/metrics/android/unsymbolized_frames.sql b/src/trace_processor/metrics/sql/android/unsymbolized_frames.sql
similarity index 100%
rename from src/trace_processor/metrics/android/unsymbolized_frames.sql
rename to src/trace_processor/metrics/sql/android/unsymbolized_frames.sql
diff --git a/src/trace_processor/metrics/chrome/OWNERS b/src/trace_processor/metrics/sql/chrome/OWNERS
similarity index 100%
rename from src/trace_processor/metrics/chrome/OWNERS
rename to src/trace_processor/metrics/sql/chrome/OWNERS
diff --git a/src/trace_processor/metrics/chrome/actual_power_by_category.sql b/src/trace_processor/metrics/sql/chrome/actual_power_by_category.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/actual_power_by_category.sql
rename to src/trace_processor/metrics/sql/chrome/actual_power_by_category.sql
diff --git a/src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql b/src/trace_processor/metrics/sql/chrome/actual_power_by_rail_mode.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql
rename to src/trace_processor/metrics/sql/chrome/actual_power_by_rail_mode.sql
diff --git a/src/trace_processor/metrics/chrome/chrome_event_metadata.sql b/src/trace_processor/metrics/sql/chrome/chrome_event_metadata.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/chrome_event_metadata.sql
rename to src/trace_processor/metrics/sql/chrome/chrome_event_metadata.sql
diff --git a/src/trace_processor/metrics/chrome/chrome_processes.sql b/src/trace_processor/metrics/sql/chrome/chrome_processes.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/chrome_processes.sql
rename to src/trace_processor/metrics/sql/chrome/chrome_processes.sql
diff --git a/src/trace_processor/metrics/chrome/chrome_thread_slice_with_cpu_time.sql b/src/trace_processor/metrics/sql/chrome/chrome_thread_slice_with_cpu_time.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/chrome_thread_slice_with_cpu_time.sql
rename to src/trace_processor/metrics/sql/chrome/chrome_thread_slice_with_cpu_time.sql
diff --git a/src/trace_processor/metrics/chrome/cpu_time_by_category.sql b/src/trace_processor/metrics/sql/chrome/cpu_time_by_category.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/cpu_time_by_category.sql
rename to src/trace_processor/metrics/sql/chrome/cpu_time_by_category.sql
diff --git a/src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql b/src/trace_processor/metrics/sql/chrome/cpu_time_by_rail_mode.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql
rename to src/trace_processor/metrics/sql/chrome/cpu_time_by_rail_mode.sql
diff --git a/src/trace_processor/metrics/chrome/estimated_power_by_category.sql b/src/trace_processor/metrics/sql/chrome/estimated_power_by_category.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/estimated_power_by_category.sql
rename to src/trace_processor/metrics/sql/chrome/estimated_power_by_category.sql
diff --git a/src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql b/src/trace_processor/metrics/sql/chrome/estimated_power_by_rail_mode.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql
rename to src/trace_processor/metrics/sql/chrome/estimated_power_by_rail_mode.sql
diff --git a/src/trace_processor/metrics/chrome/gesture_flow_event.sql b/src/trace_processor/metrics/sql/chrome/gesture_flow_event.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/gesture_flow_event.sql
rename to src/trace_processor/metrics/sql/chrome/gesture_flow_event.sql
diff --git a/src/trace_processor/metrics/chrome/gesture_flow_event_queuing_delay.sql b/src/trace_processor/metrics/sql/chrome/gesture_flow_event_queuing_delay.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/gesture_flow_event_queuing_delay.sql
rename to src/trace_processor/metrics/sql/chrome/gesture_flow_event_queuing_delay.sql
diff --git a/src/trace_processor/metrics/chrome/gesture_jank.sql b/src/trace_processor/metrics/sql/chrome/gesture_jank.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/gesture_jank.sql
rename to src/trace_processor/metrics/sql/chrome/gesture_jank.sql
diff --git a/src/trace_processor/metrics/chrome/rail_modes.sql b/src/trace_processor/metrics/sql/chrome/rail_modes.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/rail_modes.sql
rename to src/trace_processor/metrics/sql/chrome/rail_modes.sql
diff --git a/src/trace_processor/metrics/chrome/scroll_flow_event.sql b/src/trace_processor/metrics/sql/chrome/scroll_flow_event.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/scroll_flow_event.sql
rename to src/trace_processor/metrics/sql/chrome/scroll_flow_event.sql
diff --git a/src/trace_processor/metrics/chrome/scroll_flow_event_queuing_delay.sql b/src/trace_processor/metrics/sql/chrome/scroll_flow_event_queuing_delay.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/scroll_flow_event_queuing_delay.sql
rename to src/trace_processor/metrics/sql/chrome/scroll_flow_event_queuing_delay.sql
diff --git a/src/trace_processor/metrics/chrome/scroll_jank.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/scroll_jank.sql
rename to src/trace_processor/metrics/sql/chrome/scroll_jank.sql
diff --git a/src/trace_processor/metrics/chrome/scroll_jank_cause.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/scroll_jank_cause.sql
rename to src/trace_processor/metrics/sql/chrome/scroll_jank_cause.sql
diff --git a/src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_task.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_task.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_task.sql
rename to src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_task.sql
diff --git a/src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_touch_move.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_touch_move.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_touch_move.sql
rename to src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_touch_move.sql
diff --git a/src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_get_bitmap.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql
rename to src/trace_processor/metrics/sql/chrome/scroll_jank_cause_get_bitmap.sql
diff --git a/src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql
rename to src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql
diff --git a/src/trace_processor/metrics/chrome/test_chrome_metric.sql b/src/trace_processor/metrics/sql/chrome/test_chrome_metric.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/test_chrome_metric.sql
rename to src/trace_processor/metrics/sql/chrome/test_chrome_metric.sql
diff --git a/src/trace_processor/metrics/chrome/touch_flow_event.sql b/src/trace_processor/metrics/sql/chrome/touch_flow_event.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/touch_flow_event.sql
rename to src/trace_processor/metrics/sql/chrome/touch_flow_event.sql
diff --git a/src/trace_processor/metrics/chrome/touch_flow_event_queuing_delay.sql b/src/trace_processor/metrics/sql/chrome/touch_flow_event_queuing_delay.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/touch_flow_event_queuing_delay.sql
rename to src/trace_processor/metrics/sql/chrome/touch_flow_event_queuing_delay.sql
diff --git a/src/trace_processor/metrics/chrome/touch_jank.sql b/src/trace_processor/metrics/sql/chrome/touch_jank.sql
similarity index 100%
rename from src/trace_processor/metrics/chrome/touch_jank.sql
rename to src/trace_processor/metrics/sql/chrome/touch_jank.sql
diff --git a/src/trace_processor/metrics/experimental/OWNERS b/src/trace_processor/metrics/sql/experimental/OWNERS
similarity index 100%
rename from src/trace_processor/metrics/experimental/OWNERS
rename to src/trace_processor/metrics/sql/experimental/OWNERS
diff --git a/src/trace_processor/metrics/experimental/blink_gc_metric.sql b/src/trace_processor/metrics/sql/experimental/blink_gc_metric.sql
similarity index 100%
rename from src/trace_processor/metrics/experimental/blink_gc_metric.sql
rename to src/trace_processor/metrics/sql/experimental/blink_gc_metric.sql
diff --git a/src/trace_processor/metrics/experimental/chrome_dropped_frames.sql b/src/trace_processor/metrics/sql/experimental/chrome_dropped_frames.sql
similarity index 100%
rename from src/trace_processor/metrics/experimental/chrome_dropped_frames.sql
rename to src/trace_processor/metrics/sql/experimental/chrome_dropped_frames.sql
diff --git a/src/trace_processor/metrics/experimental/frame_times.sql b/src/trace_processor/metrics/sql/experimental/frame_times.sql
similarity index 100%
rename from src/trace_processor/metrics/experimental/frame_times.sql
rename to src/trace_processor/metrics/sql/experimental/frame_times.sql
diff --git a/src/trace_processor/metrics/experimental/media_metric.sql b/src/trace_processor/metrics/sql/experimental/media_metric.sql
similarity index 100%
rename from src/trace_processor/metrics/experimental/media_metric.sql
rename to src/trace_processor/metrics/sql/experimental/media_metric.sql
diff --git a/src/trace_processor/metrics/experimental/reported_by_page.sql b/src/trace_processor/metrics/sql/experimental/reported_by_page.sql
similarity index 100%
rename from src/trace_processor/metrics/experimental/reported_by_page.sql
rename to src/trace_processor/metrics/sql/experimental/reported_by_page.sql
diff --git a/src/trace_processor/metrics/trace_metadata.sql b/src/trace_processor/metrics/sql/trace_metadata.sql
similarity index 100%
rename from src/trace_processor/metrics/trace_metadata.sql
rename to src/trace_processor/metrics/sql/trace_metadata.sql
diff --git a/src/trace_processor/metrics/trace_stats.sql b/src/trace_processor/metrics/sql/trace_stats.sql
similarity index 100%
rename from src/trace_processor/metrics/trace_stats.sql
rename to src/trace_processor/metrics/sql/trace_stats.sql
diff --git a/src/trace_processor/metrics/webview/webview_power_usage.sql b/src/trace_processor/metrics/sql/webview/webview_power_usage.sql
similarity index 100%
rename from src/trace_processor/metrics/webview/webview_power_usage.sql
rename to src/trace_processor/metrics/sql/webview/webview_power_usage.sql
diff --git a/src/trace_processor/sqlite/BUILD.gn b/src/trace_processor/sqlite/BUILD.gn
index af1adbe..7863cc5 100644
--- a/src/trace_processor/sqlite/BUILD.gn
+++ b/src/trace_processor/sqlite/BUILD.gn
@@ -17,6 +17,8 @@
if (enable_perfetto_trace_processor_sqlite) {
source_set("sqlite") {
sources = [
+ "create_function.cc",
+ "create_function.h",
"db_sqlite_table.cc",
"db_sqlite_table.h",
"query_cache.h",
diff --git a/src/trace_processor/sqlite/create_function.cc b/src/trace_processor/sqlite/create_function.cc
new file mode 100644
index 0000000..692018e
--- /dev/null
+++ b/src/trace_processor/sqlite/create_function.cc
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/sqlite/create_function.h"
+
+#include "perfetto/base/status.h"
+#include "perfetto/trace_processor/basic_types.h"
+#include "src/trace_processor/sqlite/scoped_db.h"
+#include "src/trace_processor/sqlite/sqlite_utils.h"
+#include "src/trace_processor/util/status_macros.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+namespace {
+
+bool IsValidName(base::StringView str) {
+ auto pred = [](char c) { return !(isalnum(c) || c == '_'); };
+ return std::find_if(str.begin(), str.end(), pred) == str.end();
+}
+
+base::Optional<SqlValue::Type> ParseType(base::StringView str) {
+ if (str == "INT" || str == "LONG" || str == "BOOL") {
+ return SqlValue::Type::kLong;
+ } else if (str == "DOUBLE" || str == "FLOAT") {
+ return SqlValue::Type::kDouble;
+ } else if (str == "STRING") {
+ return SqlValue::Type::kString;
+ } else if (str == "PROTO" || str == "BYTES") {
+ return SqlValue::Type::kBytes;
+ }
+ return base::nullopt;
+}
+
+const char* SqliteTypeToFriendlyString(SqlValue::Type type) {
+ switch (type) {
+ case SqlValue::Type::kNull:
+ return "NULL";
+ case SqlValue::Type::kLong:
+ return "INT/LONG/BOOL";
+ case SqlValue::Type::kDouble:
+ return "FLOAT/DOUBLE";
+ case SqlValue::Type::kString:
+ return "STRING";
+ case SqlValue::Type::kBytes:
+ return "BYTES/PROTO";
+ }
+ PERFETTO_FATAL("For GCC");
+}
+
+base::Status TypeCheckSqliteValue(sqlite3_value* value,
+ SqlValue::Type expected_type) {
+ SqlValue::Type actual_type =
+ sqlite_utils::SqliteTypeToSqlValueType(sqlite3_value_type(value));
+ if (actual_type != SqlValue::Type::kNull && actual_type != expected_type) {
+ return base::ErrStatus(
+ "does not have expected type: expected %s, actual %s",
+ SqliteTypeToFriendlyString(expected_type),
+ SqliteTypeToFriendlyString(actual_type));
+ }
+ return base::OkStatus();
+}
+
+struct Prototype {
+ struct Argument {
+ std::string dollar_name;
+ SqlValue::Type type;
+
+ bool operator==(const Argument& other) const {
+ return dollar_name == other.dollar_name && type == other.type;
+ }
+ };
+ std::string function_name;
+ std::vector<Argument> arguments;
+
+ bool operator==(const Prototype& other) const {
+ return function_name == other.function_name && arguments == other.arguments;
+ }
+ bool operator!=(const Prototype& other) const { return !(*this == other); }
+};
+
+base::Status ParsePrototype(base::StringView raw, Prototype& out) {
+ // Examples of function prototypes:
+ // ANDROID_SDK_LEVEL()
+ // STARTUP_SLICE(dur_ns INT)
+ // FIND_NEXT_SLICE_WITH_NAME(ts INT, name STRING)
+
+ size_t function_name_end = raw.find('(');
+ if (function_name_end == base::StringView::npos) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s]: unable to find bracket starting "
+ "argument list",
+ raw.ToStdString().c_str());
+ }
+
+ base::StringView function_name = raw.substr(0, function_name_end);
+ if (!IsValidName(function_name)) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s]: function name %s is not alphanumeric",
+ raw.ToStdString().c_str(), function_name.ToStdString().c_str());
+ }
+
+ size_t args_start = function_name_end + 1;
+ size_t args_end = raw.find(')', function_name_end);
+ if (args_end == base::StringView::npos) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s]: unable to find bracket ending "
+ "argument list",
+ raw.ToStdString().c_str());
+ }
+
+ base::StringView args_str = raw.substr(args_start, args_end - args_start);
+ for (const auto& arg : base::SplitString(args_str.ToStdString(), ",")) {
+ const auto& arg_name_and_type = base::SplitString(arg, " ");
+ if (arg_name_and_type.size() != 2) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s, arg=%s]: argument in function "
+ "prototye should be of the form `name type`",
+ raw.ToStdString().c_str(), arg.c_str());
+ }
+
+ const auto& arg_name = arg_name_and_type[0];
+ const auto& arg_type_str = arg_name_and_type[1];
+ if (!IsValidName(base::StringView(arg_name))) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s, arg=%s]: argument is not alphanumeric",
+ raw.ToStdString().c_str(), arg.c_str());
+ }
+
+ auto opt_arg_type = ParseType(base::StringView(arg_type_str));
+ if (!opt_arg_type) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s, arg=%s]: unknown arg type",
+ raw.ToStdString().c_str(), arg.c_str());
+ }
+
+ SqlValue::Type arg_type = *opt_arg_type;
+ PERFETTO_DCHECK(arg_type != SqlValue::Type::kNull);
+ out.arguments.push_back({"$" + arg_name, arg_type});
+ }
+
+ out.function_name = function_name.ToStdString();
+ return base::OkStatus();
+}
+
+struct CreatedFunction : public SqlFunction {
+ struct Context {
+ sqlite3* db;
+ Prototype prototype;
+ SqlValue::Type return_type;
+ std::string sql;
+ sqlite3_stmt* stmt;
+ };
+
+ static base::Status Run(Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&);
+ static base::Status Cleanup(Context*);
+};
+
+base::Status SqliteRetToStatus(CreatedFunction::Context* ctx, int ret) {
+ if (ret != SQLITE_ROW && ret != SQLITE_DONE) {
+ return base::ErrStatus("%s: SQLite error while executing function body: %s",
+ ctx->prototype.function_name.c_str(),
+ sqlite3_errmsg(ctx->db));
+ }
+ return base::OkStatus();
+}
+
+base::Status CreatedFunction::Run(CreatedFunction::Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&) {
+ if (argc != ctx->prototype.arguments.size()) {
+ return base::ErrStatus(
+ "%s: invalid number of args; expected %zu, received %zu",
+ ctx->prototype.function_name.c_str(), ctx->prototype.arguments.size(),
+ argc);
+ }
+
+ // Type check all the arguments.
+ for (size_t i = 0; i < argc; ++i) {
+ sqlite3_value* arg = argv[i];
+ base::Status status =
+ TypeCheckSqliteValue(arg, ctx->prototype.arguments[i].type);
+ if (!status.ok()) {
+ return base::ErrStatus("%s[arg=%s]: argument %zu %s",
+ ctx->prototype.function_name.c_str(),
+ sqlite3_value_text(arg), i, status.c_message());
+ }
+ }
+
+ // Bind all the arguments to the appropriate places in the function.
+ for (size_t i = 0; i < argc; ++i) {
+ const auto& arg = ctx->prototype.arguments[i];
+ int index =
+ sqlite3_bind_parameter_index(ctx->stmt, arg.dollar_name.c_str());
+
+ // If the argument is not in the query, this just means its an unused
+ // argument which we can just ignore.
+ if (index == 0)
+ continue;
+
+ int ret = sqlite3_bind_value(ctx->stmt, index, argv[i]);
+ if (ret != SQLITE_OK) {
+ return base::ErrStatus(
+ "%s: SQLite error while binding value to argument %zu: %s",
+ ctx->prototype.function_name.c_str(), i, sqlite3_errmsg(ctx->db));
+ }
+ }
+
+ int ret = sqlite3_step(ctx->stmt);
+ RETURN_IF_ERROR(SqliteRetToStatus(ctx, ret));
+ if (ret == SQLITE_DONE)
+ // No return value means we just return don't set |out|.
+ return base::OkStatus();
+
+ PERFETTO_DCHECK(ret == SQLITE_ROW);
+ size_t col_count = static_cast<size_t>(sqlite3_column_count(ctx->stmt));
+ if (col_count != 1) {
+ return base::ErrStatus(
+ "%s: SQL definition should only return one column: returned %zu "
+ "columns",
+ ctx->prototype.function_name.c_str(), col_count);
+ }
+
+ out = sqlite_utils::SqliteValueToSqlValue(sqlite3_column_value(ctx->stmt, 0));
+ return base::OkStatus();
+}
+
+base::Status CreatedFunction::Cleanup(CreatedFunction::Context* ctx) {
+ int ret = sqlite3_step(ctx->stmt);
+ RETURN_IF_ERROR(SqliteRetToStatus(ctx, ret));
+ if (ret == SQLITE_ROW) {
+ return base::ErrStatus(
+ "%s: multiple values were returned when executing function body",
+ ctx->prototype.function_name.c_str());
+ }
+ PERFETTO_DCHECK(ret == SQLITE_DONE);
+
+ // Make sure to reset the statement to remove any bindings.
+ ret = sqlite3_reset(ctx->stmt);
+ if (ret != SQLITE_OK) {
+ return base::ErrStatus("%s: error while resetting metric",
+ ctx->prototype.function_name.c_str());
+ }
+ return base::OkStatus();
+}
+
+} // namespace
+
+size_t CreateFunction::NameAndArgc::Hasher::operator()(
+ const NameAndArgc& s) const noexcept {
+ base::Hash hash;
+ hash.Update(s.name.data(), s.name.size());
+ hash.Update(s.argc);
+ return static_cast<size_t>(hash.digest());
+}
+
+base::Status CreateFunction::Run(CreateFunction::Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue&,
+ Destructors&) {
+ if (argc != 3) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION: invalid number of args; expected %u, received %zu",
+ 3u, argc);
+ }
+
+ sqlite3_value* prototype_value = argv[0];
+ sqlite3_value* return_type_value = argv[1];
+ sqlite3_value* sql_defn_value = argv[2];
+
+ // Type check all the arguments.
+ {
+ auto type_check = [prototype_value](sqlite3_value* value,
+ SqlValue::Type type, const char* desc) {
+ base::Status status = TypeCheckSqliteValue(value, type);
+ if (!status.ok()) {
+ return base::ErrStatus("CREATE_FUNCTION[prototype=%s]: %s %s",
+ sqlite3_value_text(prototype_value), desc,
+ status.c_message());
+ }
+ return base::OkStatus();
+ };
+
+ RETURN_IF_ERROR(type_check(prototype_value, SqlValue::Type::kString,
+ "function name (first argument)"));
+ RETURN_IF_ERROR(type_check(return_type_value, SqlValue::Type::kString,
+ "return type (second argument)"));
+ RETURN_IF_ERROR(type_check(sql_defn_value, SqlValue::Type::kString,
+ "SQL definition (third argument)"));
+ }
+
+ // Extract the arguments from the value wrappers.
+ auto extract_string = [](sqlite3_value* value) -> base::StringView {
+ return reinterpret_cast<const char*>(sqlite3_value_text(value));
+ };
+ base::StringView prototype_str = extract_string(prototype_value);
+ base::StringView return_type_str = extract_string(return_type_value);
+ std::string sql_defn_str = extract_string(sql_defn_value).ToStdString();
+
+ // Parse all the arguments into a more friendly form.
+ Prototype prototype;
+ RETURN_IF_ERROR(ParsePrototype(prototype_str, prototype));
+
+ // Parse the return type into a enum format.
+ auto opt_return_type = ParseType(return_type_str);
+ if (!opt_return_type) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s, return=%s]: unknown return type "
+ "specified",
+ prototype_str.ToStdString().c_str(),
+ return_type_str.ToStdString().c_str());
+ }
+ SqlValue::Type return_type = *opt_return_type;
+
+ int created_argc = static_cast<int>(prototype.arguments.size());
+ NameAndArgc key{prototype.function_name, created_argc};
+ auto it = ctx->state->find(key);
+ if (it != ctx->state->end()) {
+ // If the function already exists, just verify that the prototype, return
+ // type and SQL matches exactly with what we already had registered. By
+ // doing this, we can avoid the problem plaguing C++ macros where macro
+ // ordering determines which one gets run.
+ auto* created_ctx = static_cast<CreatedFunction::Context*>(
+ it->second.created_functon_context);
+
+ if (created_ctx->prototype != prototype) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s]: function prototype changed",
+ prototype_str.ToStdString().c_str());
+ }
+
+ if (created_ctx->return_type != return_type) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s]: return type changed from %s to %s",
+ prototype_str.ToStdString().c_str(),
+ SqliteTypeToFriendlyString(created_ctx->return_type),
+ return_type_str.ToStdString().c_str());
+ }
+
+ if (created_ctx->sql != sql_defn_str) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s]: function SQL changed from %s to %s",
+ prototype_str.ToStdString().c_str(), created_ctx->sql.c_str(),
+ sql_defn_str.c_str());
+ }
+ return base::OkStatus();
+ }
+
+ // Prepare the SQL definition as a statement using SQLite.
+ ScopedStmt stmt;
+ sqlite3_stmt* stmt_raw = nullptr;
+ int ret = sqlite3_prepare_v2(ctx->db, sql_defn_str.data(),
+ static_cast<int>(sql_defn_str.size()), &stmt_raw,
+ nullptr);
+ if (ret != SQLITE_OK) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s]: SQLite error when preparing "
+ "statement "
+ "%s",
+ prototype_str.ToStdString().c_str(), sqlite3_errmsg(ctx->db));
+ }
+ stmt.reset(stmt_raw);
+
+ std::unique_ptr<CreatedFunction::Context> created(
+ new CreatedFunction::Context{ctx->db, std::move(prototype), return_type,
+ std::move(sql_defn_str), stmt.get()});
+ CreatedFunction::Context* created_ptr = created.get();
+ RETURN_IF_ERROR(RegisterSqlFunction<CreatedFunction>(
+ ctx->db, key.name.c_str(), created_argc, std::move(created)));
+ ctx->state->emplace(key, PerFunctionState{std::move(stmt), created_ptr});
+
+ // CREATE_FUNCTION doesn't have a return value so just don't sent |out|.
+ return base::OkStatus();
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/sqlite/create_function.h b/src/trace_processor/sqlite/create_function.h
new file mode 100644
index 0000000..c6778c2
--- /dev/null
+++ b/src/trace_processor/sqlite/create_function.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_SQLITE_CREATE_FUNCTION_H_
+#define SRC_TRACE_PROCESSOR_SQLITE_CREATE_FUNCTION_H_
+
+#include <sqlite3.h>
+#include <unordered_map>
+
+#include "src/trace_processor/sqlite/register_function.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+// Implementation of CREATE_FUNCTION SQL function.
+// See https://perfetto.dev/docs/analysis/metrics#metric-helper-functions for
+// usage of this function.
+struct CreateFunction : public SqlFunction {
+ struct PerFunctionState {
+ ScopedStmt stmt;
+ // void* to avoid leaking state.
+ void* created_functon_context;
+ };
+ struct NameAndArgc {
+ std::string name;
+ int argc;
+
+ struct Hasher {
+ std::size_t operator()(const NameAndArgc& s) const noexcept;
+ };
+ bool operator==(const NameAndArgc& other) const {
+ return name == other.name && argc == other.argc;
+ }
+ };
+ using State = std::unordered_map<NameAndArgc,
+ CreateFunction::PerFunctionState,
+ NameAndArgc::Hasher>;
+
+ struct Context {
+ sqlite3* db;
+ State* state;
+ };
+
+ static base::Status Run(Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&);
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_SQLITE_CREATE_FUNCTION_H_
diff --git a/src/trace_processor/sqlite/register_function.h b/src/trace_processor/sqlite/register_function.h
index 0df7dcc..1761af4 100644
--- a/src/trace_processor/sqlite/register_function.h
+++ b/src/trace_processor/sqlite/register_function.h
@@ -18,13 +18,8 @@
#define SRC_TRACE_PROCESSOR_SQLITE_REGISTER_FUNCTION_H_
#include <sqlite3.h>
-#include <cstddef>
#include <memory>
-#include <set>
-#include "perfetto/base/status.h"
-#include "perfetto/trace_processor/basic_types.h"
-#include "src/trace_processor/sqlite/scoped_db.h"
#include "src/trace_processor/sqlite/sqlite_utils.h"
namespace perfetto {
diff --git a/src/trace_processor/sqlite/sqlite_utils.h b/src/trace_processor/sqlite/sqlite_utils.h
index 66a3ed6..9bb26d7 100644
--- a/src/trace_processor/sqlite/sqlite_utils.h
+++ b/src/trace_processor/sqlite/sqlite_utils.h
@@ -20,12 +20,6 @@
#include <math.h>
#include <sqlite3.h>
-#include <functional>
-#include <limits>
-#include <string>
-
-#include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/trace_processor/basic_types.h"
#include "src/trace_processor/sqlite/scoped_db.h"
diff --git a/src/trace_processor/tp_metatrace.h b/src/trace_processor/tp_metatrace.h
index 7245ffc..7ca1865 100644
--- a/src/trace_processor/tp_metatrace.h
+++ b/src/trace_processor/tp_metatrace.h
@@ -48,7 +48,7 @@
uint64_t timestamp_ns;
// Duration of the event.
- uint32_t duration_ns;
+ uint64_t duration_ns;
// The name of the event.
// This is assumed to be a static/long lived string.
@@ -145,7 +145,7 @@
if (RingBuffer::GetInstance()->HasOverwritten(record_idx_))
return;
auto now = TraceTimeNowNs();
- record_->duration_ns = static_cast<uint32_t>(now - record_->timestamp_ns);
+ record_->duration_ns = now - record_->timestamp_ns;
}
ScopedEvent(ScopedEvent&& value) {
diff --git a/src/trace_processor/trace_database_integrationtest.cc b/src/trace_processor/trace_database_integrationtest.cc
index fa61596..c6c8095 100644
--- a/src/trace_processor/trace_database_integrationtest.cc
+++ b/src/trace_processor/trace_database_integrationtest.cc
@@ -384,13 +384,13 @@
// with opening the same trace with ninjatracing + chrome://tracing.
TEST_F(TraceProcessorIntegrationTest, NinjaLog) {
ASSERT_TRUE(LoadTrace("ninja_log", 1024).ok());
- auto it = Query("select count(*) from process where name like 'build';");
+ auto it = Query("select count(*) from process where name like 'Build';");
ASSERT_TRUE(it.Next());
ASSERT_EQ(it.Get(0).long_value, 2);
it = Query(
"select count(*) from thread left join process using(upid) where "
- "thread.name like 'worker%' and process.pid=1");
+ "thread.name like 'Worker%' and process.pid=1");
ASSERT_TRUE(it.Next());
ASSERT_EQ(it.Get(0).long_value, 14);
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index f942406..70213e4 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -47,6 +47,7 @@
#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/systrace/systrace_trace_parser.h"
#include "src/trace_processor/iterator_impl.h"
+#include "src/trace_processor/sqlite/create_function.h"
#include "src/trace_processor/sqlite/register_function.h"
#include "src/trace_processor/sqlite/span_join_operator_table.h"
#include "src/trace_processor/sqlite/sql_stats_table.h"
@@ -65,10 +66,10 @@
#include "protos/perfetto/trace/trace.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
-#include "src/trace_processor/metrics/chrome/all_chrome_metrics.descriptor.h"
+#include "src/trace_processor/metrics/all_chrome_metrics.descriptor.h"
#include "src/trace_processor/metrics/metrics.descriptor.h"
#include "src/trace_processor/metrics/metrics.h"
-#include "src/trace_processor/metrics/sql_metrics.h"
+#include "src/trace_processor/metrics/sql/amalgamated_sql_metrics.h"
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <cxxabi.h>
@@ -109,6 +110,11 @@
if (error) {
PERFETTO_FATAL("Error setting pragma temp_store: %s", error);
}
+ sqlite3_exec(db, "PRAGMA case_sensitive_like = 1", 0, 0, &error);
+ if (error) {
+ PERFETTO_FATAL("Error setting pragma case_sensitive_like: %s", error);
+ }
+
sqlite3_str_split_init(db);
// In Android tree builds, we don't have the percentile module.
// Just don't include it.
@@ -742,6 +748,10 @@
RegisterFunction<ExportJson>(db, "EXPORT_JSON", 1, context_.storage.get(),
false);
RegisterFunction<ExtractArg>(db, "EXTRACT_ARG", 2, context_.storage.get());
+ RegisterFunction<CreateFunction>(
+ db, "CREATE_FUNCTION", 3,
+ std::unique_ptr<CreateFunction::Context>(
+ new CreateFunction::Context{db_.get(), &create_function_state_}));
// Old style function registration.
// TODO(lalitm): migrate this over to using RegisterFunction once aggregate
diff --git a/src/trace_processor/trace_processor_impl.h b/src/trace_processor/trace_processor_impl.h
index f94e6d5..90a4393 100644
--- a/src/trace_processor/trace_processor_impl.h
+++ b/src/trace_processor/trace_processor_impl.h
@@ -21,6 +21,7 @@
#include <atomic>
#include <functional>
+#include <map>
#include <string>
#include <vector>
@@ -28,6 +29,7 @@
#include "perfetto/trace_processor/basic_types.h"
#include "perfetto/trace_processor/status.h"
#include "perfetto/trace_processor/trace_processor.h"
+#include "src/trace_processor/sqlite/create_function.h"
#include "src/trace_processor/sqlite/db_sqlite_table.h"
#include "src/trace_processor/sqlite/query_cache.h"
#include "src/trace_processor/sqlite/scoped_db.h"
@@ -46,6 +48,12 @@
public:
explicit TraceProcessorImpl(const Config&);
+ TraceProcessorImpl(const TraceProcessorImpl&) = delete;
+ TraceProcessorImpl& operator=(const TraceProcessorImpl&) = delete;
+
+ TraceProcessorImpl(TraceProcessorImpl&&) = delete;
+ TraceProcessorImpl& operator=(TraceProcessorImpl&&) = delete;
+
~TraceProcessorImpl() override;
// TraceProcessorStorage implementation:
@@ -104,7 +112,15 @@
}
bool IsRootMetricField(const std::string& metric_name);
+
+ // Keep this first: we need this to be destroyed after we clean up
+ // everything else.
ScopedDb db_;
+
+ // State necessary for CREATE_FUNCTION invocations. We store this here as we
+ // need to finalize any prepared statements *before* we destroy the database.
+ CreateFunction::State create_function_state_;
+
std::unique_ptr<QueryCache> query_cache_;
DescriptorPool pool_;
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index 5454b7e..3fe3486 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -42,7 +42,7 @@
#include "perfetto/trace_processor/read_trace.h"
#include "perfetto/trace_processor/trace_processor.h"
-#include "src/trace_processor/metrics/chrome/all_chrome_metrics.descriptor.h"
+#include "src/trace_processor/metrics/all_chrome_metrics.descriptor.h"
#include "src/trace_processor/metrics/metrics.descriptor.h"
#include "src/trace_processor/metrics/metrics.h"
#include "src/trace_processor/util/proto_to_json.h"
diff --git a/src/tracebox/tracebox.cc b/src/tracebox/tracebox.cc
index 4c40558..ed75b31 100644
--- a/src/tracebox/tracebox.cc
+++ b/src/tracebox/tracebox.cc
@@ -136,9 +136,9 @@
// traced will write "1" and close the FD when the IPC socket is listening
// (or traced crashed).
base::Pipe traced_sync_pipe = base::Pipe::Create();
- int wr_fd = *traced_sync_pipe.wr;
- base::SetEnv("TRACED_NOTIFY_FD", std::to_string(wr_fd));
- traced.args.preserve_fds.emplace_back(wr_fd);
+ int traced_fd = *traced_sync_pipe.wr;
+ base::SetEnv("TRACED_NOTIFY_FD", std::to_string(traced_fd));
+ traced.args.preserve_fds.emplace_back(traced_fd);
// Create a new process group so CTRL-C is delivered only to the cmdline
// process (the tracebox one) and not to traced. traced will still exit once
// the main process exits, but this allows graceful stopping of the trace
@@ -161,8 +161,28 @@
// Put traced_probes in the same process group as traced. Same reason (CTRL+C)
// but it's not worth creating a new group.
traced_probes.args.posix_proc_group_id = traced.pid();
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ // |traced_probes_sync_pipe| is used to synchronize with traced socket
+ // creation. traced will write "1" and close the FD when the IPC socket is
+ // listening (or traced crashed).
+ base::Pipe traced_probes_sync_pipe = base::Pipe::Create();
+ int traced_probes_fd = *traced_probes_sync_pipe.wr;
+ base::SetEnv("TRACED_PROBES_NOTIFY_FD", std::to_string(traced_probes_fd));
+ traced_probes.args.preserve_fds.emplace_back(traced_probes_fd);
+#endif
traced_probes.Start();
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ traced_probes_sync_pipe.wr.reset();
+
+ std::string traced_probes_notify_msg;
+ base::ReadPlatformHandle(*traced_probes_sync_pipe.rd,
+ &traced_probes_notify_msg);
+ if (traced_probes_notify_msg != "1")
+ PERFETTO_FATAL(
+ "The traced_proces service failed unexpectedly. Check the logs");
+#endif
+
perfetto_cmd.ConnectToServiceRunAndMaybeNotify();
return 0;
}
diff --git a/src/traced/probes/probes.cc b/src/traced/probes/probes.cc
index 75ba277..e13e56b 100644
--- a/src/traced/probes/probes.cc
+++ b/src/traced/probes/probes.cc
@@ -20,6 +20,7 @@
#include <unistd.h>
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/getopt.h"
#include "perfetto/ext/base/unix_task_runner.h"
#include "perfetto/ext/base/utils.h"
@@ -116,6 +117,18 @@
base::UnixTaskRunner task_runner;
ProbesProducer producer;
+ // If the TRACED_PROBES_NOTIFY_FD env var is set, write 1 and close the FD,
+ // when all data sources have been registered. This is used for //src/tracebox
+ // --background-wait, to make sure that the data sources are registered before
+ // waiting for them to be started.
+ const char* env_notif = getenv("TRACED_PROBES_NOTIFY_FD");
+ if (env_notif) {
+ int notif_fd = atoi(env_notif);
+ producer.SetAllDataSourcesRegisteredCb([notif_fd] {
+ PERFETTO_CHECK(base::WriteAll(notif_fd, "1", 1) == 1);
+ PERFETTO_CHECK(base::CloseFile(notif_fd) == 0);
+ });
+ }
producer.ConnectWithRetries(GetProducerSocket(), &task_runner);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index 9a8cd2b..e33a2a0 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -122,6 +122,11 @@
proto_desc.set_handles_incremental_state_clear(true);
endpoint_->RegisterDataSource(proto_desc);
}
+
+ // Used by tracebox to synchronize with traced_probes being registered.
+ if (all_data_sources_registered_cb_) {
+ endpoint_->Sync(all_data_sources_registered_cb_);
+ }
}
void ProbesProducer::OnDisconnect() {
diff --git a/src/traced/probes/probes_producer.h b/src/traced/probes/probes_producer.h
index eb4df63..dda1759 100644
--- a/src/traced/probes/probes_producer.h
+++ b/src/traced/probes/probes_producer.h
@@ -17,6 +17,7 @@
#ifndef SRC_TRACED_PROBES_PROBES_PRODUCER_H_
#define SRC_TRACED_PROBES_PROBES_PRODUCER_H_
+#include <functional>
#include <memory>
#include <unordered_map>
#include <utility>
@@ -100,6 +101,11 @@
const DataSourceConfig& config);
void ActivateTrigger(std::string trigger);
+ // Calls `cb` when all data sources have been registered.
+ void SetAllDataSourcesRegisteredCb(std::function<void()> cb) {
+ all_data_sources_registered_cb_ = cb;
+ }
+
private:
static ProbesProducer* instance_;
@@ -139,6 +145,8 @@
std::unordered_multimap<FlushRequestID, DataSourceInstanceID>
pending_flushes_;
+ std::function<void()> all_data_sources_registered_cb_;
+
std::unordered_map<DataSourceInstanceID, base::Watchdog::Timer> watchdogs_;
LRUInodeCache cache_{kLRUInodeCacheSize};
std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>>
diff --git a/test/trace_processor/parsing/android_log_counts.sql b/test/trace_processor/parsing/android_log_counts.sql
index f22fea1..09fc250 100644
--- a/test/trace_processor/parsing/android_log_counts.sql
+++ b/test/trace_processor/parsing/android_log_counts.sql
@@ -18,5 +18,5 @@
select count(*) as cnt from android_logs where prio > 4 union all
select count(*) as cnt from android_logs where tag = 'screen_toggled' union all
select count(*) as cnt from android_logs where tag like '%_pss' union all
-select count(*) as cnt from android_logs where msg like '%i2c_write%' union all
-select count(*) as cnt from android_logs where ts >= 1510113924391 and ts < 1512610021879;
\ No newline at end of file
+select count(*) as cnt from android_logs where msg like '%i2c_write%' or msg like '%I2C_Write%' union all
+select count(*) as cnt from android_logs where ts >= 1510113924391 and ts < 1512610021879;
diff --git a/test/trace_processor/parsing/android_log_msgs.sql b/test/trace_processor/parsing/android_log_msgs.sql
index 02093ca..9b46f43 100644
--- a/test/trace_processor/parsing/android_log_msgs.sql
+++ b/test/trace_processor/parsing/android_log_msgs.sql
@@ -17,7 +17,11 @@
create view v2 as select tag, count(*) from android_logs group by tag order by 2 asc limit 5;
-create view v3 as select tag, count(*) from android_logs where msg like '%wakelock%' group by tag;
+create view v3 as
+select tag, count(*)
+from android_logs
+where msg like '%wakelock%' or msg like '%Wakelock%' or msg like '%WakeLock%' or msg like '%wakeLock%'
+group by tag;
create view v4 as select msg, 1 from android_logs limit 10;
diff --git a/tools/gen_merged_sql_metrics.py b/tools/gen_amalgamated_sql_metrics.py
similarity index 100%
rename from tools/gen_merged_sql_metrics.py
rename to tools/gen_amalgamated_sql_metrics.py
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index 53dfbc0..af7d95d 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -744,14 +744,14 @@
return source_module
-def create_merged_sql_metrics_module(blueprint, target):
+def create_amalgamated_sql_metrics_module(blueprint, target):
bp_module_name = label_to_module_name(target.name)
module = Module('genrule', bp_module_name, target.name)
module.tool_files = [
- 'tools/gen_merged_sql_metrics.py',
+ 'tools/gen_amalgamated_sql_metrics.py',
]
module.cmd = ' '.join([
- '$(location tools/gen_merged_sql_metrics.py)',
+ '$(location tools/gen_amalgamated_sql_metrics.py)',
'--cpp_out=$(out)',
'$(in)',
])
@@ -843,8 +843,8 @@
if module is None:
return None
elif target.type == 'action':
- if 'gen_merged_sql_metrics' in target.name:
- module = create_merged_sql_metrics_module(blueprint, target)
+ if 'gen_amalgamated_sql_metrics' in target.name:
+ module = create_amalgamated_sql_metrics_module(blueprint, target)
elif re.match('.*gen_cc_.*_descriptor$', name_without_toolchain):
module = create_cc_proto_descriptor_module(blueprint, target)
elif target.type == 'action' and \
diff --git a/tools/gen_bazel b/tools/gen_bazel
index 3a1b8ae..73b4e45 100755
--- a/tools/gen_bazel
+++ b/tools/gen_bazel
@@ -108,19 +108,19 @@
'PERFETTO_CONFIG.deps.sqlite_ext_percentile'
],
'//gn:zlib': ['PERFETTO_CONFIG.deps.zlib'],
- '//src/trace_processor/metrics:gen_merged_sql_metrics': [[
- ':cc_merged_sql_metrics'
+ '//src/trace_processor/metrics/sql:gen_amalgamated_sql_metrics': [[
+ ':cc_amalgamated_sql_metrics'
]],
gn_utils.GEN_VERSION_TARGET: ['PERFETTO_CONFIG.deps.version_header'],
}
-def gen_sql_metrics(target):
+def gen_amalgamated_sql_metrics(target):
label = BazelLabel(get_bazel_label_name(target.name), 'perfetto_genrule')
label.srcs += [re.sub('^//', '', x) for x in sorted(target.inputs)]
label.outs += target.outputs
- label.cmd = r'$(location gen_merged_sql_metrics_py) --cpp_out=$@ $(SRCS)'
- label.exec_tools += [':gen_merged_sql_metrics_py']
+ label.cmd = r'$(location gen_amalgamated_sql_metrics_py) --cpp_out=$@ $(SRCS)'
+ label.exec_tools += [':gen_amalgamated_sql_metrics_py']
return [label]
@@ -144,7 +144,8 @@
custom_actions = {
gn_utils.GEN_VERSION_TARGET: gen_version_header,
- '//src/trace_processor/metrics:gen_merged_sql_metrics': gen_sql_metrics,
+ '//src/trace_processor/metrics/sql:gen_amalgamated_sql_metrics':
+ gen_amalgamated_sql_metrics,
}
# ------------------------------------------------------------------------------
diff --git a/ui/src/common/state.ts b/ui/src/common/state.ts
index 3b9cf21..5d2b388 100644
--- a/ui/src/common/state.ts
+++ b/ui/src/common/state.ts
@@ -71,12 +71,12 @@
// 6: Common PivotTableConfig and pivot table specific PivotTableState.
// 7: Split Chrome categories in two and add 'symbolize ksyms' flag.
// 8: Rename several variables
+// "[...]HeapProfileFlamegraph[...]" -> "[...]Flamegraph[...]".
// 9: Add a field to track last loaded recording profile name
// 10: Change last loaded profile tracking type to accommodate auto-save.
// 11: Rename updateChromeCategories to fetchChromeCategories.
// 12: Add a field to cache mapping from UI track ID to trace track ID in order
// to speed up flow arrows rendering.
-// "[...]HeapProfileFlamegraph[...]" -> "[...]Flamegraph[...]".
export const STATE_VERSION = 12;
export const SCROLLING_TRACK_GROUP = 'ScrollingTracks';