Merge "Mention Perfetto UI in heapprofd docs."
diff --git a/Android.bp b/Android.bp
index d42ffc9..f518385 100644
--- a/Android.bp
+++ b/Android.bp
@@ -245,7 +245,7 @@
":perfetto_src_base_base",
"src/ipc/protoc_plugin/ipc_plugin.cc",
],
- shared_libs: [
+ static_libs: [
"libprotoc",
],
defaults: [
@@ -820,6 +820,11 @@
name: "perfetto_include_perfetto_ext_ipc_ipc",
}
+// GN: //include/perfetto/ext/trace_processor:export_json
+filegroup {
+ name: "perfetto_include_perfetto_ext_trace_processor_export_json",
+}
+
// GN: //include/perfetto/ext/traced:sys_stats_counters
filegroup {
name: "perfetto_include_perfetto_ext_traced_sys_stats_counters",
@@ -4368,7 +4373,7 @@
":perfetto_src_base_base",
"src/protozero/protoc_plugin/cppgen_plugin.cc",
],
- shared_libs: [
+ static_libs: [
"libprotoc",
],
defaults: [
@@ -4546,7 +4551,6 @@
"src/trace_processor/filtered_row_index.cc",
"src/trace_processor/forwarding_trace_parser.cc",
"src/trace_processor/ftrace_utils.cc",
- "src/trace_processor/graphics_event_parser.cc",
"src/trace_processor/gzip_trace_parser.cc",
"src/trace_processor/heap_graph_tracker.cc",
"src/trace_processor/heap_profile_allocation_table.cc",
@@ -4559,14 +4563,19 @@
"src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc",
"src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc",
"src/trace_processor/importers/fuchsia/fuchsia_trace_utils.cc",
+ "src/trace_processor/importers/proto/android_probes_parser.cc",
+ "src/trace_processor/importers/proto/graphics_event_parser.cc",
+ "src/trace_processor/importers/proto/proto_trace_parser.cc",
+ "src/trace_processor/importers/proto/proto_trace_tokenizer.cc",
+ "src/trace_processor/importers/proto/system_probes_parser.cc",
+ "src/trace_processor/importers/proto/track_event_parser.cc",
+ "src/trace_processor/importers/proto/track_event_tokenizer.cc",
"src/trace_processor/importers/systrace/systrace_parser.cc",
"src/trace_processor/importers/systrace/systrace_trace_parser.cc",
"src/trace_processor/instants_table.cc",
"src/trace_processor/metadata_table.cc",
"src/trace_processor/process_table.cc",
"src/trace_processor/process_tracker.cc",
- "src/trace_processor/proto_trace_parser.cc",
- "src/trace_processor/proto_trace_tokenizer.cc",
"src/trace_processor/raw_table.cc",
"src/trace_processor/read_trace.cc",
"src/trace_processor/row_iterators.cc",
@@ -4659,12 +4668,12 @@
"src/trace_processor/ftrace_utils_unittest.cc",
"src/trace_processor/heap_profile_tracker_unittest.cc",
"src/trace_processor/importers/fuchsia/fuchsia_trace_utils_unittest.cc",
+ "src/trace_processor/importers/proto/proto_trace_parser_unittest.cc",
"src/trace_processor/importers/systrace/systrace_parser_unittest.cc",
"src/trace_processor/metadata_table_unittest.cc",
"src/trace_processor/null_term_string_view_unittest.cc",
"src/trace_processor/process_table_unittest.cc",
"src/trace_processor/process_tracker_unittest.cc",
- "src/trace_processor/proto_trace_parser_unittest.cc",
"src/trace_processor/sched_slice_table_unittest.cc",
"src/trace_processor/slice_tracker_unittest.cc",
"src/trace_processor/span_join_operator_table_unittest.cc",
@@ -4967,9 +4976,10 @@
"src/tracing/internal/in_process_tracing_backend.cc",
"src/tracing/internal/system_tracing_backend.cc",
"src/tracing/internal/tracing_muxer_impl.cc",
+ "src/tracing/internal/track_event_internal.cc",
"src/tracing/platform.cc",
"src/tracing/tracing.cc",
- "src/tracing/track_event.cc",
+ "src/tracing/track_event_category_registry.cc",
"src/tracing/virtual_destructors.cc",
],
}
@@ -4979,6 +4989,8 @@
name: "perfetto_src_tracing_client_api_integrationtests",
srcs: [
"src/tracing/api_integrationtest.cc",
+ "src/tracing/test/tracing_module.cc",
+ "src/tracing/test/tracing_module2.cc",
],
}
@@ -5282,6 +5294,7 @@
":perfetto_include_perfetto_base_base",
":perfetto_include_perfetto_ext_base_base",
":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_trace_processor_export_json",
":perfetto_include_perfetto_ext_traced_sys_stats_counters",
":perfetto_include_perfetto_ext_traced_traced",
":perfetto_include_perfetto_ext_tracing_core_core",
@@ -5543,7 +5556,7 @@
":perfetto_src_base_base",
"src/protozero/protoc_plugin/protozero_plugin.cc",
],
- shared_libs: [
+ static_libs: [
"libprotoc",
],
defaults: [
@@ -5561,6 +5574,7 @@
srcs: [
":perfetto_include_perfetto_base_base",
":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_trace_processor_export_json",
":perfetto_include_perfetto_ext_traced_sys_stats_counters",
":perfetto_include_perfetto_protozero_protozero",
":perfetto_include_perfetto_trace_processor_trace_processor",
@@ -5602,12 +5616,10 @@
"src/trace_processor/proto_to_json.cc",
"src/trace_processor/trace_processor_shell.cc",
],
- shared_libs: [
- "libprotoc",
- "libz",
- ],
static_libs: [
+ "libprotoc",
"libsqlite",
+ "libz",
],
generated_headers: [
"gen_merged_sql_metrics",
@@ -5647,6 +5659,7 @@
"-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
"-DHAVE_HIDDEN",
],
+ static_executable: true,
}
// GN: //tools/trace_to_text:trace_to_text
@@ -5655,6 +5668,7 @@
srcs: [
":perfetto_include_perfetto_base_base",
":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_trace_processor_export_json",
":perfetto_include_perfetto_ext_traced_sys_stats_counters",
":perfetto_include_perfetto_profiling_symbolizer",
":perfetto_include_perfetto_protozero_protozero",
@@ -5729,10 +5743,10 @@
shared_libs: [
"libprotobuf-cpp-full",
"libprotobuf-cpp-lite",
- "libz",
],
static_libs: [
"libsqlite",
+ "libz",
],
generated_headers: [
"gen_merged_sql_metrics",
diff --git a/BUILD b/BUILD
index a716bda..e3e4f79 100644
--- a/BUILD
+++ b/BUILD
@@ -273,6 +273,14 @@
],
)
+# GN target: //include/perfetto/ext/trace_processor:export_json
+filegroup(
+ name = "include_perfetto_ext_trace_processor_export_json",
+ srcs = [
+ "include/perfetto/ext/trace_processor/export_json.h",
+ ],
+)
+
# GN target: //include/perfetto/ext/traced:sys_stats_counters
filegroup(
name = "include_perfetto_ext_traced_sys_stats_counters",
@@ -392,12 +400,15 @@
"include/perfetto/tracing/internal/tracing_muxer.h",
"include/perfetto/tracing/internal/tracing_tls.h",
"include/perfetto/tracing/internal/track_event_data_source.h",
+ "include/perfetto/tracing/internal/track_event_internal.h",
+ "include/perfetto/tracing/internal/track_event_macros.h",
"include/perfetto/tracing/locked_handle.h",
"include/perfetto/tracing/platform.h",
"include/perfetto/tracing/trace_writer_base.h",
"include/perfetto/tracing/tracing.h",
"include/perfetto/tracing/tracing_backend.h",
"include/perfetto/tracing/track_event.h",
+ "include/perfetto/tracing/track_event_category_registry.h",
],
)
@@ -644,8 +655,6 @@
"src/trace_processor/forwarding_trace_parser.h",
"src/trace_processor/ftrace_utils.cc",
"src/trace_processor/ftrace_utils.h",
- "src/trace_processor/graphics_event_parser.cc",
- "src/trace_processor/graphics_event_parser.h",
"src/trace_processor/gzip_trace_parser.cc",
"src/trace_processor/gzip_trace_parser.h",
"src/trace_processor/heap_graph_tracker.cc",
@@ -677,8 +686,27 @@
"src/trace_processor/importers/json/json_trace_tokenizer.h",
"src/trace_processor/importers/json/json_trace_utils.cc",
"src/trace_processor/importers/json/json_trace_utils.h",
+ "src/trace_processor/importers/proto/android_probes_module.h",
+ "src/trace_processor/importers/proto/android_probes_parser.cc",
+ "src/trace_processor/importers/proto/android_probes_parser.h",
+ "src/trace_processor/importers/proto/graphics_event_module.h",
+ "src/trace_processor/importers/proto/graphics_event_parser.cc",
+ "src/trace_processor/importers/proto/graphics_event_parser.h",
+ "src/trace_processor/importers/proto/packet_sequence_state.h",
"src/trace_processor/importers/proto/proto_importer_module.h",
+ "src/trace_processor/importers/proto/proto_incremental_state.h",
+ "src/trace_processor/importers/proto/proto_trace_parser.cc",
+ "src/trace_processor/importers/proto/proto_trace_parser.h",
+ "src/trace_processor/importers/proto/proto_trace_tokenizer.cc",
+ "src/trace_processor/importers/proto/proto_trace_tokenizer.h",
+ "src/trace_processor/importers/proto/system_probes_module.h",
+ "src/trace_processor/importers/proto/system_probes_parser.cc",
+ "src/trace_processor/importers/proto/system_probes_parser.h",
"src/trace_processor/importers/proto/track_event_module.h",
+ "src/trace_processor/importers/proto/track_event_parser.cc",
+ "src/trace_processor/importers/proto/track_event_parser.h",
+ "src/trace_processor/importers/proto/track_event_tokenizer.cc",
+ "src/trace_processor/importers/proto/track_event_tokenizer.h",
"src/trace_processor/importers/systrace/systrace_parser.cc",
"src/trace_processor/importers/systrace/systrace_parser.h",
"src/trace_processor/importers/systrace/systrace_trace_parser.cc",
@@ -692,11 +720,6 @@
"src/trace_processor/process_table.h",
"src/trace_processor/process_tracker.cc",
"src/trace_processor/process_tracker.h",
- "src/trace_processor/proto_incremental_state.h",
- "src/trace_processor/proto_trace_parser.cc",
- "src/trace_processor/proto_trace_parser.h",
- "src/trace_processor/proto_trace_tokenizer.cc",
- "src/trace_processor/proto_trace_tokenizer.h",
"src/trace_processor/raw_table.cc",
"src/trace_processor/raw_table.h",
"src/trace_processor/read_trace.cc",
@@ -926,9 +949,10 @@
"src/tracing/internal/system_tracing_backend.h",
"src/tracing/internal/tracing_muxer_impl.cc",
"src/tracing/internal/tracing_muxer_impl.h",
+ "src/tracing/internal/track_event_internal.cc",
"src/tracing/platform.cc",
"src/tracing/tracing.cc",
- "src/tracing/track_event.cc",
+ "src/tracing/track_event_category_registry.cc",
"src/tracing/virtual_destructors.cc",
],
)
@@ -1076,28 +1100,8 @@
perfetto_cc_protocpp_library(
name = "protos_perfetto_common_cpp",
deps = [
- ":protos_perfetto_common_cpp_protos",
- ":protos_perfetto_common_lite",
- ],
-)
-
-# GN target: //protos/perfetto/common:cpp
-perfetto_proto_library(
- name = "protos_perfetto_common_cpp_protos",
- srcs = [
- "protos/perfetto/common/android_log_constants.proto",
- "protos/perfetto/common/commit_data_request.proto",
- "protos/perfetto/common/data_source_descriptor.proto",
- "protos/perfetto/common/descriptor.proto",
- "protos/perfetto/common/gpu_counter_descriptor.proto",
- "protos/perfetto/common/observable_events.proto",
- "protos/perfetto/common/sys_stats_counters.proto",
- "protos/perfetto/common/trace_stats.proto",
- "protos/perfetto/common/tracing_service_state.proto",
- "protos/perfetto/common/track_event_descriptor.proto",
- ],
- deps = [
":protos_perfetto_common_protos",
+ ":protos_perfetto_common_lite",
],
)
@@ -1138,27 +1142,13 @@
perfetto_cc_protocpp_library(
name = "protos_perfetto_config_android_cpp",
deps = [
- ":protos_perfetto_config_android_cpp_protos",
+ ":protos_perfetto_config_android_protos",
":protos_perfetto_common_lite",
":protos_perfetto_config_android_lite",
":protos_perfetto_common_cpp",
],
)
-# GN target: //protos/perfetto/config/android:cpp
-perfetto_proto_library(
- name = "protos_perfetto_config_android_cpp_protos",
- srcs = [
- "protos/perfetto/config/android/android_log_config.proto",
- "protos/perfetto/config/android/packages_list_config.proto",
- ],
- deps = [
- ":protos_perfetto_common_cpp_protos",
- ":protos_perfetto_common_protos",
- ":protos_perfetto_config_android_protos",
- ],
-)
-
# GN target: //protos/perfetto/config/android:lite
perfetto_cc_proto_library(
name = "protos_perfetto_config_android_lite",
@@ -1191,7 +1181,7 @@
perfetto_cc_protocpp_library(
name = "protos_perfetto_config_cpp",
deps = [
- ":protos_perfetto_config_cpp_protos",
+ ":protos_perfetto_config_protos",
":protos_perfetto_config_inode_file_cpp",
":protos_perfetto_config_android_cpp",
":protos_perfetto_config_lite",
@@ -1214,55 +1204,12 @@
],
)
-# GN target: //protos/perfetto/config:cpp
-perfetto_proto_library(
- name = "protos_perfetto_config_cpp_protos",
- srcs = [
- "protos/perfetto/config/chrome/chrome_config.proto",
- "protos/perfetto/config/data_source_config.proto",
- "protos/perfetto/config/test_config.proto",
- "protos/perfetto/config/trace_config.proto",
- ],
- deps = [
- ":protos_perfetto_common_cpp_protos",
- ":protos_perfetto_common_protos",
- ":protos_perfetto_config_android_cpp_protos",
- ":protos_perfetto_config_android_protos",
- ":protos_perfetto_config_ftrace_cpp_protos",
- ":protos_perfetto_config_ftrace_protos",
- ":protos_perfetto_config_gpu_cpp_protos",
- ":protos_perfetto_config_gpu_protos",
- ":protos_perfetto_config_inode_file_cpp_protos",
- ":protos_perfetto_config_inode_file_protos",
- ":protos_perfetto_config_power_cpp_protos",
- ":protos_perfetto_config_power_protos",
- ":protos_perfetto_config_process_stats_cpp_protos",
- ":protos_perfetto_config_process_stats_protos",
- ":protos_perfetto_config_profiling_cpp_protos",
- ":protos_perfetto_config_profiling_protos",
- ":protos_perfetto_config_protos",
- ":protos_perfetto_config_sys_stats_cpp_protos",
- ":protos_perfetto_config_sys_stats_protos",
- ],
-)
-
# GN target: //protos/perfetto/config/ftrace:cpp
perfetto_cc_protocpp_library(
name = "protos_perfetto_config_ftrace_cpp",
deps = [
- ":protos_perfetto_config_ftrace_cpp_protos",
- ":protos_perfetto_config_ftrace_lite",
- ],
-)
-
-# GN target: //protos/perfetto/config/ftrace:cpp
-perfetto_proto_library(
- name = "protos_perfetto_config_ftrace_cpp_protos",
- srcs = [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
- ],
- deps = [
":protos_perfetto_config_ftrace_protos",
+ ":protos_perfetto_config_ftrace_lite",
],
)
@@ -1294,19 +1241,8 @@
perfetto_cc_protocpp_library(
name = "protos_perfetto_config_gpu_cpp",
deps = [
- ":protos_perfetto_config_gpu_cpp_protos",
- ":protos_perfetto_config_gpu_lite",
- ],
-)
-
-# GN target: //protos/perfetto/config/gpu:cpp
-perfetto_proto_library(
- name = "protos_perfetto_config_gpu_cpp_protos",
- srcs = [
- "protos/perfetto/config/gpu/gpu_counter_config.proto",
- ],
- deps = [
":protos_perfetto_config_gpu_protos",
+ ":protos_perfetto_config_gpu_lite",
],
)
@@ -1338,19 +1274,8 @@
perfetto_cc_protocpp_library(
name = "protos_perfetto_config_inode_file_cpp",
deps = [
- ":protos_perfetto_config_inode_file_cpp_protos",
- ":protos_perfetto_config_inode_file_lite",
- ],
-)
-
-# GN target: //protos/perfetto/config/inode_file:cpp
-perfetto_proto_library(
- name = "protos_perfetto_config_inode_file_cpp_protos",
- srcs = [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
- ],
- deps = [
":protos_perfetto_config_inode_file_protos",
+ ":protos_perfetto_config_inode_file_lite",
],
)
@@ -1409,19 +1334,8 @@
perfetto_cc_protocpp_library(
name = "protos_perfetto_config_power_cpp",
deps = [
- ":protos_perfetto_config_power_cpp_protos",
- ":protos_perfetto_config_power_lite",
- ],
-)
-
-# GN target: //protos/perfetto/config/power:cpp
-perfetto_proto_library(
- name = "protos_perfetto_config_power_cpp_protos",
- srcs = [
- "protos/perfetto/config/power/android_power_config.proto",
- ],
- deps = [
":protos_perfetto_config_power_protos",
+ ":protos_perfetto_config_power_lite",
],
)
@@ -1453,19 +1367,8 @@
perfetto_cc_protocpp_library(
name = "protos_perfetto_config_process_stats_cpp",
deps = [
- ":protos_perfetto_config_process_stats_cpp_protos",
- ":protos_perfetto_config_process_stats_lite",
- ],
-)
-
-# GN target: //protos/perfetto/config/process_stats:cpp
-perfetto_proto_library(
- name = "protos_perfetto_config_process_stats_cpp_protos",
- srcs = [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
- ],
- deps = [
":protos_perfetto_config_process_stats_protos",
+ ":protos_perfetto_config_process_stats_lite",
],
)
@@ -1497,20 +1400,8 @@
perfetto_cc_protocpp_library(
name = "protos_perfetto_config_profiling_cpp",
deps = [
- ":protos_perfetto_config_profiling_cpp_protos",
- ":protos_perfetto_config_profiling_lite",
- ],
-)
-
-# GN target: //protos/perfetto/config/profiling:cpp
-perfetto_proto_library(
- name = "protos_perfetto_config_profiling_cpp_protos",
- srcs = [
- "protos/perfetto/config/profiling/heapprofd_config.proto",
- "protos/perfetto/config/profiling/java_hprof_config.proto",
- ],
- deps = [
":protos_perfetto_config_profiling_protos",
+ ":protos_perfetto_config_profiling_lite",
],
)
@@ -1565,26 +1456,13 @@
perfetto_cc_protocpp_library(
name = "protos_perfetto_config_sys_stats_cpp",
deps = [
- ":protos_perfetto_config_sys_stats_cpp_protos",
+ ":protos_perfetto_config_sys_stats_protos",
":protos_perfetto_common_lite",
":protos_perfetto_config_sys_stats_lite",
":protos_perfetto_common_cpp",
],
)
-# GN target: //protos/perfetto/config/sys_stats:cpp
-perfetto_proto_library(
- name = "protos_perfetto_config_sys_stats_cpp_protos",
- srcs = [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
- ],
- deps = [
- ":protos_perfetto_common_cpp_protos",
- ":protos_perfetto_common_protos",
- ":protos_perfetto_config_sys_stats_protos",
- ],
-)
-
# GN target: //protos/perfetto/config/sys_stats:lite
perfetto_cc_proto_library(
name = "protos_perfetto_config_sys_stats_lite",
@@ -2448,6 +2326,7 @@
hdrs = [
":include_perfetto_base_base",
":include_perfetto_ext_base_base",
+ ":include_perfetto_ext_trace_processor_export_json",
":include_perfetto_ext_traced_sys_stats_counters",
":include_perfetto_protozero_protozero",
":include_perfetto_trace_processor_trace_processor",
@@ -2500,6 +2379,7 @@
"src/trace_processor/trace_processor_shell.cc",
":include_perfetto_base_base",
":include_perfetto_ext_base_base",
+ ":include_perfetto_ext_trace_processor_export_json",
":include_perfetto_ext_traced_sys_stats_counters",
":include_perfetto_protozero_protozero",
":include_perfetto_trace_processor_trace_processor",
@@ -2602,6 +2482,7 @@
hdrs = [
":include_perfetto_base_base",
":include_perfetto_ext_base_base",
+ ":include_perfetto_ext_trace_processor_export_json",
":include_perfetto_ext_traced_sys_stats_counters",
":include_perfetto_profiling_symbolizer",
":include_perfetto_protozero_protozero",
@@ -2677,6 +2558,7 @@
srcs = [
":include_perfetto_base_base",
":include_perfetto_ext_base_base",
+ ":include_perfetto_ext_trace_processor_export_json",
":include_perfetto_ext_traced_sys_stats_counters",
":include_perfetto_profiling_symbolizer",
":include_perfetto_protozero_protozero",
diff --git a/BUILD.gn b/BUILD.gn
index be4b48c..7557952 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -233,6 +233,7 @@
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ]
public_deps = [
+ "include/perfetto/ext/trace_processor:export_json",
"include/perfetto/trace_processor",
]
}
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index 5340b14..60c8654 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -74,6 +74,9 @@
"PERFETTO_TP_LINENOISE=$enable_perfetto_trace_processor_linenoise",
"PERFETTO_TP_METRICS=$enable_perfetto_trace_processor_metrics",
"PERFETTO_TP_FTRACE=$enable_perfetto_trace_processor_ftrace",
+ "PERFETTO_TP_SYSTEM_PROBES=$enable_perfetto_trace_processor_system_probes",
+ "PERFETTO_TP_ANDROID_PROBES=$enable_perfetto_trace_processor_android_probes",
+ "PERFETTO_TP_GRAPHICS=$enable_perfetto_trace_processor_graphics",
"PERFETTO_TP_JSON=$enable_perfetto_trace_processor_json",
"PERFETTO_TP_FUCHSIA=$enable_perfetto_trace_processor_fuchsia",
"PERFETTO_LOCAL_SYMBOLIZER=$perfetto_local_symbolizer",
diff --git a/gn/perfetto.gni b/gn/perfetto.gni
index c4fa398..1185ed4 100644
--- a/gn/perfetto.gni
+++ b/gn/perfetto.gni
@@ -214,6 +214,18 @@
enable_perfetto_trace_processor_ftrace =
enable_perfetto_trace_processor && !build_with_chromium
+ # Enables parsing support for system probes in trace processor.
+ enable_perfetto_trace_processor_system_probes =
+ enable_perfetto_trace_processor && !build_with_chromium
+
+ # Enables parsing support for android system probes in trace processor.
+ enable_perfetto_trace_processor_android_probes =
+ enable_perfetto_trace_processor && !build_with_chromium
+
+ # Enables graphics event support in the trace processor.
+ enable_perfetto_trace_processor_graphics =
+ enable_perfetto_trace_processor && !build_with_chromium
+
# Enables JSON support in the trace processor.
enable_perfetto_trace_processor_json =
enable_perfetto_trace_processor && !perfetto_build_with_android
diff --git a/gn/perfetto_benchmarks.gni b/gn/perfetto_benchmarks.gni
index d5668d6..f711222 100644
--- a/gn/perfetto_benchmarks.gni
+++ b/gn/perfetto_benchmarks.gni
@@ -18,6 +18,7 @@
"gn:default_deps",
"src/traced/probes/ftrace:benchmarks",
"src/trace_processor/db:benchmarks",
+ "src/trace_processor/tables:benchmarks",
"src/tracing:benchmarks",
"test:benchmark_main",
"test:end_to_end_benchmarks",
diff --git a/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h b/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
index 2fa7fa2..be6d5fc 100644
--- a/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
+++ b/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
@@ -19,6 +19,9 @@
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_LINENOISE() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_METRICS() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_FTRACE() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_SYSTEM_PROBES() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_ANDROID_PROBES() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_GRAPHICS() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_FUCHSIA() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LOCAL_SYMBOLIZER() (PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX())
diff --git a/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
index 12fdb96..db367e5 100644
--- a/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
+++ b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
@@ -19,6 +19,9 @@
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_LINENOISE() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_METRICS() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_FTRACE() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_SYSTEM_PROBES() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_ANDROID_PROBES() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_GRAPHICS() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_FUCHSIA() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LOCAL_SYMBOLIZER() (PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX())
diff --git a/include/perfetto/base/compiler.h b/include/perfetto/base/compiler.h
index a4cb6ec..fa44b6b 100644
--- a/include/perfetto/base/compiler.h
+++ b/include/perfetto/base/compiler.h
@@ -30,10 +30,12 @@
#if defined(__clang__)
#define PERFETTO_ALWAYS_INLINE __attribute__((__always_inline__))
+#define PERFETTO_NO_INLINE __attribute__((__noinline__))
#else
// GCC is too pedantic and often fails with the error:
// "always_inline function might not be inlinable"
#define PERFETTO_ALWAYS_INLINE
+#define PERFETTO_NO_INLINE
#endif
// TODO(lalitm): is_trivially_constructible is currently not available
diff --git a/include/perfetto/ext/base/string_utils.h b/include/perfetto/ext/base/string_utils.h
index df1ed7c..657ff17 100644
--- a/include/perfetto/ext/base/string_utils.h
+++ b/include/perfetto/ext/base/string_utils.h
@@ -20,6 +20,10 @@
#include <string>
#include <vector>
+#include <inttypes.h>
+#include <stdlib.h>
+
+#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/string_view.h"
namespace perfetto {
@@ -33,6 +37,45 @@
return ('a' <= c && c <= 'z') ? (c += 'A' - 'a') : c;
}
+inline Optional<uint32_t> CStringToUInt32(const char* s) {
+ char* endptr = nullptr;
+ uint64_t value = strtoul(s, &endptr, 10);
+ Optional<uint32_t> result(base::nullopt);
+ if (*s != '\0' && *endptr == '\0')
+ result = static_cast<uint32_t>(value);
+ return result;
+}
+
+inline Optional<int32_t> CStringToInt32(const char* s) {
+ char* endptr = nullptr;
+ int64_t value = strtol(s, &endptr, 10);
+ Optional<int32_t> result(base::nullopt);
+ if (*s != '\0' && *endptr == '\0')
+ result = static_cast<int32_t>(value);
+ return result;
+}
+
+inline Optional<double> CStringToDouble(const char* s) {
+ char* endptr = nullptr;
+ double value = strtod(s, &endptr);
+ Optional<double> result(base::nullopt);
+ if (*s != '\0' && *endptr == '\0')
+ result = value;
+ return result;
+}
+
+inline Optional<uint32_t> StringToUInt32(const std::string& s) {
+ return CStringToUInt32(s.c_str());
+}
+
+inline Optional<int32_t> StringToInt32(const std::string& s) {
+ return CStringToInt32(s.c_str());
+}
+
+inline Optional<double> StringToDouble(const std::string& s) {
+ return CStringToDouble(s.c_str());
+}
+
bool StartsWith(const std::string& str, const std::string& prefix);
bool EndsWith(const std::string& str, const std::string& suffix);
bool Contains(const std::string& haystack, const std::string& needle);
diff --git a/include/perfetto/ext/base/unix_socket.h b/include/perfetto/ext/base/unix_socket.h
index b4e8e04..4bb9b04 100644
--- a/include/perfetto/ext/base/unix_socket.h
+++ b/include/perfetto/ext/base/unix_socket.h
@@ -37,8 +37,9 @@
// Use arbitrarily high values to avoid that some code accidentally ends up
// assuming that these enum values match the sysroot's SOCK_xxx defines rather
-// than using GetUnixSockType().
+// than using GetSockType() / GetSockFamily().
enum class SockType { kStream = 100, kDgram, kSeqPacket };
+enum class SockFamily { kUnix = 200, kInet };
// UnixSocketRaw is a basic wrapper around UNIX sockets. It exposes wrapper
// methods that take care of most common pitfalls (e.g., marking fd as
@@ -47,17 +48,20 @@
class UnixSocketRaw {
public:
// Creates a new unconnected unix socket.
- static UnixSocketRaw CreateMayFail(SockType t) { return UnixSocketRaw(t); }
+ static UnixSocketRaw CreateMayFail(SockFamily family, SockType type) {
+ return UnixSocketRaw(family, type);
+ }
// Crates a pair of connected sockets.
- static std::pair<UnixSocketRaw, UnixSocketRaw> CreatePair(SockType);
+ static std::pair<UnixSocketRaw, UnixSocketRaw> CreatePair(SockFamily,
+ SockType);
// Creates an uninitialized unix socket.
UnixSocketRaw();
// Creates a unix socket adopting an existing file descriptor. This is
// typically used to inherit fds from init via environment variables.
- UnixSocketRaw(ScopedFile, SockType);
+ UnixSocketRaw(ScopedFile, SockFamily, SockType);
~UnixSocketRaw() = default;
UnixSocketRaw(UnixSocketRaw&&) noexcept = default;
@@ -73,6 +77,7 @@
bool IsBlocking() const;
void RetainOnExec();
SockType type() const { return type_; }
+ SockFamily family() const { return family_; }
int fd() const { return *fd_; }
explicit operator bool() const { return !!fd_; }
@@ -98,13 +103,14 @@
static void ShiftMsgHdr(size_t n, struct msghdr* msg);
private:
- explicit UnixSocketRaw(SockType);
+ UnixSocketRaw(SockFamily, SockType);
UnixSocketRaw(const UnixSocketRaw&) = delete;
UnixSocketRaw& operator=(const UnixSocketRaw&) = delete;
ScopedFile fd_;
- SockType type_{SockType::kStream};
+ SockFamily family_ = SockFamily::kUnix;
+ SockType type_ = SockType::kStream;
};
// A non-blocking UNIX domain socket. Allows also to transfer file descriptors.
@@ -179,22 +185,26 @@
enum class BlockingMode { kNonBlocking, kBlocking };
- // Creates a Unix domain socket and starts listening. If |socket_name|
- // starts with a '@', an abstract socket will be created (Linux/Android only).
+ // Creates a socket and starts listening. If SockFamily::kUnix and
+ // |socket_name| starts with a '@', an abstract UNIX dmoain socket will be
+ // created instead of a filesystem-linked UNIX socket (Linux/Android only).
+ // If SockFamily::kInet, |socket_name| is host:port (e.g., "1.2.3.4:8000").
// Returns always an instance. In case of failure (e.g., another socket
// with the same name is already listening) the returned socket will have
// is_listening() == false and last_error() will contain the failure reason.
static std::unique_ptr<UnixSocket> Listen(const std::string& socket_name,
EventListener*,
TaskRunner*,
- SockType = SockType::kStream);
+ SockFamily,
+ SockType);
// Attaches to a pre-existing socket. The socket must have been created in
// SOCK_STREAM mode and the caller must have called bind() on it.
static std::unique_ptr<UnixSocket> Listen(ScopedFile,
EventListener*,
TaskRunner*,
- SockType = SockType::kStream);
+ SockFamily,
+ SockType);
// Creates a Unix domain socket and connects to the listening endpoint.
// Returns always an instance. EventListener::OnConnect(bool success) will
@@ -202,14 +212,15 @@
static std::unique_ptr<UnixSocket> Connect(const std::string& socket_name,
EventListener*,
TaskRunner*,
- SockType = SockType::kStream);
+ SockFamily,
+ SockType);
// Constructs a UnixSocket using the given connected socket.
- static std::unique_ptr<UnixSocket> AdoptConnected(
- ScopedFile fd,
- EventListener* event_listener,
- TaskRunner* task_runner,
- SockType sock_type);
+ static std::unique_ptr<UnixSocket> AdoptConnected(ScopedFile,
+ EventListener*,
+ TaskRunner*,
+ SockFamily,
+ SockType);
UnixSocket(const UnixSocket&) = delete;
UnixSocket& operator=(const UnixSocket&) = delete;
@@ -303,8 +314,13 @@
UnixSocketRaw ReleaseSocket();
private:
- UnixSocket(EventListener*, TaskRunner*, SockType);
- UnixSocket(EventListener*, TaskRunner*, ScopedFile, State, SockType);
+ UnixSocket(EventListener*, TaskRunner*, SockFamily, SockType);
+ UnixSocket(EventListener*,
+ TaskRunner*,
+ ScopedFile,
+ State,
+ SockFamily,
+ SockType);
// Called once by the corresponding public static factory methods.
void DoConnect(const std::string& socket_name);
diff --git a/include/perfetto/ext/trace_processor/BUILD.gn b/include/perfetto/ext/trace_processor/BUILD.gn
new file mode 100644
index 0000000..a2fd7fa
--- /dev/null
+++ b/include/perfetto/ext/trace_processor/BUILD.gn
@@ -0,0 +1,23 @@
+# 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.
+
+import("../../../../gn/perfetto.gni")
+
+# Exposed for Chromium only. May be removed in the future.
+source_set("export_json") {
+ sources = []
+ if (enable_perfetto_trace_processor_json) {
+ sources += [ "export_json.h" ]
+ }
+}
diff --git a/include/perfetto/ext/trace_processor/export_json.h b/include/perfetto/ext/trace_processor/export_json.h
new file mode 100644
index 0000000..b50de47
--- /dev/null
+++ b/include/perfetto/ext/trace_processor/export_json.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACE_PROCESSOR_EXPORT_JSON_H_
+#define INCLUDE_PERFETTO_EXT_TRACE_PROCESSOR_EXPORT_JSON_H_
+
+#include <stdio.h>
+
+#include <functional>
+
+#include "perfetto/base/export.h"
+#include "perfetto/trace_processor/status.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class TraceProcessor;
+
+namespace json {
+
+using ArgumentNameFilterPredicate = std::function<bool(const char* arg_name)>;
+using ArgumentFilterPredicate =
+ std::function<bool(const char* category_group_name,
+ const char* event_name,
+ ArgumentNameFilterPredicate*)>;
+using MetadataFilterPredicate = std::function<bool(const char* metadata_name)>;
+using LabelFilterPredicate = std::function<bool(const char* label_name)>;
+
+class PERFETTO_EXPORT OutputWriter {
+ public:
+ OutputWriter();
+ virtual ~OutputWriter();
+
+ virtual util::Status AppendString(const std::string&) = 0;
+};
+
+// Public for Chrome. Exports the trace loaded in TraceProcessor to json,
+// applying argument, metadata and label filtering using the callbacks.
+util::Status PERFETTO_EXPORT ExportJson(TraceProcessor*,
+ OutputWriter*,
+ ArgumentFilterPredicate = nullptr,
+ MetadataFilterPredicate = nullptr,
+ LabelFilterPredicate = nullptr);
+
+} // namespace json
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_TRACE_PROCESSOR_EXPORT_JSON_H_
diff --git a/include/perfetto/trace_processor/basic_types.h b/include/perfetto/trace_processor/basic_types.h
index 4c0f951..efac31c 100644
--- a/include/perfetto/trace_processor/basic_types.h
+++ b/include/perfetto/trace_processor/basic_types.h
@@ -30,7 +30,12 @@
namespace perfetto {
namespace trace_processor {
-struct PERFETTO_EXPORT Config {};
+// Struct for configuring a TraceProcessor instance (see trace_processor.h).
+struct PERFETTO_EXPORT Config {
+ // When set to true, this option forces trace processor to perform a full
+ // sort ignoring any internal heureustics to skip sorting parts of the data.
+ bool force_full_sort = false;
+};
// Represents a dynamically typed value returned by SQL.
struct PERFETTO_EXPORT SqlValue {
diff --git a/include/perfetto/trace_processor/trace_processor.h b/include/perfetto/trace_processor/trace_processor.h
index 2c07b53..f6f5089 100644
--- a/include/perfetto/trace_processor/trace_processor.h
+++ b/include/perfetto/trace_processor/trace_processor.h
@@ -25,7 +25,6 @@
#include "perfetto/trace_processor/status.h"
namespace perfetto {
-
namespace trace_processor {
// Coordinates the loading of traces from an arbitrary source and allows
diff --git a/include/perfetto/tracing/BUILD.gn b/include/perfetto/tracing/BUILD.gn
index 8be1aa8..289abf3 100644
--- a/include/perfetto/tracing/BUILD.gn
+++ b/include/perfetto/tracing/BUILD.gn
@@ -29,11 +29,14 @@
"internal/tracing_muxer.h",
"internal/tracing_tls.h",
"internal/track_event_data_source.h",
+ "internal/track_event_internal.h",
+ "internal/track_event_macros.h",
"locked_handle.h",
"platform.h",
"trace_writer_base.h",
"tracing.h",
"tracing_backend.h",
"track_event.h",
+ "track_event_category_registry.h",
]
}
diff --git a/include/perfetto/tracing/data_source.h b/include/perfetto/tracing/data_source.h
index c6fa774..312ba34 100644
--- a/include/perfetto/tracing/data_source.h
+++ b/include/perfetto/tracing/data_source.h
@@ -44,6 +44,9 @@
#include "protos/perfetto/trace/trace_packet.pbzero.h"
namespace perfetto {
+namespace internal {
+class TracingMuxerImpl;
+} // namespace internal
class DataSourceConfig;
@@ -65,10 +68,17 @@
// This is valid only within the scope of the OnSetup() call and must not
// be retained.
const DataSourceConfig* config = nullptr;
+
+ // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+ uint32_t internal_instance_index = 0;
};
virtual void OnSetup(const SetupArgs&);
- class StartArgs {};
+ class StartArgs {
+ public:
+ // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+ uint32_t internal_instance_index = 0;
+ };
virtual void OnStart(const StartArgs&);
class StopArgs {
@@ -94,20 +104,49 @@
// other words, it is fine to accidentally hold onto this closure for too
// long but, if that happens, some tracing data will be lost.
virtual std::function<void()> HandleStopAsynchronously() const = 0;
+
+ // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+ uint32_t internal_instance_index = 0;
};
virtual void OnStop(const StopArgs&);
};
+struct DefaultDataSourceTraits {
+ // |IncrementalStateType| can optionally be used store custom per-sequence
+ // incremental data (e.g., interning tables). It should have a Clear() method
+ // for when incremental state needs to be cleared. See
+ // TraceContext::GetIncrementalState().
+ using IncrementalStateType = void;
+
+ // Allows overriding what type of thread-local state configuration the data
+ // source uses. By default every data source gets independent thread-local
+ // state, which means every instance uses separate trace writers and
+ // incremental state even on the same thread. Some data sources (most notably
+ // the track event data source) want to share trace writers and incremental
+ // state on the same thread.
+ static internal::DataSourceThreadLocalState* GetDataSourceTLS(
+ internal::DataSourceStaticState* static_state,
+ internal::TracingTLS* root_tls) {
+ auto* ds_tls = &root_tls->data_sources_tls[static_state->index];
+ // The per-type TLS is either zero-initialized or must have been initialized
+ // for this specific data source type.
+ assert(!ds_tls->static_state ||
+ ds_tls->static_state->index == static_state->index);
+ return ds_tls;
+ }
+};
+
// Templated base class meant to be derived by embedders to create a custom data
// source. DataSourceType must be the type of the derived class itself, e.g.:
// class MyDataSource : public DataSourceBase<MyDataSource> {...}.
//
-// |IncrementalStateType| can optionally be used store custom per-sequence
-// incremental data (e.g., interning tables). It should have a Clear() method
-// for when incremental state needs to be cleared. See
-// TraceContext::GetIncrementalState().
-template <typename DataSourceType, typename IncrementalStateType = void>
+// |DataSourceTraits| allows customizing the behavior of the data source. See
+// |DefaultDataSourceTraits|.
+template <typename DataSourceType,
+ typename DataSourceTraits = DefaultDataSourceTraits>
class DataSource : public DataSourceBase {
+ struct DefaultTracePointTraits;
+
public:
// The BufferExhaustedPolicy to use for TraceWriters of this DataSource.
// Override this in your DataSource class to change the default, which is to
@@ -162,11 +201,13 @@
static_cast<DataSourceType*>(internal_state->data_source.get()));
}
- IncrementalStateType* GetIncrementalState() {
- return reinterpret_cast<IncrementalStateType*>(
+ typename DataSourceTraits::IncrementalStateType* GetIncrementalState() {
+ return reinterpret_cast<typename DataSourceTraits::IncrementalStateType*>(
tls_inst_->incremental_state.get());
}
+ uint32_t internal_instance_index() const { return instance_index_; }
+
private:
friend class DataSource;
TraceContext(internal::DataSourceInstanceThreadLocalState* tls_inst,
@@ -189,33 +230,55 @@
// twice within the same trace config).
template <typename Lambda>
static void Trace(Lambda tracing_fn) {
- constexpr auto kMaxDataSourceInstances = internal::kMaxDataSourceInstances;
+ CallIfEnabled<DefaultTracePointTraits>([&tracing_fn](uint32_t instances) {
+ TraceWithInstances<DefaultTracePointTraits>(instances,
+ std::move(tracing_fn));
+ });
+ }
+ // An efficient trace point guard for checking if this data source is active.
+ // |callback| is a function which will only be called if there are active
+ // instances. It is given an instance state parameter, which should be passed
+ // to TraceWithInstances() to actually record trace data.
+ template <typename Traits = DefaultTracePointTraits, typename Callback>
+ static void CallIfEnabled(Callback callback) PERFETTO_ALWAYS_INLINE {
// |instances| is a per-class bitmap that tells:
// 1. If the data source is enabled at all.
- // 2. The index of the slot within |valid_instances| that holds the instance
+ // 2. The index of the slot within |static_state_| that holds the instance
// state. In turn this allows to map the data source to the tracing
// session and buffers.
// memory_order_relaxed is okay because:
// - |instances| is re-read with an acquire barrier below if this succeeds.
// - The code between this point and the acquire-load is based on static
// storage which has indefinite lifetime.
- auto instances =
- static_state_.valid_instances.load(std::memory_order_relaxed);
+ uint32_t instances =
+ Traits::GetActiveInstances()->load(std::memory_order_relaxed);
// This is the tracing fast-path. Bail out immediately if tracing is not
// enabled (or tracing is enabled but not for this data source).
if (PERFETTO_LIKELY(!instances))
return;
+ callback(instances);
+ }
- // TODO(primiano): all the stuff below should be outlined. Or at least
- // we should have some compile-time traits like kOptimizeBinarySize /
- // kOptimizeTracingLatency.
+ // The "lower half" of a trace point which actually performs tracing after
+ // this data source has been determined to be active.
+ // |instances| must be the instance state value retrieved through
+ // CallIfEnabled().
+ // |tracing_fn| will be called to record trace data as in Trace().
+ //
+ // TODO(primiano): all the stuff below should be outlined from the trace
+ // point. Or at least we should have some compile-time traits like
+ // kOptimizeBinarySize / kOptimizeTracingLatency.
+ template <typename Traits = DefaultTracePointTraits, typename Lambda>
+ static void TraceWithInstances(uint32_t instances, Lambda tracing_fn) {
+ PERFETTO_DCHECK(instances);
+ constexpr auto kMaxDataSourceInstances = internal::kMaxDataSourceInstances;
// See tracing_muxer.h for the structure of the TLS.
auto* tracing_impl = internal::TracingMuxer::Get();
if (PERFETTO_UNLIKELY(!tls_state_))
- tls_state_ = tracing_impl->GetOrCreateDataSourceTLS(&static_state_);
+ tls_state_ = GetOrCreateDataSourceTLS(&static_state_);
// TracingTLS::generation is a global monotonic counter that is incremented
// every time a tracing session is stopped. We use that as a signal to force
@@ -276,7 +339,7 @@
// by TracingMuxerImpl::SetupDataSource(), to ensure that the backend_id
// and buffer_id are consistent.
instances =
- static_state_.valid_instances.load(std::memory_order_acquire);
+ Traits::GetActiveInstances()->load(std::memory_order_acquire);
instance_state = static_state_.TryGetCached(instances, i);
if (!instance_state || !instance_state->trace_lambda_enabled)
return;
@@ -284,8 +347,10 @@
tls_inst.buffer_id = instance_state->buffer_id;
tls_inst.trace_writer = tracing_impl->CreateTraceWriter(
instance_state, DataSourceType::kBufferExhaustedPolicy);
- CreateIncrementalState(&tls_inst,
- static_cast<IncrementalStateType*>(nullptr));
+ CreateIncrementalState(
+ &tls_inst,
+ static_cast<typename DataSourceTraits::IncrementalStateType*>(
+ nullptr));
// Even in the case of out-of-IDs, SharedMemoryArbiterImpl returns a
// NullTraceWriter. The returned pointer should never be null.
@@ -320,6 +385,20 @@
}
private:
+ // Traits for customizing the behavior of a specific trace point.
+ struct DefaultTracePointTraits {
+ // By default, every call to DataSource::Trace() will record trace events
+ // for every active instance of that data source. A single trace point can,
+ // however, use a custom set of enable flags for more fine grained control
+ // of when that trace point is active.
+ //
+ // DANGER: when doing this, the data source must use the appropriate memory
+ // fences when changing the state of the bitmap.
+ static constexpr std::atomic<uint32_t>* GetActiveInstances() {
+ return &static_state_.valid_instances;
+ }
+ };
+
// Create the user provided incremental state in the given thread-local
// storage. Note: The second parameter here is used to specialize the case
// where there is no incremental state type.
@@ -337,6 +416,22 @@
internal::DataSourceInstanceThreadLocalState*,
const void*) {}
+ // Note that the returned object is one per-thread per-data-source-type, NOT
+ // per data-source *instance*.
+ static internal::DataSourceThreadLocalState* GetOrCreateDataSourceTLS(
+ internal::DataSourceStaticState* static_state) {
+ auto* tracing_impl = internal::TracingMuxer::Get();
+ internal::TracingTLS* root_tls = tracing_impl->GetOrCreateTracingTLS();
+ internal::DataSourceThreadLocalState* ds_tls =
+ DataSourceTraits::GetDataSourceTLS(static_state, root_tls);
+ // We keep re-initializing as the initialization is idempotent and not worth
+ // the code for extra checks.
+ ds_tls->static_state = static_state;
+ assert(!ds_tls->root_tls || ds_tls->root_tls == root_tls);
+ ds_tls->root_tls = root_tls;
+ return ds_tls;
+ }
+
// Static state. Accessed by the static Trace() method fastpaths.
static internal::DataSourceStaticState static_state_;
@@ -350,17 +445,16 @@
static thread_local internal::DataSourceThreadLocalState* tls_state_;
};
+template <typename T, typename D>
+internal::DataSourceStaticState DataSource<T, D>::static_state_;
+template <typename T, typename D>
+thread_local internal::DataSourceThreadLocalState* DataSource<T, D>::tls_state_;
+
} // namespace perfetto
-// If a data source is used across translation units, this declaration must be
-// placed into the header file defining the data source.
-#define PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(...) \
- template <> \
- perfetto::internal::DataSourceStaticState \
- perfetto::DataSource<__VA_ARGS__>::static_state_; \
- template <> \
- thread_local perfetto::internal::DataSourceThreadLocalState* \
- perfetto::DataSource<__VA_ARGS__>::tls_state_
+// Not needed -- only here for backwards compatibility.
+// TODO(skyostil): Remove this macro.
+#define PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(...)
// The API client must use this in a translation unit. This is because it needs
// to instantiate the static storage for the datasource to allow the fastpath
diff --git a/include/perfetto/tracing/internal/data_source_internal.h b/include/perfetto/tracing/internal/data_source_internal.h
index 6a373f7..8e06ee4 100644
--- a/include/perfetto/tracing/internal/data_source_internal.h
+++ b/include/perfetto/tracing/internal/data_source_internal.h
@@ -75,6 +75,11 @@
// Only the tuple (backend_id, data_source_instance_id) is globally unique.
uint64_t data_source_instance_id = 0;
+ // A hash of the trace config used by this instance. This is used to
+ // de-duplicate instances for data sources with identical names (e.g., track
+ // event).
+ uint64_t config_hash = 0;
+
// This lock is not held to implement Trace() and it's used only if the trace
// code wants to access its own data source state.
// This is to prevent that accessing the data source on an arbitrary embedder
@@ -93,8 +98,8 @@
// Per-DataSource-type global state.
struct DataSourceStaticState {
- uint32_t index =
- kMaxDataSources; // Unique ID, assigned at registration time.
+ // Unique index of the data source, assigned at registration time.
+ uint32_t index = kMaxDataSources;
// A bitmap that tells about the validity of each |instances| entry. When the
// i-th bit of the bitmap it's set, instances[i] is valid.
diff --git a/include/perfetto/tracing/internal/tracing_muxer.h b/include/perfetto/tracing/internal/tracing_muxer.h
index 6cc7187..4556ed3 100644
--- a/include/perfetto/tracing/internal/tracing_muxer.h
+++ b/include/perfetto/tracing/internal/tracing_muxer.h
@@ -57,23 +57,6 @@
return static_cast<TracingTLS*>(platform_->GetOrCreateThreadLocalObject());
}
- // Note that the returned object is one per-thread per-data-source-type, NOT
- // per data-soruce *instance*.
- DataSourceThreadLocalState* GetOrCreateDataSourceTLS(
- DataSourceStaticState* static_state) {
- TracingTLS* root_tls = GetOrCreateTracingTLS();
- auto* ds_tls = &root_tls->data_sources_tls[static_state->index];
-
- // The per-type TLS is either zero-initialized or must have been initialized
- // for this specific data source type. We keep re-initializing as the
- // initialization is idempotent and not worth the code for extra checks.
- assert(!ds_tls->static_state || ds_tls->static_state == static_state);
- ds_tls->static_state = static_state;
- assert(!ds_tls->root_tls || ds_tls->root_tls == root_tls);
- ds_tls->root_tls = root_tls;
- return ds_tls;
- }
-
// This method can fail and return false if trying to register more than
// kMaxDataSources types.
using DataSourceFactory = std::function<std::unique_ptr<DataSourceBase>()>;
diff --git a/include/perfetto/tracing/internal/tracing_tls.h b/include/perfetto/tracing/internal/tracing_tls.h
index 8c39dfa..67f0637 100644
--- a/include/perfetto/tracing/internal/tracing_tls.h
+++ b/include/perfetto/tracing/internal/tracing_tls.h
@@ -74,7 +74,14 @@
// thread-local TraceWriter(s) is issued.
uint32_t generation = 0;
+ // By default all data source instances have independent thread-local state
+ // (see above).
std::array<DataSourceThreadLocalState, kMaxDataSources> data_sources_tls{};
+
+ // Track event data sources, however, share the same thread-local state in
+ // order to be able to share trace writers and interning state across all
+ // track event categories.
+ DataSourceThreadLocalState track_event_tls{};
};
} // namespace internal
diff --git a/include/perfetto/tracing/internal/track_event_data_source.h b/include/perfetto/tracing/internal/track_event_data_source.h
index a2a8199..742e438 100644
--- a/include/perfetto/tracing/internal/track_event_data_source.h
+++ b/include/perfetto/tracing/internal/track_event_data_source.h
@@ -17,61 +17,105 @@
#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_DATA_SOURCE_H_
#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_DATA_SOURCE_H_
+#include "perfetto/base/compiler.h"
+#include "perfetto/protozero/message_handle.h"
#include "perfetto/tracing/data_source.h"
+#include "perfetto/tracing/internal/track_event_internal.h"
+#include "perfetto/tracing/track_event_category_registry.h"
#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
#include <unordered_map>
namespace perfetto {
-class TrackEvent;
-
namespace internal {
-struct TrackEventIncrementalState {
- bool was_cleared = true;
+struct TrackEventDataSourceTraits : public perfetto::DefaultDataSourceTraits {
+ using IncrementalStateType = TrackEventIncrementalState;
- // Interned data.
- // TODO(skyostil): Replace this with something more clever that supports
- // dynamic strings too.
- std::unordered_map<const char*, uint64_t> event_names;
- std::unordered_map<const char*, uint64_t> categories;
+ // Use a one shared TLS slot so that all track event data sources write into
+ // the same sequence and share interning dictionaries.
+ static DataSourceThreadLocalState* GetDataSourceTLS(DataSourceStaticState*,
+ TracingTLS* root_tls) {
+ return &root_tls->track_event_tls;
+ }
};
+// A generic track event data source which is instantiated once per track event
+// category namespace.
+template <typename DataSourceType, const TrackEventCategoryRegistry* Registry>
class TrackEventDataSource
- : public DataSource<TrackEventDataSource, TrackEventIncrementalState> {
+ : public DataSource<DataSourceType, TrackEventDataSourceTraits> {
+ using Base = DataSource<DataSourceType, TrackEventDataSourceTraits>;
+
public:
- void OnSetup(const SetupArgs&) override;
- void OnStart(const StartArgs&) override;
- void OnStop(const StopArgs&) override;
-
- private:
- friend class perfetto::TrackEvent;
-
- static void WriteEvent(const char* category,
- const char* name,
- perfetto::protos::pbzero::TrackEvent::Type type) {
- Trace([category, name, type](TraceContext ctx) {
- WriteEventImpl(std::move(ctx), category, name, type);
- });
+ // DataSource implementation.
+ void OnSetup(const DataSourceBase::SetupArgs& args) override {
+ TrackEventInternal::EnableTracing(*Registry, *args.config,
+ args.internal_instance_index);
}
- // Outlined to reduce binary size.
- static void WriteEventImpl(TraceContext ctx,
- const char* category,
- const char* name,
- perfetto::protos::pbzero::TrackEvent::Type type);
+ void OnStart(const DataSourceBase::StartArgs&) override {}
- static void WriteSequenceDescriptors(
- internal::TrackEventDataSource::TraceContext*,
- uint64_t timestamp);
+ void OnStop(const DataSourceBase::StopArgs& args) override {
+ TrackEventInternal::DisableTracing(*Registry, args.internal_instance_index);
+ }
+
+ static void Flush() {
+ Base::template Trace([](typename Base::TraceContext ctx) { ctx.Flush(); });
+ }
+
+ // This is the inlined entrypoint for all track event trace points. It tries
+ // to be as lightweight as possible in terms of instructions and aims to
+ // compile down to an unlikely conditional jump to the actual trace writing
+ // function.
+ template <size_t CategoryIndex, typename Callback>
+ static void CallIfCategoryEnabled(Callback callback) PERFETTO_ALWAYS_INLINE {
+ Base::template CallIfEnabled<CategoryTracePointTraits<CategoryIndex>>(
+ [&callback](uint32_t instances) { callback(instances); });
+ }
+
+ // Once we've determined tracing to be enabled for this category, actually
+ // write a trace event. Outlined to avoid bloating code at the actual trace
+ // point.
+ // TODO(skyostil): Investigate whether this should be fully outlined to reduce
+ // binary size.
+ template <size_t CategoryIndex>
+ static void TraceForCategory(uint32_t instances,
+ const char* event_name,
+ perfetto::protos::pbzero::TrackEvent::Type type)
+ PERFETTO_NO_INLINE {
+ Base::template TraceWithInstances<CategoryTracePointTraits<CategoryIndex>>(
+ instances, [&](typename Base::TraceContext ctx) {
+ TrackEventTraceContext track_event_ctx(
+ ctx.GetIncrementalState(),
+ [&ctx]() { return ctx.NewTracePacket(); });
+ // TODO(skyostil): Intern categories at compile time.
+ TrackEventInternal::WriteEvent(
+ &track_event_ctx, Registry->GetCategory(CategoryIndex)->name,
+ event_name, type);
+ });
+ }
+
+ static bool Register() {
+ TrackEventInternal::Initialize();
+ perfetto::DataSourceDescriptor dsd;
+ // TODO(skyostil): Advertise the known categories.
+ dsd.set_name("track_event");
+ return Base::Register(dsd);
+ }
+
+ private:
+ // Each category has its own enabled/disabled state, stored in the category
+ // registry.
+ template <size_t CategoryIndex>
+ struct CategoryTracePointTraits {
+ static constexpr std::atomic<uint8_t>* GetActiveInstances() {
+ return Registry->GetCategoryState(CategoryIndex);
+ }
+ };
};
} // namespace internal
-
} // namespace perfetto
-PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(
- perfetto::internal::TrackEventDataSource,
- perfetto::internal::TrackEventIncrementalState);
-
#endif // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_DATA_SOURCE_H_
diff --git a/include/perfetto/tracing/internal/track_event_internal.h b/include/perfetto/tracing/internal/track_event_internal.h
new file mode 100644
index 0000000..5f594fb
--- /dev/null
+++ b/include/perfetto/tracing/internal/track_event_internal.h
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNAL_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNAL_H_
+
+#include "perfetto/protozero/message_handle.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+#include <unordered_map>
+
+namespace perfetto {
+class DataSourceConfig;
+
+namespace internal {
+class TrackEventCategoryRegistry;
+
+struct TrackEventIncrementalState {
+ bool was_cleared = true;
+
+ // Interned data.
+ // TODO(skyostil): Replace this with something more clever that supports
+ // dynamic strings too.
+ std::unordered_map<const char*, uint64_t> event_names;
+ std::unordered_map<const char*, uint64_t> categories;
+};
+
+class TrackEventTraceContext {
+ public:
+ using TracePacketHandle =
+ ::protozero::MessageHandle<::perfetto::protos::pbzero::TracePacket>;
+ using TracePacketCreator = std::function<TracePacketHandle()>;
+
+ TrackEventTraceContext(TrackEventIncrementalState* incremental_state,
+ TracePacketCreator new_trace_packet);
+
+ TrackEventIncrementalState* incremental_state() const {
+ return incremental_state_;
+ }
+
+ TracePacketHandle NewTracePacket();
+
+ private:
+ TrackEventIncrementalState* incremental_state_;
+ TracePacketCreator new_trace_packet_;
+};
+
+// The backend portion of the track event trace point implemention. Outlined to
+// a separate .cc file so it can be shared by different track event category
+// namespaces.
+class TrackEventInternal {
+ public:
+ static void Initialize();
+
+ static void EnableTracing(const TrackEventCategoryRegistry& registry,
+ const DataSourceConfig& config,
+ uint32_t instance_index);
+ static void DisableTracing(const TrackEventCategoryRegistry& registry,
+ uint32_t instance_index);
+
+ static void WriteEvent(TrackEventTraceContext*,
+ const char* category,
+ const char* name,
+ perfetto::protos::pbzero::TrackEvent::Type);
+};
+
+} // namespace internal
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNAL_H_
diff --git a/include/perfetto/tracing/internal/track_event_macros.h b/include/perfetto/tracing/internal/track_event_macros.h
new file mode 100644
index 0000000..915176c
--- /dev/null
+++ b/include/perfetto/tracing/internal/track_event_macros.h
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
+
+// This file contains underlying macros for the trace point track event
+// implementation. Perfetto API users typically don't need to use anything here
+// directly.
+
+#include "perfetto/base/compiler.h"
+#include "perfetto/tracing/internal/track_event_data_source.h"
+#include "perfetto/tracing/track_event_category_registry.h"
+
+// Defines data structures for backing a category registry.
+//
+// Each category has one enabled/disabled bit per possible data source instance.
+// The bits are packed, i.e., each byte holds the state for instances. To
+// improve cache locality, the bits for each instance are stored separately from
+// the names of the categories:
+//
+// byte 0 byte 1
+// (inst0, inst1, ..., inst7), (inst0, inst1, ..., inst7)
+//
+#define PERFETTO_INTERNAL_DECLARE_CATEGORIES(...) \
+ namespace internal { \
+ constexpr ::perfetto::internal::TrackEventCategory kCategories[] = { \
+ __VA_ARGS__}; \
+ constexpr size_t kCategoryCount = \
+ sizeof(kCategories) / sizeof(kCategories[0]); \
+ /* The per-instance enable/disable state per category */ \
+ extern std::atomic<uint8_t> g_category_state_storage[kCategoryCount]; \
+ /* The category registry which mediates access to the above structures. */ \
+ /* The registry is used for two purposes: */ \
+ /**/ \
+ /* 1) For looking up categories at build (constexpr) time. */ \
+ /* 2) For declaring the per-namespace TrackEvent data source. */ \
+ /**/ \
+ /* Because usage #1 requires a constexpr type and usage #2 requires an */ \
+ /* extern type (to avoid declaring a type based on a translation-unit */ \
+ /* variable), we need two separate copies of the registry with different */ \
+ /* storage specifiers. */ \
+ /**/ \
+ /* TODO(skyostil): Unify these using a C++17 inline constexpr variable. */ \
+ constexpr ::perfetto::internal::TrackEventCategoryRegistry \
+ kConstExprCategoryRegistry(kCategoryCount, \
+ &kCategories[0], \
+ &g_category_state_storage[0]); \
+ extern const ::perfetto::internal::TrackEventCategoryRegistry \
+ kCategoryRegistry; \
+ } // namespace internal
+
+// In a .cc file, declares storage for each category's runtime state.
+#define PERFETTO_INTERNAL_CATEGORY_STORAGE() \
+ namespace internal { \
+ std::atomic<uint8_t> g_category_state_storage[kCategoryCount]; \
+ constexpr ::perfetto::internal::TrackEventCategoryRegistry \
+ kCategoryRegistry(kCategoryCount, \
+ &kCategories[0], \
+ &g_category_state_storage[0]); \
+ } // namespace internal
+
+// Defines the TrackEvent data source for the current track event namespace.
+#define PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE() \
+ struct TrackEvent : public ::perfetto::internal::TrackEventDataSource< \
+ TrackEvent, &internal::kCategoryRegistry> {}
+
+// At compile time, turns a category name represented by a static string into an
+// index into the current category registry. A build error will be generated if
+// the category hasn't been registered. See PERFETTO_DEFINE_CATEGORIES.
+#define PERFETTO_GET_CATEGORY_INDEX(category) \
+ ::perfetto::internal::TrackEventCategoryRegistry::Validate< \
+ ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry \
+ .Find(category)>()
+
+// Efficiently determines whether tracing is enabled for the given category, and
+// if so, emits one trace event with the given arguments.
+#define PERFETTO_INTERNAL_TRACK_EVENT(category, ...) \
+ ::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::CallIfCategoryEnabled< \
+ PERFETTO_GET_CATEGORY_INDEX(category)>([&](uint32_t instances) { \
+ ::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::TraceForCategory< \
+ PERFETTO_GET_CATEGORY_INDEX(category)>(instances, __VA_ARGS__); \
+ })
+
+#endif // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
diff --git a/include/perfetto/tracing/track_event.h b/include/perfetto/tracing/track_event.h
index 3c6dee1..e6e9689 100644
--- a/include/perfetto/tracing/track_event.h
+++ b/include/perfetto/tracing/track_event.h
@@ -19,57 +19,98 @@
#include "perfetto/base/time.h"
#include "perfetto/tracing/internal/track_event_data_source.h"
+#include "perfetto/tracing/internal/track_event_macros.h"
+#include "perfetto/tracing/track_event_category_registry.h"
#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
-namespace perfetto {
+// This file contains a set of macros designed for instrumenting applications
+// with track event trace points. While the underlying TrackEvent API can also
+// be used directly, doing so efficiently requires some care (e.g., to avoid
+// evaluating arguments while tracing is disabled). These types of optimizations
+// are abstracted away by the macros below.
+//
+// ================
+// Quickstart guide
+// ================
+//
+// To add track events to your application, first define your categories in,
+// e.g., my_tracing.h:
+//
+// PERFETTO_DEFINE_CATEGORIES(
+// PERFETTO_CATEGORY(base),
+// PERFETTO_CATEGORY(v8),
+// PERFETTO_CATEGORY(cc));
+//
+// Then in a single .cc file, e.g., my_tracing.cc:
+//
+// #include "my_tracing.h"
+// PERFETTO_TRACK_EVENT_STATIC_STORAGE();
+//
+// Finally, register track events at startup, after which you can record
+// events with the TRACE_EVENT macros:
+//
+// #include "my_tracing.h"
+//
+// int main() {
+// perfetto::TrackEvent::Register();
+// TRACK_EVENT_BEGIN("category", "MyEvent");
+// TRACK_EVENT_END("category");
+// ...
+// }
-// Track events are time-based markers that an application can use to construct
-// a timeline of its operation.
-class TrackEvent {
- public:
- // Initializes the track event data source. Must be called before any other
- // method on this class.
- static void Initialize();
+// Each compilation unit can be in exactly one track event namespace,
+// allowing the overall program to use multiple track event data sources and
+// category lists if necessary. Use this macro to select the namespace for the
+// current compilation unit.
+//
+// If the program uses multiple track event namespaces, category & track event
+// registration (see quickstart above) needs to happen for both namespaces
+// separately.
+#ifndef PERFETTO_TRACK_EVENT_NAMESPACE
+#define PERFETTO_TRACK_EVENT_NAMESPACE perfetto
+#endif
- // Returns the current tracing clock in nanoseconds.
- static uint64_t GetTimeNs() {
- // TODO(skyostil): Consider using boot time where available.
- return static_cast<uint64_t>(perfetto::base::GetWallTimeNs().count());
- }
+// A name for a single category. Wrapped in a macro in case we need to introduce
+// more fields in the future.
+#define PERFETTO_CATEGORY(name) \
+ { #name }
- // Begin a slice on the current thread. |category| and |name| are free-form
- // strings that describe the event. Both |category| and |name| must be
- // statically allocated.
- static void Begin(const char* category, const char* name) {
- internal::TrackEventDataSource::WriteEvent(
- category, name, perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN);
- }
+// Register the set of available categories by passing a list of categories to
+// this macro: PERFETTO_CATEGORY(cat1), PERFETTO_CATEGORY(cat2), ...
+#define PERFETTO_DEFINE_CATEGORIES(...) \
+ namespace PERFETTO_TRACK_EVENT_NAMESPACE { \
+ /* The list of category names */ \
+ PERFETTO_INTERNAL_DECLARE_CATEGORIES(__VA_ARGS__); \
+ /* The track event data source for this set of categories */ \
+ PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE(); \
+ } // namespace PERFETTO_TRACK_EVENT_NAMESPACE
- // End a slice on the current thread.
- static void End(const char* category) {
- internal::TrackEventDataSource::WriteEvent(
- category, nullptr,
- perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END);
- }
+// Allocate storage for each category by using this macro once per track event
+// namespace.
+#define PERFETTO_TRACK_EVENT_STATIC_STORAGE() \
+ namespace PERFETTO_TRACK_EVENT_NAMESPACE { \
+ PERFETTO_INTERNAL_CATEGORY_STORAGE(); \
+ } // namespace PERFETTO_TRACK_EVENT_NAMESPACE
- // TODO(skyostil): Add per-category enable/disable.
- // TODO(skyostil): Add arguments.
- // TODO(skyostil): Add scoped events.
- // TODO(skyostil): Add async events.
- // TODO(skyostil): Add flow events.
- // TODO(skyostil): Add instant events.
- // TODO(skyostil): Add counters.
+// Begin a thread-scoped slice under |category| with the title |name|. Both
+// strings must be static constants. The track event is only recorded if
+// |category| is enabled for a tracing session.
+#define TRACE_EVENT_BEGIN(category, name) \
+ PERFETTO_INTERNAL_TRACK_EVENT( \
+ category, name, \
+ ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN)
- static void Flush() {
- internal::TrackEventDataSource::Trace(
- [&](internal::TrackEventDataSource::TraceContext ctx) { ctx.Flush(); });
- }
-};
+// End a thread-scoped slice under |category|.
+#define TRACE_EVENT_END(category) \
+ PERFETTO_INTERNAL_TRACK_EVENT( \
+ category, nullptr, \
+ ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END)
-} // namespace perfetto
-
-PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(
- perfetto::internal::TrackEventDataSource,
- perfetto::internal::TrackEventIncrementalState);
+// TODO(skyostil): Add arguments.
+// TODO(skyostil): Add scoped events.
+// TODO(skyostil): Add async events.
+// TODO(skyostil): Add flow events.
+// TODO(skyostil): Add instant events.
+// TODO(skyostil): Add counters.
#endif // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_
diff --git a/include/perfetto/tracing/track_event_category_registry.h b/include/perfetto/tracing/track_event_category_registry.h
new file mode 100644
index 0000000..3e15db6
--- /dev/null
+++ b/include/perfetto/tracing/track_event_category_registry.h
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_CATEGORY_REGISTRY_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_CATEGORY_REGISTRY_H_
+
+#include "perfetto/tracing/data_source.h"
+
+#include <atomic>
+
+namespace perfetto {
+namespace internal {
+
+// A compile-time representation of a track event category. See
+// PERFETTO_DEFINE_CATEGORIES for registering your own categories.
+struct TrackEventCategory {
+ const char* const name;
+};
+
+// Holds all the registered categories for one category namespace. See
+// PERFETTO_DEFINE_CATEGORIES for building the registry.
+class TrackEventCategoryRegistry {
+ public:
+ constexpr TrackEventCategoryRegistry(size_t category_count,
+ const TrackEventCategory* categories,
+ std::atomic<uint8_t>* state_storage)
+ : categories_(categories),
+ category_count_(category_count),
+ state_storage_(state_storage) {
+ static_assert(
+ sizeof(state_storage[0].load()) * 8 >= kMaxDataSourceInstances,
+ "The category state must have enough bits for all possible data source "
+ "instances");
+ }
+
+ size_t category_count() const { return category_count_; }
+
+ // Returns a category based on its index.
+ const TrackEventCategory* GetCategory(size_t index) const;
+
+ // Turn tracing on or off for the given category in a track event data source
+ // instance.
+ void EnableCategoryForInstance(size_t category_index,
+ uint32_t instance_index) const;
+ void DisableCategoryForInstance(size_t category_index,
+ uint32_t instance_index) const;
+
+ constexpr std::atomic<uint8_t>* GetCategoryState(
+ size_t category_index) const {
+ return &state_storage_[category_index];
+ }
+
+ // --------------------------------------------------------------------------
+ // Trace point support
+ // --------------------------------------------------------------------------
+ //
+ // (The following methods are used by the track event trace point
+ // implementation and typically don't need to be called by other code.)
+
+ // At compile time, turn a category name into an index into the registry.
+ // Returns kInvalidCategoryIndex if the category was not found.
+ static constexpr size_t kInvalidCategoryIndex = static_cast<size_t>(-1);
+ constexpr size_t Find(const char* name, size_t index = 0) const {
+ return (index == category_count_) ? kInvalidCategoryIndex
+ : StringEq(categories_[index].name, name)
+ ? index
+ : Find(name, index + 1);
+ }
+
+ // A helper for validating that a category was registered at compile time.
+ template <size_t CategoryIndex>
+ static constexpr size_t Validate() {
+ static_assert(CategoryIndex != kInvalidCategoryIndex,
+ "A track event used an unknown category. Please add it to "
+ "PERFETTO_DEFINE_CATEGORIES().");
+ return CategoryIndex;
+ }
+
+ private:
+ // TODO(skyostil): Make the compile-time routines nicer with C++14.
+ static constexpr bool StringEq(const char* a, const char* b) {
+ return *a != *b ? false
+ : (!*a || !*b) ? (*a == *b) : StringEq(a + 1, b + 1);
+ }
+
+ const TrackEventCategory* const categories_;
+ const size_t category_count_;
+ std::atomic<uint8_t>* const state_storage_;
+};
+
+} // namespace internal
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_CATEGORY_REGISTRY_H_
diff --git a/protos/perfetto/trace/gpu/gpu_render_stage_event.proto b/protos/perfetto/trace/gpu/gpu_render_stage_event.proto
index a2a4cfd..e719b2b 100644
--- a/protos/perfetto/trace/gpu/gpu_render_stage_event.proto
+++ b/protos/perfetto/trace/gpu/gpu_render_stage_event.proto
@@ -19,7 +19,7 @@
package perfetto.protos;
-// next id: 12
+// next id: 13
message GpuRenderStageEvent {
// required. Unique ID for the event.
optional uint64 event_id = 1;
@@ -43,6 +43,9 @@
// optional. The Vulkan render pass handle.
optional uint64 render_pass_handle = 9;
+ // optional. The Vulkan command buffer handle.
+ optional uint64 command_buffer_handle = 12;
+
// optional. Submission ID generated by the UMD.
optional uint32 submission_id = 10;
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 084679f..0ae22f5 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -4267,7 +4267,7 @@
// Begin of protos/perfetto/trace/gpu/gpu_render_stage_event.proto
-// next id: 12
+// next id: 13
message GpuRenderStageEvent {
// required. Unique ID for the event.
optional uint64 event_id = 1;
@@ -4291,6 +4291,9 @@
// optional. The Vulkan render pass handle.
optional uint64 render_pass_handle = 9;
+ // optional. The Vulkan command buffer handle.
+ optional uint64 command_buffer_handle = 12;
+
// optional. Submission ID generated by the UMD.
optional uint32 submission_id = 10;
diff --git a/protos/perfetto/trace_processor/BUILD.gn b/protos/perfetto/trace_processor/BUILD.gn
index 9ee65fe..e645a3a 100644
--- a/protos/perfetto/trace_processor/BUILD.gn
+++ b/protos/perfetto/trace_processor/BUILD.gn
@@ -15,8 +15,8 @@
import("../../../gn/proto_library.gni")
import("proto_files.gni")
-perfetto_proto_library("lite") {
- proto_generators = [ "lite" ]
+perfetto_proto_library("@TYPE@") {
+ proto_generators = [ "zero" ]
sources = []
foreach(source, trace_processor_protos) {
sources += [ "$source.proto" ]
diff --git a/src/base/string_utils_unittest.cc b/src/base/string_utils_unittest.cc
index c38f746..d67976f 100644
--- a/src/base/string_utils_unittest.cc
+++ b/src/base/string_utils_unittest.cc
@@ -15,8 +15,11 @@
*/
#include "perfetto/ext/base/string_utils.h"
+
#include "test/gtest_and_gmock.h"
+#include "perfetto/ext/base/optional.h"
+
namespace perfetto {
namespace base {
namespace {
@@ -39,6 +42,68 @@
EXPECT_EQ(Uppercase('!'), '!');
}
+TEST(StringUtilsTest, CStringToUInt32) {
+ EXPECT_EQ(CStringToUInt32("0"), make_optional<uint32_t>(0U));
+ EXPECT_EQ(CStringToUInt32("1"), make_optional<uint32_t>(1U));
+ EXPECT_EQ(CStringToUInt32("42"), make_optional<uint32_t>(42U));
+ EXPECT_EQ(CStringToUInt32(""), nullopt);
+ EXPECT_EQ(CStringToUInt32("!?"), nullopt);
+ EXPECT_EQ(CStringToUInt32("abc"), nullopt);
+ EXPECT_EQ(CStringToUInt32("123 abc"), nullopt);
+}
+
+TEST(StringUtilsTest, CStringToInt32) {
+ EXPECT_EQ(CStringToInt32("0"), make_optional<int32_t>(0));
+ EXPECT_EQ(CStringToInt32("1"), make_optional<int32_t>(1));
+ EXPECT_EQ(CStringToInt32("-42"), make_optional<int32_t>(-42));
+ EXPECT_EQ(CStringToInt32(""), nullopt);
+ EXPECT_EQ(CStringToInt32("!?"), nullopt);
+ EXPECT_EQ(CStringToInt32("abc"), nullopt);
+ EXPECT_EQ(CStringToInt32("123 abc"), nullopt);
+}
+
+TEST(StringUtilsTest, CStringToDouble) {
+ EXPECT_DOUBLE_EQ(CStringToDouble("0").value(), 0l);
+ EXPECT_DOUBLE_EQ(CStringToDouble("1").value(), 1l);
+ EXPECT_DOUBLE_EQ(CStringToDouble("-42").value(), -42l);
+ EXPECT_DOUBLE_EQ(CStringToDouble("-42.5").value(), -42.5l);
+ EXPECT_EQ(CStringToDouble(""), nullopt);
+ EXPECT_EQ(CStringToDouble("!?"), nullopt);
+ EXPECT_EQ(CStringToDouble("abc"), nullopt);
+ EXPECT_EQ(CStringToDouble("123 abc"), nullopt);
+}
+
+TEST(StringUtilsTest, StringToUInt32) {
+ EXPECT_EQ(StringToUInt32("0"), make_optional<uint32_t>(0U));
+ EXPECT_EQ(StringToUInt32("1"), make_optional<uint32_t>(1U));
+ EXPECT_EQ(StringToUInt32("42"), make_optional<uint32_t>(42U));
+ EXPECT_EQ(StringToUInt32(""), nullopt);
+ EXPECT_EQ(StringToUInt32("!?"), nullopt);
+ EXPECT_EQ(StringToUInt32("abc"), nullopt);
+ EXPECT_EQ(StringToUInt32("123 abc"), nullopt);
+}
+
+TEST(StringUtilsTest, StringToInt32) {
+ EXPECT_EQ(StringToInt32("0"), make_optional<int32_t>(0));
+ EXPECT_EQ(StringToInt32("1"), make_optional<int32_t>(1));
+ EXPECT_EQ(StringToInt32("-42"), make_optional<int32_t>(-42));
+ EXPECT_EQ(StringToInt32(""), nullopt);
+ EXPECT_EQ(StringToInt32("!?"), nullopt);
+ EXPECT_EQ(StringToInt32("abc"), nullopt);
+ EXPECT_EQ(StringToInt32("123 abc"), nullopt);
+}
+
+TEST(StringUtilsTest, StringToDouble) {
+ EXPECT_DOUBLE_EQ(StringToDouble("0").value(), 0l);
+ EXPECT_DOUBLE_EQ(StringToDouble("1").value(), 1l);
+ EXPECT_DOUBLE_EQ(StringToDouble("-42").value(), -42l);
+ EXPECT_DOUBLE_EQ(StringToDouble("-42.5").value(), -42.5l);
+ EXPECT_EQ(StringToDouble(""), nullopt);
+ EXPECT_EQ(StringToDouble("!?"), nullopt);
+ EXPECT_EQ(StringToDouble("abc"), nullopt);
+ EXPECT_EQ(StringToDouble("123 abc"), nullopt);
+}
+
TEST(StringUtilsTest, StartsWith) {
EXPECT_TRUE(StartsWith("", ""));
EXPECT_TRUE(StartsWith("abc", ""));
diff --git a/src/base/unix_socket.cc b/src/base/unix_socket.cc
index 663cb14..e63f978 100644
--- a/src/base/unix_socket.cc
+++ b/src/base/unix_socket.cc
@@ -18,6 +18,8 @@
#include <errno.h>
#include <fcntl.h>
+#include <netdb.h>
+#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
@@ -32,6 +34,7 @@
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/utils.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
@@ -48,6 +51,7 @@
#endif
namespace {
+
// MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
// created with SO_NOSIGPIPE (See InitializeSocket()).
#if PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
@@ -63,7 +67,36 @@
using CBufLenType = socklen_t;
#endif
-inline int GetUnixSockType(SockType type) {
+// A wrapper around variable-size sockaddr structs.
+// This is solving the following problem: when calling connect() or bind(), the
+// caller needs to take care to allocate the right struct (sockaddr_un for
+// AF_UNIX, sockaddr_in for AF_INET). Those structs have different sizes and,
+// more importantly, are bigger than the base struct sockaddr.
+struct SockaddrAny {
+ SockaddrAny() : size() {}
+ SockaddrAny(const void* addr, socklen_t sz) : data(new char[sz]), size(sz) {
+ memcpy(data.get(), addr, static_cast<size_t>(size));
+ }
+
+ const struct sockaddr* addr() const {
+ return reinterpret_cast<const struct sockaddr*>(data.get());
+ }
+
+ std::unique_ptr<char[]> data;
+ socklen_t size;
+};
+
+inline int GetSockFamily(SockFamily family) {
+ switch (family) {
+ case SockFamily::kUnix:
+ return AF_UNIX;
+ case SockFamily::kInet:
+ return AF_INET;
+ }
+ PERFETTO_CHECK(false); // For GCC.
+}
+
+inline int GetSockType(SockType type) {
switch (type) {
case SockType::kStream:
return SOCK_STREAM;
@@ -72,25 +105,42 @@
case SockType::kSeqPacket:
return SOCK_SEQPACKET;
}
- PERFETTO_CHECK(false);
+ PERFETTO_CHECK(false); // For GCC.
}
-bool MakeSockAddr(const std::string& socket_name,
- sockaddr_un* addr,
- socklen_t* addr_size) {
- memset(addr, 0, sizeof(*addr));
- const size_t name_len = socket_name.size();
- if (name_len >= sizeof(addr->sun_path)) {
- errno = ENAMETOOLONG;
- return false;
+SockaddrAny MakeSockAddr(SockFamily family, const std::string& socket_name) {
+ switch (family) {
+ case SockFamily::kUnix: {
+ struct sockaddr_un saddr {};
+ const size_t name_len = socket_name.size();
+ if (name_len >= sizeof(saddr.sun_path)) {
+ errno = ENAMETOOLONG;
+ return SockaddrAny();
+ }
+ memcpy(saddr.sun_path, socket_name.data(), name_len);
+ if (saddr.sun_path[0] == '@')
+ saddr.sun_path[0] = '\0';
+ saddr.sun_family = AF_UNIX;
+ auto size = static_cast<socklen_t>(
+ __builtin_offsetof(sockaddr_un, sun_path) + name_len + 1);
+ PERFETTO_CHECK(static_cast<size_t>(size) <= sizeof(saddr));
+ return SockaddrAny(&saddr, size);
+ }
+ case SockFamily::kInet: {
+ auto parts = SplitString(socket_name, ":");
+ PERFETTO_CHECK(parts.size() == 2);
+ struct addrinfo* addr_info = nullptr;
+ struct addrinfo hints {};
+ hints.ai_family = AF_INET;
+ PERFETTO_CHECK(getaddrinfo(parts[0].c_str(), parts[1].c_str(), &hints,
+ &addr_info) == 0);
+ PERFETTO_CHECK(addr_info->ai_family == AF_INET);
+ SockaddrAny res(addr_info->ai_addr, addr_info->ai_addrlen);
+ freeaddrinfo(addr_info);
+ return res;
+ }
}
- memcpy(addr->sun_path, socket_name.data(), name_len);
- if (addr->sun_path[0] == '@')
- addr->sun_path[0] = '\0';
- addr->sun_family = AF_UNIX;
- *addr_size = static_cast<socklen_t>(
- __builtin_offsetof(sockaddr_un, sun_path) + name_len + 1);
- return true;
+ PERFETTO_CHECK(false); // For GCC.
}
} // namespace
@@ -122,29 +172,39 @@
}
// static
-std::pair<UnixSocketRaw, UnixSocketRaw> UnixSocketRaw::CreatePair(SockType t) {
+std::pair<UnixSocketRaw, UnixSocketRaw> UnixSocketRaw::CreatePair(
+ SockFamily family,
+ SockType type) {
int fds[2];
- if (socketpair(AF_UNIX, GetUnixSockType(t), 0, fds) != 0)
+ if (socketpair(GetSockFamily(family), GetSockType(type), 0, fds) != 0)
return std::make_pair(UnixSocketRaw(), UnixSocketRaw());
- return std::make_pair(UnixSocketRaw(ScopedFile(fds[0]), t),
- UnixSocketRaw(ScopedFile(fds[1]), t));
+ return std::make_pair(UnixSocketRaw(ScopedFile(fds[0]), family, type),
+ UnixSocketRaw(ScopedFile(fds[1]), family, type));
}
UnixSocketRaw::UnixSocketRaw() = default;
-UnixSocketRaw::UnixSocketRaw(SockType type)
- : UnixSocketRaw(ScopedFile(socket(AF_UNIX, GetUnixSockType(type), 0)),
- type) {}
+UnixSocketRaw::UnixSocketRaw(SockFamily family, SockType type)
+ : UnixSocketRaw(
+ ScopedFile(socket(GetSockFamily(family), GetSockType(type), 0)),
+ family,
+ type) {}
-UnixSocketRaw::UnixSocketRaw(ScopedFile fd, SockType type)
- : fd_(std::move(fd)), type_(type) {
+UnixSocketRaw::UnixSocketRaw(ScopedFile fd, SockFamily family, SockType type)
+ : fd_(std::move(fd)), family_(family), type_(type) {
PERFETTO_CHECK(fd_);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
const int no_sigpipe = 1;
setsockopt(*fd_, SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe));
#endif
+ if (family == SockFamily::kInet) {
+ int flag = 1;
+ PERFETTO_CHECK(
+ !setsockopt(*fd_, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)));
+ }
+
// There is no reason why a socket should outlive the process in case of
// exec() by default, this is just working around a broken unix design.
int fcntl_res = fcntl(*fd_, F_SETFD, FD_CLOEXEC);
@@ -178,12 +238,11 @@
bool UnixSocketRaw::Bind(const std::string& socket_name) {
PERFETTO_DCHECK(fd_);
- sockaddr_un addr;
- socklen_t addr_size;
- if (!MakeSockAddr(socket_name, &addr, &addr_size))
+ SockaddrAny addr = MakeSockAddr(family_, socket_name);
+ if (addr.size == 0)
return false;
- if (bind(*fd_, reinterpret_cast<sockaddr*>(&addr), addr_size)) {
+ if (bind(*fd_, addr.addr(), addr.size)) {
PERFETTO_DPLOG("bind(%s)", socket_name.c_str());
return false;
}
@@ -199,13 +258,11 @@
bool UnixSocketRaw::Connect(const std::string& socket_name) {
PERFETTO_DCHECK(fd_);
- sockaddr_un addr;
- socklen_t addr_size;
- if (!MakeSockAddr(socket_name, &addr, &addr_size))
+ SockaddrAny addr = MakeSockAddr(family_, socket_name);
+ if (addr.size == 0)
return false;
- int res = PERFETTO_EINTR(
- connect(*fd_, reinterpret_cast<sockaddr*>(&addr), addr_size));
+ int res = PERFETTO_EINTR(connect(*fd_, addr.addr(), addr.size));
if (res && errno != EINPROGRESS)
return false;
@@ -371,32 +428,36 @@
std::unique_ptr<UnixSocket> UnixSocket::Listen(const std::string& socket_name,
EventListener* event_listener,
TaskRunner* task_runner,
+ SockFamily sock_family,
SockType sock_type) {
- auto sock_raw = UnixSocketRaw::CreateMayFail(sock_type);
+ auto sock_raw = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
if (!sock_raw || !sock_raw.Bind(socket_name))
return nullptr;
// Forward the call to the Listen() overload below.
- return Listen(sock_raw.ReleaseFd(), event_listener, task_runner, sock_type);
+ return Listen(sock_raw.ReleaseFd(), event_listener, task_runner, sock_family,
+ sock_type);
}
// static
std::unique_ptr<UnixSocket> UnixSocket::Listen(ScopedFile fd,
EventListener* event_listener,
TaskRunner* task_runner,
+ SockFamily sock_family,
SockType sock_type) {
return std::unique_ptr<UnixSocket>(
new UnixSocket(event_listener, task_runner, std::move(fd),
- State::kListening, sock_type));
+ State::kListening, sock_family, sock_type));
}
// static
std::unique_ptr<UnixSocket> UnixSocket::Connect(const std::string& socket_name,
EventListener* event_listener,
TaskRunner* task_runner,
+ SockFamily sock_family,
SockType sock_type) {
std::unique_ptr<UnixSocket> sock(
- new UnixSocket(event_listener, task_runner, sock_type));
+ new UnixSocket(event_listener, task_runner, sock_family, sock_type));
sock->DoConnect(socket_name);
return sock;
}
@@ -406,25 +467,29 @@
ScopedFile fd,
EventListener* event_listener,
TaskRunner* task_runner,
+ SockFamily sock_family,
SockType sock_type) {
return std::unique_ptr<UnixSocket>(
new UnixSocket(event_listener, task_runner, std::move(fd),
- State::kConnected, sock_type));
+ State::kConnected, sock_family, sock_type));
}
UnixSocket::UnixSocket(EventListener* event_listener,
TaskRunner* task_runner,
+ SockFamily sock_family,
SockType sock_type)
: UnixSocket(event_listener,
task_runner,
ScopedFile(),
State::kDisconnected,
+ sock_family,
sock_type) {}
UnixSocket::UnixSocket(EventListener* event_listener,
TaskRunner* task_runner,
ScopedFile adopt_fd,
State adopt_state,
+ SockFamily sock_family,
SockType sock_type)
: event_listener_(event_listener),
task_runner_(task_runner),
@@ -432,14 +497,14 @@
state_ = State::kDisconnected;
if (adopt_state == State::kDisconnected) {
PERFETTO_DCHECK(!adopt_fd);
- sock_raw_ = UnixSocketRaw::CreateMayFail(sock_type);
+ sock_raw_ = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
if (!sock_raw_) {
last_error_ = errno;
return;
}
} else if (adopt_state == State::kConnected) {
PERFETTO_DCHECK(adopt_fd);
- sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_type);
+ sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
state_ = State::kConnected;
ReadPeerCredentials();
} else if (adopt_state == State::kListening) {
@@ -451,7 +516,7 @@
return;
}
- sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_type);
+ sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
if (!sock_raw_.Listen()) {
last_error_ = errno;
PERFETTO_DPLOG("listen()");
@@ -468,6 +533,7 @@
sock_raw_.SetBlocking(false);
WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+
task_runner_->AddFileDescriptorWatch(sock_raw_.fd(), [weak_ptr] {
if (weak_ptr)
weak_ptr->OnEvent();
@@ -522,6 +588,10 @@
}
void UnixSocket::ReadPeerCredentials() {
+ // Peer credentials are supported only on AF_UNIX sockets.
+ if (sock_raw_.family() != SockFamily::kUnix)
+ return;
+
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
struct ucred user_cred;
@@ -554,6 +624,7 @@
socklen_t err_len = sizeof(sock_err);
int res =
getsockopt(sock_raw_.fd(), SOL_SOCKET, SO_ERROR, &sock_err, &err_len);
+
if (res == 0 && sock_err == EINPROGRESS)
return; // Not connected yet, just a spurious FD watch wakeup.
if (res == 0 && sock_err == 0) {
@@ -561,6 +632,7 @@
state_ = State::kConnected;
return event_listener_->OnConnect(this, true /* connected */);
}
+ PERFETTO_DLOG("Connection error: %s", strerror(sock_err));
last_error_ = sock_err;
Shutdown(false);
return event_listener_->OnConnect(this, false /* connected */);
@@ -571,15 +643,15 @@
// There could be more than one incoming connection behind each FD watch
// notification. Drain'em all.
for (;;) {
- sockaddr_un cli_addr = {};
+ struct sockaddr_in cli_addr {};
socklen_t size = sizeof(cli_addr);
ScopedFile new_fd(PERFETTO_EINTR(accept(
sock_raw_.fd(), reinterpret_cast<sockaddr*>(&cli_addr), &size)));
if (!new_fd)
return;
- std::unique_ptr<UnixSocket> new_sock(
- new UnixSocket(event_listener_, task_runner_, std::move(new_fd),
- State::kConnected, sock_raw_.type()));
+ std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
+ event_listener_, task_runner_, std::move(new_fd), State::kConnected,
+ sock_raw_.family(), sock_raw_.type()));
event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
}
}
diff --git a/src/base/unix_socket_unittest.cc b/src/base/unix_socket_unittest.cc
index 8f54cab..138f631 100644
--- a/src/base/unix_socket_unittest.cc
+++ b/src/base/unix_socket_unittest.cc
@@ -84,7 +84,8 @@
};
TEST_F(UnixSocketTest, ConnectionFailureIfUnreachable) {
- auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_);
+ auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
ASSERT_FALSE(cli->is_connected());
auto checkpoint = task_runner_.CreateCheckpoint("failure");
EXPECT_CALL(event_listener_, OnConnect(cli.get(), false))
@@ -95,7 +96,8 @@
// Both server and client should see an OnDisconnect() if the server drops
// incoming connections immediately as they are created.
TEST_F(UnixSocketTest, ConnectionImmediatelyDroppedByServer) {
- auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_);
+ auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
ASSERT_TRUE(srv->is_listening());
// The server will immediately shutdown the connection upon
@@ -110,7 +112,8 @@
}));
auto checkpoint = task_runner_.CreateCheckpoint("cli_connected");
- auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_);
+ auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
.WillOnce(InvokeWithoutArgs(checkpoint));
task_runner_.RunUntilCheckpoint("cli_connected");
@@ -125,10 +128,12 @@
}
TEST_F(UnixSocketTest, ClientAndServerExchangeData) {
- auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_);
+ auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
ASSERT_TRUE(srv->is_listening());
- auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_);
+ auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
EXPECT_CALL(event_listener_, OnConnect(cli.get(), true));
auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
auto srv_disconnected = task_runner_.CreateCheckpoint("srv_disconnected");
@@ -184,10 +189,12 @@
constexpr char srv_str[] = "srv>cli";
TEST_F(UnixSocketTest, ClientAndServerExchangeFDs) {
- auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_);
+ auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
ASSERT_TRUE(srv->is_listening());
- auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_);
+ auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
EXPECT_CALL(event_listener_, OnConnect(cli.get(), true));
auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
auto srv_disconnected = task_runner_.CreateCheckpoint("srv_disconnected");
@@ -266,13 +273,16 @@
}
TEST_F(UnixSocketTest, ListenWithPassedFileDescriptor) {
- auto sock_raw = UnixSocketRaw::CreateMayFail(SockType::kStream);
+ auto sock_raw =
+ UnixSocketRaw::CreateMayFail(SockFamily::kUnix, SockType::kStream);
ASSERT_TRUE(sock_raw.Bind(kSocketName));
auto fd = sock_raw.ReleaseFd();
- auto srv = UnixSocket::Listen(std::move(fd), &event_listener_, &task_runner_);
+ auto srv = UnixSocket::Listen(std::move(fd), &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
ASSERT_TRUE(srv->is_listening());
- auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_);
+ auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
EXPECT_CALL(event_listener_, OnConnect(cli.get(), true));
auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
auto srv_disconnected = task_runner_.CreateCheckpoint("srv_disconnected");
@@ -296,7 +306,8 @@
// Mostly a stress tests. Connects kNumClients clients to the same server and
// tests that all can exchange data and can see the expected sequence of events.
TEST_F(UnixSocketTest, SeveralClients) {
- auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_);
+ auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
ASSERT_TRUE(srv->is_listening());
constexpr size_t kNumClients = 32;
std::unique_ptr<UnixSocket> cli[kNumClients];
@@ -312,7 +323,8 @@
}));
for (size_t i = 0; i < kNumClients; i++) {
- cli[i] = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_);
+ cli[i] = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
EXPECT_CALL(event_listener_, OnConnect(cli[i].get(), true))
.WillOnce(Invoke([](UnixSocket* s, bool success) {
ASSERT_TRUE(success);
@@ -352,7 +364,8 @@
ASSERT_NE(nullptr, mem);
memcpy(mem, "shm rocks", 10);
- auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_);
+ auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
ASSERT_TRUE(srv->is_listening());
// Signal the other process that it can connect.
ASSERT_EQ(1, base::WriteAll(*pipe.wr, ".", 1));
@@ -377,8 +390,8 @@
char sync_cmd = '\0';
ASSERT_EQ(1, PERFETTO_EINTR(read(*pipe.rd, &sync_cmd, 1)));
ASSERT_EQ('.', sync_cmd);
- auto cli =
- UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_);
+ auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
EXPECT_CALL(event_listener_, OnConnect(cli.get(), true));
auto checkpoint = task_runner_.CreateCheckpoint("change_seen_by_client");
EXPECT_CALL(event_listener_, OnDataAvailable(cli.get()))
@@ -412,7 +425,8 @@
// layer needs to rely on this to validate messages received immediately before
// a client disconnects.
TEST_F(UnixSocketTest, PeerCredentialsRetainedAfterDisconnect) {
- auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_);
+ auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
ASSERT_TRUE(srv->is_listening());
UnixSocket* srv_client_conn = nullptr;
auto srv_connected = task_runner_.CreateCheckpoint("srv_connected");
@@ -428,7 +442,8 @@
srv_connected();
}));
auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
- auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_);
+ auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
.WillOnce(InvokeWithoutArgs(cli_connected));
@@ -458,7 +473,8 @@
}
TEST_F(UnixSocketTest, BlockingSend) {
- auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_);
+ auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
ASSERT_TRUE(srv->is_listening());
auto all_frames_done = task_runner_.CreateCheckpoint("all_frames_done");
@@ -485,7 +501,8 @@
std::thread tx_thread([] {
TestTaskRunner tx_task_runner;
MockEventListener tx_events;
- auto cli = UnixSocket::Connect(kSocketName, &tx_events, &tx_task_runner);
+ auto cli = UnixSocket::Connect(kSocketName, &tx_events, &tx_task_runner,
+ SockFamily::kUnix, SockType::kStream);
auto cli_connected = tx_task_runner.CreateCheckpoint("cli_connected");
EXPECT_CALL(tx_events, OnConnect(cli.get(), true))
@@ -510,7 +527,8 @@
// sender is in the middle of a large send(), the socket should gracefully give
// up (i.e. Shutdown()) but not crash.
TEST_F(UnixSocketTest, ReceiverDisconnectsDuringSend) {
- auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_);
+ auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
ASSERT_TRUE(srv->is_listening());
const int kTimeoutMs = 30000;
@@ -531,7 +549,8 @@
std::thread tx_thread([] {
TestTaskRunner tx_task_runner;
MockEventListener tx_events;
- auto cli = UnixSocket::Connect(kSocketName, &tx_events, &tx_task_runner);
+ auto cli = UnixSocket::Connect(kSocketName, &tx_events, &tx_task_runner,
+ SockFamily::kUnix, SockType::kStream);
auto cli_connected = tx_task_runner.CreateCheckpoint("cli_connected");
EXPECT_CALL(tx_events, OnConnect(cli.get(), true))
@@ -644,7 +663,8 @@
TEST_F(UnixSocketTest, PartialSendMsgAll) {
UnixSocketRaw send_sock;
UnixSocketRaw recv_sock;
- std::tie(send_sock, recv_sock) = UnixSocketRaw::CreatePair(SockType::kStream);
+ std::tie(send_sock, recv_sock) =
+ UnixSocketRaw::CreatePair(SockFamily::kUnix, SockType::kStream);
ASSERT_TRUE(send_sock);
ASSERT_TRUE(recv_sock);
@@ -717,7 +737,8 @@
}
TEST_F(UnixSocketTest, ReleaseSocket) {
- auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_);
+ auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
ASSERT_TRUE(srv->is_listening());
auto connected = task_runner_.CreateCheckpoint("connected");
UnixSocket* peer = nullptr;
@@ -727,7 +748,8 @@
connected();
}));
- auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_);
+ auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
+ SockFamily::kUnix, SockType::kStream);
EXPECT_CALL(event_listener_, OnConnect(cli.get(), true));
task_runner_.RunUntilCheckpoint("connected");
srv->Shutdown(true);
@@ -747,6 +769,57 @@
ASSERT_STREQ(buf, "test");
}
+TEST_F(UnixSocketTest, TcpStream) {
+ char host_and_port[32];
+ int attempt = 0;
+ std::unique_ptr<UnixSocket> srv;
+
+ // Try listening on a random port. Some ports might be taken by other syste
+ // services. Do a bunch of attempts on different ports before giving up.
+ do {
+ sprintf(host_and_port, "127.0.0.1:%d", 10000 + (rand() % 10000));
+ srv = UnixSocket::Listen(host_and_port, &event_listener_, &task_runner_,
+ SockFamily::kInet, SockType::kStream);
+ } while ((!srv || !srv->is_listening()) && attempt++ < 10);
+ ASSERT_TRUE(srv->is_listening());
+
+ constexpr size_t kNumClients = 3;
+ std::unique_ptr<UnixSocket> cli[kNumClients];
+ EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
+ .Times(kNumClients)
+ .WillRepeatedly(Invoke([&](UnixSocket*, UnixSocket* s) {
+ // OnDisconnect() might spuriously happen depending on the dtor order.
+ EXPECT_CALL(event_listener_, OnDisconnect(s)).Times(AtLeast(0));
+ EXPECT_CALL(event_listener_, OnDataAvailable(s))
+ .WillRepeatedly(Invoke([](UnixSocket* cli_sock) {
+ cli_sock->ReceiveString(); // Read connection EOF;
+ }));
+ ASSERT_TRUE(s->Send("welcome", kBlocking));
+ }));
+
+ for (size_t i = 0; i < kNumClients; i++) {
+ cli[i] = UnixSocket::Connect(host_and_port, &event_listener_, &task_runner_,
+ SockFamily::kInet, SockType::kStream);
+ // PERFETTO_ILOG("cli : %p", reinterpret_cast<void*>(cli[i].get()));
+ auto checkpoint = task_runner_.CreateCheckpoint(std::to_string(i));
+ EXPECT_CALL(event_listener_, OnDisconnect(cli[i].get())).Times(AtLeast(0));
+ EXPECT_CALL(event_listener_, OnConnect(cli[i].get(), true));
+ EXPECT_CALL(event_listener_, OnDataAvailable(cli[i].get()))
+ .WillRepeatedly(Invoke([checkpoint](UnixSocket* s) {
+ auto str = s->ReceiveString();
+ if (str == "")
+ return; // Connection EOF.
+ ASSERT_EQ("welcome", str);
+ checkpoint();
+ }));
+ }
+
+ for (size_t i = 0; i < kNumClients; i++) {
+ task_runner_.RunUntilCheckpoint(std::to_string(i));
+ ASSERT_TRUE(Mock::VerifyAndClearExpectations(cli[i].get()));
+ }
+}
+
// TODO(primiano): add a test to check that in the case of a peer sending a fd
// and the other end just doing a recv (without taking it), the fd is closed and
// not left around.
diff --git a/src/ipc/client_impl.cc b/src/ipc/client_impl.cc
index c3bd830..b563d95 100644
--- a/src/ipc/client_impl.cc
+++ b/src/ipc/client_impl.cc
@@ -43,7 +43,9 @@
ClientImpl::ClientImpl(const char* socket_name, base::TaskRunner* task_runner)
: task_runner_(task_runner), weak_ptr_factory_(this) {
- sock_ = base::UnixSocket::Connect(socket_name, this, task_runner);
+ sock_ = base::UnixSocket::Connect(socket_name, this, task_runner,
+ base::SockFamily::kUnix,
+ base::SockType::kStream);
}
ClientImpl::~ClientImpl() {
diff --git a/src/ipc/client_impl_unittest.cc b/src/ipc/client_impl_unittest.cc
index 84a9dd1..e8e634e 100644
--- a/src/ipc/client_impl_unittest.cc
+++ b/src/ipc/client_impl_unittest.cc
@@ -103,7 +103,9 @@
explicit FakeHost(base::TaskRunner* task_runner) {
DESTROY_TEST_SOCK(kSockName);
- listening_sock = base::UnixSocket::Listen(kSockName, this, task_runner);
+ listening_sock = base::UnixSocket::Listen(kSockName, this, task_runner,
+ base::SockFamily::kUnix,
+ base::SockType::kStream);
EXPECT_TRUE(listening_sock->is_listening());
}
~FakeHost() override { DESTROY_TEST_SOCK(kSockName); }
diff --git a/src/ipc/host_impl.cc b/src/ipc/host_impl.cc
index 7a7d95c..0a56b85 100644
--- a/src/ipc/host_impl.cc
+++ b/src/ipc/host_impl.cc
@@ -55,13 +55,17 @@
HostImpl::HostImpl(base::ScopedFile socket_fd, base::TaskRunner* task_runner)
: task_runner_(task_runner), weak_ptr_factory_(this) {
PERFETTO_DCHECK_THREAD(thread_checker_);
- sock_ = base::UnixSocket::Listen(std::move(socket_fd), this, task_runner_);
+ sock_ = base::UnixSocket::Listen(std::move(socket_fd), this, task_runner_,
+ base::SockFamily::kUnix,
+ base::SockType::kStream);
}
HostImpl::HostImpl(const char* socket_name, base::TaskRunner* task_runner)
: task_runner_(task_runner), weak_ptr_factory_(this) {
PERFETTO_DCHECK_THREAD(thread_checker_);
- sock_ = base::UnixSocket::Listen(socket_name, this, task_runner_);
+ sock_ = base::UnixSocket::Listen(socket_name, this, task_runner_,
+ base::SockFamily::kUnix,
+ base::SockType::kStream);
}
HostImpl::~HostImpl() = default;
diff --git a/src/ipc/host_impl_unittest.cc b/src/ipc/host_impl_unittest.cc
index 70215ff..0624cd7 100644
--- a/src/ipc/host_impl_unittest.cc
+++ b/src/ipc/host_impl_unittest.cc
@@ -88,7 +88,9 @@
MOCK_METHOD0(OnRequestError, void());
explicit FakeClient(base::TaskRunner* task_runner) {
- sock_ = base::UnixSocket::Connect(kSockName, this, task_runner);
+ sock_ = base::UnixSocket::Connect(kSockName, this, task_runner,
+ base::SockFamily::kUnix,
+ base::SockType::kStream);
}
~FakeClient() override = default;
@@ -334,15 +336,15 @@
sizeof(kFileContent))),
sizeof(kFileContent));
EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
- .WillOnce(Invoke([on_reply_sent, &tx_file](const RequestProto&,
- DeferredBase* reply) {
- std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
- auto async_res = AsyncResult<ProtoMessage>(
- std::unique_ptr<ProtoMessage>(reply_args.release()));
- async_res.set_fd(tx_file.fd());
- reply->Resolve(std::move(async_res));
- on_reply_sent();
- }));
+ .WillOnce(Invoke(
+ [on_reply_sent, &tx_file](const RequestProto&, DeferredBase* reply) {
+ std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
+ auto async_res = AsyncResult<ProtoMessage>(
+ std::unique_ptr<ProtoMessage>(reply_args.release()));
+ async_res.set_fd(tx_file.fd());
+ reply->Resolve(std::move(async_res));
+ on_reply_sent();
+ }));
task_runner_->RunUntilCheckpoint("on_reply_sent");
tx_file.ReleaseFD();
diff --git a/src/perfetto_cmd/pbtxt_to_pb.cc b/src/perfetto_cmd/pbtxt_to_pb.cc
index 101100d..9d8ad5c 100644
--- a/src/perfetto_cmd/pbtxt_to_pb.cc
+++ b/src/perfetto_cmd/pbtxt_to_pb.cc
@@ -23,6 +23,8 @@
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/string_view.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/protozero/message.h"
@@ -372,8 +374,8 @@
template <typename T>
void FixedFloatField(const FieldDescriptorProto* field, Token t) {
uint32_t field_id = static_cast<uint32_t>(field->number());
- double n = std::stod(t.ToStdString());
- msg()->AppendFixed<T>(field_id, static_cast<T>(n));
+ base::Optional<double> opt_n = base::StringToDouble(t.ToStdString());
+ msg()->AppendFixed<T>(field_id, static_cast<T>(opt_n.value_or(0l)));
}
template <typename T>
diff --git a/src/profiling/memory/client.cc b/src/profiling/memory/client.cc
index e3a0e7d..8065733 100644
--- a/src/profiling/memory/client.cc
+++ b/src/profiling/memory/client.cc
@@ -101,7 +101,8 @@
// static
base::Optional<base::UnixSocketRaw> Client::ConnectToHeapprofd(
const std::string& sock_name) {
- auto sock = base::UnixSocketRaw::CreateMayFail(base::SockType::kStream);
+ auto sock = base::UnixSocketRaw::CreateMayFail(base::SockFamily::kUnix,
+ base::SockType::kStream);
if (!sock || !sock.Connect(sock_name)) {
PERFETTO_PLOG("Failed to connect to %s", sock_name.c_str());
return base::nullopt;
diff --git a/src/profiling/memory/heapprofd_producer.cc b/src/profiling/memory/heapprofd_producer.cc
index d1024cc..c10adc3 100644
--- a/src/profiling/memory/heapprofd_producer.cc
+++ b/src/profiling/memory/heapprofd_producer.cc
@@ -137,7 +137,7 @@
PERFETTO_DCHECK(mode_ == HeapprofdMode::kChild);
auto socket = base::UnixSocket::AdoptConnected(
std::move(inherited_fd_), &socket_delegate_, task_runner_,
- base::SockType::kStream);
+ base::SockFamily::kUnix, base::SockType::kStream);
HandleClientConnection(std::move(socket), target_process_);
}
@@ -610,7 +610,6 @@
}
DataSource& data_source = it->second;
-
for (std::pair<const pid_t, ProcessState>& pid_and_process_state :
data_source.process_states) {
pid_t pid = pid_and_process_state.first;
diff --git a/src/profiling/memory/main.cc b/src/profiling/memory/main.cc
index 7df39e7..ff5ac97 100644
--- a/src/profiling/memory/main.cc
+++ b/src/profiling/memory/main.cc
@@ -159,9 +159,9 @@
HeapprofdProducer producer(HeapprofdMode::kCentral, &task_runner);
int listening_raw_socket = GetListeningSocket();
- auto listening_socket =
- base::UnixSocket::Listen(base::ScopedFile(listening_raw_socket),
- &producer.socket_delegate(), &task_runner);
+ auto listening_socket = base::UnixSocket::Listen(
+ base::ScopedFile(listening_raw_socket), &producer.socket_delegate(),
+ &task_runner, base::SockFamily::kUnix, base::SockType::kStream);
struct sigaction action = {};
action.sa_handler = [](int) { g_dump_evt->Notify(); };
diff --git a/src/profiling/memory/malloc_hooks.cc b/src/profiling/memory/malloc_hooks.cc
index 2eb4cd4..f696e58 100644
--- a/src/profiling/memory/malloc_hooks.cc
+++ b/src/profiling/memory/malloc_hooks.cc
@@ -256,7 +256,7 @@
perfetto::base::UnixSocketRaw parent_sock;
perfetto::base::UnixSocketRaw child_sock;
std::tie(parent_sock, child_sock) = perfetto::base::UnixSocketRaw::CreatePair(
- perfetto::base::SockType::kStream);
+ perfetto::base::SockFamily::kUnix, perfetto::base::SockType::kStream);
if (!parent_sock || !child_sock) {
PERFETTO_PLOG("Failed to create socketpair.");
diff --git a/src/profiling/memory/unwinding.cc b/src/profiling/memory/unwinding.cc
index 59a4dca..ced87f9 100644
--- a/src/profiling/memory/unwinding.cc
+++ b/src/profiling/memory/unwinding.cc
@@ -374,7 +374,7 @@
void UnwindingWorker::HandleHandoffSocket(HandoffData handoff_data) {
auto sock = base::UnixSocket::AdoptConnected(
handoff_data.sock.ReleaseFd(), this, this->thread_task_runner_.get(),
- base::SockType::kStream);
+ base::SockFamily::kUnix, base::SockType::kStream);
pid_t peer_pid = sock->peer_pid();
UnwindingMetadata metadata(peer_pid, std::move(handoff_data.maps_fd),
diff --git a/src/profiling/memory/wire_protocol_unittest.cc b/src/profiling/memory/wire_protocol_unittest.cc
index a8d623e..462ea06 100644
--- a/src/profiling/memory/wire_protocol_unittest.cc
+++ b/src/profiling/memory/wire_protocol_unittest.cc
@@ -56,8 +56,10 @@
int sv[2];
PERFETTO_CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
base::UnixSocketRaw send_sock(base::ScopedFile(sv[0]),
+ base::SockFamily::kUnix,
base::SockType::kStream);
base::UnixSocketRaw recv_sock(base::ScopedFile(sv[1]),
+ base::SockFamily::kUnix,
base::SockType::kStream);
char msg[] = "a";
PERFETTO_CHECK(send_sock.Send(msg, sizeof(msg), &fd, 1));
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 4814052..5c88371 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -32,9 +32,9 @@
# outer "is_wasm" block.
deps = [
":lib",
+ ":rpc",
"../../gn:default_deps",
"../../include/perfetto/ext/base",
- "../../protos/perfetto/trace_processor:lite",
]
}
}
@@ -72,8 +72,6 @@
"forwarding_trace_parser.cc",
"forwarding_trace_parser.h",
"ftrace_utils.h",
- "graphics_event_parser.cc",
- "graphics_event_parser.h",
"gzip_trace_parser.cc",
"gzip_trace_parser.h",
"heap_graph_tracker.cc",
@@ -88,8 +86,24 @@
"importers/ftrace/ftrace_tokenizer.h",
"importers/ftrace/sched_event_tracker.h",
"importers/fuchsia/fuchsia_provider_view.h",
+ "importers/proto/android_probes_module.h",
+ "importers/proto/android_probes_parser.h",
+ "importers/proto/graphics_event_module.h",
+ "importers/proto/graphics_event_parser.h",
+ "importers/proto/packet_sequence_state.h",
"importers/proto/proto_importer_module.h",
+ "importers/proto/proto_incremental_state.h",
+ "importers/proto/proto_trace_parser.cc",
+ "importers/proto/proto_trace_parser.h",
+ "importers/proto/proto_trace_tokenizer.cc",
+ "importers/proto/proto_trace_tokenizer.h",
+ "importers/proto/system_probes_module.h",
+ "importers/proto/system_probes_parser.h",
"importers/proto/track_event_module.h",
+ "importers/proto/track_event_parser.cc",
+ "importers/proto/track_event_parser.h",
+ "importers/proto/track_event_tokenizer.cc",
+ "importers/proto/track_event_tokenizer.h",
"importers/systrace/systrace_parser.h",
"importers/systrace/systrace_trace_parser.h",
"instants_table.cc",
@@ -101,11 +115,6 @@
"process_table.h",
"process_tracker.cc",
"process_tracker.h",
- "proto_incremental_state.h",
- "proto_trace_parser.cc",
- "proto_trace_parser.h",
- "proto_trace_tokenizer.cc",
- "proto_trace_tokenizer.h",
"raw_table.cc",
"raw_table.h",
"read_trace.cc",
@@ -172,6 +181,7 @@
"../../gn:default_deps",
"../../gn:sqlite",
"../../gn:zlib",
+ "../../include/perfetto/ext/trace_processor:export_json",
"../../include/perfetto/ext/traced:sys_stats_counters",
"../../protos/perfetto/common:zero",
"../../protos/perfetto/config:zero",
@@ -224,6 +234,15 @@
enable_perfetto_trace_processor_fuchsia) {
sources += [ "ftrace_utils.cc" ]
}
+ if (enable_perfetto_trace_processor_system_probes) {
+ sources += [ "importers/proto/system_probes_parser.cc" ]
+ }
+ if (enable_perfetto_trace_processor_android_probes) {
+ sources += [ "importers/proto/android_probes_parser.cc" ]
+ }
+ if (enable_perfetto_trace_processor_graphics) {
+ sources += [ "importers/proto/graphics_event_parser.cc" ]
+ }
if (enable_perfetto_trace_processor_metrics) {
deps += [
"../../protos/perfetto/metrics:zero",
@@ -259,6 +278,22 @@
]
}
+# This source_set is used both by WASM (for the function-call-based query
+# interface) and by the upcoming :httpd module for the HTTP interface.
+source_set("rpc") {
+ sources = [
+ "rpc.cc",
+ "rpc.h",
+ ]
+ deps = [
+ ":lib",
+ "../../gn:default_deps",
+ "../../include/perfetto/ext/base",
+ "../../include/perfetto/protozero",
+ "../../protos/perfetto/trace_processor:zero",
+ ]
+}
+
if (enable_perfetto_trace_processor_metrics) { # shell requires metrics.
perfetto_host_executable("trace_processor_shell") {
deps = [
@@ -292,12 +327,12 @@
"filtered_row_index_unittest.cc",
"forwarding_trace_parser_unittest.cc",
"heap_profile_tracker_unittest.cc",
+ "importers/proto/proto_trace_parser_unittest.cc",
"importers/systrace/systrace_parser_unittest.cc",
"metadata_table_unittest.cc",
"null_term_string_view_unittest.cc",
"process_table_unittest.cc",
"process_tracker_unittest.cc",
- "proto_trace_parser_unittest.cc",
"slice_tracker_unittest.cc",
"span_join_operator_table_unittest.cc",
"string_pool_unittest.cc",
@@ -338,6 +373,7 @@
# export_json_unittest.cc uses base::TempFile, which is not supported on
# windows.
sources += [ "export_json_unittest.cc" ]
+ deps += [ "../../include/perfetto/ext/trace_processor:export_json" ]
}
deps += [ "../../gn:jsoncpp" ]
}
@@ -363,7 +399,6 @@
"../../gn:default_deps",
"../../gn:gtest_and_gmock",
"../../protos/perfetto/trace:lite",
- "../../protos/perfetto/trace_processor:lite",
"../base",
"../base:test_support",
"sqlite",
diff --git a/src/trace_processor/db/column.cc b/src/trace_processor/db/column.cc
index 62da919..61a4a7c 100644
--- a/src/trace_processor/db/column.cc
+++ b/src/trace_processor/db/column.cc
@@ -54,8 +54,7 @@
col_idx, row_map_idx, nullptr);
}
-void Column::FilterInto(FilterOp op, SqlValue value, RowMap* iv) const {
- // TODO(lalitm): add special logic here to deal with kId and kSorted flags.
+void Column::FilterIntoSlow(FilterOp op, SqlValue value, RowMap* iv) const {
switch (op) {
case FilterOp::kLt:
iv->RemoveIf([this, value](uint32_t row) { return Get(row) >= value; });
diff --git a/src/trace_processor/db/column.h b/src/trace_processor/db/column.h
index e01a0da..6e9c9c4 100644
--- a/src/trace_processor/db/column.h
+++ b/src/trace_processor/db/column.h
@@ -164,7 +164,19 @@
// Updates the given RowMap by only keeping rows where this column meets the
// given filter constraint.
- void FilterInto(FilterOp, SqlValue value, RowMap*) const;
+ void FilterInto(FilterOp op, SqlValue value, RowMap* rm) const {
+ // TODO(lalitm): add special logic here to deal with kId and kSorted flags.
+ if (type_ == ColumnType::kId && op == FilterOp::kEq) {
+ auto opt_idx = IndexOf(value);
+ if (opt_idx) {
+ rm->Intersect(RowMap::SingleRow(*opt_idx));
+ } else {
+ rm->Intersect(RowMap());
+ }
+ return;
+ }
+ FilterIntoSlow(op, value, rm);
+ }
// Returns true if this column is considered an id column.
bool IsId() const { return (flags_ & Flag::kId) != 0; }
@@ -275,6 +287,8 @@
Column(const Column&) = delete;
Column& operator=(const Column&) = delete;
+ void FilterIntoSlow(FilterOp, SqlValue value, RowMap*) const;
+
template <typename T>
static ColumnType ToColumnType() {
if (std::is_same<T, uint32_t>::value) {
diff --git a/src/trace_processor/db/row_map.cc b/src/trace_processor/db/row_map.cc
index b9a3a9c..021e6bb 100644
--- a/src/trace_processor/db/row_map.cc
+++ b/src/trace_processor/db/row_map.cc
@@ -19,42 +19,171 @@
namespace perfetto {
namespace trace_processor {
-RowMap::RowMap(BitVector bit_vector)
- : compact_(true), bit_vector_(std::move(bit_vector)) {}
+namespace {
-RowMap::RowMap(std::vector<uint32_t> vec)
- : compact_(false), index_vector_(std::move(vec)) {}
+RowMap SelectRangeWithRange(uint32_t start,
+ uint32_t end,
+ uint32_t selector_start,
+ uint32_t selector_end) {
+ PERFETTO_DCHECK(start <= end);
+ PERFETTO_DCHECK(selector_start <= selector_end);
+ PERFETTO_DCHECK(selector_end <= end - start);
-RowMap RowMap::Copy() const {
- return compact_ ? RowMap(bit_vector_.Copy()) : RowMap(index_vector_);
+ return RowMap(start + selector_start, start + selector_end);
}
-RowMap RowMap::SelectRows(const RowMap& picker) const {
- if (compact_ && picker.compact_) {
- BitVector bv = bit_vector_.Copy();
- bv.UpdateSetBits(picker.bit_vector_);
- return RowMap(std::move(bv));
- } else if (compact_ && !picker.compact_) {
- std::vector<uint32_t> iv(picker.index_vector_.size());
- for (uint32_t i = 0; i < picker.index_vector_.size(); ++i) {
- // TODO(lalitm): this is pretty inefficient.
- iv[i] = bit_vector_.IndexOfNthSet(picker.index_vector_[i]);
- }
- return RowMap(std::move(iv));
- } else if (!compact_ && picker.compact_) {
- RowMap rm = Copy();
- uint32_t idx = 0;
- rm.RemoveIf(
- [&idx, &picker](uint32_t) { return !picker.bit_vector_.IsSet(idx++); });
- return rm;
- } else /* (!compact_ && !picker.compact_) */ {
- std::vector<uint32_t> iv(picker.index_vector_.size());
- for (uint32_t i = 0; i < picker.index_vector_.size(); ++i) {
- PERFETTO_DCHECK(picker.index_vector_[i] < index_vector_.size());
- iv[i] = index_vector_[picker.index_vector_[i]];
- }
- return RowMap(std::move(iv));
+RowMap SelectRangeWithBv(uint32_t start,
+ uint32_t end,
+ const BitVector& selector) {
+ PERFETTO_DCHECK(start <= end);
+
+ BitVector bv(start, false);
+ bv.Resize(end, true);
+ bv.UpdateSetBits(selector);
+ return RowMap(std::move(bv));
+}
+
+RowMap SelectRangeWithIv(uint32_t start,
+ uint32_t end,
+ const std::vector<uint32_t>& selector) {
+ PERFETTO_DCHECK(start <= end);
+
+ std::vector<uint32_t> iv(selector.size());
+ for (uint32_t i = 0; i < selector.size(); ++i) {
+ PERFETTO_DCHECK(selector[i] < end - start);
+ iv[i] = selector[i] + start;
}
+ return RowMap(std::move(iv));
+}
+
+RowMap SelectBvWithRange(const BitVector& bv,
+ uint32_t selector_start,
+ uint32_t selector_end) {
+ PERFETTO_DCHECK(selector_start <= selector_end);
+ PERFETTO_DCHECK(selector_end <= bv.GetNumBitsSet());
+
+ BitVector ret = bv.Copy();
+ for (auto it = ret.IterateSetBits(); it; it.Next()) {
+ auto set_idx = it.set_bit_index();
+ if (set_idx < selector_start || set_idx >= selector_end)
+ it.Clear();
+ }
+ return RowMap(std::move(ret));
+}
+
+RowMap SelectBvWithBv(const BitVector& bv, const BitVector& selector) {
+ BitVector ret = bv.Copy();
+ ret.UpdateSetBits(selector);
+ return RowMap(std::move(ret));
+}
+
+RowMap SelectBvWithIv(const BitVector& bv,
+ const std::vector<uint32_t>& selector) {
+ std::vector<uint32_t> iv(selector.size());
+ for (uint32_t i = 0; i < selector.size(); ++i) {
+ // TODO(lalitm): this is pretty inefficient.
+ iv[i] = bv.IndexOfNthSet(selector[i]);
+ }
+ return RowMap(std::move(iv));
+}
+
+RowMap SelectIvWithRange(const std::vector<uint32_t>& iv,
+ uint32_t selector_start,
+ uint32_t selector_end) {
+ PERFETTO_DCHECK(selector_start <= selector_end);
+ PERFETTO_DCHECK(selector_end <= iv.size());
+
+ std::vector<uint32_t> ret(selector_end - selector_start);
+ for (uint32_t i = selector_start; i < selector_end; ++i) {
+ ret[i - selector_start] = iv[i];
+ }
+ return RowMap(std::move(ret));
+}
+
+RowMap SelectIvWithBv(const std::vector<uint32_t>& iv,
+ const BitVector& selector) {
+ RowMap rm(iv);
+ uint32_t idx = 0;
+ rm.RemoveIf([&idx, &selector](uint32_t) { return !selector.IsSet(idx++); });
+ return rm;
+}
+
+RowMap SelectIvWithIv(const std::vector<uint32_t>& iv,
+ const std::vector<uint32_t>& selector) {
+ std::vector<uint32_t> ret(selector.size());
+ for (uint32_t i = 0; i < selector.size(); ++i) {
+ PERFETTO_DCHECK(selector[i] < iv.size());
+ ret[i] = iv[selector[i]];
+ }
+ return RowMap(std::move(ret));
+}
+
+} // namespace
+
+RowMap::RowMap() : RowMap(0, 0) {}
+
+RowMap::RowMap(uint32_t start, uint32_t end)
+ : mode_(Mode::kRange), start_idx_(start), end_idx_(end) {}
+
+RowMap::RowMap(BitVector bit_vector)
+ : mode_(Mode::kBitVector), bit_vector_(std::move(bit_vector)) {}
+
+RowMap::RowMap(std::vector<uint32_t> vec)
+ : mode_(Mode::kIndexVector), index_vector_(std::move(vec)) {}
+
+RowMap RowMap::Copy() const {
+ switch (mode_) {
+ case Mode::kRange:
+ return RowMap(start_idx_, end_idx_);
+ case Mode::kBitVector:
+ return RowMap(bit_vector_.Copy());
+ case Mode::kIndexVector:
+ return RowMap(index_vector_);
+ }
+ PERFETTO_FATAL("For GCC");
+}
+
+RowMap RowMap::SelectRowsSlow(const RowMap& selector) const {
+ // Pick the strategy based on the selector as there is more common code
+ // between selectors of the same mode than between the RowMaps being
+ // selected of the same mode.
+ switch (selector.mode_) {
+ case Mode::kRange:
+ switch (mode_) {
+ case Mode::kRange:
+ return SelectRangeWithRange(start_idx_, end_idx_, selector.start_idx_,
+ selector.end_idx_);
+ case Mode::kBitVector:
+ return SelectBvWithRange(bit_vector_, selector.start_idx_,
+ selector.end_idx_);
+ case Mode::kIndexVector:
+ return SelectIvWithRange(index_vector_, selector.start_idx_,
+ selector.end_idx_);
+ }
+ break;
+ case Mode::kBitVector:
+ switch (mode_) {
+ case Mode::kRange:
+ return SelectRangeWithBv(start_idx_, end_idx_, selector.bit_vector_);
+ case Mode::kBitVector:
+ return SelectBvWithBv(bit_vector_, selector.bit_vector_);
+ case Mode::kIndexVector:
+ return SelectIvWithBv(index_vector_, selector.bit_vector_);
+ }
+ break;
+ case Mode::kIndexVector:
+ switch (mode_) {
+ case Mode::kRange:
+ return SelectRangeWithIv(start_idx_, end_idx_,
+ selector.index_vector_);
+ case Mode::kBitVector:
+ return SelectBvWithIv(bit_vector_, selector.index_vector_);
+ case Mode::kIndexVector:
+ return SelectIvWithIv(index_vector_, selector.index_vector_);
+ }
+ break;
+ }
+ PERFETTO_FATAL("For GCC");
}
} // namespace trace_processor
diff --git a/src/trace_processor/db/row_map.h b/src/trace_processor/db/row_map.h
index 2a85d99..0a2932a 100644
--- a/src/trace_processor/db/row_map.h
+++ b/src/trace_processor/db/row_map.h
@@ -33,65 +33,149 @@
// columns can refer to the same RowMap. The RowMap defines the access pattern
// to iterate on rows.
//
-// Behind the scenes, this class is impelemented using one of two backing
-// data-structures:
-// 1. BitVector
-// 2. std::vector<uint32_t>
+// Implementation details:
//
-// Generally a BitVector is used whenever possible because of its space
-// efficiency compared to the small overhead of searching through the
-// bitvector.
-// However, as soon as sorting or duplicate rows come into play, we cannot use a
-// BitVector anymore as ordering/duplicate row information cannot be captured by
-// a BitVector. At this point, we switch to using an std::vector<uint32_t> and
-// continue to do so even after the RowMap is modified to keep preserving
-// ordering/duplicates.
+// Behind the scenes, this class is impelemented using one of three backing
+// data-structures:
+// 1. A start and end index (internally named 'range')
+// 1. BitVector
+// 2. std::vector<uint32_t> (internally named IndexVector).
+//
+// Generally the preference for data structures is range > BitVector >
+// std::vector<uint32>; this ordering is based mainly on memory efficiency as we
+// expect RowMaps to be large.
+//
+// However, BitVector and std::vector<uint32_t> allow things which are not
+// possible with the data-structures preferred to them:
+// * a range (as the name suggests) can only store a compact set of indices
+// with no holes. A BitVector works around this limitation by storing a 1 at an
+// index where that row is part of the RowMap and 0 otherwise.
+// * as soon as ordering or duplicate rows come into play, we cannot use a
+// BitVector anymore as ordering/duplicate row information cannot be captured
+// by a BitVector.
+//
+// For small, sparse RowMaps, it is possible that a std::vector<uint32_t> is
+// more efficient than a BitVector; in this case, we will make a best effort
+// switch to it but the cases where this happens is not precisely defined.
class RowMap {
public:
+ // Creates an empty RowMap.
+ // By default this will be implemented using a range.
+ RowMap();
+
+ // Creates a RowMap containing the range of rows between |start| and |end|
+ // i.e. all rows between |start| (inclusive) and |end| (exclusive).
+ explicit RowMap(uint32_t start, uint32_t end);
+
// Creates a RowMap backed by a BitVector.
explicit RowMap(BitVector bit_vector);
// Creates a RowMap backed by an std::vector<uint32_t>.
explicit RowMap(std::vector<uint32_t> vec);
+ // Creates a RowMap containing just |row|.
+ // By default this will be implemented using a range.
+ static RowMap SingleRow(uint32_t row) { return RowMap(row, row + 1); }
+
// Creates a copy of the RowMap.
+ // We have an explicit copy function because RowMap can hold onto large chunks
+ // of memory and we want to be very explicit when making a copy to avoid
+ // accidental leaks and copies.
RowMap Copy() const;
// Returns the size of the RowMap; that is the number of rows in the RowMap.
uint32_t size() const {
- return compact_ ? bit_vector_.GetNumBitsSet()
- : static_cast<uint32_t>(index_vector_.size());
+ switch (mode_) {
+ case Mode::kRange:
+ return end_idx_ - start_idx_;
+ case Mode::kBitVector:
+ return bit_vector_.GetNumBitsSet();
+ case Mode::kIndexVector:
+ return static_cast<uint32_t>(index_vector_.size());
+ }
+ PERFETTO_FATAL("For GCC");
}
// Returns the row at index |row|.
uint32_t Get(uint32_t idx) const {
PERFETTO_DCHECK(idx < size());
- return compact_ ? bit_vector_.IndexOfNthSet(idx) : index_vector_[idx];
+ switch (mode_) {
+ case Mode::kRange:
+ return start_idx_ + idx;
+ case Mode::kBitVector:
+ return bit_vector_.IndexOfNthSet(idx);
+ case Mode::kIndexVector:
+ return index_vector_[idx];
+ }
+ PERFETTO_FATAL("For GCC");
+ }
+
+ // Returns whether the RowMap contains the given row.
+ bool Contains(uint32_t row) const {
+ switch (mode_) {
+ case Mode::kRange: {
+ return row >= start_idx_ && row < end_idx_;
+ }
+ case Mode::kBitVector: {
+ return row < bit_vector_.size() && bit_vector_.IsSet(row);
+ }
+ case Mode::kIndexVector: {
+ auto it = std::find(index_vector_.begin(), index_vector_.end(), row);
+ return it != index_vector_.end();
+ }
+ }
+ PERFETTO_FATAL("For GCC");
}
// Returns the first index of the given |row| in the RowMap.
base::Optional<uint32_t> IndexOf(uint32_t row) const {
- if (compact_) {
- return row < bit_vector_.size() && bit_vector_.IsSet(row)
- ? base::make_optional(bit_vector_.GetNumBitsSet(row))
- : base::nullopt;
- } else {
- auto it = std::find(index_vector_.begin(), index_vector_.end(), row);
- return it != index_vector_.end()
- ? base::make_optional(static_cast<uint32_t>(
- std::distance(index_vector_.begin(), it)))
- : base::nullopt;
+ switch (mode_) {
+ case Mode::kRange: {
+ if (row < start_idx_ || row >= end_idx_)
+ return base::nullopt;
+ return row - start_idx_;
+ }
+ case Mode::kBitVector: {
+ return row < bit_vector_.size() && bit_vector_.IsSet(row)
+ ? base::make_optional(bit_vector_.GetNumBitsSet(row))
+ : base::nullopt;
+ }
+ case Mode::kIndexVector: {
+ auto it = std::find(index_vector_.begin(), index_vector_.end(), row);
+ return it != index_vector_.end()
+ ? base::make_optional(static_cast<uint32_t>(
+ std::distance(index_vector_.begin(), it)))
+ : base::nullopt;
+ }
}
+ PERFETTO_FATAL("For GCC");
}
// Adds the given |row| to the RowMap.
void Add(uint32_t row) {
- if (compact_) {
- if (row >= bit_vector_.size())
- bit_vector_.Resize(row + 1, false);
- bit_vector_.Set(row);
- } else {
- index_vector_.emplace_back(row);
+ switch (mode_) {
+ case Mode::kRange:
+ // TODO(lalitm): if row == end_index_, we can keep the RowMap in range
+ // mode and just bump the pointer instead of converting to a BitVector.
+
+ // TODO(lalitm): if row < end_index_, we need to switch to IndexVector
+ // mode instead of staying in BitVector mode.
+
+ bit_vector_.Resize(start_idx_, false);
+ bit_vector_.Resize(end_idx_, true);
+
+ start_idx_ = 0;
+ end_idx_ = 0;
+ mode_ = Mode::kBitVector;
+
+ AddToBitVector(row);
+ break;
+ case Mode::kBitVector:
+ AddToBitVector(row);
+ break;
+ case Mode::kIndexVector:
+ index_vector_.emplace_back(row);
+ break;
}
}
@@ -109,31 +193,112 @@
// for (idx : picker)
// rm[i++] = this[idx]
// return rm;
- RowMap SelectRows(const RowMap& picker) const;
+ RowMap SelectRows(const RowMap& selector) const {
+ uint32_t size = selector.size();
+
+ // If the selector is empty, just return an empty RowMap.
+ if (size == 0u)
+ return RowMap();
+
+ // If the selector is just picking a single row, just return that row
+ // without any additional overhead.
+ if (size == 1u)
+ return RowMap::SingleRow(Get(selector.Get(0)));
+
+ // For all other cases, go into the slow-path.
+ return SelectRowsSlow(selector);
+ }
// Removes any row where |p(row)| returns false from this RowMap.
template <typename Predicate>
void RemoveIf(Predicate p) {
- if (compact_) {
- for (auto it = bit_vector_.IterateSetBits(); it; it.Next()) {
- if (p(it.index()))
- it.Clear();
+ switch (mode_) {
+ case Mode::kRange: {
+ bit_vector_.Resize(start_idx_, false);
+ for (uint32_t i = start_idx_; i < end_idx_; ++i) {
+ if (p(i))
+ bit_vector_.AppendFalse();
+ else
+ bit_vector_.AppendTrue();
+ }
+ *this = RowMap(std::move(bit_vector_));
+ break;
}
- } else {
- auto it = std::remove_if(index_vector_.begin(), index_vector_.end(), p);
- index_vector_.erase(it, index_vector_.end());
+ case Mode::kBitVector: {
+ for (auto it = bit_vector_.IterateSetBits(); it; it.Next()) {
+ if (p(it.index()))
+ it.Clear();
+ }
+ break;
+ }
+ case Mode::kIndexVector: {
+ auto it = std::remove_if(index_vector_.begin(), index_vector_.end(), p);
+ index_vector_.erase(it, index_vector_.end());
+ break;
+ }
}
}
- private:
- // TODO(lalitm): add a mode with two indicies marking out a range as well
- // or integrate this with BitVector.
- bool compact_ = false;
+ // Intersects |other| with |this| writing the result into |this|.
+ // By "intersect", we mean to keep only the rows present in both RowMaps. The
+ // order of the preserved rows will be the same as |this|.
+ //
+ // Conceptually, we are performing the following algorithm:
+ // for (idx : this)
+ // if (!other.Contains(idx))
+ // Remove(idx)
+ void Intersect(const RowMap& other) {
+ uint32_t size = other.size();
- // Only valid when |compact_| == true.
+ if (size == 0u) {
+ // If other is empty, then we will also end up being empty.
+ *this = RowMap();
+ return;
+ }
+
+ if (size == 1u) {
+ // If other just has a single row, see if we also have that row. If we
+ // do, then just return that row. Otherwise, make ourselves empty.
+ uint32_t row = other.Get(0);
+ *this = Contains(row) ? RowMap::SingleRow(row) : RowMap();
+ return;
+ }
+
+ // TODO(lalitm): improve efficiency of this if we end up needing it.
+ RemoveIf([&other](uint32_t row) { return !other.Contains(row); });
+ }
+
+ private:
+ enum class Mode {
+ kRange,
+ kBitVector,
+ kIndexVector,
+ };
+
+ void AddToBitVector(uint32_t row) {
+ PERFETTO_DCHECK(mode_ == Mode::kBitVector);
+
+ // TODO(lalitm): RowMap should be an ordered container but we do not
+ // currently support this when in BitVector mode. Fix this by turning to
+ // IndexVector mode if we add a row before the end.
+ PERFETTO_CHECK(row >= bit_vector_.size());
+
+ bit_vector_.Resize(row + 1, false);
+ bit_vector_.Set(row);
+ }
+
+ RowMap SelectRowsSlow(const RowMap& selector) const;
+
+ Mode mode_ = Mode::kRange;
+
+ // Only valid when |mode_| == Mode::kRange.
+ uint32_t start_idx_ = 0; // This is an inclusive index.
+ uint32_t end_idx_ = 0; // This is an exclusive index.
+
+ // Only valid when |mode_| == Mode::kBitVector.
BitVector bit_vector_;
- // Only valid when |compact_| == false.
+ // Only valid when |mode_| == Mode::kIndexVector.
std::vector<uint32_t> index_vector_;
};
diff --git a/src/trace_processor/db/row_map_benchmark.cc b/src/trace_processor/db/row_map_benchmark.cc
index 0e388c1..274aefe 100644
--- a/src/trace_processor/db/row_map_benchmark.cc
+++ b/src/trace_processor/db/row_map_benchmark.cc
@@ -26,7 +26,16 @@
static constexpr uint32_t kPoolSize = 100000;
static constexpr uint32_t kSize = 123456;
-std::vector<uint32_t> CreateRandomIndexVector(uint32_t size, uint32_t mod) {
+RowMap CreateRange(uint32_t end) {
+ static constexpr uint32_t kRandomSeed = 32;
+ std::minstd_rand0 rnd_engine(kRandomSeed);
+
+ uint32_t start = rnd_engine() % end;
+ uint32_t size = rnd_engine() % (end - start);
+ return RowMap(start, start + size);
+}
+
+std::vector<uint32_t> CreateIndexVector(uint32_t size, uint32_t mod) {
static constexpr uint32_t kRandomSeed = 476;
std::minstd_rand0 rnd_engine(kRandomSeed);
std::vector<uint32_t> rows(size);
@@ -36,7 +45,7 @@
return rows;
}
-BitVector CreateRandomBitVector(uint32_t size) {
+BitVector CreateBitVector(uint32_t size) {
static constexpr uint32_t kRandomSeed = 42;
std::minstd_rand0 rnd_engine(kRandomSeed);
BitVector bv;
@@ -50,127 +59,164 @@
return bv;
}
+void BenchRowMapGet(benchmark::State& state, RowMap rm) {
+ auto pool_vec = CreateIndexVector(kPoolSize, rm.size());
+
+ uint32_t pool_idx = 0;
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(rm.Get(pool_vec[pool_idx]));
+ pool_idx = (pool_idx + 1) % kPoolSize;
+ }
+}
+
+template <typename Factory>
+void BenchRowMapAddToEmpty(benchmark::State& state, Factory factory) {
+ auto pool_vec = CreateIndexVector(kPoolSize, kSize);
+
+ uint32_t pool_idx = 0;
+ for (auto _ : state) {
+ RowMap rm = factory();
+
+ rm.Add(pool_vec[pool_idx]);
+ pool_idx = (pool_idx + 1) % kPoolSize;
+
+ benchmark::ClobberMemory();
+ }
+}
+
+void BenchRowMapSelect(benchmark::State& state,
+ RowMap rm,
+ const RowMap& selector) {
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(rm.SelectRows(selector));
+ }
+}
+
+template <typename Factory>
+void BenchRowMapRemoveIf(benchmark::State& state, Factory factory) {
+ auto pool_vec = CreateIndexVector(kPoolSize, kSize);
+
+ uint32_t pool_idx = 0;
+ for (auto _ : state) {
+ state.PauseTiming();
+ RowMap rm = factory();
+ state.ResumeTiming();
+
+ auto fn = [&pool_vec, pool_idx](uint32_t row) {
+ return (row % pool_vec[pool_idx]) != 0;
+ };
+ rm.RemoveIf(fn);
+ pool_idx = (pool_idx + 1) % kPoolSize;
+
+ benchmark::ClobberMemory();
+ }
+}
+
} // namespace
-static void BM_RowMapBitVectorGet(benchmark::State& state) {
- RowMap rm(CreateRandomBitVector(kSize));
- auto pool_vec = CreateRandomIndexVector(kPoolSize, rm.size());
-
- uint32_t pool_idx = 0;
- for (auto _ : state) {
- benchmark::DoNotOptimize(rm.Get(pool_vec[pool_idx]));
- pool_idx = (pool_idx + 1) % kPoolSize;
- }
+static void BM_RowMapRangeGet(benchmark::State& state) {
+ BenchRowMapGet(state, RowMap(CreateRange(kSize)));
}
-BENCHMARK(BM_RowMapBitVectorGet);
+BENCHMARK(BM_RowMapRangeGet);
-static void BM_RowMapIndexVectorGet(benchmark::State& state) {
- RowMap rm(CreateRandomIndexVector(kSize, kSize));
- auto pool_vec = CreateRandomIndexVector(kPoolSize, kSize);
-
- uint32_t pool_idx = 0;
- for (auto _ : state) {
- benchmark::DoNotOptimize(rm.Get(pool_vec[pool_idx]));
- pool_idx = (pool_idx + 1) % kPoolSize;
- }
+static void BM_RowMapBvGet(benchmark::State& state) {
+ BenchRowMapGet(state, RowMap(CreateBitVector(kSize)));
}
-BENCHMARK(BM_RowMapIndexVectorGet);
+BENCHMARK(BM_RowMapBvGet);
+
+static void BM_RowMapIvGet(benchmark::State& state) {
+ BenchRowMapGet(state, RowMap(CreateIndexVector(kSize, kSize)));
+}
+BENCHMARK(BM_RowMapIvGet);
// TODO(lalitm): add benchmarks for IndexOf after BitVector is made faster.
// We can't add them right now because they are just too slow to run.
-static void BM_RowMapBitVectorAdd(benchmark::State& state) {
- auto pool_vec = CreateRandomIndexVector(kPoolSize, kSize);
-
- RowMap rm(BitVector{});
- uint32_t pool_idx = 0;
- for (auto _ : state) {
- rm.Add(pool_vec[pool_idx]);
- pool_idx = (pool_idx + 1) % kPoolSize;
- benchmark::ClobberMemory();
- }
+static void BM_RowMapRangeAddToEmpty(benchmark::State& state) {
+ BenchRowMapAddToEmpty(state, []() { return RowMap(0, 0); });
}
-BENCHMARK(BM_RowMapBitVectorAdd);
+BENCHMARK(BM_RowMapRangeAddToEmpty);
-static void BM_RowMapIndexVectorAdd(benchmark::State& state) {
- auto pool_vec = CreateRandomIndexVector(kPoolSize, kSize);
-
- RowMap rm(std::vector<uint32_t>{});
- uint32_t pool_idx = 0;
- for (auto _ : state) {
- rm.Add(pool_vec[pool_idx]);
- pool_idx = (pool_idx + 1) % kPoolSize;
- benchmark::ClobberMemory();
- }
+static void BM_RowMapBvAddToEmpty(benchmark::State& state) {
+ BenchRowMapAddToEmpty(state, []() { return RowMap(BitVector{}); });
}
-BENCHMARK(BM_RowMapIndexVectorAdd);
+BENCHMARK(BM_RowMapBvAddToEmpty);
-static void BM_RowMapBvSelectBv(benchmark::State& state) {
- RowMap rm(CreateRandomBitVector(kSize));
- RowMap selector(CreateRandomBitVector(rm.size()));
-
- for (auto _ : state) {
- benchmark::DoNotOptimize(rm.SelectRows(selector));
- }
+static void BM_RowMapIvAddToEmpty(benchmark::State& state) {
+ BenchRowMapAddToEmpty(state,
+ []() { return RowMap(std::vector<uint32_t>{}); });
}
-BENCHMARK(BM_RowMapBvSelectBv);
+BENCHMARK(BM_RowMapIvAddToEmpty);
-// TODO(lalitm): add benchmarks for BvSelectIv after BitVector is made faster.
-// We can't add them right now because they are just too slow to run.
-
-static void BM_RowMapIvSelectBv(benchmark::State& state) {
- RowMap rm(CreateRandomIndexVector(kSize, kSize));
- RowMap selector(CreateRandomBitVector(rm.size()));
-
- for (auto _ : state) {
- benchmark::DoNotOptimize(rm.SelectRows(selector));
- }
+static void BM_RowMapSelectRangeWithRange(benchmark::State& state) {
+ RowMap rm(CreateRange(kSize));
+ RowMap selector(CreateRange(rm.size()));
+ BenchRowMapSelect(state, std::move(rm), std::move(selector));
}
-BENCHMARK(BM_RowMapIvSelectBv);
+BENCHMARK(BM_RowMapSelectRangeWithRange);
-static void BM_RowMapIvSelectIv(benchmark::State& state) {
- RowMap rm(CreateRandomIndexVector(kSize, kSize));
- RowMap selector(CreateRandomIndexVector(rm.size(), rm.size()));
-
- for (auto _ : state) {
- benchmark::DoNotOptimize(rm.SelectRows(selector));
- }
+static void BM_RowMapSelectRangeWithBv(benchmark::State& state) {
+ RowMap rm(CreateRange(kSize));
+ RowMap selector(CreateBitVector(rm.size()));
+ BenchRowMapSelect(state, std::move(rm), std::move(selector));
}
-BENCHMARK(BM_RowMapIvSelectIv);
+BENCHMARK(BM_RowMapSelectRangeWithBv);
-static void BM_RowMapBvSelectSingleRow(benchmark::State& state) {
- // This benchmark tests the performance of selecting just a single
- // row of a RowMap. We specially test this case as it occurs on every join
- // based on id originating from SQLite; nested subqueries will be performed
- // on the id column and will select just a single row.
- RowMap rm(CreateRandomBitVector(kSize));
-
- static constexpr uint32_t kRandomSeed = 123;
- std::minstd_rand0 rnd_engine(kRandomSeed);
- BitVector bv(rm.size(), false);
- bv.Set(rnd_engine() % bv.size());
- RowMap selector(std::move(bv));
-
- for (auto _ : state) {
- benchmark::DoNotOptimize(rm.SelectRows(selector));
- }
+static void BM_RowMapSelectRangeWithIv(benchmark::State& state) {
+ RowMap rm(CreateRange(kSize));
+ RowMap selector(CreateIndexVector(rm.size(), rm.size()));
+ BenchRowMapSelect(state, std::move(rm), std::move(selector));
}
-BENCHMARK(BM_RowMapBvSelectSingleRow);
+BENCHMARK(BM_RowMapSelectRangeWithIv);
+
+static void BM_RowMapSelectBvWithRange(benchmark::State& state) {
+ RowMap rm(CreateBitVector(kSize));
+ RowMap selector(CreateRange(rm.size()));
+ BenchRowMapSelect(state, std::move(rm), std::move(selector));
+}
+BENCHMARK(BM_RowMapSelectBvWithRange);
+
+static void BM_RowMapSelectBvWithBv(benchmark::State& state) {
+ RowMap rm(CreateBitVector(kSize));
+ RowMap selector(CreateBitVector(rm.size()));
+ BenchRowMapSelect(state, std::move(rm), std::move(selector));
+}
+BENCHMARK(BM_RowMapSelectBvWithBv);
+
+static void BM_RowMapSelectBvWithIv(benchmark::State& state) {
+ RowMap rm(CreateBitVector(kSize));
+ RowMap selector(CreateIndexVector(rm.size(), rm.size()));
+ BenchRowMapSelect(state, std::move(rm), std::move(selector));
+}
+BENCHMARK(BM_RowMapSelectBvWithIv);
+
+static void BM_RowMapSelectIvWithRange(benchmark::State& state) {
+ RowMap rm(CreateIndexVector(kSize, kSize));
+ RowMap selector(CreateRange(rm.size()));
+ BenchRowMapSelect(state, std::move(rm), std::move(selector));
+}
+BENCHMARK(BM_RowMapSelectIvWithRange);
+
+static void BM_RowMapSelectIvWithBv(benchmark::State& state) {
+ RowMap rm(CreateIndexVector(kSize, kSize));
+ RowMap selector(CreateBitVector(rm.size()));
+ BenchRowMapSelect(state, std::move(rm), std::move(selector));
+}
+BENCHMARK(BM_RowMapSelectIvWithBv);
+
+static void BM_RowMapSelectIvWithIv(benchmark::State& state) {
+ RowMap rm(CreateIndexVector(kSize, kSize));
+ RowMap selector(CreateIndexVector(rm.size(), rm.size()));
+ BenchRowMapSelect(state, std::move(rm), std::move(selector));
+}
+BENCHMARK(BM_RowMapSelectIvWithIv);
+
+static void BM_RowMapRangeRemoveIf(benchmark::State& state) {
+ BenchRowMapRemoveIf(state, []() { return RowMap(CreateRange(kSize)); });
+}
+BENCHMARK(BM_RowMapRangeRemoveIf);
static void BM_RowMapBvRemoveIf(benchmark::State& state) {
- RowMap rm(CreateRandomBitVector(kSize));
-
- static constexpr uint32_t kRandomSeed = 123;
- std::minstd_rand0 rnd_engine(kRandomSeed);
- for (auto _ : state) {
- state.PauseTiming();
- RowMap copy = rm.Copy();
- uint32_t mod_row_to_keep = rnd_engine() % kSize;
- state.ResumeTiming();
-
- copy.RemoveIf(
- [mod_row_to_keep](uint32_t row) { return row % mod_row_to_keep != 0; });
- benchmark::ClobberMemory();
- }
+ BenchRowMapRemoveIf(state, []() { return RowMap(CreateBitVector(kSize)); });
}
BENCHMARK(BM_RowMapBvRemoveIf);
diff --git a/src/trace_processor/db/row_map_unittest.cc b/src/trace_processor/db/row_map_unittest.cc
index 2a4cebc..cb2905d 100644
--- a/src/trace_processor/db/row_map_unittest.cc
+++ b/src/trace_processor/db/row_map_unittest.cc
@@ -25,6 +25,22 @@
namespace trace_processor {
namespace {
+TEST(RowMapUnittest, SmokeRange) {
+ RowMap rm(30, 47);
+
+ ASSERT_EQ(rm.size(), 17u);
+
+ ASSERT_EQ(rm.Get(0), 30u);
+ ASSERT_EQ(rm.Get(1), 31u);
+ ASSERT_EQ(rm.Get(16), 46u);
+
+ ASSERT_EQ(rm.IndexOf(29), base::nullopt);
+ ASSERT_EQ(rm.IndexOf(30), 0u);
+ ASSERT_EQ(rm.IndexOf(37), 7u);
+ ASSERT_EQ(rm.IndexOf(46), 16u);
+ ASSERT_EQ(rm.IndexOf(47), base::nullopt);
+}
+
TEST(RowMapUnittest, SmokeBitVector) {
RowMap rm(BitVector{true, false, false, false, true, true});
@@ -62,6 +78,18 @@
ASSERT_EQ(rm.IndexOf(1u), 5u);
}
+// TODO(lalitm): add a test here for AddToRangeBefore when we fix the issue
+// in RowMap which has incorrect behaviour for this case.
+
+TEST(RowMapUnittest, AddToRangeAfter) {
+ RowMap rm(3u, 7u);
+ rm.Add(10u);
+
+ ASSERT_EQ(rm.size(), 5u);
+ ASSERT_EQ(rm.Get(4u), 10u);
+ ASSERT_EQ(rm.IndexOf(10u), 4u);
+}
+
// TODO(lalitm): add a test here for AddToBitVectorBefore when we fix the issue
// in RowMap which has incorrect behaviour for this case.
@@ -83,6 +111,84 @@
ASSERT_EQ(rm.IndexOf(10u), 4u);
}
+TEST(RowMapUnittest, ContainsRange) {
+ RowMap rm(93, 157);
+
+ ASSERT_TRUE(rm.Contains(93));
+ ASSERT_TRUE(rm.Contains(105));
+ ASSERT_TRUE(rm.Contains(156));
+
+ ASSERT_FALSE(rm.Contains(0));
+ ASSERT_FALSE(rm.Contains(92));
+ ASSERT_FALSE(rm.Contains(157));
+}
+
+TEST(RowMapUnittest, ContainsBitVector) {
+ RowMap rm(BitVector{true, false, true, true, false, true});
+
+ ASSERT_TRUE(rm.Contains(0));
+ ASSERT_TRUE(rm.Contains(2));
+ ASSERT_TRUE(rm.Contains(3));
+
+ ASSERT_FALSE(rm.Contains(1));
+ ASSERT_FALSE(rm.Contains(4));
+ ASSERT_FALSE(rm.Contains(6));
+}
+
+TEST(RowMapUnittest, ContainsIndexVector) {
+ RowMap rm(std::vector<uint32_t>{0u, 2u, 3u, 5u});
+
+ ASSERT_TRUE(rm.Contains(0));
+ ASSERT_TRUE(rm.Contains(2));
+ ASSERT_TRUE(rm.Contains(3));
+
+ ASSERT_FALSE(rm.Contains(1));
+ ASSERT_FALSE(rm.Contains(4));
+ ASSERT_FALSE(rm.Contains(6));
+}
+
+TEST(RowMapUnittest, SelectRangeWithRange) {
+ RowMap rm(93, 157);
+ RowMap picker(4, 7);
+ auto res = rm.SelectRows(picker);
+
+ ASSERT_EQ(res.size(), 3u);
+ ASSERT_EQ(res.Get(0u), 97u);
+ ASSERT_EQ(res.Get(1u), 98u);
+ ASSERT_EQ(res.Get(2u), 99u);
+}
+
+TEST(RowMapUnittest, SelectBitVectorWithRange) {
+ RowMap rm(BitVector{true, false, false, true, false, true, false});
+ RowMap picker(1u, 3u);
+ auto res = rm.SelectRows(picker);
+
+ ASSERT_EQ(res.size(), 2u);
+ ASSERT_EQ(res.Get(0u), 3u);
+ ASSERT_EQ(res.Get(1u), 5u);
+}
+
+TEST(RowMapUnittest, SelectIndexVectorWithRange) {
+ RowMap rm(std::vector<uint32_t>{33, 2u, 45u, 7u, 8u, 9u});
+ RowMap picker(2, 5);
+ auto res = rm.SelectRows(picker);
+
+ ASSERT_EQ(res.size(), 3u);
+ ASSERT_EQ(res.Get(0u), 45u);
+ ASSERT_EQ(res.Get(1u), 7u);
+ ASSERT_EQ(res.Get(2u), 8u);
+}
+
+TEST(RowMapUnittest, SelectRangeWithBitVector) {
+ RowMap rm(27, 31);
+ RowMap picker(BitVector{true, false, false, true});
+ auto res = rm.SelectRows(picker);
+
+ ASSERT_EQ(res.size(), 2u);
+ ASSERT_EQ(res.Get(0u), 27u);
+ ASSERT_EQ(res.Get(1u), 30u);
+}
+
TEST(RowMapUnittest, SelectBitVectorWithBitVector) {
RowMap rm(BitVector{true, false, true, true, false, true});
RowMap picker(BitVector{true, false, false, true});
@@ -103,6 +209,20 @@
ASSERT_EQ(res.Get(1u), 5u);
}
+TEST(RowMapUnittest, SelectRangeWithIndexVector) {
+ RowMap rm(27, 31);
+ RowMap picker(std::vector<uint32_t>{3u, 2u, 0u, 1u, 1u, 3u});
+ auto res = rm.SelectRows(picker);
+
+ ASSERT_EQ(res.size(), 6u);
+ ASSERT_EQ(res.Get(0u), 30u);
+ ASSERT_EQ(res.Get(1u), 29u);
+ ASSERT_EQ(res.Get(2u), 27u);
+ ASSERT_EQ(res.Get(3u), 28u);
+ ASSERT_EQ(res.Get(4u), 28u);
+ ASSERT_EQ(res.Get(5u), 30u);
+}
+
TEST(RowMapUnittest, SelectBitVectorWithIndexVector) {
RowMap rm(BitVector{true, false, true, true, false, true});
RowMap picker(std::vector<uint32_t>{3u, 2u, 0u, 1u, 1u, 3u});
@@ -131,13 +251,22 @@
ASSERT_EQ(res.Get(5u), 7u);
}
+TEST(RowMapUnittest, RemoveIfRange) {
+ RowMap rm(27u, 31u);
+ rm.RemoveIf([](uint32_t row) { return row == 27u || row == 29u; });
+
+ ASSERT_EQ(rm.size(), 2u);
+ ASSERT_EQ(rm.Get(0u), 28u);
+ ASSERT_EQ(rm.Get(1u), 30u);
+}
+
TEST(RowMapUnittest, RemoveIfBitVector) {
RowMap rm(BitVector{true, false, true, true, false, true});
rm.RemoveIf([](uint32_t row) { return row == 2u || row == 5u; });
ASSERT_EQ(rm.size(), 2u);
- ASSERT_EQ(rm.Get(0), 0u);
- ASSERT_EQ(rm.Get(1), 3u);
+ ASSERT_EQ(rm.Get(0u), 0u);
+ ASSERT_EQ(rm.Get(1u), 3u);
}
TEST(RowMapUnittest, RemoveIfIndexVector) {
@@ -145,10 +274,42 @@
rm.RemoveIf([](uint32_t row) { return row == 3u; });
ASSERT_EQ(rm.size(), 4u);
- ASSERT_EQ(rm.Get(0), 2u);
- ASSERT_EQ(rm.Get(1), 0u);
- ASSERT_EQ(rm.Get(2), 1u);
- ASSERT_EQ(rm.Get(3), 1u);
+ ASSERT_EQ(rm.Get(0u), 2u);
+ ASSERT_EQ(rm.Get(1u), 0u);
+ ASSERT_EQ(rm.Get(2u), 1u);
+ ASSERT_EQ(rm.Get(3u), 1u);
+}
+
+TEST(RowMapUnittest, IntersectNone) {
+ RowMap rm(BitVector{true, false, true, true, false, true});
+ rm.Intersect(RowMap());
+
+ ASSERT_EQ(rm.size(), 0u);
+}
+
+TEST(RowMapUnittest, IntersectSinglePresent) {
+ RowMap rm(BitVector{true, false, true, true, false, true});
+ rm.Intersect(RowMap::SingleRow(2u));
+
+ ASSERT_EQ(rm.size(), 1u);
+ ASSERT_EQ(rm.Get(0u), 2u);
+}
+
+TEST(RowMapUnittest, IntersectSingleAbsent) {
+ RowMap rm(BitVector{true, false, true, true, false, true});
+ rm.Intersect(RowMap::SingleRow(1u));
+
+ ASSERT_EQ(rm.size(), 0u);
+}
+
+TEST(RowMapUnittest, IntersectMany) {
+ RowMap rm(std::vector<uint32_t>{3u, 2u, 0u, 1u, 1u, 3u});
+ rm.Intersect(RowMap(BitVector{false, false, true, true}));
+
+ ASSERT_EQ(rm.size(), 3u);
+ ASSERT_EQ(rm.Get(0u), 3u);
+ ASSERT_EQ(rm.Get(1u), 2u);
+ ASSERT_EQ(rm.Get(2u), 3u);
}
} // namespace
diff --git a/src/trace_processor/db/table.cc b/src/trace_processor/db/table.cc
index 90afc19..1fa8257 100644
--- a/src/trace_processor/db/table.cc
+++ b/src/trace_processor/db/table.cc
@@ -69,7 +69,7 @@
// Create a RowMap indexing all rows and filter this down to the rows which
// meet all the constraints.
- RowMap rm(BitVector(size_, true));
+ RowMap rm(0, size_);
for (const Constraint& c : cs) {
columns_[c.col_idx].FilterInto(c.op, c.value, &rm);
}
diff --git a/src/trace_processor/export_json.cc b/src/trace_processor/export_json.cc
index 67ef29d..69e97c2 100644
--- a/src/trace_processor/export_json.cc
+++ b/src/trace_processor/export_json.cc
@@ -17,6 +17,9 @@
#include "perfetto/base/build_config.h"
#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
+#include "perfetto/ext/trace_processor/export_json.h"
+#include "src/trace_processor/export_json.h"
+
#include <inttypes.h>
#include <json/reader.h>
#include <json/value.h>
@@ -26,8 +29,9 @@
#include <vector>
#include "perfetto/ext/base/string_splitter.h"
-#include "src/trace_processor/export_json.h"
#include "src/trace_processor/metadata.h"
+#include "src/trace_processor/trace_processor_context.h"
+#include "src/trace_processor/trace_processor_impl.h"
#include "src/trace_processor/trace_storage.h"
namespace perfetto {
@@ -58,25 +62,74 @@
const char kFlowDirectionValueIn[] = "in";
const char kFlowDirectionValueOut[] = "out";
const char kFlowDirectionValueInout[] = "inout";
+const char kStrippedArgument[] = "__stripped__";
const char* GetNonNullString(const TraceStorage* storage, StringId id) {
return id == kNullStringId ? "" : storage->GetString(id).c_str();
}
+class FileWriter : public OutputWriter {
+ public:
+ FileWriter(FILE* file) : file_(file) {}
+ ~FileWriter() override { fflush(file_); }
+
+ util::Status AppendString(const std::string& s) override {
+ size_t written =
+ fwrite(s.data(), sizeof(std::string::value_type), s.size(), file_);
+ if (written != s.size())
+ return util::ErrStatus("Error writing to file: %d", ferror(file_));
+ return util::OkStatus();
+ }
+
+ private:
+ FILE* file_;
+};
+
class TraceFormatWriter {
public:
- TraceFormatWriter(FILE* output) : output_(output), first_event_(true) {
+ TraceFormatWriter(OutputWriter* output,
+ ArgumentFilterPredicate argument_filter,
+ MetadataFilterPredicate metadata_filter,
+ LabelFilterPredicate label_filter)
+ : output_(output),
+ argument_filter_(argument_filter),
+ metadata_filter_(metadata_filter),
+ label_filter_(label_filter),
+ first_event_(true) {
WriteHeader();
}
~TraceFormatWriter() { WriteFooter(); }
void WriteCommonEvent(const Json::Value& event) {
+ if (label_filter_ && !label_filter_("traceEvents"))
+ return;
+
if (!first_event_) {
- fputs(",", output_);
+ output_->AppendString(",");
}
Json::FastWriter writer;
- fputs(writer.write(event).c_str(), output_);
+
+ ArgumentNameFilterPredicate argument_name_filter;
+ bool strip_args =
+ argument_filter_ &&
+ !argument_filter_(event["cat"].asCString(), event["name"].asCString(),
+ &argument_name_filter);
+ if ((strip_args || argument_name_filter) && event.isMember("args")) {
+ Json::Value event_copy = event;
+ if (strip_args) {
+ event_copy["args"] = kStrippedArgument;
+ } else {
+ auto& args = event_copy["args"];
+ for (const auto& member : event["args"].getMemberNames()) {
+ if (!argument_name_filter(member.c_str()))
+ args[member] = kStrippedArgument;
+ }
+ }
+ output_->AppendString(writer.write(event_copy));
+ } else {
+ output_->AppendString(writer.write(event));
+ }
first_event_ = false;
}
@@ -84,8 +137,11 @@
const char* metadata_value,
uint32_t tid,
uint32_t pid) {
+ if (label_filter_ && !label_filter_("traceEvents"))
+ return;
+
if (!first_event_) {
- fputs(",", output_);
+ output_->AppendString(",");
}
Json::FastWriter writer;
Json::Value value;
@@ -100,7 +156,7 @@
args["name"] = metadata_value;
value["args"] = args;
- fputs(writer.write(value).c_str(), output_);
+ output_->AppendString(writer.write(value));
first_event_ = false;
}
@@ -141,38 +197,63 @@
system_trace_data_ += data;
}
- void AddUserTraceData(const std::string& data) { user_trace_data_ += data; }
+ void AddUserTraceData(const std::string& data) {
+ if (user_trace_data_.empty())
+ user_trace_data_ = "[";
+ user_trace_data_ += data;
+ }
private:
- void WriteHeader() { fputs("{\"traceEvents\":[\n", output_); }
+ void WriteHeader() {
+ if (!label_filter_)
+ output_->AppendString("{\"traceEvents\":[\n");
+ }
void WriteFooter() {
+ // Filter metadata entries.
+ if (metadata_filter_) {
+ for (const auto& member : metadata_.getMemberNames()) {
+ if (!metadata_filter_(member.c_str()))
+ metadata_[member] = kStrippedArgument;
+ }
+ }
+
Json::FastWriter writer;
- if (!user_trace_data_.empty()) {
+ if ((!label_filter_ || label_filter_("traceEvents")) &&
+ !user_trace_data_.empty()) {
+ user_trace_data_ += "]";
Json::Reader reader;
Json::Value result;
if (reader.parse(user_trace_data_, result)) {
- WriteCommonEvent(result);
+ for (const auto& event : result) {
+ WriteCommonEvent(event);
+ }
} else {
PERFETTO_DLOG(
"can't parse legacy user json trace export, skipping. data: %s",
user_trace_data_.c_str());
}
}
- fputs("]", output_);
- if (!system_trace_data_.empty()) {
- fputs(",\"systemTraceEvents\":\n", output_);
- fputs(writer.write(Json::Value(system_trace_data_)).c_str(), output_);
+ if (!label_filter_)
+ output_->AppendString("]");
+ if ((!label_filter_ || label_filter_("systemTraceEvents")) &&
+ !system_trace_data_.empty()) {
+ output_->AppendString(",\"systemTraceEvents\":\n");
+ output_->AppendString(writer.write(Json::Value(system_trace_data_)));
}
- if (!metadata_.empty()) {
- fputs(",\"metadata\":\n", output_);
- fputs(writer.write(metadata_).c_str(), output_);
+ if ((!label_filter_ || label_filter_("metadata")) && !metadata_.empty()) {
+ output_->AppendString(",\"metadata\":\n");
+ output_->AppendString(writer.write(metadata_));
}
- fputs("}", output_);
- fflush(output_);
+ if (!label_filter_)
+ output_->AppendString("}");
}
- FILE* output_;
+ OutputWriter* output_;
+ ArgumentFilterPredicate argument_filter_;
+ MetadataFilterPredicate metadata_filter_;
+ LabelFilterPredicate label_filter_;
+
bool first_event_;
Json::Value metadata_;
std::string system_trace_data_;
@@ -315,8 +396,8 @@
}
}
-ResultCode ExportThreadNames(const TraceStorage* storage,
- TraceFormatWriter* writer) {
+util::Status ExportThreadNames(const TraceStorage* storage,
+ TraceFormatWriter* writer) {
for (UniqueTid i = 1; i < storage->thread_count(); ++i) {
auto thread = storage->GetThread(i);
if (!thread.name_id.is_null()) {
@@ -325,11 +406,11 @@
writer->WriteMetadataEvent("thread_name", thread_name, thread.tid, pid);
}
}
- return kResultOk;
+ return util::OkStatus();
}
-ResultCode ExportProcessNames(const TraceStorage* storage,
- TraceFormatWriter* writer) {
+util::Status ExportProcessNames(const TraceStorage* storage,
+ TraceFormatWriter* writer) {
for (UniquePid i = 1; i < storage->process_count(); ++i) {
auto process = storage->GetProcess(i);
if (!process.name_id.is_null()) {
@@ -337,12 +418,12 @@
writer->WriteMetadataEvent("process_name", process_name, 0, process.pid);
}
}
- return kResultOk;
+ return util::OkStatus();
}
-ResultCode ExportSlices(const TraceStorage* storage,
- const ArgsBuilder& args_builder,
- TraceFormatWriter* writer) {
+util::Status ExportSlices(const TraceStorage* storage,
+ const ArgsBuilder& args_builder,
+ TraceFormatWriter* writer) {
const auto& slices = storage->nestable_slices();
for (uint32_t i = 0; i < slices.slice_count(); ++i) {
Json::Value event;
@@ -362,28 +443,44 @@
}
}
- if (slices.types()[i] == RefType::kRefTrack) { // Async event.
- TrackId track_id = static_cast<TrackId>(slices.refs()[i]);
+ // To prevent duplicate export of slices, only export slices on descriptor
+ // or chrome tracks (i.e. TrackEvent slices). Slices on other tracks may
+ // also be present as raw events and handled by trace_to_text. Only add more
+ // track types here if they are not already covered by trace_to_text.
+ auto track_id = slices.track_id()[i];
+ auto track_args_id = storage->track_table().source_arg_set_id()[track_id];
+ if (!track_args_id)
+ continue;
+ const auto& track_args = args_builder.GetArgs(*track_args_id);
+ bool legacy_chrome_track = track_args["source"].asString() == "chrome";
+ if (!track_args.isMember("source") ||
+ (!legacy_chrome_track &&
+ track_args["source"].asString() != "descriptor")) {
+ continue;
+ }
- // TODO(lalitm): add a check here for looking up source_arg_set_id
- // and checking that this track originated from Chrome.
+ const auto& thread_track = storage->thread_track_table();
+ const auto& process_track = storage->process_track_table();
+ const auto& thread_slices = storage->thread_slices();
+ const auto& virtual_track_slices = storage->virtual_track_slices();
- const auto& process_track = storage->process_track_table();
- auto opt_process_row =
- process_track.id().IndexOf(SqlValue::Long(track_id));
- if (opt_process_row.has_value()) {
- uint32_t upid = process_track.upid()[*opt_process_row];
- event["id2"]["local"] = PrintUint64(track_id);
- event["pid"] = storage->GetProcess(upid).pid;
- } else {
- event["id2"]["global"] = PrintUint64(track_id);
- }
+ int64_t duration_ns = slices.durations()[i];
+ int64_t thread_ts_ns = 0;
+ int64_t thread_duration_ns = 0;
+ int64_t thread_instruction_count = 0;
+ int64_t thread_instruction_delta = 0;
- const auto& virtual_track_slices = storage->virtual_track_slices();
- int64_t thread_ts_ns = 0;
- int64_t thread_duration_ns = 0;
- int64_t thread_instruction_count = 0;
- int64_t thread_instruction_delta = 0;
+ base::Optional<uint32_t> thread_slice_row =
+ thread_slices.FindRowForSliceId(i);
+ if (thread_slice_row) {
+ thread_ts_ns = thread_slices.thread_timestamp_ns()[*thread_slice_row];
+ thread_duration_ns =
+ thread_slices.thread_duration_ns()[*thread_slice_row];
+ thread_instruction_count =
+ thread_slices.thread_instruction_counts()[*thread_slice_row];
+ thread_instruction_delta =
+ thread_slices.thread_instruction_deltas()[*thread_slice_row];
+ } else {
base::Optional<uint32_t> vtrack_slice_row =
virtual_track_slices.FindRowForSliceId(i);
if (vtrack_slice_row) {
@@ -396,6 +493,68 @@
thread_instruction_delta =
virtual_track_slices.thread_instruction_deltas()[*vtrack_slice_row];
}
+ }
+
+ auto opt_thread_track_row =
+ thread_track.id().IndexOf(SqlValue::Long(track_id));
+
+ if (opt_thread_track_row) {
+ // Synchronous (thread) slice or instant event.
+ UniqueTid utid = thread_track.utid()[*opt_thread_track_row];
+ auto thread = storage->GetThread(utid);
+
+ if (duration_ns == 0) {
+ event["ph"] = "i";
+ if (thread.upid) {
+ event["pid"] = storage->GetProcess(*thread.upid).pid;
+ }
+ if (thread_ts_ns > 0) {
+ event["tts"] = Json::Int64(thread_ts_ns / 1000);
+ }
+ if (thread_instruction_count > 0) {
+ event["ticount"] = Json::Int64(thread_instruction_count);
+ }
+ event["tid"] = thread.tid;
+ event["s"] = "t";
+ } else {
+ if (duration_ns > 0) {
+ event["ph"] = "X";
+ event["dur"] = Json::Int64(duration_ns / 1000);
+ } else {
+ // If the slice didn't finish, the duration may be negative. Only
+ // write a begin event without end event in this case.
+ event["ph"] = "B";
+ }
+ event["tid"] = thread.tid;
+ if (thread.upid) {
+ event["pid"] = storage->GetProcess(*thread.upid).pid;
+ }
+ if (thread_ts_ns > 0) {
+ event["tts"] = Json::Int64(thread_ts_ns / 1000);
+ // Only write thread duration for completed events.
+ if (duration_ns > 0)
+ event["tdur"] = Json::Int64(thread_duration_ns / 1000);
+ }
+ if (thread_instruction_count > 0) {
+ event["ticount"] = Json::Int64(thread_instruction_count);
+ // Only write thread instruction delta for completed events.
+ if (duration_ns > 0)
+ event["tidelta"] = Json::Int64(thread_instruction_delta);
+ }
+ }
+ writer->WriteCommonEvent(event);
+ } else if (!legacy_chrome_track ||
+ (legacy_chrome_track && track_args.isMember("source_id"))) {
+ // Async event slice.
+ auto opt_process_row =
+ process_track.id().IndexOf(SqlValue::Long(track_id));
+ if (opt_process_row) {
+ uint32_t upid = process_track.upid()[*opt_process_row];
+ event["id2"]["local"] = PrintUint64(track_id);
+ event["pid"] = storage->GetProcess(upid).pid;
+ } else {
+ event["id2"]["global"] = PrintUint64(track_id);
+ }
if (thread_ts_ns > 0) {
event["tts"] = Json::Int64(thread_ts_ns / 1000);
@@ -406,7 +565,6 @@
event["use_async_tts"] = Json::Int(1);
}
- int64_t duration_ns = slices.durations()[i];
if (duration_ns == 0) { // Instant async event.
event["ph"] = "n";
writer->WriteCommonEvent(event);
@@ -431,85 +589,24 @@
writer->WriteCommonEvent(event);
}
}
- } else { // Sync event.
- const auto& thread_slices = storage->thread_slices();
- int64_t thread_ts_ns = 0;
- int64_t thread_duration_ns = 0;
- int64_t thread_instruction_count = 0;
- int64_t thread_instruction_delta = 0;
- base::Optional<uint32_t> thread_slice_row =
- thread_slices.FindRowForSliceId(i);
- if (thread_slice_row) {
- thread_ts_ns = thread_slices.thread_timestamp_ns()[*thread_slice_row];
- thread_duration_ns =
- thread_slices.thread_duration_ns()[*thread_slice_row];
- thread_instruction_count =
- thread_slices.thread_instruction_counts()[*thread_slice_row];
- thread_instruction_delta =
- thread_slices.thread_instruction_deltas()[*thread_slice_row];
+ } else {
+ // Global or process-scoped instant event.
+ PERFETTO_DCHECK(duration_ns == 0);
+ event["ph"] = "i";
+
+ auto opt_process_row =
+ process_track.id().IndexOf(SqlValue::Long(track_id));
+ if (opt_process_row.has_value()) {
+ uint32_t upid = process_track.upid()[*opt_process_row];
+ event["pid"] = storage->GetProcess(upid).pid;
+ event["s"] = "p";
+ } else {
+ event["s"] = "g";
}
- int64_t duration_ns = slices.durations()[i];
- if (duration_ns == 0) { // Instant event.
- event["ph"] = "i";
- if (slices.types()[i] == RefType::kRefUtid) {
- UniqueTid utid = static_cast<UniqueTid>(slices.refs()[i]);
- auto thread = storage->GetThread(utid);
- if (thread.upid) {
- event["pid"] = storage->GetProcess(*thread.upid).pid;
- }
- if (thread_ts_ns > 0) {
- event["tts"] = Json::Int64(thread_ts_ns / 1000);
- }
- if (thread_instruction_count > 0) {
- event["ticount"] = Json::Int64(thread_instruction_count);
- }
- event["tid"] = thread.tid;
- event["s"] = "t";
- } else if (slices.types()[i] == RefType::kRefUpid) {
- UniquePid upid = static_cast<UniquePid>(slices.refs()[i]);
- event["pid"] = storage->GetProcess(upid).pid;
- event["s"] = "p";
- } else if (slices.types()[i] == RefType::kRefNoRef) {
- event["s"] = "g";
- } else {
- return kResultWrongRefType;
- }
- writer->WriteCommonEvent(event);
- } else { // Complete event.
- if (slices.types()[i] != RefType::kRefUtid) {
- return kResultWrongRefType;
- }
- if (duration_ns > 0) {
- event["ph"] = "X";
- event["dur"] = Json::Int64(duration_ns / 1000);
- } else {
- // If the slice didn't finish, the duration may be negative. Only
- // write a begin event without end event in this case.
- event["ph"] = "B";
- }
- UniqueTid utid = static_cast<UniqueTid>(slices.refs()[i]);
- auto thread = storage->GetThread(utid);
- event["tid"] = thread.tid;
- if (thread.upid) {
- event["pid"] = storage->GetProcess(*thread.upid).pid;
- }
- if (thread_ts_ns > 0) {
- event["tts"] = Json::Int64(thread_ts_ns / 1000);
- // Only write thread duration for completed events.
- if (duration_ns > 0)
- event["tdur"] = Json::Int64(thread_duration_ns / 1000);
- }
- if (thread_instruction_count > 0) {
- event["ticount"] = Json::Int64(thread_instruction_count);
- // Only write thread instruction delta for completed events.
- if (duration_ns > 0)
- event["tidelta"] = Json::Int64(thread_instruction_delta);
- }
- writer->WriteCommonEvent(event);
- }
+ writer->WriteCommonEvent(event);
}
}
- return kResultOk;
+ return util::OkStatus();
}
Json::Value ConvertLegacyRawEventToJson(const TraceStorage* storage,
@@ -587,9 +684,9 @@
return event;
}
-ResultCode ExportRawEvents(const TraceStorage* storage,
- const ArgsBuilder& args_builder,
- TraceFormatWriter* writer) {
+util::Status ExportRawEvents(const TraceStorage* storage,
+ const ArgsBuilder& args_builder,
+ TraceFormatWriter* writer) {
base::Optional<StringId> raw_legacy_event_key_id =
storage->string_pool().GetId("track_event.legacy_event");
base::Optional<StringId> raw_legacy_system_trace_event_id =
@@ -621,11 +718,11 @@
writer->MergeMetadata(args);
}
}
- return kResultOk;
+ return util::OkStatus();
}
-ResultCode ExportCpuProfileSamples(const TraceStorage* storage,
- TraceFormatWriter* writer) {
+util::Status ExportCpuProfileSamples(const TraceStorage* storage,
+ TraceFormatWriter* writer) {
const TraceStorage::CpuProfileStackSamples& samples =
storage->cpu_profile_stack_samples();
for (uint32_t i = 0; i < samples.size(); ++i) {
@@ -695,11 +792,11 @@
writer->WriteCommonEvent(event);
}
- return kResultOk;
+ return util::OkStatus();
}
-ResultCode ExportMetadata(const TraceStorage* storage,
- TraceFormatWriter* writer) {
+util::Status ExportMetadata(const TraceStorage* storage,
+ TraceFormatWriter* writer) {
const auto& trace_metadata = storage->metadata();
const auto& keys = trace_metadata.keys();
const auto& values = trace_metadata.values();
@@ -761,10 +858,11 @@
break;
}
}
- return kResultOk;
+ return util::OkStatus();
}
-ResultCode ExportStats(const TraceStorage* storage, TraceFormatWriter* writer) {
+util::Status ExportStats(const TraceStorage* storage,
+ TraceFormatWriter* writer) {
const auto& stats = storage->stats();
writer->SetPerfettoStats("producers_connected",
@@ -833,44 +931,69 @@
"trace_writer_packet_loss",
stats[stats::traced_buf_trace_writer_packet_loss].indexed_values);
- return kResultOk;
+ return util::OkStatus();
}
} // namespace
-ResultCode ExportJson(const TraceStorage* storage, FILE* output) {
- TraceFormatWriter writer(output);
+OutputWriter::OutputWriter() = default;
+OutputWriter::~OutputWriter() = default;
+
+util::Status ExportJson(const TraceStorage* storage,
+ OutputWriter* output,
+ ArgumentFilterPredicate argument_filter,
+ MetadataFilterPredicate metadata_filter,
+ LabelFilterPredicate label_filter) {
+ // TODO(eseckler): Implement argument/metadata/label filtering.
+ TraceFormatWriter writer(output, argument_filter, metadata_filter,
+ label_filter);
ArgsBuilder args_builder(storage);
- ResultCode code = ExportThreadNames(storage, &writer);
- if (code != kResultOk)
- return code;
+ util::Status status = ExportThreadNames(storage, &writer);
+ if (!status.ok())
+ return status;
- code = ExportProcessNames(storage, &writer);
- if (code != kResultOk)
- return code;
+ status = ExportProcessNames(storage, &writer);
+ if (!status.ok())
+ return status;
- code = ExportSlices(storage, args_builder, &writer);
- if (code != kResultOk)
- return code;
+ status = ExportSlices(storage, args_builder, &writer);
+ if (!status.ok())
+ return status;
- code = ExportRawEvents(storage, args_builder, &writer);
- if (code != kResultOk)
- return code;
+ status = ExportRawEvents(storage, args_builder, &writer);
+ if (!status.ok())
+ return status;
- code = ExportCpuProfileSamples(storage, &writer);
- if (code != kResultOk)
- return code;
+ status = ExportCpuProfileSamples(storage, &writer);
+ if (!status.ok())
+ return status;
- code = ExportMetadata(storage, &writer);
- if (code != kResultOk)
- return code;
+ status = ExportMetadata(storage, &writer);
+ if (!status.ok())
+ return status;
- code = ExportStats(storage, &writer);
- if (code != kResultOk)
- return code;
+ status = ExportStats(storage, &writer);
+ if (!status.ok())
+ return status;
- return kResultOk;
+ return util::OkStatus();
+}
+
+util::Status ExportJson(TraceProcessor* tp,
+ OutputWriter* output,
+ ArgumentFilterPredicate argument_filter,
+ MetadataFilterPredicate metadata_filter,
+ LabelFilterPredicate label_filter) {
+ const TraceStorage* storage =
+ reinterpret_cast<TraceProcessorImpl*>(tp)->context()->storage.get();
+ return ExportJson(storage, output, argument_filter, metadata_filter,
+ label_filter);
+}
+
+util::Status ExportJson(const TraceStorage* storage, FILE* output) {
+ FileWriter writer(output);
+ return ExportJson(storage, &writer, nullptr, nullptr, nullptr);
}
} // namespace json
diff --git a/src/trace_processor/export_json.h b/src/trace_processor/export_json.h
index 0ceefd8..5d2ea54 100644
--- a/src/trace_processor/export_json.h
+++ b/src/trace_processor/export_json.h
@@ -17,21 +17,25 @@
#ifndef SRC_TRACE_PROCESSOR_EXPORT_JSON_H_
#define SRC_TRACE_PROCESSOR_EXPORT_JSON_H_
-#include "src/trace_processor/trace_storage.h"
-
#include <stdio.h>
+#include "perfetto/ext/trace_processor/export_json.h"
+#include "perfetto/trace_processor/status.h"
+#include "src/trace_processor/trace_storage.h"
+
namespace perfetto {
namespace trace_processor {
namespace json {
-enum ResultCode {
- kResultOk = 0,
- kResultWrongRefType = 1,
-};
+// Export trace to a file stream in json format.
+util::Status ExportJson(const TraceStorage*, FILE* output);
-// Export trace to a stream in json format.
-ResultCode ExportJson(const TraceStorage* storage, FILE* output);
+// For testing.
+util::Status ExportJson(const TraceStorage* storage,
+ OutputWriter*,
+ ArgumentFilterPredicate = nullptr,
+ MetadataFilterPredicate = nullptr,
+ LabelFilterPredicate = nullptr);
} // namespace json
} // namespace trace_processor
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index 51e1b57..f68afcd 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -14,18 +14,22 @@
* limitations under the License.
*/
+#include "perfetto/ext/trace_processor/export_json.h"
#include "src/trace_processor/export_json.h"
-#include "perfetto/ext/base/temp_file.h"
-#include "src/trace_processor/args_tracker.h"
-#include "src/trace_processor/trace_processor_context.h"
+#include <string.h>
-#include "test/gtest_and_gmock.h"
+#include <limits>
#include <json/reader.h>
#include <json/value.h>
-#include <limits>
+#include "perfetto/ext/base/temp_file.h"
+#include "src/trace_processor/args_tracker.h"
+#include "src/trace_processor/trace_processor_context.h"
+#include "src/trace_processor/track_tracker.h"
+
+#include "test/gtest_and_gmock.h"
namespace perfetto {
namespace trace_processor {
@@ -41,23 +45,64 @@
return std::string(buffer, ret);
}
-TEST(ExportJsonTest, EmptyStorage) {
- TraceStorage storage;
+class StringOutputWriter : public OutputWriter {
+ public:
+ StringOutputWriter() { str_.reserve(1024); }
+ ~StringOutputWriter() override {}
+ util::Status AppendString(const std::string& str) override {
+ str_ += str;
+ return util::OkStatus();
+ }
+
+ std::string TakeStr() { return std::move(str_); }
+
+ private:
+ std::string str_;
+};
+
+class ExportJsonTest : public ::testing::Test {
+ public:
+ ExportJsonTest() {
+ context_.args_tracker.reset(new ArgsTracker(&context_));
+ context_.storage.reset(new TraceStorage());
+ context_.track_tracker.reset(new TrackTracker(&context_));
+ }
+
+ std::string ToJson(ArgumentFilterPredicate argument_filter = nullptr,
+ MetadataFilterPredicate metadata_filter = nullptr,
+ LabelFilterPredicate label_filter = nullptr) {
+ StringOutputWriter writer;
+ util::Status status =
+ ExportJson(context_.storage.get(), &writer, argument_filter,
+ metadata_filter, label_filter);
+ EXPECT_TRUE(status.ok());
+ return writer.TakeStr();
+ }
+
+ Json::Value ToJsonValue(const std::string& json) {
+ Json::Reader reader;
+ Json::Value result;
+ EXPECT_TRUE(reader.parse(json, result));
+ return result;
+ }
+
+ protected:
+ TraceProcessorContext context_;
+};
+
+TEST_F(ExportJsonTest, EmptyStorage) {
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
-
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 0u);
}
-TEST(ExportJsonTest, StorageWithOneSlice) {
+TEST_F(ExportJsonTest, StorageWithOneSlice) {
const int64_t kTimestamp = 10000000;
const int64_t kDuration = 10000;
const int64_t kThreadTimestamp = 20000000;
@@ -67,28 +112,27 @@
const int64_t kThreadID = 100;
const char* kCategory = "cat";
const char* kName = "name";
- constexpr TrackId track = 22;
- TraceStorage storage;
- UniqueTid utid = storage.AddEmptyThread(kThreadID);
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
- storage.mutable_nestable_slices()->AddSlice(kTimestamp, kDuration, track,
- utid, RefType::kRefUtid, cat_id,
- name_id, 0, 0, 0);
- storage.mutable_thread_slices()->AddThreadSlice(
+ UniqueTid utid = context_.storage->AddEmptyThread(kThreadID);
+ TrackId track =
+ context_.track_tracker->GetOrCreateDescriptorTrackForThread(utid);
+ context_.args_tracker->Flush(); // Flush track args.
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
+ context_.storage->mutable_nestable_slices()->AddSlice(
+ kTimestamp, kDuration, track, utid, RefType::kRefUtid, cat_id, name_id, 0,
+ 0, 0);
+ context_.storage->mutable_thread_slices()->AddThreadSlice(
0, kThreadTimestamp, kThreadDuration, kThreadInstructionCount,
kThreadInstructionDelta);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -105,7 +149,7 @@
EXPECT_FALSE(event.isMember("args"));
}
-TEST(ExportJsonTest, StorageWithOneUnfinishedSlice) {
+TEST_F(ExportJsonTest, StorageWithOneUnfinishedSlice) {
const int64_t kTimestamp = 10000000;
const int64_t kDuration = -1;
const int64_t kThreadTimestamp = 20000000;
@@ -115,28 +159,27 @@
const int64_t kThreadID = 100;
const char* kCategory = "cat";
const char* kName = "name";
- constexpr TrackId track = 22;
- TraceStorage storage;
- UniqueTid utid = storage.AddEmptyThread(kThreadID);
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
- storage.mutable_nestable_slices()->AddSlice(kTimestamp, kDuration, track,
- utid, RefType::kRefUtid, cat_id,
- name_id, 0, 0, 0);
- storage.mutable_thread_slices()->AddThreadSlice(
+ UniqueTid utid = context_.storage->AddEmptyThread(kThreadID);
+ TrackId track =
+ context_.track_tracker->GetOrCreateDescriptorTrackForThread(utid);
+ context_.args_tracker->Flush(); // Flush track args.
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
+ context_.storage->mutable_nestable_slices()->AddSlice(
+ kTimestamp, kDuration, track, utid, RefType::kRefUtid, cat_id, name_id, 0,
+ 0, 0);
+ context_.storage->mutable_thread_slices()->AddThreadSlice(
0, kThreadTimestamp, kThreadDuration, kThreadInstructionCount,
kThreadInstructionDelta);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -153,24 +196,21 @@
EXPECT_FALSE(event.isMember("args"));
}
-TEST(ExportJsonTest, StorageWithThreadName) {
+TEST_F(ExportJsonTest, StorageWithThreadName) {
const int64_t kThreadID = 100;
const char* kName = "thread";
- TraceStorage storage;
- UniqueTid utid = storage.AddEmptyThread(kThreadID);
- StringId name_id = storage.InternString(base::StringView(kName));
- storage.GetMutableThread(utid)->name_id = name_id;
+ UniqueTid utid = context_.storage->AddEmptyThread(kThreadID);
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
+ context_.storage->GetMutableThread(utid)->name_id = name_id;
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -180,23 +220,28 @@
EXPECT_EQ(event["args"]["name"].asString(), kName);
}
-TEST(ExportJsonTest, WrongRefType) {
- constexpr TrackId track = 22;
+TEST_F(ExportJsonTest, WrongTrackTypeIgnored) {
+ constexpr int64_t kCookie = 22;
+ TrackId track = context_.track_tracker->InternAndroidAsyncTrack(
+ /*name=*/0, /*upid=*/0, kCookie);
+ context_.args_tracker->Flush(); // Flush track args.
- TraceStorage storage;
- StringId cat_id = storage.InternString("cat");
- StringId name_id = storage.InternString("name");
- storage.mutable_nestable_slices()->AddSlice(
- 0, 0, track, 0, RefType::kRefCpuId, cat_id, name_id, 0, 0, 0);
+ StringId cat_id = context_.storage->InternString("cat");
+ StringId name_id = context_.storage->InternString("name");
+ context_.storage->mutable_nestable_slices()->AddSlice(
+ 0, 0, track, track, RefType::kRefTrack, cat_id, name_id, 0, 0, 0);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultWrongRefType);
+ EXPECT_TRUE(status.ok());
+
+ Json::Value result = ToJsonValue(ReadFile(output));
+ EXPECT_EQ(result["traceEvents"].size(), 0u);
}
-TEST(ExportJsonTest, StorageWithMetadata) {
+TEST_F(ExportJsonTest, StorageWithMetadata) {
const char* kDescription = "description";
const char* kBenchmarkName = "benchmark name";
const char* kStoryName = "story name";
@@ -206,47 +251,49 @@
const int64_t kStoryStart = 2000000;
const bool kHadFailures = true;
- TraceStorage storage;
-
- StringId desc_id = storage.InternString(base::StringView(kDescription));
+ StringId desc_id =
+ context_.storage->InternString(base::StringView(kDescription));
Variadic description = Variadic::String(desc_id);
- storage.SetMetadata(metadata::benchmark_description, description);
+ context_.storage->SetMetadata(metadata::benchmark_description, description);
StringId benchmark_name_id =
- storage.InternString(base::StringView(kBenchmarkName));
+ context_.storage->InternString(base::StringView(kBenchmarkName));
Variadic benchmark_name = Variadic::String(benchmark_name_id);
- storage.SetMetadata(metadata::benchmark_name, benchmark_name);
+ context_.storage->SetMetadata(metadata::benchmark_name, benchmark_name);
- StringId story_name_id = storage.InternString(base::StringView(kStoryName));
+ StringId story_name_id =
+ context_.storage->InternString(base::StringView(kStoryName));
Variadic story_name = Variadic::String(story_name_id);
- storage.SetMetadata(metadata::benchmark_story_name, story_name);
+ context_.storage->SetMetadata(metadata::benchmark_story_name, story_name);
- StringId tag1_id = storage.InternString(base::StringView(kStoryTag1));
- StringId tag2_id = storage.InternString(base::StringView(kStoryTag2));
+ StringId tag1_id =
+ context_.storage->InternString(base::StringView(kStoryTag1));
+ StringId tag2_id =
+ context_.storage->InternString(base::StringView(kStoryTag2));
Variadic tag1 = Variadic::String(tag1_id);
Variadic tag2 = Variadic::String(tag2_id);
- storage.AppendMetadata(metadata::benchmark_story_tags, tag1);
- storage.AppendMetadata(metadata::benchmark_story_tags, tag2);
+ context_.storage->AppendMetadata(metadata::benchmark_story_tags, tag1);
+ context_.storage->AppendMetadata(metadata::benchmark_story_tags, tag2);
Variadic benchmark_start = Variadic::Integer(kBenchmarkStart);
- storage.SetMetadata(metadata::benchmark_start_time_us, benchmark_start);
+ context_.storage->SetMetadata(metadata::benchmark_start_time_us,
+ benchmark_start);
Variadic story_start = Variadic::Integer(kStoryStart);
- storage.SetMetadata(metadata::benchmark_story_run_time_us, story_start);
+ context_.storage->SetMetadata(metadata::benchmark_story_run_time_us,
+ story_start);
Variadic had_failures = Variadic::Integer(kHadFailures);
- storage.SetMetadata(metadata::benchmark_had_failures, had_failures);
+ context_.storage->SetMetadata(metadata::benchmark_had_failures, had_failures);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
+ Json::Value result = ToJsonValue(ReadFile(output));
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
EXPECT_TRUE(result.isMember("metadata"));
EXPECT_TRUE(result["metadata"].isMember("telemetry"));
Json::Value telemetry_metadata = result["metadata"]["telemetry"];
@@ -275,26 +322,24 @@
EXPECT_EQ(telemetry_metadata["hadFailures"][0].asBool(), kHadFailures);
}
-TEST(ExportJsonTest, StorageWithStats) {
+TEST_F(ExportJsonTest, StorageWithStats) {
int64_t kProducers = 10;
int64_t kBufferSize0 = 1000;
int64_t kBufferSize1 = 2000;
- TraceStorage storage;
-
- storage.SetStats(stats::traced_producers_connected, kProducers);
- storage.SetIndexedStats(stats::traced_buf_buffer_size, 0, kBufferSize0);
- storage.SetIndexedStats(stats::traced_buf_buffer_size, 1, kBufferSize1);
+ context_.storage->SetStats(stats::traced_producers_connected, kProducers);
+ context_.storage->SetIndexedStats(stats::traced_buf_buffer_size, 0,
+ kBufferSize0);
+ context_.storage->SetIndexedStats(stats::traced_buf_buffer_size, 1,
+ kBufferSize1);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
- EXPECT_EQ(code, kResultOk);
+ util::Status status = ExportJson(context_.storage.get(), output);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
+ Json::Value result = ToJsonValue(ReadFile(output));
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
EXPECT_TRUE(result.isMember("metadata"));
EXPECT_TRUE(result["metadata"].isMember("perfetto_trace_stats"));
Json::Value stats = result["metadata"]["perfetto_trace_stats"];
@@ -305,16 +350,13 @@
EXPECT_EQ(stats["buffer_stats"][1]["buffer_size"].asInt(), kBufferSize1);
}
-TEST(ExportJsonTest, StorageWithChromeMetadata) {
+TEST_F(ExportJsonTest, StorageWithChromeMetadata) {
const char* kName1 = "name1";
const char* kName2 = "name2";
const char* kValue1 = "value1";
const int kValue2 = 222;
- TraceProcessorContext context;
- context.storage.reset(new TraceStorage());
- TraceStorage* storage = context.storage.get();
- ArgsTracker args(&context);
+ TraceStorage* storage = context_.storage.get();
RowId row_id = storage->mutable_raw_events()->AddRawEvent(
0, storage->InternString("chrome_event.metadata"), 0, 0);
@@ -322,19 +364,19 @@
StringId name1_id = storage->InternString(base::StringView(kName1));
StringId name2_id = storage->InternString(base::StringView(kName2));
StringId value1_id = storage->InternString(base::StringView(kValue1));
- args.AddArg(row_id, name1_id, name1_id, Variadic::String(value1_id));
- args.AddArg(row_id, name2_id, name2_id, Variadic::Integer(kValue2));
- args.Flush();
+ context_.args_tracker->AddArg(row_id, name1_id, name1_id,
+ Variadic::String(value1_id));
+ context_.args_tracker->AddArg(row_id, name2_id, name2_id,
+ Variadic::Integer(kValue2));
+ context_.args_tracker->Flush();
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(storage, output);
- EXPECT_EQ(code, kResultOk);
+ util::Status status = ExportJson(storage, output);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
+ Json::Value result = ToJsonValue(ReadFile(output));
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
EXPECT_TRUE(result.isMember("metadata"));
Json::Value metadata = result["metadata"];
@@ -342,38 +384,38 @@
EXPECT_EQ(metadata[kName2].asInt(), kValue2);
}
-TEST(ExportJsonTest, StorageWithArgs) {
+TEST_F(ExportJsonTest, StorageWithArgs) {
const char* kCategory = "cat";
const char* kName = "name";
const char* kSrc = "source_file.cc";
- constexpr TrackId track = 22;
- TraceStorage storage;
- UniqueTid utid = storage.AddEmptyThread(0);
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
- storage.mutable_nestable_slices()->AddSlice(
+ UniqueTid utid = context_.storage->AddEmptyThread(0);
+ TrackId track =
+ context_.track_tracker->GetOrCreateDescriptorTrackForThread(utid);
+ context_.args_tracker->Flush(); // Flush track args.
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
+ context_.storage->mutable_nestable_slices()->AddSlice(
0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
- StringId arg_key_id =
- storage.InternString(base::StringView("task.posted_from.file_name"));
- StringId arg_value_id = storage.InternString(base::StringView(kSrc));
+ StringId arg_key_id = context_.storage->InternString(
+ base::StringView("task.posted_from.file_name"));
+ StringId arg_value_id =
+ context_.storage->InternString(base::StringView(kSrc));
TraceStorage::Args::Arg arg;
arg.flat_key = arg_key_id;
arg.key = arg_key_id;
arg.value = Variadic::String(arg_value_id);
- storage.mutable_args()->AddArgSet({arg}, 0, 1);
- storage.mutable_nestable_slices()->set_arg_set_id(0, 1);
+ ArgSetId args = context_.storage->mutable_args()->AddArgSet({arg}, 0, 1);
+ context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -382,20 +424,20 @@
EXPECT_EQ(event["args"]["src"].asString(), kSrc);
}
-TEST(ExportJsonTest, StorageWithSliceAndFlowEventArgs) {
+TEST_F(ExportJsonTest, StorageWithSliceAndFlowEventArgs) {
const char* kCategory = "cat";
const char* kName = "name";
- constexpr TrackId track = 22;
const uint64_t kBindId = 0xaa00aa00aa00aa00;
const char* kFlowDirection = "inout";
const char* kArgName = "arg_name";
const int kArgValue = 123;
- TraceProcessorContext context;
- context.storage.reset(new TraceStorage());
- TraceStorage* storage = context.storage.get();
+ TraceStorage* storage = context_.storage.get();
UniqueTid utid = storage->AddEmptyThread(0);
+ TrackId track =
+ context_.track_tracker->GetOrCreateDescriptorTrackForThread(utid);
+ context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = storage->InternString(base::StringView(kCategory));
StringId name_id = storage->InternString(base::StringView(kName));
RowId row_id = TraceStorage::CreateRowId(
@@ -403,10 +445,9 @@
storage->mutable_nestable_slices()->AddSlice(
0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0));
- ArgsTracker args(&context);
auto add_arg = [&](const char* key, Variadic value) {
StringId key_id = storage->InternString(key);
- args.AddArg(row_id, key_id, key_id, value);
+ context_.args_tracker->AddArg(row_id, key_id, key_id, value);
};
add_arg("legacy_event.bind_id", Variadic::UnsignedInteger(kBindId));
@@ -416,17 +457,15 @@
add_arg(kArgName, Variadic::Integer(kArgValue));
- args.Flush();
+ context_.args_tracker->Flush();
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(storage, output);
+ util::Status status = ExportJson(storage, output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -439,25 +478,26 @@
EXPECT_EQ(event["args"][kArgName].asInt(), kArgValue);
}
-TEST(ExportJsonTest, StorageWithListArgs) {
+TEST_F(ExportJsonTest, StorageWithListArgs) {
const char* kCategory = "cat";
const char* kName = "name";
double kValues[] = {1.234, 2.345};
- constexpr TrackId track = 22;
- TraceStorage storage;
- UniqueTid utid = storage.AddEmptyThread(0);
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
- storage.mutable_nestable_slices()->AddSlice(
+ UniqueTid utid = context_.storage->AddEmptyThread(0);
+ TrackId track =
+ context_.track_tracker->GetOrCreateDescriptorTrackForThread(utid);
+ context_.args_tracker->Flush(); // Flush track args.
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
+ context_.storage->mutable_nestable_slices()->AddSlice(
0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
- StringId arg_flat_key_id =
- storage.InternString(base::StringView("debug.draw_duration_ms"));
- StringId arg_key0_id =
- storage.InternString(base::StringView("debug.draw_duration_ms[0]"));
- StringId arg_key1_id =
- storage.InternString(base::StringView("debug.draw_duration_ms[1]"));
+ StringId arg_flat_key_id = context_.storage->InternString(
+ base::StringView("debug.draw_duration_ms"));
+ StringId arg_key0_id = context_.storage->InternString(
+ base::StringView("debug.draw_duration_ms[0]"));
+ StringId arg_key1_id = context_.storage->InternString(
+ base::StringView("debug.draw_duration_ms[1]"));
TraceStorage::Args::Arg arg0;
arg0.flat_key = arg_flat_key_id;
arg0.key = arg_key0_id;
@@ -466,18 +506,17 @@
arg1.flat_key = arg_flat_key_id;
arg1.key = arg_key1_id;
arg1.value = Variadic::Real(kValues[1]);
- storage.mutable_args()->AddArgSet({arg0, arg1}, 0, 2);
- storage.mutable_nestable_slices()->set_arg_set_id(0, 1);
+ ArgSetId args =
+ context_.storage->mutable_args()->AddArgSet({arg0, arg1}, 0, 2);
+ context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -488,22 +527,25 @@
EXPECT_DOUBLE_EQ(event["args"]["draw_duration_ms"][1].asDouble(), kValues[1]);
}
-TEST(ExportJsonTest, StorageWithMultiplePointerArgs) {
+TEST_F(ExportJsonTest, StorageWithMultiplePointerArgs) {
const char* kCategory = "cat";
const char* kName = "name";
uint64_t kValue0 = 1;
uint64_t kValue1 = std::numeric_limits<uint64_t>::max();
- constexpr TrackId track = 22;
- TraceStorage storage;
- UniqueTid utid = storage.AddEmptyThread(0);
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
- storage.mutable_nestable_slices()->AddSlice(
+ UniqueTid utid = context_.storage->AddEmptyThread(0);
+ TrackId track =
+ context_.track_tracker->GetOrCreateDescriptorTrackForThread(utid);
+ context_.args_tracker->Flush(); // Flush track args.
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
+ context_.storage->mutable_nestable_slices()->AddSlice(
0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
- StringId arg_key0_id = storage.InternString(base::StringView("arg0"));
- StringId arg_key1_id = storage.InternString(base::StringView("arg1"));
+ StringId arg_key0_id =
+ context_.storage->InternString(base::StringView("arg0"));
+ StringId arg_key1_id =
+ context_.storage->InternString(base::StringView("arg1"));
TraceStorage::Args::Arg arg0;
arg0.flat_key = arg_key0_id;
arg0.key = arg_key0_id;
@@ -512,18 +554,17 @@
arg1.flat_key = arg_key1_id;
arg1.key = arg_key1_id;
arg1.value = Variadic::Pointer(kValue1);
- storage.mutable_args()->AddArgSet({arg0, arg1}, 0, 2);
- storage.mutable_nestable_slices()->set_arg_set_id(0, 1);
+ ArgSetId args =
+ context_.storage->mutable_args()->AddArgSet({arg0, arg1}, 0, 2);
+ context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -533,22 +574,26 @@
EXPECT_EQ(event["args"]["arg1"].asString(), "0xffffffffffffffff");
}
-TEST(ExportJsonTest, StorageWithObjectListArgs) {
+TEST_F(ExportJsonTest, StorageWithObjectListArgs) {
const char* kCategory = "cat";
const char* kName = "name";
int kValues[] = {123, 234};
- constexpr TrackId track = 22;
- TraceStorage storage;
- UniqueTid utid = storage.AddEmptyThread(0);
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
- storage.mutable_nestable_slices()->AddSlice(
+ UniqueTid utid = context_.storage->AddEmptyThread(0);
+ TrackId track =
+ context_.track_tracker->GetOrCreateDescriptorTrackForThread(utid);
+ context_.args_tracker->Flush(); // Flush track args.
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
+ context_.storage->mutable_nestable_slices()->AddSlice(
0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
- StringId arg_flat_key_id = storage.InternString(base::StringView("a.b"));
- StringId arg_key0_id = storage.InternString(base::StringView("a[0].b"));
- StringId arg_key1_id = storage.InternString(base::StringView("a[1].b"));
+ StringId arg_flat_key_id =
+ context_.storage->InternString(base::StringView("a.b"));
+ StringId arg_key0_id =
+ context_.storage->InternString(base::StringView("a[0].b"));
+ StringId arg_key1_id =
+ context_.storage->InternString(base::StringView("a[1].b"));
TraceStorage::Args::Arg arg0;
arg0.flat_key = arg_flat_key_id;
arg0.key = arg_key0_id;
@@ -557,18 +602,17 @@
arg1.flat_key = arg_flat_key_id;
arg1.key = arg_key1_id;
arg1.value = Variadic::Integer(kValues[1]);
- storage.mutable_args()->AddArgSet({arg0, arg1}, 0, 2);
- storage.mutable_nestable_slices()->set_arg_set_id(0, 1);
+ ArgSetId args =
+ context_.storage->mutable_args()->AddArgSet({arg0, arg1}, 0, 2);
+ context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -579,22 +623,26 @@
EXPECT_EQ(event["args"]["a"][1]["b"].asInt(), kValues[1]);
}
-TEST(ExportJsonTest, StorageWithNestedListArgs) {
+TEST_F(ExportJsonTest, StorageWithNestedListArgs) {
const char* kCategory = "cat";
const char* kName = "name";
int kValues[] = {123, 234};
- constexpr TrackId track = 22;
- TraceStorage storage;
- UniqueTid utid = storage.AddEmptyThread(0);
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
- storage.mutable_nestable_slices()->AddSlice(
+ UniqueTid utid = context_.storage->AddEmptyThread(0);
+ TrackId track =
+ context_.track_tracker->GetOrCreateDescriptorTrackForThread(utid);
+ context_.args_tracker->Flush(); // Flush track args.
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
+ context_.storage->mutable_nestable_slices()->AddSlice(
0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
- StringId arg_flat_key_id = storage.InternString(base::StringView("a"));
- StringId arg_key0_id = storage.InternString(base::StringView("a[0][0]"));
- StringId arg_key1_id = storage.InternString(base::StringView("a[0][1]"));
+ StringId arg_flat_key_id =
+ context_.storage->InternString(base::StringView("a"));
+ StringId arg_key0_id =
+ context_.storage->InternString(base::StringView("a[0][0]"));
+ StringId arg_key1_id =
+ context_.storage->InternString(base::StringView("a[0][1]"));
TraceStorage::Args::Arg arg0;
arg0.flat_key = arg_flat_key_id;
arg0.key = arg_key0_id;
@@ -603,18 +651,17 @@
arg1.flat_key = arg_flat_key_id;
arg1.key = arg_key1_id;
arg1.value = Variadic::Integer(kValues[1]);
- storage.mutable_args()->AddArgSet({arg0, arg1}, 0, 2);
- storage.mutable_nestable_slices()->set_arg_set_id(0, 1);
+ ArgSetId args =
+ context_.storage->mutable_args()->AddArgSet({arg0, arg1}, 0, 2);
+ context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -626,36 +673,36 @@
EXPECT_EQ(event["args"]["a"][0][1].asInt(), kValues[1]);
}
-TEST(ExportJsonTest, StorageWithLegacyJsonArgs) {
+TEST_F(ExportJsonTest, StorageWithLegacyJsonArgs) {
const char* kCategory = "cat";
const char* kName = "name";
- constexpr TrackId track = 22;
- TraceStorage storage;
- UniqueTid utid = storage.AddEmptyThread(0);
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
- storage.mutable_nestable_slices()->AddSlice(
+ UniqueTid utid = context_.storage->AddEmptyThread(0);
+ TrackId track =
+ context_.track_tracker->GetOrCreateDescriptorTrackForThread(utid);
+ context_.args_tracker->Flush(); // Flush track args.
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
+ context_.storage->mutable_nestable_slices()->AddSlice(
0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
- StringId arg_key_id = storage.InternString(base::StringView("a"));
- StringId arg_value_id = storage.InternString(base::StringView("{\"b\":123}"));
+ StringId arg_key_id = context_.storage->InternString(base::StringView("a"));
+ StringId arg_value_id =
+ context_.storage->InternString(base::StringView("{\"b\":123}"));
TraceStorage::Args::Arg arg;
arg.flat_key = arg_key_id;
arg.key = arg_key_id;
arg.value = Variadic::Json(arg_value_id);
- storage.mutable_args()->AddArgSet({arg}, 0, 1);
- storage.mutable_nestable_slices()->set_arg_set_id(0, 1);
+ ArgSetId args = context_.storage->mutable_args()->AddArgSet({arg}, 0, 1);
+ context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -664,27 +711,26 @@
EXPECT_EQ(event["args"]["a"]["b"].asInt(), 123);
}
-TEST(ExportJsonTest, InstantEvent) {
+TEST_F(ExportJsonTest, InstantEvent) {
const int64_t kTimestamp = 10000000;
const char* kCategory = "cat";
const char* kName = "name";
- constexpr TrackId track = 22;
- TraceStorage storage;
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
- storage.mutable_nestable_slices()->AddSlice(
+ TrackId track =
+ context_.track_tracker->GetOrCreateLegacyChromeGlobalInstantTrack();
+ context_.args_tracker->Flush(); // Flush track args.
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
+ context_.storage->mutable_nestable_slices()->AddSlice(
kTimestamp, 0, track, 0, RefType::kRefNoRef, cat_id, name_id, 0, 0, 0);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -695,7 +741,40 @@
EXPECT_EQ(event["name"].asString(), kName);
}
-TEST(ExportJsonTest, AsyncEvent) {
+TEST_F(ExportJsonTest, InstantEventOnThread) {
+ const int64_t kTimestamp = 10000000;
+ const int64_t kThreadID = 100;
+ const char* kCategory = "cat";
+ const char* kName = "name";
+
+ UniqueTid utid = context_.storage->AddEmptyThread(kThreadID);
+ TrackId track =
+ context_.track_tracker->GetOrCreateDescriptorTrackForThread(utid);
+ context_.args_tracker->Flush(); // Flush track args.
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
+ context_.storage->mutable_nestable_slices()->AddSlice(
+ kTimestamp, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
+
+ base::TempFile temp_file = base::TempFile::Create();
+ FILE* output = fopen(temp_file.path().c_str(), "w+");
+ util::Status status = ExportJson(context_.storage.get(), output);
+
+ EXPECT_TRUE(status.ok());
+
+ Json::Value result = ToJsonValue(ReadFile(output));
+ EXPECT_EQ(result["traceEvents"].size(), 1u);
+
+ Json::Value event = result["traceEvents"][0];
+ EXPECT_EQ(event["tid"].asUInt(), kThreadID);
+ EXPECT_EQ(event["ph"].asString(), "i");
+ EXPECT_EQ(event["ts"].asInt64(), kTimestamp / 1000);
+ EXPECT_EQ(event["s"].asString(), "t");
+ EXPECT_EQ(event["cat"].asString(), kCategory);
+ EXPECT_EQ(event["name"].asString(), kName);
+}
+
+TEST_F(ExportJsonTest, AsyncEvent) {
const int64_t kTimestamp = 10000000;
const int64_t kDuration = 100000;
const int64_t kProcessID = 100;
@@ -704,35 +783,35 @@
const char* kArgName = "arg_name";
const int kArgValue = 123;
- TraceStorage storage;
- UniquePid upid = storage.AddEmptyProcess(kProcessID);
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
+ UniquePid upid = context_.storage->AddEmptyProcess(kProcessID);
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
- tables::ProcessTrackTable::Row track(name_id);
- track.upid = upid;
- TrackId track_id = storage.mutable_process_track_table()->Insert(track);
+ constexpr int64_t kSourceId = 235;
+ TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
+ name_id, upid, kSourceId, /*source_id_is_process_scoped=*/true,
+ /*source_scope=*/0);
+ context_.args_tracker->Flush(); // Flush track args.
- storage.mutable_nestable_slices()->AddSlice(kTimestamp, kDuration, track_id,
- track_id, RefType::kRefTrack,
- cat_id, name_id, 0, 0, 0);
- StringId arg_key_id = storage.InternString(base::StringView(kArgName));
+ context_.storage->mutable_nestable_slices()->AddSlice(
+ kTimestamp, kDuration, track, track, RefType::kRefTrack, cat_id, name_id,
+ 0, 0, 0);
+ StringId arg_key_id =
+ context_.storage->InternString(base::StringView(kArgName));
TraceStorage::Args::Arg arg;
arg.flat_key = arg_key_id;
arg.key = arg_key_id;
arg.value = Variadic::Integer(kArgValue);
- storage.mutable_args()->AddArgSet({arg}, 0, 1);
- storage.mutable_nestable_slices()->set_arg_set_id(0, 1);
+ ArgSetId args = context_.storage->mutable_args()->AddArgSet({arg}, 0, 1);
+ context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 2u);
Json::Value begin_event = result["traceEvents"][0];
@@ -758,7 +837,7 @@
EXPECT_FALSE(end_event.isMember("use_async_tts"));
}
-TEST(ExportJsonTest, AsyncEventWithThreadTimestamp) {
+TEST_F(ExportJsonTest, AsyncEventWithThreadTimestamp) {
const int64_t kTimestamp = 10000000;
const int64_t kDuration = 100000;
const int64_t kThreadTimestamp = 10000001;
@@ -767,30 +846,29 @@
const char* kCategory = "cat";
const char* kName = "name";
- TraceStorage storage;
- UniquePid upid = storage.AddEmptyProcess(kProcessID);
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
+ UniquePid upid = context_.storage->AddEmptyProcess(kProcessID);
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
- tables::ProcessTrackTable::Row track(name_id);
- track.upid = upid;
- TrackId track_id = storage.mutable_process_track_table()->Insert(track);
+ constexpr int64_t kSourceId = 235;
+ TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
+ name_id, upid, kSourceId, /*source_id_is_process_scoped=*/true,
+ /*source_scope=*/0);
+ context_.args_tracker->Flush(); // Flush track args.
- auto slice_id = storage.mutable_nestable_slices()->AddSlice(
- kTimestamp, kDuration, track_id, track_id, RefType::kRefTrack, cat_id,
- name_id, 0, 0, 0);
- storage.mutable_virtual_track_slices()->AddVirtualTrackSlice(
+ auto slice_id = context_.storage->mutable_nestable_slices()->AddSlice(
+ kTimestamp, kDuration, track, track, RefType::kRefTrack, cat_id, name_id,
+ 0, 0, 0);
+ context_.storage->mutable_virtual_track_slices()->AddVirtualTrackSlice(
slice_id, kThreadTimestamp, kThreadDuration, 0, 0);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 2u);
Json::Value begin_event = result["traceEvents"][0];
@@ -815,7 +893,7 @@
EXPECT_EQ(end_event["name"].asString(), kName);
}
-TEST(ExportJsonTest, UnfinishedAsyncEvent) {
+TEST_F(ExportJsonTest, UnfinishedAsyncEvent) {
const int64_t kTimestamp = 10000000;
const int64_t kDuration = -1;
const int64_t kThreadTimestamp = 10000001;
@@ -824,30 +902,29 @@
const char* kCategory = "cat";
const char* kName = "name";
- TraceStorage storage;
- UniquePid upid = storage.AddEmptyProcess(kProcessID);
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
+ UniquePid upid = context_.storage->AddEmptyProcess(kProcessID);
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
- tables::ProcessTrackTable::Row track(name_id);
- track.upid = upid;
- TrackId track_id = storage.mutable_process_track_table()->Insert(track);
+ constexpr int64_t kSourceId = 235;
+ TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
+ name_id, upid, kSourceId, /*source_id_is_process_scoped=*/true,
+ /*source_scope=*/0);
+ context_.args_tracker->Flush(); // Flush track args.
- auto slice_id = storage.mutable_nestable_slices()->AddSlice(
- kTimestamp, kDuration, track_id, track_id, RefType::kRefTrack, cat_id,
- name_id, 0, 0, 0);
- storage.mutable_virtual_track_slices()->AddVirtualTrackSlice(
+ auto slice_id = context_.storage->mutable_nestable_slices()->AddSlice(
+ kTimestamp, kDuration, track, track, RefType::kRefTrack, cat_id, name_id,
+ 0, 0, 0);
+ context_.storage->mutable_virtual_track_slices()->AddVirtualTrackSlice(
slice_id, kThreadTimestamp, kThreadDuration, 0, 0);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value begin_event = result["traceEvents"][0];
@@ -861,7 +938,7 @@
EXPECT_EQ(begin_event["name"].asString(), kName);
}
-TEST(ExportJsonTest, AsyncInstantEvent) {
+TEST_F(ExportJsonTest, AsyncInstantEvent) {
const int64_t kTimestamp = 10000000;
const int64_t kProcessID = 100;
const char* kCategory = "cat";
@@ -869,35 +946,35 @@
const char* kArgName = "arg_name";
const int kArgValue = 123;
- TraceStorage storage;
- UniquePid upid = storage.AddEmptyProcess(kProcessID);
- StringId cat_id = storage.InternString(base::StringView(kCategory));
- StringId name_id = storage.InternString(base::StringView(kName));
+ UniquePid upid = context_.storage->AddEmptyProcess(kProcessID);
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
- tables::ProcessTrackTable::Row track(name_id);
- track.upid = upid;
- TrackId track_id = storage.mutable_process_track_table()->Insert(track);
+ constexpr int64_t kSourceId = 235;
+ TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
+ name_id, upid, kSourceId, /*source_id_is_process_scoped=*/true,
+ /*source_scope=*/0);
+ context_.args_tracker->Flush(); // Flush track args.
- storage.mutable_nestable_slices()->AddSlice(kTimestamp, 0, track_id, track_id,
- RefType::kRefTrack, cat_id,
- name_id, 0, 0, 0);
- StringId arg_key_id = storage.InternString(base::StringView("arg_name"));
+ context_.storage->mutable_nestable_slices()->AddSlice(
+ kTimestamp, 0, track, track, RefType::kRefTrack, cat_id, name_id, 0, 0,
+ 0);
+ StringId arg_key_id =
+ context_.storage->InternString(base::StringView("arg_name"));
TraceStorage::Args::Arg arg;
arg.flat_key = arg_key_id;
arg.key = arg_key_id;
arg.value = Variadic::Integer(kArgValue);
- storage.mutable_args()->AddArgSet({arg}, 0, 1);
- storage.mutable_nestable_slices()->set_arg_set_id(0, 1);
+ ArgSetId args = context_.storage->mutable_args()->AddArgSet({arg}, 0, 1);
+ context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(&storage, output);
+ util::Status status = ExportJson(context_.storage.get(), output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -910,7 +987,7 @@
EXPECT_EQ(event["args"][kArgName].asInt(), kArgValue);
}
-TEST(ExportJsonTest, RawEvent) {
+TEST_F(ExportJsonTest, RawEvent) {
const int64_t kTimestamp = 10000000;
const int64_t kDuration = 10000;
const int64_t kThreadTimestamp = 20000000;
@@ -929,9 +1006,7 @@
const char* kArgName = "arg_name";
const int kArgValue = 123;
- TraceProcessorContext context;
- context.storage.reset(new TraceStorage());
- TraceStorage* storage = context.storage.get();
+ TraceStorage* storage = context_.storage.get();
UniquePid upid = storage->AddEmptyProcess(kProcessID);
UniqueTid utid = storage->AddEmptyThread(kThreadID);
@@ -941,10 +1016,9 @@
kTimestamp, storage->InternString("track_event.legacy_event"), /*cpu=*/0,
utid);
- ArgsTracker args(&context);
auto add_arg = [&](const char* key, Variadic value) {
StringId key_id = storage->InternString(key);
- args.AddArg(row_id, key_id, key_id, value);
+ context_.args_tracker->AddArg(row_id, key_id, key_id, value);
};
StringId cat_id = storage->InternString(base::StringView(kCategory));
@@ -974,17 +1048,15 @@
add_arg(kArgName, Variadic::Integer(kArgValue));
- args.Flush();
+ context_.args_tracker->Flush();
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(storage, output);
+ util::Status status = ExportJson(storage, output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -1008,59 +1080,55 @@
EXPECT_EQ(event["args"][kArgName].asInt(), kArgValue);
}
-TEST(ExportJsonTest, LegacyRawEvents) {
+TEST_F(ExportJsonTest, LegacyRawEvents) {
const char* kLegacyFtraceData = "some \"data\"\nsome :data:";
const char* kLegacyJsonData1 = "{\"us";
- const char* kLegacyJsonData2 = "er\": 1}";
+ const char* kLegacyJsonData2 = "er\": 1},{\"user\": 2}";
- TraceProcessorContext context;
- context.storage.reset(new TraceStorage());
- TraceStorage* storage = context.storage.get();
+ TraceStorage* storage = context_.storage.get();
RowId row_id = storage->mutable_raw_events()->AddRawEvent(
0, storage->InternString("chrome_event.legacy_system_trace"), 0, 0);
- ArgsTracker args(&context);
StringId data_id = storage->InternString("data");
StringId ftrace_data_id = storage->InternString(kLegacyFtraceData);
- args.AddArg(row_id, data_id, data_id, Variadic::String(ftrace_data_id));
+ context_.args_tracker->AddArg(row_id, data_id, data_id,
+ Variadic::String(ftrace_data_id));
row_id = storage->mutable_raw_events()->AddRawEvent(
0, storage->InternString("chrome_event.legacy_user_trace"), 0, 0);
StringId json_data1_id = storage->InternString(kLegacyJsonData1);
- args.AddArg(row_id, data_id, data_id, Variadic::String(json_data1_id));
+ context_.args_tracker->AddArg(row_id, data_id, data_id,
+ Variadic::String(json_data1_id));
row_id = storage->mutable_raw_events()->AddRawEvent(
0, storage->InternString("chrome_event.legacy_user_trace"), 0, 0);
StringId json_data2_id = storage->InternString(kLegacyJsonData2);
- args.AddArg(row_id, data_id, data_id, Variadic::String(json_data2_id));
+ context_.args_tracker->AddArg(row_id, data_id, data_id,
+ Variadic::String(json_data2_id));
- args.Flush();
+ context_.args_tracker->Flush();
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(storage, output);
+ util::Status status = ExportJson(storage, output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
- EXPECT_EQ(result["traceEvents"].size(), 1u);
- Json::Value user_event = result["traceEvents"][0];
- EXPECT_EQ(user_event["user"].asInt(), 1);
+ EXPECT_EQ(result["traceEvents"].size(), 2u);
+ EXPECT_EQ(result["traceEvents"][0]["user"].asInt(), 1);
+ EXPECT_EQ(result["traceEvents"][1]["user"].asInt(), 2);
EXPECT_EQ(result["systemTraceEvents"].asString(), kLegacyFtraceData);
}
-TEST(ExportJsonTest, CpuProfileEvent) {
+TEST_F(ExportJsonTest, CpuProfileEvent) {
const int64_t kProcessID = 100;
const int64_t kThreadID = 200;
const int64_t kTimestamp = 10000000;
- TraceProcessorContext context;
- context.storage.reset(new TraceStorage());
- TraceStorage* storage = context.storage.get();
+ TraceStorage* storage = context_.storage.get();
UniquePid upid = storage->AddEmptyProcess(kProcessID);
UniqueTid utid = storage->AddEmptyThread(kThreadID);
@@ -1109,13 +1177,11 @@
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
- int code = ExportJson(storage, output);
+ util::Status status = ExportJson(storage, output);
- EXPECT_EQ(code, kResultOk);
+ EXPECT_TRUE(status.ok());
- Json::Reader reader;
- Json::Value result;
- EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ Json::Value result = ToJsonValue(ReadFile(output));
EXPECT_EQ(result["traceEvents"].size(), 1u);
Json::Value event = result["traceEvents"][0];
@@ -1130,6 +1196,158 @@
"bar_module_name [bar_module_id]\n");
}
+TEST_F(ExportJsonTest, ArgumentFilter) {
+ UniqueTid utid = context_.storage->AddEmptyThread(0);
+ TrackId track =
+ context_.track_tracker->GetOrCreateDescriptorTrackForThread(utid);
+ context_.args_tracker->Flush(); // Flush track args.
+
+ StringId cat_id = context_.storage->InternString(base::StringView("cat"));
+ std::array<StringId, 3> name_ids{
+ context_.storage->InternString(base::StringView("name1")),
+ context_.storage->InternString(base::StringView("name2")),
+ context_.storage->InternString(base::StringView("name3"))};
+ StringId arg1_id = context_.storage->InternString(base::StringView("arg1"));
+ StringId arg2_id = context_.storage->InternString(base::StringView("arg2"));
+ StringId val_id = context_.storage->InternString(base::StringView("val"));
+
+ std::array<RowId, 3> slice_ids;
+ for (size_t i = 0; i < name_ids.size(); i++) {
+ slice_ids[i] = TraceStorage::CreateRowId(
+ kNestableSlices, context_.storage->mutable_nestable_slices()->AddSlice(
+ 0, 0, track, utid, RefType::kRefUtid, cat_id,
+ name_ids[i], 0, 0, 0));
+ }
+
+ for (RowId row : slice_ids) {
+ context_.args_tracker->AddArg(row, arg1_id, arg1_id, Variadic::Integer(5));
+ context_.args_tracker->AddArg(row, arg2_id, arg2_id,
+ Variadic::String(val_id));
+ }
+ context_.args_tracker->Flush();
+
+ auto arg_filter = [](const char* category_group_name, const char* event_name,
+ ArgumentNameFilterPredicate* arg_name_filter) {
+ EXPECT_TRUE(strcmp(category_group_name, "cat") == 0);
+ if (strcmp(event_name, "name1") == 0) {
+ // Filter all args for name1.
+ return false;
+ } else if (strcmp(event_name, "name2") == 0) {
+ // Filter only the second arg for name2.
+ *arg_name_filter = [](const char* arg_name) {
+ if (strcmp(arg_name, "arg1") == 0) {
+ return true;
+ }
+ EXPECT_TRUE(strcmp(arg_name, "arg2") == 0);
+ return false;
+ };
+ return true;
+ }
+ // Filter no args for name3.
+ EXPECT_TRUE(strcmp(event_name, "name3") == 0);
+ return true;
+ };
+
+ Json::Value result = ToJsonValue(ToJson(arg_filter));
+
+ EXPECT_EQ(result["traceEvents"].size(), 3u);
+
+ EXPECT_EQ(result["traceEvents"][0]["cat"].asString(), "cat");
+ EXPECT_EQ(result["traceEvents"][0]["name"].asString(), "name1");
+ EXPECT_EQ(result["traceEvents"][0]["args"].asString(), "__stripped__");
+
+ EXPECT_EQ(result["traceEvents"][1]["cat"].asString(), "cat");
+ EXPECT_EQ(result["traceEvents"][1]["name"].asString(), "name2");
+ EXPECT_EQ(result["traceEvents"][1]["args"]["arg1"].asInt(), 5);
+ EXPECT_EQ(result["traceEvents"][1]["args"]["arg2"].asString(),
+ "__stripped__");
+
+ EXPECT_EQ(result["traceEvents"][2]["cat"].asString(), "cat");
+ EXPECT_EQ(result["traceEvents"][2]["name"].asString(), "name3");
+ EXPECT_EQ(result["traceEvents"][2]["args"]["arg1"].asInt(), 5);
+ EXPECT_EQ(result["traceEvents"][2]["args"]["arg2"].asString(), "val");
+}
+
+TEST_F(ExportJsonTest, MetadataFilter) {
+ const char* kName1 = "name1";
+ const char* kName2 = "name2";
+ const char* kValue1 = "value1";
+ const int kValue2 = 222;
+
+ TraceStorage* storage = context_.storage.get();
+
+ RowId row_id = storage->mutable_raw_events()->AddRawEvent(
+ 0, storage->InternString("chrome_event.metadata"), 0, 0);
+
+ StringId name1_id = storage->InternString(base::StringView(kName1));
+ StringId name2_id = storage->InternString(base::StringView(kName2));
+ StringId value1_id = storage->InternString(base::StringView(kValue1));
+ context_.args_tracker->AddArg(row_id, name1_id, name1_id,
+ Variadic::String(value1_id));
+ context_.args_tracker->AddArg(row_id, name2_id, name2_id,
+ Variadic::Integer(kValue2));
+ context_.args_tracker->Flush();
+
+ auto metadata_filter = [](const char* metadata_name) {
+ // Only allow name1.
+ return strcmp(metadata_name, "name1") == 0;
+ };
+
+ Json::Value result = ToJsonValue(ToJson(nullptr, metadata_filter));
+
+ EXPECT_TRUE(result.isMember("metadata"));
+ Json::Value metadata = result["metadata"];
+
+ EXPECT_EQ(metadata[kName1].asString(), kValue1);
+ EXPECT_EQ(metadata[kName2].asString(), "__stripped__");
+}
+
+TEST_F(ExportJsonTest, LabelFilter) {
+ const int64_t kTimestamp1 = 10000000;
+ const int64_t kTimestamp2 = 20000000;
+ const int64_t kDuration = 10000;
+ const int64_t kThreadID = 100;
+ const char* kCategory = "cat";
+ const char* kName = "name";
+
+ UniqueTid utid = context_.storage->AddEmptyThread(kThreadID);
+ TrackId track =
+ context_.track_tracker->GetOrCreateDescriptorTrackForThread(utid);
+ context_.args_tracker->Flush(); // Flush track args.
+ StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
+ StringId name_id = context_.storage->InternString(base::StringView(kName));
+
+ context_.storage->mutable_nestable_slices()->AddSlice(
+ kTimestamp1, kDuration, track, utid, RefType::kRefUtid, cat_id, name_id,
+ 0, 0, 0);
+ context_.storage->mutable_nestable_slices()->AddSlice(
+ kTimestamp2, kDuration, track, utid, RefType::kRefUtid, cat_id, name_id,
+ 0, 0, 0);
+
+ auto label_filter = [](const char* label_name) {
+ return strcmp(label_name, "traceEvents") == 0;
+ };
+
+ Json::Value result =
+ ToJsonValue("[" + ToJson(nullptr, nullptr, label_filter) + "]");
+
+ EXPECT_TRUE(result.isArray());
+ EXPECT_EQ(result.size(), 2u);
+
+ EXPECT_EQ(result[0]["ph"].asString(), "X");
+ EXPECT_EQ(result[0]["ts"].asInt64(), kTimestamp1 / 1000);
+ EXPECT_EQ(result[0]["dur"].asInt64(), kDuration / 1000);
+ EXPECT_EQ(result[0]["tid"].asUInt(), kThreadID);
+ EXPECT_EQ(result[0]["cat"].asString(), kCategory);
+ EXPECT_EQ(result[0]["name"].asString(), kName);
+ EXPECT_EQ(result[1]["ph"].asString(), "X");
+ EXPECT_EQ(result[1]["ts"].asInt64(), kTimestamp2 / 1000);
+ EXPECT_EQ(result[1]["dur"].asInt64(), kDuration / 1000);
+ EXPECT_EQ(result[1]["tid"].asUInt(), kThreadID);
+ EXPECT_EQ(result[1]["cat"].asString(), kCategory);
+ EXPECT_EQ(result[1]["name"].asString(), kName);
+}
+
} // namespace
} // namespace json
} // namespace trace_processor
diff --git a/src/trace_processor/forwarding_trace_parser.cc b/src/trace_processor/forwarding_trace_parser.cc
index 3ea88e4..07934cb 100644
--- a/src/trace_processor/forwarding_trace_parser.cc
+++ b/src/trace_processor/forwarding_trace_parser.cc
@@ -19,9 +19,9 @@
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_utils.h"
#include "src/trace_processor/gzip_trace_parser.h"
+#include "src/trace_processor/importers/proto/proto_trace_parser.h"
+#include "src/trace_processor/importers/proto/proto_trace_tokenizer.h"
#include "src/trace_processor/importers/systrace/systrace_trace_parser.h"
-#include "src/trace_processor/proto_trace_parser.h"
-#include "src/trace_processor/proto_trace_tokenizer.h"
#include "src/trace_processor/trace_sorter.h"
#if PERFETTO_BUILDFLAG(PERFETTO_TP_FUCHSIA)
diff --git a/src/trace_processor/importers/ftrace/ftrace_module.h b/src/trace_processor/importers/ftrace/ftrace_module.h
index a08eecd..9d8d489 100644
--- a/src/trace_processor/importers/ftrace/ftrace_module.h
+++ b/src/trace_processor/importers/ftrace/ftrace_module.h
@@ -40,7 +40,8 @@
ModuleResult TokenizePacket(
const protos::pbzero::TracePacket::Decoder& decoder,
TraceBlobView* packet,
- int64_t /*packet_timestamp*/) {
+ int64_t /*packet_timestamp*/,
+ PacketSequenceState* /*state*/) {
if (decoder.has_ftrace_events()) {
auto ftrace_field = decoder.ftrace_events();
const size_t fld_off = packet->offset_of(ftrace_field.data);
diff --git a/src/trace_processor/importers/proto/android_probes_module.h b/src/trace_processor/importers/proto/android_probes_module.h
new file mode 100644
index 0000000..b3534a6
--- /dev/null
+++ b/src/trace_processor/importers/proto/android_probes_module.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROBES_MODULE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROBES_MODULE_H_
+
+#include "perfetto/base/build_config.h"
+#include "src/trace_processor/importers/proto/android_probes_parser.h"
+#include "src/trace_processor/importers/proto/proto_importer_module.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class AndroidProbesModule : public ProtoImporterModuleBase<PERFETTO_BUILDFLAG(
+ PERFETTO_TP_ANDROID_PROBES)> {
+ public:
+ explicit AndroidProbesModule(TraceProcessorContext* context)
+ : ProtoImporterModuleBase(context), parser_(context) {}
+
+ ModuleResult ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp) {
+ if (decoder.has_battery()) {
+ parser_.ParseBatteryCounters(ttp.timestamp, decoder.battery());
+ return ModuleResult::Handled();
+ }
+
+ if (decoder.has_power_rails()) {
+ parser_.ParsePowerRails(ttp.timestamp, decoder.power_rails());
+ return ModuleResult::Handled();
+ }
+
+ if (decoder.has_android_log()) {
+ parser_.ParseAndroidLogPacket(decoder.android_log());
+ return ModuleResult::Handled();
+ }
+
+ if (decoder.has_packages_list()) {
+ parser_.ParseAndroidPackagesList(decoder.packages_list());
+ return ModuleResult::Handled();
+ }
+
+ return ModuleResult::Ignored();
+ }
+
+ ModuleResult ParseTraceConfig(
+ const protos::pbzero::TraceConfig::Decoder& decoder) {
+ if (decoder.has_statsd_metadata()) {
+ parser_.ParseStatsdMetadata(decoder.statsd_metadata());
+ return ModuleResult::Handled();
+ }
+ return ModuleResult::Ignored();
+ }
+
+ private:
+ AndroidProbesParser parser_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROBES_MODULE_H_
diff --git a/src/trace_processor/importers/proto/android_probes_parser.cc b/src/trace_processor/importers/proto/android_probes_parser.cc
new file mode 100644
index 0000000..2d3f46e
--- /dev/null
+++ b/src/trace_processor/importers/proto/android_probes_parser.cc
@@ -0,0 +1,235 @@
+/*
+ * 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/importers/proto/android_probes_parser.h"
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/traced/sys_stats_counters.h"
+#include "src/trace_processor/args_tracker.h"
+#include "src/trace_processor/clock_tracker.h"
+#include "src/trace_processor/event_tracker.h"
+#include "src/trace_processor/process_tracker.h"
+#include "src/trace_processor/syscall_tracker.h"
+#include "src/trace_processor/trace_processor_context.h"
+
+#include "protos/perfetto/common/android_log_constants.pbzero.h"
+#include "protos/perfetto/trace/android/android_log.pbzero.h"
+#include "protos/perfetto/trace/android/packages_list.pbzero.h"
+#include "protos/perfetto/trace/clock_snapshot.pbzero.h"
+#include "protos/perfetto/trace/power/battery_counters.pbzero.h"
+#include "protos/perfetto/trace/power/power_rails.pbzero.h"
+#include "protos/perfetto/trace/ps/process_stats.pbzero.h"
+#include "protos/perfetto/trace/ps/process_tree.pbzero.h"
+#include "protos/perfetto/trace/sys_stats/sys_stats.pbzero.h"
+#include "protos/perfetto/trace/system_info.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+AndroidProbesParser::AndroidProbesParser(TraceProcessorContext* context)
+ : context_(context),
+ batt_charge_id_(context->storage->InternString("batt.charge_uah")),
+ batt_capacity_id_(context->storage->InternString("batt.capacity_pct")),
+ batt_current_id_(context->storage->InternString("batt.current_ua")),
+ batt_current_avg_id_(
+ context->storage->InternString("batt.current.avg_ua")) {}
+
+void AndroidProbesParser::ParseBatteryCounters(int64_t ts, ConstBytes blob) {
+ protos::pbzero::BatteryCounters::Decoder evt(blob.data, blob.size);
+ if (evt.has_charge_counter_uah()) {
+ context_->event_tracker->PushCounter(
+ ts, evt.charge_counter_uah(), batt_charge_id_, 0, RefType::kRefNoRef);
+ }
+ if (evt.has_capacity_percent()) {
+ context_->event_tracker->PushCounter(
+ ts, static_cast<double>(evt.capacity_percent()), batt_capacity_id_, 0,
+ RefType::kRefNoRef);
+ }
+ if (evt.has_current_ua()) {
+ context_->event_tracker->PushCounter(ts, evt.current_ua(), batt_current_id_,
+ 0, RefType::kRefNoRef);
+ }
+ if (evt.has_current_avg_ua()) {
+ context_->event_tracker->PushCounter(
+ ts, evt.current_avg_ua(), batt_current_avg_id_, 0, RefType::kRefNoRef);
+ }
+}
+
+void AndroidProbesParser::ParsePowerRails(int64_t ts, ConstBytes blob) {
+ protos::pbzero::PowerRails::Decoder evt(blob.data, blob.size);
+ if (evt.has_rail_descriptor()) {
+ for (auto it = evt.rail_descriptor(); it; ++it) {
+ protos::pbzero::PowerRails::RailDescriptor::Decoder desc(*it);
+ uint32_t idx = desc.index();
+ if (PERFETTO_UNLIKELY(idx > 256)) {
+ PERFETTO_DLOG("Skipping excessively large power_rail index %" PRIu32,
+ idx);
+ continue;
+ }
+ if (power_rails_strs_id_.size() <= idx)
+ power_rails_strs_id_.resize(idx + 1);
+ char counter_name[255];
+ snprintf(counter_name, sizeof(counter_name), "power.%.*s_uws",
+ int(desc.rail_name().size), desc.rail_name().data);
+ power_rails_strs_id_[idx] = context_->storage->InternString(counter_name);
+ }
+ }
+
+ if (evt.has_energy_data()) {
+ for (auto it = evt.energy_data(); it; ++it) {
+ protos::pbzero::PowerRails::EnergyData::Decoder desc(*it);
+ if (desc.index() < power_rails_strs_id_.size()) {
+ int64_t actual_ts =
+ desc.has_timestamp_ms()
+ ? static_cast<int64_t>(desc.timestamp_ms()) * 1000000
+ : ts;
+ context_->event_tracker->PushCounter(actual_ts, desc.energy(),
+ power_rails_strs_id_[desc.index()],
+ 0, RefType::kRefNoRef);
+ } else {
+ context_->storage->IncrementStats(stats::power_rail_unknown_index);
+ }
+ }
+ }
+}
+
+void AndroidProbesParser::ParseAndroidLogPacket(ConstBytes blob) {
+ protos::pbzero::AndroidLogPacket::Decoder packet(blob.data, blob.size);
+ for (auto it = packet.events(); it; ++it)
+ ParseAndroidLogEvent(*it);
+
+ if (packet.has_stats())
+ ParseAndroidLogStats(packet.stats());
+}
+
+void AndroidProbesParser::ParseAndroidLogEvent(ConstBytes blob) {
+ // TODO(primiano): Add events and non-stringified fields to the "raw" table.
+ protos::pbzero::AndroidLogPacket::LogEvent::Decoder evt(blob.data, blob.size);
+ int64_t ts = static_cast<int64_t>(evt.timestamp());
+ uint32_t pid = static_cast<uint32_t>(evt.pid());
+ uint32_t tid = static_cast<uint32_t>(evt.tid());
+ uint8_t prio = static_cast<uint8_t>(evt.prio());
+ StringId tag_id = context_->storage->InternString(
+ evt.has_tag() ? evt.tag() : base::StringView());
+ StringId msg_id = context_->storage->InternString(
+ evt.has_message() ? evt.message() : base::StringView());
+
+ char arg_msg[4096];
+ char* arg_str = &arg_msg[0];
+ *arg_str = '\0';
+ auto arg_avail = [&arg_msg, &arg_str]() {
+ return sizeof(arg_msg) - static_cast<size_t>(arg_str - arg_msg);
+ };
+ for (auto it = evt.args(); it; ++it) {
+ protos::pbzero::AndroidLogPacket::LogEvent::Arg::Decoder arg(*it);
+ if (!arg.has_name())
+ continue;
+ arg_str +=
+ snprintf(arg_str, arg_avail(),
+ " %.*s=", static_cast<int>(arg.name().size), arg.name().data);
+ if (arg.has_string_value()) {
+ arg_str += snprintf(arg_str, arg_avail(), "\"%.*s\"",
+ static_cast<int>(arg.string_value().size),
+ arg.string_value().data);
+ } else if (arg.has_int_value()) {
+ arg_str += snprintf(arg_str, arg_avail(), "%" PRId64, arg.int_value());
+ } else if (arg.has_float_value()) {
+ arg_str += snprintf(arg_str, arg_avail(), "%f",
+ static_cast<double>(arg.float_value()));
+ }
+ }
+
+ if (prio == 0)
+ prio = protos::pbzero::AndroidLogPriority::PRIO_INFO;
+
+ if (arg_str != &arg_msg[0]) {
+ PERFETTO_DCHECK(msg_id.is_null());
+ // Skip the first space char (" foo=1 bar=2" -> "foo=1 bar=2").
+ msg_id = context_->storage->InternString(&arg_msg[1]);
+ }
+ UniquePid utid = tid ? context_->process_tracker->UpdateThread(tid, pid) : 0;
+ base::Optional<int64_t> opt_trace_time = context_->clock_tracker->ToTraceTime(
+ protos::pbzero::ClockSnapshot::Clock::REALTIME, ts);
+ if (!opt_trace_time)
+ return;
+
+ // Log events are NOT required to be sorted by trace_time. The virtual table
+ // will take care of sorting on-demand.
+ context_->storage->mutable_android_log()->AddLogEvent(
+ opt_trace_time.value(), utid, prio, tag_id, msg_id);
+}
+
+void AndroidProbesParser::ParseAndroidLogStats(ConstBytes blob) {
+ protos::pbzero::AndroidLogPacket::Stats::Decoder evt(blob.data, blob.size);
+ if (evt.has_num_failed()) {
+ context_->storage->SetStats(stats::android_log_num_failed,
+ static_cast<int64_t>(evt.num_failed()));
+ }
+
+ if (evt.has_num_skipped()) {
+ context_->storage->SetStats(stats::android_log_num_skipped,
+ static_cast<int64_t>(evt.num_skipped()));
+ }
+
+ if (evt.has_num_total()) {
+ context_->storage->SetStats(stats::android_log_num_total,
+ static_cast<int64_t>(evt.num_total()));
+ }
+}
+
+void AndroidProbesParser::ParseStatsdMetadata(ConstBytes blob) {
+ protos::pbzero::TraceConfig::StatsdMetadata::Decoder metadata(blob.data,
+ blob.size);
+ if (metadata.has_triggering_subscription_id()) {
+ context_->storage->SetMetadata(
+ metadata::statsd_triggering_subscription_id,
+ Variadic::Integer(metadata.triggering_subscription_id()));
+ }
+}
+
+void AndroidProbesParser::ParseAndroidPackagesList(ConstBytes blob) {
+ protos::pbzero::PackagesList::Decoder pkg_list(blob.data, blob.size);
+ context_->storage->SetStats(stats::packages_list_has_read_errors,
+ pkg_list.read_error());
+ context_->storage->SetStats(stats::packages_list_has_parse_errors,
+ pkg_list.parse_error());
+
+ // Insert the package info into arg sets (one set per package), with the arg
+ // set ids collected in the Metadata table, under
+ // metadata::android_packages_list key type.
+ for (auto it = pkg_list.packages(); it; ++it) {
+ // Insert a placeholder metadata entry, which will be overwritten by the
+ // arg_set_id when the arg tracker is flushed.
+ RowId row_id = context_->storage->AppendMetadata(
+ metadata::android_packages_list, Variadic::Integer(0));
+
+ auto add_arg = [this, row_id](base::StringView name, Variadic value) {
+ StringId key_id = context_->storage->InternString(name);
+ context_->args_tracker->AddArg(row_id, key_id, key_id, value);
+ };
+ protos::pbzero::PackagesList_PackageInfo::Decoder pkg(*it);
+ add_arg("name",
+ Variadic::String(context_->storage->InternString(pkg.name())));
+ add_arg("uid", Variadic::UnsignedInteger(pkg.uid()));
+ add_arg("debuggable", Variadic::Boolean(pkg.debuggable()));
+ add_arg("profileable_from_shell",
+ Variadic::Boolean(pkg.profileable_from_shell()));
+ add_arg("version_code", Variadic::Integer(pkg.version_code()));
+ }
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/android_probes_parser.h b/src/trace_processor/importers/proto/android_probes_parser.h
new file mode 100644
index 0000000..41362ed
--- /dev/null
+++ b/src/trace_processor/importers/proto/android_probes_parser.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROBES_PARSER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROBES_PARSER_H_
+
+#include <vector>
+
+#include "perfetto/protozero/field.h"
+#include "src/trace_processor/trace_storage.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class TraceProcessorContext;
+
+class AndroidProbesParser {
+ public:
+ using ConstBytes = protozero::ConstBytes;
+
+ explicit AndroidProbesParser(TraceProcessorContext*);
+
+ void ParseBatteryCounters(int64_t ts, ConstBytes);
+ void ParsePowerRails(int64_t ts, ConstBytes);
+ void ParseAndroidLogPacket(ConstBytes);
+ void ParseAndroidLogEvent(ConstBytes);
+ void ParseAndroidLogStats(ConstBytes);
+ void ParseStatsdMetadata(ConstBytes);
+ void ParseAndroidPackagesList(ConstBytes);
+
+ private:
+ TraceProcessorContext* const context_;
+
+ const StringId batt_charge_id_;
+ const StringId batt_capacity_id_;
+ const StringId batt_current_id_;
+ const StringId batt_current_avg_id_;
+ std::vector<StringId> power_rails_strs_id_;
+};
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROBES_PARSER_H_
diff --git a/src/trace_processor/importers/proto/graphics_event_module.h b/src/trace_processor/importers/proto/graphics_event_module.h
new file mode 100644
index 0000000..b336398
--- /dev/null
+++ b/src/trace_processor/importers/proto/graphics_event_module.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_EVENT_MODULE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_EVENT_MODULE_H_
+
+#include "perfetto/base/build_config.h"
+#include "src/trace_processor/importers/proto/graphics_event_parser.h"
+#include "src/trace_processor/importers/proto/proto_importer_module.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class GraphicsEventModule
+ : public ProtoImporterModuleBase<PERFETTO_BUILDFLAG(PERFETTO_TP_GRAPHICS)> {
+ public:
+ explicit GraphicsEventModule(TraceProcessorContext* context)
+ : ProtoImporterModuleBase(context), parser_(context) {}
+
+ ModuleResult ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp) {
+ if (decoder.has_gpu_counter_event()) {
+ parser_.ParseGpuCounterEvent(ttp.timestamp, decoder.gpu_counter_event());
+ return ModuleResult::Handled();
+ }
+
+ if (decoder.has_gpu_render_stage_event()) {
+ parser_.ParseGpuRenderStageEvent(ttp.timestamp,
+ decoder.gpu_render_stage_event());
+ return ModuleResult::Handled();
+ }
+
+ if (decoder.has_gpu_log()) {
+ parser_.ParseGpuLog(ttp.timestamp, decoder.gpu_log());
+ return ModuleResult::Handled();
+ }
+
+ if (decoder.has_graphics_frame_event()) {
+ parser_.ParseGraphicsFrameEvent(ttp.timestamp,
+ decoder.graphics_frame_event());
+ return ModuleResult::Handled();
+ }
+
+ if (decoder.has_vulkan_memory_event()) {
+ parser_.ParseVulkanMemoryEvent(decoder.vulkan_memory_event());
+ return ModuleResult::Handled();
+ }
+
+ return ModuleResult::Ignored();
+ }
+
+ private:
+ GraphicsEventParser parser_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_EVENT_MODULE_H_
diff --git a/src/trace_processor/graphics_event_parser.cc b/src/trace_processor/importers/proto/graphics_event_parser.cc
similarity index 99%
rename from src/trace_processor/graphics_event_parser.cc
rename to src/trace_processor/importers/proto/graphics_event_parser.cc
index 3ab5dee..17909bd 100644
--- a/src/trace_processor/graphics_event_parser.cc
+++ b/src/trace_processor/importers/proto/graphics_event_parser.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/trace_processor/graphics_event_parser.h"
+#include "src/trace_processor/importers/proto/graphics_event_parser.h"
#include "perfetto/protozero/field.h"
#include "src/trace_processor/args_tracker.h"
@@ -35,8 +35,6 @@
namespace perfetto {
namespace trace_processor {
-GraphicsEventParser::~GraphicsEventParser() = default;
-
GraphicsEventParser::GraphicsEventParser(TraceProcessorContext* context)
: context_(context),
gpu_render_stage_scope_id_(
diff --git a/src/trace_processor/graphics_event_parser.h b/src/trace_processor/importers/proto/graphics_event_parser.h
similarity index 92%
rename from src/trace_processor/graphics_event_parser.h
rename to src/trace_processor/importers/proto/graphics_event_parser.h
index 8cac922..25ab411 100644
--- a/src/trace_processor/graphics_event_parser.h
+++ b/src/trace_processor/importers/proto/graphics_event_parser.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef SRC_TRACE_PROCESSOR_GRAPHICS_EVENT_PARSER_H_
-#define SRC_TRACE_PROCESSOR_GRAPHICS_EVENT_PARSER_H_
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_EVENT_PARSER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_EVENT_PARSER_H_
#include <vector>
@@ -32,7 +32,6 @@
public:
using ConstBytes = protozero::ConstBytes;
explicit GraphicsEventParser(TraceProcessorContext*);
- ~GraphicsEventParser();
void ParseGpuCounterEvent(int64_t ts, ConstBytes);
void ParseGpuRenderStageEvent(int64_t ts, ConstBytes);
@@ -81,4 +80,4 @@
} // namespace trace_processor
} // namespace perfetto
-#endif // SRC_TRACE_PROCESSOR_GRAPHICS_EVENT_PARSER_H_
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_EVENT_PARSER_H_
diff --git a/src/trace_processor/importers/proto/packet_sequence_state.h b/src/trace_processor/importers/proto/packet_sequence_state.h
new file mode 100644
index 0000000..8ee597b
--- /dev/null
+++ b/src/trace_processor/importers/proto/packet_sequence_state.h
@@ -0,0 +1,238 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PACKET_SEQUENCE_STATE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PACKET_SEQUENCE_STATE_H_
+
+#include <stdint.h>
+
+#include <unordered_map>
+#include <vector>
+
+#include "perfetto/protozero/proto_decoder.h"
+#include "src/trace_processor/stack_profile_tracker.h"
+#include "src/trace_processor/trace_blob_view.h"
+#include "src/trace_processor/trace_processor_context.h"
+#include "src/trace_processor/trace_storage.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+#if PERFETTO_DCHECK_IS_ON() && defined(__GNUC__)
+// When called from GetOrCreateDecoder(), __PRETTY_FUNCTION__ (supported by GCC
+// + clang) should include the stringified name of the MessageType.
+#define PERFETTO_TYPE_IDENTIFIER __PRETTY_FUNCTION__
+#else // PERFETTO_DCHECK_IS_ON() && defined(__GNUC__)
+#define PERFETTO_TYPE_IDENTIFIER nullptr
+#endif // PERFETTO_DCHECK_IS_ON() && defined(__GNUC__)
+
+class PacketSequenceState {
+ public:
+ // Entry in an interning index, refers to the interned message.
+ struct InternedMessageView {
+ InternedMessageView(TraceBlobView msg) : message(std::move(msg)) {}
+
+ template <typename MessageType>
+ typename MessageType::Decoder* GetOrCreateDecoder() {
+ if (!decoder) {
+ // Lazy init the decoder and save it away, so that we don't have to
+ // reparse the message every time we access the interning entry.
+ decoder = std::unique_ptr<void, std::function<void(void*)>>(
+ new typename MessageType::Decoder(message.data(), message.length()),
+ [](void* obj) {
+ delete reinterpret_cast<typename MessageType::Decoder*>(obj);
+ });
+ decoder_type = PERFETTO_TYPE_IDENTIFIER;
+ }
+ // Verify that the type of the decoder didn't change.
+ if (PERFETTO_TYPE_IDENTIFIER &&
+ strcmp(decoder_type,
+ // GCC complains if this arg can be null.
+ PERFETTO_TYPE_IDENTIFIER ? PERFETTO_TYPE_IDENTIFIER : "") !=
+ 0) {
+ PERFETTO_FATAL(
+ "Interning entry accessed under different types! previous type: "
+ "%s. new type: %s.",
+ decoder_type, __PRETTY_FUNCTION__);
+ }
+ return reinterpret_cast<typename MessageType::Decoder*>(decoder.get());
+ }
+
+ TraceBlobView message;
+ std::unique_ptr<void, std::function<void(void*)>> decoder;
+
+ private:
+ const char* decoder_type = nullptr;
+ };
+
+ using InternedMessageMap =
+ std::unordered_map<uint64_t /*iid*/, InternedMessageView>;
+ using InternedFieldMap =
+ std::unordered_map<uint32_t /*field_id*/, InternedMessageMap>;
+ using InternedDataGenerationList = std::vector<InternedFieldMap>;
+
+ PacketSequenceState(TraceProcessorContext* context)
+ : context_(context), stack_profile_tracker_(context) {
+ interned_data_.emplace_back();
+ }
+
+ int64_t IncrementAndGetTrackEventTimeNs(int64_t delta_ns) {
+ PERFETTO_DCHECK(track_event_timestamps_valid());
+ track_event_timestamp_ns_ += delta_ns;
+ return track_event_timestamp_ns_;
+ }
+
+ int64_t IncrementAndGetTrackEventThreadTimeNs(int64_t delta_ns) {
+ PERFETTO_DCHECK(track_event_timestamps_valid());
+ track_event_thread_timestamp_ns_ += delta_ns;
+ return track_event_thread_timestamp_ns_;
+ }
+
+ int64_t IncrementAndGetTrackEventThreadInstructionCount(int64_t delta) {
+ PERFETTO_DCHECK(track_event_timestamps_valid());
+ track_event_thread_instruction_count_ += delta;
+ return track_event_thread_instruction_count_;
+ }
+
+ void OnPacketLoss() {
+ packet_loss_ = true;
+ track_event_timestamps_valid_ = false;
+ }
+
+ void OnIncrementalStateCleared() {
+ packet_loss_ = false;
+ interned_data_.emplace_back(); // Bump generation number
+ }
+
+ void SetThreadDescriptor(int32_t pid,
+ int32_t tid,
+ int64_t timestamp_ns,
+ int64_t thread_timestamp_ns,
+ int64_t thread_instruction_count) {
+ track_event_timestamps_valid_ = true;
+ pid_and_tid_valid_ = true;
+ pid_ = pid;
+ tid_ = tid;
+ track_event_timestamp_ns_ = timestamp_ns;
+ track_event_thread_timestamp_ns_ = thread_timestamp_ns;
+ track_event_thread_instruction_count_ = thread_instruction_count;
+ }
+
+ bool IsIncrementalStateValid() const { return !packet_loss_; }
+
+ StackProfileTracker& stack_profile_tracker() {
+ return stack_profile_tracker_;
+ }
+
+ // Returns the index of the current generation in the
+ // InternedDataGenerationList.
+ size_t current_generation() const { return interned_data_.size() - 1; }
+
+ bool track_event_timestamps_valid() const {
+ return track_event_timestamps_valid_;
+ }
+
+ bool pid_and_tid_valid() const { return pid_and_tid_valid_; }
+
+ int32_t pid() const { return pid_; }
+ int32_t tid() const { return tid_; }
+
+ void InternMessage(uint32_t field_id, TraceBlobView message) {
+ constexpr auto kIidFieldNumber = 1;
+
+ uint64_t iid = 0;
+ auto message_start = message.data();
+ auto message_size = message.length();
+ protozero::ProtoDecoder decoder(message_start, message_size);
+
+ auto field = decoder.FindField(kIidFieldNumber);
+ if (PERFETTO_UNLIKELY(!field)) {
+ PERFETTO_DLOG("Interned message without interning_id");
+ context_->storage->IncrementStats(stats::interned_data_tokenizer_errors);
+ return;
+ }
+ iid = field.as_uint64();
+
+ auto* map = &interned_data_.back()[field_id];
+ auto res = map->emplace(iid, InternedMessageView(std::move(message)));
+
+ // If a message with this ID is already interned in the same generation,
+ // its data should not have changed (this is forbidden by the InternedData
+ // proto).
+ // TODO(eseckler): This DCHECK assumes that the message is encoded the
+ // same way if it is re-emitted.
+ PERFETTO_DCHECK(res.second ||
+ (res.first->second.message.length() == message_size &&
+ memcmp(res.first->second.message.data(), message_start,
+ message_size) == 0));
+ }
+
+ template <uint32_t FieldId, typename MessageType>
+ typename MessageType::Decoder* LookupInternedMessage(size_t generation,
+ uint64_t iid) {
+ PERFETTO_CHECK(generation <= interned_data_.size());
+ auto* field_map = &interned_data_[generation];
+ auto field_it = field_map->find(FieldId);
+ if (field_it != field_map->end()) {
+ auto* message_map = &field_it->second;
+ auto it = message_map->find(iid);
+ if (it != message_map->end()) {
+ return it->second.GetOrCreateDecoder<MessageType>();
+ }
+ }
+ context_->storage->IncrementStats(stats::interned_data_tokenizer_errors);
+ PERFETTO_DLOG("Could not find interning entry for field ID %" PRIu32
+ ", generation %zu, and IID %" PRIu64,
+ FieldId, generation, iid);
+ return nullptr;
+ }
+
+ private:
+ TraceProcessorContext* context_;
+
+ // If true, incremental state on the sequence is considered invalid until we
+ // see the next packet with incremental_state_cleared. We assume that we
+ // missed some packets at the beginning of the trace.
+ bool packet_loss_ = true;
+
+ // We can only consider TrackEvent delta timestamps to be correct after we
+ // have observed a thread descriptor (since the last packet loss).
+ bool track_event_timestamps_valid_ = false;
+
+ // |pid_| and |tid_| are only valid after we parsed at least one
+ // ThreadDescriptor packet on the sequence.
+ bool pid_and_tid_valid_ = false;
+
+ // Process/thread ID of the packet sequence set by a ThreadDescriptor
+ // packet. Used as default values for TrackEvents that don't specify a
+ // pid/tid override. Only valid after |pid_and_tid_valid_| is set to true.
+ int32_t pid_ = 0;
+ int32_t tid_ = 0;
+
+ // Current wall/thread timestamps/counters used as reference for the next
+ // TrackEvent delta timestamp.
+ int64_t track_event_timestamp_ns_ = 0;
+ int64_t track_event_thread_timestamp_ns_ = 0;
+ int64_t track_event_thread_instruction_count_ = 0;
+
+ InternedDataGenerationList interned_data_;
+ StackProfileTracker stack_profile_tracker_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PACKET_SEQUENCE_STATE_H_
diff --git a/src/trace_processor/importers/proto/proto_importer_module.h b/src/trace_processor/importers/proto/proto_importer_module.h
index 23b3fac..05936ab 100644
--- a/src/trace_processor/importers/proto/proto_importer_module.h
+++ b/src/trace_processor/importers/proto/proto_importer_module.h
@@ -21,11 +21,13 @@
#include "perfetto/trace_processor/status.h"
#include "src/trace_processor/trace_blob_view.h"
+#include "protos/perfetto/config/trace_config.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
namespace perfetto {
namespace trace_processor {
+class PacketSequenceState;
struct TimestampedTracePiece;
class TraceProcessorContext;
@@ -121,9 +123,11 @@
ModuleResult TokenizePacket(
const protos::pbzero::TracePacket::Decoder& decoder,
TraceBlobView* packet,
- int64_t packet_timestamp) {
- if (ModuleType::kEnabled)
- return impl_->TokenizePacket(decoder, packet, packet_timestamp);
+ int64_t packet_timestamp,
+ PacketSequenceState* state) {
+ if (ModuleType::kEnabled) {
+ return impl_->TokenizePacket(decoder, packet, packet_timestamp, state);
+ }
return ModuleResult::Ignored();
}
@@ -139,6 +143,16 @@
return ModuleResult::Ignored();
}
+ // Wraps ModuleType::ParseTraceConfig(). If the module is disabled, compiles
+ // into a noop in optimized builds. Called by ProtoTraceParser for trace
+ // config packets after the sorting stage.
+ ModuleResult ParseTraceConfig(
+ const protos::pbzero::TraceConfig::Decoder& decoder) {
+ if (ModuleType::kEnabled)
+ return impl_->ParseTraceConfig(decoder);
+ return ModuleResult::Ignored();
+ }
+
// For FtraceModule only. Wraps ModuleType::ParseFtracePacket(). If the module
// is disabled, compiles into a noop in optimized builds. Called by
// ProtoTraceParser for each ftrace TracePacket after the sorting stage.
diff --git a/src/trace_processor/importers/proto/proto_incremental_state.h b/src/trace_processor/importers/proto/proto_incremental_state.h
new file mode 100644
index 0000000..aaac42f
--- /dev/null
+++ b/src/trace_processor/importers/proto/proto_incremental_state.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_INCREMENTAL_STATE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_INCREMENTAL_STATE_H_
+
+#include <stdint.h>
+
+#include <map>
+
+#include "src/trace_processor/importers/proto/packet_sequence_state.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class TraceProcessorContext;
+
+// Stores per-packet-sequence incremental state during trace parsing, such as
+// reference timestamps for delta timestamp calculation and interned messages.
+class ProtoIncrementalState {
+ public:
+ ProtoIncrementalState(TraceProcessorContext* context) : context_(context) {}
+
+ // Returns the PacketSequenceState for the packet sequence with the given id.
+ // If this is a new sequence which we haven't tracked before, initializes and
+ // inserts a new PacketSequenceState into the state map.
+ PacketSequenceState* GetOrCreateStateForPacketSequence(uint32_t sequence_id) {
+ auto& ptr = packet_sequence_states_[sequence_id];
+ if (!ptr)
+ ptr.reset(new PacketSequenceState(context_));
+ return ptr.get();
+ }
+
+ private:
+ // Stores unique_ptrs to ensure that pointers to a PacketSequenceState remain
+ // valid even if the map rehashes.
+ std::map<uint32_t, std::unique_ptr<PacketSequenceState>>
+ packet_sequence_states_;
+
+ TraceProcessorContext* context_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_INCREMENTAL_STATE_H_
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
new file mode 100644
index 0000000..ec07e1a
--- /dev/null
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -0,0 +1,745 @@
+/*
+ * Copyright (C) 2018 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/importers/proto/proto_trace_parser.h"
+
+#include <inttypes.h>
+#include <string.h>
+
+#include <string>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/metatrace_events.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/string_writer.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/trace_processor/status.h"
+#include "src/trace_processor/args_tracker.h"
+#include "src/trace_processor/event_tracker.h"
+#include "src/trace_processor/heap_graph_tracker.h"
+#include "src/trace_processor/heap_profile_tracker.h"
+#include "src/trace_processor/importers/ftrace/ftrace_module.h"
+#include "src/trace_processor/importers/proto/android_probes_module.h"
+#include "src/trace_processor/importers/proto/graphics_event_module.h"
+#include "src/trace_processor/importers/proto/packet_sequence_state.h"
+#include "src/trace_processor/importers/proto/system_probes_module.h"
+#include "src/trace_processor/importers/proto/track_event_module.h"
+#include "src/trace_processor/importers/systrace/systrace_parser.h"
+#include "src/trace_processor/metadata.h"
+#include "src/trace_processor/process_tracker.h"
+#include "src/trace_processor/slice_tracker.h"
+#include "src/trace_processor/stack_profile_tracker.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
+#include "src/trace_processor/trace_processor_context.h"
+#include "src/trace_processor/track_tracker.h"
+#include "src/trace_processor/variadic.h"
+
+#include "protos/perfetto/common/trace_stats.pbzero.h"
+#include "protos/perfetto/config/trace_config.pbzero.h"
+#include "protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h"
+#include "protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h"
+#include "protos/perfetto/trace/clock_snapshot.pbzero.h"
+#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+#include "protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h"
+#include "protos/perfetto/trace/profiling/heap_graph.pbzero.h"
+#include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
+#include "protos/perfetto/trace/profiling/profile_packet.pbzero.h"
+#include "protos/perfetto/trace/trace.pbzero.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+namespace {
+
+StackProfileTracker::SourceMapping MakeSourceMapping(
+ const protos::pbzero::Mapping::Decoder& entry) {
+ StackProfileTracker::SourceMapping src_mapping{};
+ src_mapping.build_id = entry.build_id();
+ src_mapping.exact_offset = entry.exact_offset();
+ src_mapping.start_offset = entry.start_offset();
+ src_mapping.start = entry.start();
+ src_mapping.end = entry.end();
+ src_mapping.load_bias = entry.load_bias();
+ for (auto path_string_id_it = entry.path_string_ids(); path_string_id_it;
+ ++path_string_id_it)
+ src_mapping.name_ids.emplace_back(*path_string_id_it);
+ return src_mapping;
+}
+
+StackProfileTracker::SourceFrame MakeSourceFrame(
+ const protos::pbzero::Frame::Decoder& entry) {
+ StackProfileTracker::SourceFrame src_frame;
+ src_frame.name_id = entry.function_name_id();
+ src_frame.mapping_id = entry.mapping_id();
+ src_frame.rel_pc = entry.rel_pc();
+ return src_frame;
+}
+
+StackProfileTracker::SourceCallstack MakeSourceCallstack(
+ const protos::pbzero::Callstack::Decoder& entry) {
+ StackProfileTracker::SourceCallstack src_callstack;
+ for (auto frame_it = entry.frame_ids(); frame_it; ++frame_it)
+ src_callstack.emplace_back(*frame_it);
+ return src_callstack;
+}
+
+class ProfilePacketInternLookup : public StackProfileTracker::InternLookup {
+ public:
+ ProfilePacketInternLookup(PacketSequenceState* seq_state,
+ size_t seq_state_generation)
+ : seq_state_(seq_state), seq_state_generation_(seq_state_generation) {}
+
+ base::Optional<base::StringView> GetString(
+ StackProfileTracker::SourceStringId iid,
+ StackProfileTracker::InternedStringType type) const override {
+ protos::pbzero::InternedString::Decoder* decoder = nullptr;
+ switch (type) {
+ case StackProfileTracker::InternedStringType::kBuildId:
+ decoder = seq_state_->LookupInternedMessage<
+ protos::pbzero::InternedData::kBuildIdsFieldNumber,
+ protos::pbzero::InternedString>(seq_state_generation_, iid);
+ break;
+ case StackProfileTracker::InternedStringType::kFunctionName:
+ decoder = seq_state_->LookupInternedMessage<
+ protos::pbzero::InternedData::kFunctionNamesFieldNumber,
+ protos::pbzero::InternedString>(seq_state_generation_, iid);
+ break;
+ case StackProfileTracker::InternedStringType::kMappingPath:
+ decoder = seq_state_->LookupInternedMessage<
+ protos::pbzero::InternedData::kMappingPathsFieldNumber,
+ protos::pbzero::InternedString>(seq_state_generation_, iid);
+ break;
+ }
+ if (!decoder)
+ return base::nullopt;
+ return base::StringView(reinterpret_cast<const char*>(decoder->str().data),
+ decoder->str().size);
+ }
+
+ base::Optional<StackProfileTracker::SourceMapping> GetMapping(
+ StackProfileTracker::SourceMappingId iid) const override {
+ auto* decoder = seq_state_->LookupInternedMessage<
+ protos::pbzero::InternedData::kMappingsFieldNumber,
+ protos::pbzero::Mapping>(seq_state_generation_, iid);
+ if (!decoder)
+ return base::nullopt;
+ return MakeSourceMapping(*decoder);
+ }
+
+ base::Optional<StackProfileTracker::SourceFrame> GetFrame(
+ StackProfileTracker::SourceFrameId iid) const override {
+ auto* decoder = seq_state_->LookupInternedMessage<
+ protos::pbzero::InternedData::kFramesFieldNumber,
+ protos::pbzero::Frame>(seq_state_generation_, iid);
+ if (!decoder)
+ return base::nullopt;
+ return MakeSourceFrame(*decoder);
+ }
+
+ base::Optional<StackProfileTracker::SourceCallstack> GetCallstack(
+ StackProfileTracker::SourceCallstackId iid) const override {
+ auto* decoder = seq_state_->LookupInternedMessage<
+ protos::pbzero::InternedData::kCallstacksFieldNumber,
+ protos::pbzero::Callstack>(seq_state_generation_, iid);
+ if (!decoder)
+ return base::nullopt;
+ return MakeSourceCallstack(*decoder);
+ }
+
+ private:
+ PacketSequenceState* seq_state_;
+ size_t seq_state_generation_;
+};
+
+const char* HeapGraphRootTypeToString(int32_t type) {
+ switch (type) {
+ case protos::pbzero::HeapGraphRoot::ROOT_UNKNOWN:
+ return "ROOT_UNKNOWN";
+ case protos::pbzero::HeapGraphRoot::ROOT_JNI_GLOBAL:
+ return "ROOT_JNI_GLOBAL";
+ case protos::pbzero::HeapGraphRoot::ROOT_JNI_LOCAL:
+ return "ROOT_JNI_LOCAL";
+ case protos::pbzero::HeapGraphRoot::ROOT_JAVA_FRAME:
+ return "ROOT_JAVA_FRAME";
+ case protos::pbzero::HeapGraphRoot::ROOT_NATIVE_STACK:
+ return "ROOT_NATIVE_STACK";
+ case protos::pbzero::HeapGraphRoot::ROOT_STICKY_CLASS:
+ return "ROOT_STICKY_CLASS";
+ case protos::pbzero::HeapGraphRoot::ROOT_THREAD_BLOCK:
+ return "ROOT_THREAD_BLOCK";
+ case protos::pbzero::HeapGraphRoot::ROOT_MONITOR_USED:
+ return "ROOT_MONITOR_USED";
+ case protos::pbzero::HeapGraphRoot::ROOT_THREAD_OBJECT:
+ return "ROOT_THREAD_OBJECT";
+ case protos::pbzero::HeapGraphRoot::ROOT_INTERNED_STRING:
+ return "ROOT_INTERNED_STRING";
+ case protos::pbzero::HeapGraphRoot::ROOT_FINALIZING:
+ return "ROOT_FINALIZING";
+ case protos::pbzero::HeapGraphRoot::ROOT_DEBUGGER:
+ return "ROOT_DEBUGGER";
+ case protos::pbzero::HeapGraphRoot::ROOT_REFERENCE_CLEANUP:
+ return "ROOT_REFERENCE_CLEANUP";
+ case protos::pbzero::HeapGraphRoot::ROOT_VM_INTERNAL:
+ return "ROOT_VM_INTERNAL";
+ case protos::pbzero::HeapGraphRoot::ROOT_JNI_MONITOR:
+ return "ROOT_JNI_MONITOR";
+ default:
+ return "ROOT_UNKNOWN";
+ }
+}
+
+} // namespace
+
+ProtoTraceParser::ProtoTraceParser(TraceProcessorContext* context)
+ : context_(context),
+ metatrace_id_(context->storage->InternString("metatrace")),
+ data_name_id_(context->storage->InternString("data")),
+ raw_chrome_metadata_event_id_(
+ context->storage->InternString("chrome_event.metadata")),
+ raw_chrome_legacy_system_trace_event_id_(
+ context->storage->InternString("chrome_event.legacy_system_trace")),
+ raw_chrome_legacy_user_trace_event_id_(
+ context->storage->InternString("chrome_event.legacy_user_trace")) {
+ // TODO(140860736): Once we support null values for
+ // stack_profile_frame.symbol_set_id remove this hack
+ context_->storage->mutable_symbol_table()->Insert({0, 0, 0, 0});
+}
+
+ProtoTraceParser::~ProtoTraceParser() = default;
+
+void ProtoTraceParser::ParseTracePacket(int64_t ts, TimestampedTracePiece ttp) {
+ PERFETTO_DCHECK(ttp.json_value == nullptr);
+
+ const TraceBlobView& blob = ttp.blob_view;
+ protos::pbzero::TracePacket::Decoder packet(blob.data(), blob.length());
+
+ ParseTracePacketImpl(ts, std::move(ttp), packet);
+
+ // TODO(lalitm): maybe move this to the flush method in the trace processor
+ // once we have it. This may reduce performance in the ArgsTracker though so
+ // needs to be handled carefully.
+ context_->args_tracker->Flush();
+ PERFETTO_DCHECK(!packet.bytes_left());
+}
+
+void ProtoTraceParser::ParseTracePacketImpl(
+ int64_t ts,
+ TimestampedTracePiece ttp,
+ const protos::pbzero::TracePacket::Decoder& packet) {
+ // TODO(eseckler): Propagate statuses from modules.
+ if (!context_->ftrace_module->ParsePacket(packet, ttp).ignored())
+ return;
+
+ if (!context_->track_event_module->ParsePacket(packet, ttp).ignored())
+ return;
+
+ if (!context_->systrace_module->ParsePacket(packet, ttp).ignored())
+ return;
+
+ if (!context_->android_probes_module->ParsePacket(packet, ttp).ignored())
+ return;
+
+ if (!context_->graphics_event_module->ParsePacket(packet, ttp).ignored())
+ return;
+
+ if (packet.has_trace_stats())
+ ParseTraceStats(packet.trace_stats());
+
+ if (packet.has_profile_packet()) {
+ ParseProfilePacket(ts, ttp.packet_sequence_state,
+ ttp.packet_sequence_state_generation,
+ packet.profile_packet());
+ }
+
+ if (packet.has_streaming_profile_packet()) {
+ ParseStreamingProfilePacket(ttp.packet_sequence_state,
+ ttp.packet_sequence_state_generation,
+ packet.streaming_profile_packet());
+ }
+
+ if (packet.has_chrome_benchmark_metadata()) {
+ ParseChromeBenchmarkMetadata(packet.chrome_benchmark_metadata());
+ }
+
+ if (packet.has_chrome_events()) {
+ ParseChromeEvents(ts, packet.chrome_events());
+ }
+
+ if (packet.has_perfetto_metatrace()) {
+ ParseMetatraceEvent(ts, packet.perfetto_metatrace());
+ }
+
+ if (packet.has_trace_config()) {
+ ParseTraceConfig(packet.trace_config());
+ }
+
+ if (packet.has_module_symbols()) {
+ ParseModuleSymbols(packet.module_symbols());
+ }
+
+ if (packet.has_heap_graph()) {
+ ParseHeapGraph(ts, packet.heap_graph());
+ }
+}
+
+void ProtoTraceParser::ParseFtracePacket(uint32_t cpu,
+ int64_t /*ts*/,
+ TimestampedTracePiece ttp) {
+ PERFETTO_DCHECK(ttp.json_value == nullptr);
+
+ ModuleResult res = context_->ftrace_module->ParseFtracePacket(cpu, ttp);
+ PERFETTO_DCHECK(!res.ignored());
+ // TODO(eseckler): Propagate status.
+ if (!res.ok()) {
+ PERFETTO_ELOG("%s", res.message().c_str());
+ }
+
+ // TODO(lalitm): maybe move this to the flush method in the trace processor
+ // once we have it. This may reduce performance in the ArgsTracker though so
+ // needs to be handled carefully.
+ context_->args_tracker->Flush();
+}
+
+void ProtoTraceParser::ParseTraceStats(ConstBytes blob) {
+ protos::pbzero::TraceStats::Decoder evt(blob.data, blob.size);
+ auto* storage = context_->storage.get();
+ storage->SetStats(stats::traced_producers_connected,
+ static_cast<int64_t>(evt.producers_connected()));
+ storage->SetStats(stats::traced_data_sources_registered,
+ static_cast<int64_t>(evt.data_sources_registered()));
+ storage->SetStats(stats::traced_data_sources_seen,
+ static_cast<int64_t>(evt.data_sources_seen()));
+ storage->SetStats(stats::traced_tracing_sessions,
+ static_cast<int64_t>(evt.tracing_sessions()));
+ storage->SetStats(stats::traced_total_buffers,
+ static_cast<int64_t>(evt.total_buffers()));
+ storage->SetStats(stats::traced_chunks_discarded,
+ static_cast<int64_t>(evt.chunks_discarded()));
+ storage->SetStats(stats::traced_patches_discarded,
+ static_cast<int64_t>(evt.patches_discarded()));
+
+ int buf_num = 0;
+ for (auto it = evt.buffer_stats(); it; ++it, ++buf_num) {
+ protos::pbzero::TraceStats::BufferStats::Decoder buf(*it);
+ storage->SetIndexedStats(stats::traced_buf_buffer_size, buf_num,
+ static_cast<int64_t>(buf.buffer_size()));
+ storage->SetIndexedStats(stats::traced_buf_bytes_written, buf_num,
+ static_cast<int64_t>(buf.bytes_written()));
+ storage->SetIndexedStats(stats::traced_buf_bytes_overwritten, buf_num,
+ static_cast<int64_t>(buf.bytes_overwritten()));
+ storage->SetIndexedStats(stats::traced_buf_bytes_read, buf_num,
+ static_cast<int64_t>(buf.bytes_read()));
+ storage->SetIndexedStats(stats::traced_buf_padding_bytes_written, buf_num,
+ static_cast<int64_t>(buf.padding_bytes_written()));
+ storage->SetIndexedStats(stats::traced_buf_padding_bytes_cleared, buf_num,
+ static_cast<int64_t>(buf.padding_bytes_cleared()));
+ storage->SetIndexedStats(stats::traced_buf_chunks_written, buf_num,
+ static_cast<int64_t>(buf.chunks_written()));
+ storage->SetIndexedStats(stats::traced_buf_chunks_rewritten, buf_num,
+ static_cast<int64_t>(buf.chunks_rewritten()));
+ storage->SetIndexedStats(stats::traced_buf_chunks_overwritten, buf_num,
+ static_cast<int64_t>(buf.chunks_overwritten()));
+ storage->SetIndexedStats(stats::traced_buf_chunks_discarded, buf_num,
+ static_cast<int64_t>(buf.chunks_discarded()));
+ storage->SetIndexedStats(stats::traced_buf_chunks_read, buf_num,
+ static_cast<int64_t>(buf.chunks_read()));
+ storage->SetIndexedStats(
+ stats::traced_buf_chunks_committed_out_of_order, buf_num,
+ static_cast<int64_t>(buf.chunks_committed_out_of_order()));
+ storage->SetIndexedStats(stats::traced_buf_write_wrap_count, buf_num,
+ static_cast<int64_t>(buf.write_wrap_count()));
+ storage->SetIndexedStats(stats::traced_buf_patches_succeeded, buf_num,
+ static_cast<int64_t>(buf.patches_succeeded()));
+ storage->SetIndexedStats(stats::traced_buf_patches_failed, buf_num,
+ static_cast<int64_t>(buf.patches_failed()));
+ storage->SetIndexedStats(stats::traced_buf_readaheads_succeeded, buf_num,
+ static_cast<int64_t>(buf.readaheads_succeeded()));
+ storage->SetIndexedStats(stats::traced_buf_readaheads_failed, buf_num,
+ static_cast<int64_t>(buf.readaheads_failed()));
+ storage->SetIndexedStats(
+ stats::traced_buf_trace_writer_packet_loss, buf_num,
+ static_cast<int64_t>(buf.trace_writer_packet_loss()));
+ }
+}
+
+void ProtoTraceParser::ParseProfilePacket(int64_t,
+ PacketSequenceState* sequence_state,
+ size_t sequence_state_generation,
+ ConstBytes blob) {
+ protos::pbzero::ProfilePacket::Decoder packet(blob.data, blob.size);
+ context_->heap_profile_tracker->SetProfilePacketIndex(packet.index());
+
+ for (auto it = packet.strings(); it; ++it) {
+ protos::pbzero::InternedString::Decoder entry(*it);
+
+ const char* str = reinterpret_cast<const char*>(entry.str().data);
+ auto str_view = base::StringView(str, entry.str().size);
+ sequence_state->stack_profile_tracker().AddString(entry.iid(), str_view);
+ }
+
+ for (auto it = packet.mappings(); it; ++it) {
+ protos::pbzero::Mapping::Decoder entry(*it);
+ StackProfileTracker::SourceMapping src_mapping = MakeSourceMapping(entry);
+ sequence_state->stack_profile_tracker().AddMapping(entry.iid(),
+ src_mapping);
+ }
+
+ for (auto it = packet.frames(); it; ++it) {
+ protos::pbzero::Frame::Decoder entry(*it);
+ StackProfileTracker::SourceFrame src_frame = MakeSourceFrame(entry);
+ sequence_state->stack_profile_tracker().AddFrame(entry.iid(), src_frame);
+ }
+
+ for (auto it = packet.callstacks(); it; ++it) {
+ protos::pbzero::Callstack::Decoder entry(*it);
+ StackProfileTracker::SourceCallstack src_callstack =
+ MakeSourceCallstack(entry);
+ sequence_state->stack_profile_tracker().AddCallstack(entry.iid(),
+ src_callstack);
+ }
+
+ for (auto it = packet.process_dumps(); it; ++it) {
+ protos::pbzero::ProfilePacket::ProcessHeapSamples::Decoder entry(*it);
+
+ int pid = static_cast<int>(entry.pid());
+
+ if (entry.buffer_corrupted())
+ context_->storage->IncrementIndexedStats(
+ stats::heapprofd_buffer_corrupted, pid);
+ if (entry.buffer_overran())
+ context_->storage->IncrementIndexedStats(stats::heapprofd_buffer_overran,
+ pid);
+ if (entry.rejected_concurrent())
+ context_->storage->IncrementIndexedStats(
+ stats::heapprofd_rejected_concurrent, pid);
+
+ for (auto sample_it = entry.samples(); sample_it; ++sample_it) {
+ protos::pbzero::ProfilePacket::HeapSample::Decoder sample(*sample_it);
+
+ HeapProfileTracker::SourceAllocation src_allocation;
+ src_allocation.pid = entry.pid();
+ src_allocation.timestamp = static_cast<int64_t>(entry.timestamp());
+ src_allocation.callstack_id = sample.callstack_id();
+ src_allocation.self_allocated = sample.self_allocated();
+ src_allocation.self_freed = sample.self_freed();
+ src_allocation.alloc_count = sample.alloc_count();
+ src_allocation.free_count = sample.free_count();
+
+ context_->heap_profile_tracker->StoreAllocation(src_allocation);
+ }
+ }
+ if (!packet.continued()) {
+ PERFETTO_CHECK(sequence_state);
+ ProfilePacketInternLookup intern_lookup(sequence_state,
+ sequence_state_generation);
+ context_->heap_profile_tracker->FinalizeProfile(
+ &sequence_state->stack_profile_tracker(), &intern_lookup);
+ }
+}
+
+void ProtoTraceParser::ParseStreamingProfilePacket(
+ PacketSequenceState* sequence_state,
+ size_t sequence_state_generation,
+ ConstBytes blob) {
+ protos::pbzero::StreamingProfilePacket::Decoder packet(blob.data, blob.size);
+
+ ProcessTracker* procs = context_->process_tracker.get();
+ TraceStorage* storage = context_->storage.get();
+ StackProfileTracker& stack_profile_tracker =
+ sequence_state->stack_profile_tracker();
+ ProfilePacketInternLookup intern_lookup(sequence_state,
+ sequence_state_generation);
+
+ uint32_t pid = static_cast<uint32_t>(sequence_state->pid());
+ uint32_t tid = static_cast<uint32_t>(sequence_state->tid());
+ UniqueTid utid = procs->UpdateThread(tid, pid);
+
+ auto timestamp_it = packet.timestamp_delta_us();
+ for (auto callstack_it = packet.callstack_iid(); callstack_it;
+ ++callstack_it, ++timestamp_it) {
+ if (!timestamp_it) {
+ context_->storage->IncrementStats(stats::stackprofile_parser_error);
+ PERFETTO_ELOG(
+ "StreamingProfilePacket has less callstack IDs than timestamps!");
+ break;
+ }
+
+ auto maybe_callstack_id =
+ stack_profile_tracker.FindCallstack(*callstack_it, &intern_lookup);
+ if (!maybe_callstack_id) {
+ context_->storage->IncrementStats(stats::stackprofile_parser_error);
+ PERFETTO_ELOG("StreamingProfilePacket referencing invalid callstack!");
+ continue;
+ }
+
+ int64_t callstack_id = *maybe_callstack_id;
+
+ TraceStorage::CpuProfileStackSamples::Row sample_row{
+ sequence_state->IncrementAndGetTrackEventTimeNs(*timestamp_it),
+ callstack_id, utid};
+ storage->mutable_cpu_profile_stack_samples()->Insert(sample_row);
+ }
+}
+
+void ProtoTraceParser::ParseChromeBenchmarkMetadata(ConstBytes blob) {
+ TraceStorage* storage = context_->storage.get();
+ protos::pbzero::ChromeBenchmarkMetadata::Decoder packet(blob.data, blob.size);
+ if (packet.has_benchmark_name()) {
+ auto benchmark_name_id = storage->InternString(packet.benchmark_name());
+ storage->SetMetadata(metadata::benchmark_name,
+ Variadic::String(benchmark_name_id));
+ }
+ if (packet.has_benchmark_description()) {
+ auto benchmark_description_id =
+ storage->InternString(packet.benchmark_description());
+ storage->SetMetadata(metadata::benchmark_description,
+ Variadic::String(benchmark_description_id));
+ }
+ if (packet.has_label()) {
+ auto label_id = storage->InternString(packet.label());
+ storage->SetMetadata(metadata::benchmark_label, Variadic::String(label_id));
+ }
+ if (packet.has_story_name()) {
+ auto story_name_id = storage->InternString(packet.story_name());
+ storage->SetMetadata(metadata::benchmark_story_name,
+ Variadic::String(story_name_id));
+ }
+ for (auto it = packet.story_tags(); it; ++it) {
+ auto story_tag_id = storage->InternString(*it);
+ storage->AppendMetadata(metadata::benchmark_story_tags,
+ Variadic::String(story_tag_id));
+ }
+ if (packet.has_benchmark_start_time_us()) {
+ storage->SetMetadata(metadata::benchmark_start_time_us,
+ Variadic::Integer(packet.benchmark_start_time_us()));
+ }
+ if (packet.has_story_run_time_us()) {
+ storage->SetMetadata(metadata::benchmark_story_run_time_us,
+ Variadic::Integer(packet.story_run_time_us()));
+ }
+ if (packet.has_story_run_index()) {
+ storage->SetMetadata(metadata::benchmark_story_run_index,
+ Variadic::Integer(packet.story_run_index()));
+ }
+ if (packet.has_had_failures()) {
+ storage->SetMetadata(metadata::benchmark_had_failures,
+ Variadic::Integer(packet.had_failures()));
+ }
+}
+
+void ProtoTraceParser::ParseChromeEvents(int64_t ts, ConstBytes blob) {
+ TraceStorage* storage = context_->storage.get();
+ protos::pbzero::ChromeEventBundle::Decoder bundle(blob.data, blob.size);
+ ArgsTracker args(context_);
+ if (bundle.has_metadata()) {
+ RowId row_id = storage->mutable_raw_events()->AddRawEvent(
+ ts, raw_chrome_metadata_event_id_, 0, 0);
+
+ // Metadata is proxied via a special event in the raw table to JSON export.
+ for (auto it = bundle.metadata(); it; ++it) {
+ protos::pbzero::ChromeMetadata::Decoder metadata(*it);
+ StringId name_id = storage->InternString(metadata.name());
+ Variadic value;
+ if (metadata.has_string_value()) {
+ value =
+ Variadic::String(storage->InternString(metadata.string_value()));
+ } else if (metadata.has_int_value()) {
+ value = Variadic::Integer(metadata.int_value());
+ } else if (metadata.has_bool_value()) {
+ value = Variadic::Integer(metadata.bool_value());
+ } else if (metadata.has_json_value()) {
+ value = Variadic::Json(storage->InternString(metadata.json_value()));
+ } else {
+ PERFETTO_FATAL("Empty ChromeMetadata message");
+ }
+ args.AddArg(row_id, name_id, name_id, value);
+ }
+ }
+
+ if (bundle.has_legacy_ftrace_output()) {
+ RowId row_id = storage->mutable_raw_events()->AddRawEvent(
+ ts, raw_chrome_legacy_system_trace_event_id_, 0, 0);
+
+ std::string data;
+ for (auto it = bundle.legacy_ftrace_output(); it; ++it) {
+ data += (*it).ToStdString();
+ }
+ Variadic value =
+ Variadic::String(storage->InternString(base::StringView(data)));
+ args.AddArg(row_id, data_name_id_, data_name_id_, value);
+ }
+
+ if (bundle.has_legacy_json_trace()) {
+ for (auto it = bundle.legacy_json_trace(); it; ++it) {
+ protos::pbzero::ChromeLegacyJsonTrace::Decoder legacy_trace(*it);
+ if (legacy_trace.type() !=
+ protos::pbzero::ChromeLegacyJsonTrace::USER_TRACE) {
+ continue;
+ }
+ RowId row_id = storage->mutable_raw_events()->AddRawEvent(
+ ts, raw_chrome_legacy_user_trace_event_id_, 0, 0);
+ Variadic value =
+ Variadic::String(storage->InternString(legacy_trace.data()));
+ args.AddArg(row_id, data_name_id_, data_name_id_, value);
+ }
+ }
+}
+
+void ProtoTraceParser::ParseMetatraceEvent(int64_t ts, ConstBytes blob) {
+ protos::pbzero::PerfettoMetatrace::Decoder event(blob.data, blob.size);
+ auto utid = context_->process_tracker->GetOrCreateThread(event.thread_id());
+
+ StringId cat_id = metatrace_id_;
+ StringId name_id = 0;
+ char fallback[64];
+
+ if (event.has_event_id()) {
+ auto eid = event.event_id();
+ if (eid < metatrace::EVENTS_MAX) {
+ name_id = context_->storage->InternString(metatrace::kEventNames[eid]);
+ } else {
+ sprintf(fallback, "Event %d", eid);
+ name_id = context_->storage->InternString(fallback);
+ }
+ TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
+ context_->slice_tracker->Scoped(ts, track_id, utid, RefType::kRefUtid,
+ cat_id, name_id, event.event_duration_ns());
+ } else if (event.has_counter_id()) {
+ auto cid = event.counter_id();
+ if (cid < metatrace::COUNTERS_MAX) {
+ name_id = context_->storage->InternString(metatrace::kCounterNames[cid]);
+ } else {
+ sprintf(fallback, "Counter %d", cid);
+ name_id = context_->storage->InternString(fallback);
+ }
+ context_->event_tracker->PushCounter(ts, event.counter_value(), name_id,
+ utid, RefType::kRefUtid);
+ }
+
+ if (event.has_overruns())
+ context_->storage->IncrementStats(stats::metatrace_overruns);
+}
+
+void ProtoTraceParser::ParseTraceConfig(ConstBytes blob) {
+ protos::pbzero::TraceConfig::Decoder trace_config(blob.data, blob.size);
+
+ // TODO(eseckler): Propagate statuses from modules.
+ context_->android_probes_module->ParseTraceConfig(trace_config);
+}
+
+void ProtoTraceParser::ParseModuleSymbols(ConstBytes blob) {
+ protos::pbzero::ModuleSymbols::Decoder module_symbols(blob.data, blob.size);
+ std::string hex_build_id = base::ToHex(module_symbols.build_id().data,
+ module_symbols.build_id().size);
+ auto mapping_rows =
+ context_->storage->stack_profile_mappings().FindMappingRow(
+ context_->storage->InternString(module_symbols.path()),
+ context_->storage->InternString(base::StringView(hex_build_id)));
+ if (mapping_rows.empty()) {
+ context_->storage->IncrementStats(stats::stackprofile_invalid_mapping_id);
+ return;
+ }
+ for (auto addr_it = module_symbols.address_symbols(); addr_it; ++addr_it) {
+ protos::pbzero::AddressSymbols::Decoder address_symbols(*addr_it);
+
+ ssize_t frame_row = -1;
+ for (int64_t mapping_row : mapping_rows) {
+ frame_row = context_->storage->stack_profile_frames().FindFrameRow(
+ static_cast<size_t>(mapping_row), address_symbols.address());
+ if (frame_row != -1)
+ break;
+ }
+ if (frame_row == -1) {
+ context_->storage->IncrementStats(stats::stackprofile_invalid_frame_id);
+ continue;
+ }
+ uint32_t symbol_set_id = context_->storage->symbol_table().size();
+ context_->storage->mutable_stack_profile_frames()->SetSymbolSetId(
+ static_cast<size_t>(frame_row), symbol_set_id);
+ for (auto line_it = address_symbols.lines(); line_it; ++line_it) {
+ protos::pbzero::Line::Decoder line(*line_it);
+ context_->storage->mutable_symbol_table()->Insert(
+ {symbol_set_id, context_->storage->InternString(line.function_name()),
+ context_->storage->InternString(line.source_file_name()),
+ line.line_number()});
+ }
+ }
+}
+
+void ProtoTraceParser::ParseHeapGraph(int64_t ts, ConstBytes blob) {
+ protos::pbzero::HeapGraph::Decoder heap_graph(blob.data, blob.size);
+ UniquePid upid = context_->process_tracker->GetOrCreateProcess(
+ static_cast<uint32_t>(heap_graph.pid()));
+ context_->heap_graph_tracker->SetPacketIndex(heap_graph.index());
+ for (auto it = heap_graph.objects(); it; ++it) {
+ protos::pbzero::HeapGraphObject::Decoder object(*it);
+ HeapGraphTracker::SourceObject obj;
+ obj.object_id = object.id();
+ obj.self_size = object.self_size();
+ obj.type_id = object.type_id();
+ auto ref_field_ids_it = object.reference_field_id();
+ auto ref_object_ids_it = object.reference_object_id();
+ for (; ref_field_ids_it && ref_object_ids_it;
+ ++ref_field_ids_it, ++ref_object_ids_it) {
+ HeapGraphTracker::SourceObject::Reference ref;
+ ref.field_name_id = *ref_field_ids_it;
+ ref.owned_object_id = *ref_object_ids_it;
+ obj.references.emplace_back(std::move(ref));
+ }
+
+ if (ref_field_ids_it || ref_object_ids_it) {
+ context_->storage->IncrementIndexedStats(stats::heap_graph_missing_packet,
+ static_cast<int>(upid));
+ continue;
+ }
+ context_->heap_graph_tracker->AddObject(upid, ts, std::move(obj));
+ }
+ for (auto it = heap_graph.type_names(); it; ++it) {
+ protos::pbzero::InternedString::Decoder entry(*it);
+ const char* str = reinterpret_cast<const char*>(entry.str().data);
+ auto str_view = base::StringView(str, entry.str().size);
+
+ context_->heap_graph_tracker->AddInternedTypeName(
+ entry.iid(), context_->storage->InternString(str_view));
+ }
+ for (auto it = heap_graph.field_names(); it; ++it) {
+ protos::pbzero::InternedString::Decoder entry(*it);
+ const char* str = reinterpret_cast<const char*>(entry.str().data);
+ auto str_view = base::StringView(str, entry.str().size);
+
+ context_->heap_graph_tracker->AddInternedFieldName(
+ entry.iid(), context_->storage->InternString(str_view));
+ }
+ for (auto it = heap_graph.roots(); it; ++it) {
+ protos::pbzero::HeapGraphRoot::Decoder entry(*it);
+ const char* str = HeapGraphRootTypeToString(entry.root_type());
+ auto str_view = base::StringView(str);
+
+ HeapGraphTracker::SourceRoot src_root;
+ src_root.root_type = context_->storage->InternString(str_view);
+ for (auto obj_it = entry.object_ids(); obj_it; ++obj_it)
+ src_root.object_ids.emplace_back(*obj_it);
+ context_->heap_graph_tracker->AddRoot(upid, ts, std::move(src_root));
+ }
+ if (!heap_graph.continued()) {
+ context_->heap_graph_tracker->FinalizeProfile();
+ }
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.h b/src/trace_processor/importers/proto/proto_trace_parser.h
new file mode 100644
index 0000000..745ccc6
--- /dev/null
+++ b/src/trace_processor/importers/proto/proto_trace_parser.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 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_IMPORTERS_PROTO_PROTO_TRACE_PARSER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_PARSER_H_
+
+#include <stdint.h>
+
+#include <array>
+#include <memory>
+
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/protozero/field.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
+#include "src/trace_processor/trace_blob_view.h"
+#include "src/trace_processor/trace_parser.h"
+#include "src/trace_processor/trace_storage.h"
+
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class ArgsTracker;
+class PacketSequenceState;
+class TraceProcessorContext;
+
+class ProtoTraceParser : public TraceParser {
+ public:
+ using ConstBytes = protozero::ConstBytes;
+ explicit ProtoTraceParser(TraceProcessorContext*);
+ ~ProtoTraceParser() override;
+
+ // TraceParser implementation.
+ void ParseTracePacket(int64_t timestamp, TimestampedTracePiece) override;
+ void ParseFtracePacket(uint32_t cpu,
+ int64_t timestamp,
+ TimestampedTracePiece) override;
+
+ void ParseTracePacketImpl(int64_t ts,
+ TimestampedTracePiece,
+ const protos::pbzero::TracePacket::Decoder&);
+
+ void ParseTraceStats(ConstBytes);
+ void ParseProfilePacket(int64_t ts,
+ PacketSequenceState*,
+ size_t sequence_state_generation,
+ ConstBytes);
+ void ParseStreamingProfilePacket(PacketSequenceState*,
+ size_t sequence_state_generation,
+ ConstBytes);
+ void ParseChromeBenchmarkMetadata(ConstBytes);
+ void ParseChromeEvents(int64_t ts, ConstBytes);
+ void ParseMetatraceEvent(int64_t ts, ConstBytes);
+ void ParseTraceConfig(ConstBytes);
+ void ParseModuleSymbols(ConstBytes);
+ void ParseHeapGraph(int64_t ts, ConstBytes);
+
+ private:
+ TraceProcessorContext* context_;
+
+ const StringId metatrace_id_;
+ const StringId data_name_id_;
+ const StringId raw_chrome_metadata_event_id_;
+ const StringId raw_chrome_legacy_system_trace_event_id_;
+ const StringId raw_chrome_legacy_user_trace_event_id_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_PARSER_H_
diff --git a/src/trace_processor/proto_trace_parser_unittest.cc b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
similarity index 97%
rename from src/trace_processor/proto_trace_parser_unittest.cc
rename to src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
index 387fb38..1d92dd6 100644
--- a/src/trace_processor/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/trace_processor/proto_trace_tokenizer.h"
+#include "src/trace_processor/importers/proto/proto_trace_tokenizer.h"
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_view.h"
@@ -24,12 +24,15 @@
#include "src/trace_processor/event_tracker.h"
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
#include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
+#include "src/trace_processor/importers/proto/android_probes_module.h"
+#include "src/trace_processor/importers/proto/graphics_event_module.h"
#include "src/trace_processor/importers/proto/proto_importer_module.h"
+#include "src/trace_processor/importers/proto/proto_trace_parser.h"
+#include "src/trace_processor/importers/proto/system_probes_module.h"
#include "src/trace_processor/importers/proto/track_event_module.h"
#include "src/trace_processor/importers/systrace/systrace_parser.h"
#include "src/trace_processor/metadata.h"
#include "src/trace_processor/process_tracker.h"
-#include "src/trace_processor/proto_trace_parser.h"
#include "src/trace_processor/slice_tracker.h"
#include "src/trace_processor/stack_profile_tracker.h"
#include "src/trace_processor/trace_sorter.h"
@@ -155,6 +158,7 @@
MOCK_METHOD2(UpdateThreadName,
UniqueTid(uint32_t tid, StringId thread_name_id));
+ MOCK_METHOD2(SetThreadName, void(UniqueTid utid, StringId thread_name_id));
MOCK_METHOD2(UpdateThread, UniqueTid(uint32_t tid, uint32_t tgid));
MOCK_METHOD1(GetOrCreateProcess, UniquePid(uint32_t pid));
@@ -253,8 +257,14 @@
context_.vulkan_memory_tracker.reset(new VulkanMemoryTracker(&context_));
context_.ftrace_module.reset(
new ProtoImporterModule<FtraceModule>(&context_));
+ context_.systrace_module.reset(
+ new ProtoImporterModule<SystraceProtoModule>(&context_));
+ context_.android_probes_module.reset(
+ new ProtoImporterModule<AndroidProbesModule>(&context_));
context_.track_event_module.reset(
new ProtoImporterModule<TrackEventModule>(&context_));
+ context_.graphics_event_module.reset(
+ new ProtoImporterModule<GraphicsEventModule>(&context_));
}
void ResetTraceBuffers() {
@@ -266,15 +276,17 @@
void SetUp() override { ResetTraceBuffers(); }
- void Tokenize() {
+ util::Status Tokenize() {
trace_.Finalize();
std::vector<uint8_t> trace_bytes = heap_buf_->StitchSlices();
std::unique_ptr<uint8_t[]> raw_trace(new uint8_t[trace_bytes.size()]);
memcpy(raw_trace.get(), trace_bytes.data(), trace_bytes.size());
context_.chunk_reader.reset(new ProtoTraceTokenizer(&context_));
- context_.chunk_reader->Parse(std::move(raw_trace), trace_bytes.size());
+ auto status =
+ context_.chunk_reader->Parse(std::move(raw_trace), trace_bytes.size());
ResetTraceBuffers();
+ return status;
}
bool HasArg(ArgSetId set_id, StringId key_id, Variadic value) {
@@ -592,6 +604,8 @@
#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_SYSTEM_PROBES)
+
TEST_F(ProtoTraceParserTest, LoadMemInfo) {
auto* packet = trace_.add_packet();
uint64_t ts = 1000;
@@ -663,6 +677,8 @@
Tokenize();
}
+#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_SYSTEM_PROBES)
+
TEST_F(ProtoTraceParserTest, ThreadNameFromThreadDescriptor) {
context_.sorter.reset(new TraceSorter(
&context_, std::numeric_limits<int64_t>::max() /*window size*/));
@@ -700,18 +716,20 @@
thread_desc->set_thread_name("DifferentThreadName");
}
- InSequence in_sequence; // Below slices should be sorted by timestamp.
+ EXPECT_CALL(*process_, UpdateThread(16, 15))
+ .WillRepeatedly(testing::Return(1u));
+ EXPECT_CALL(*process_, UpdateThread(11, 15)).WillOnce(testing::Return(2u));
EXPECT_CALL(*storage_, InternString(base::StringView("OldThreadName")))
.WillOnce(Return(1));
- EXPECT_CALL(*process_, UpdateThreadName(16, StringId(1)));
+ EXPECT_CALL(*process_, SetThreadName(1u, StringId(1)));
// Packet with same thread, but different name should update the name.
EXPECT_CALL(*storage_, InternString(base::StringView("NewThreadName")))
.WillOnce(Return(2));
- EXPECT_CALL(*process_, UpdateThreadName(16, StringId(2)));
+ EXPECT_CALL(*process_, SetThreadName(1u, StringId(2)));
EXPECT_CALL(*storage_, InternString(base::StringView("DifferentThreadName")))
.WillOnce(Return(3));
- EXPECT_CALL(*process_, UpdateThreadName(11, StringId(3)));
+ EXPECT_CALL(*process_, SetThreadName(2u, StringId(3)));
Tokenize();
context_.sorter->ExtractEventsForced();
@@ -1196,8 +1214,7 @@
Tokenize();
- EXPECT_CALL(*process_, UpdateThread(16, 15))
- .WillRepeatedly(Return(1));
+ EXPECT_CALL(*process_, UpdateThread(16, 15)).WillRepeatedly(Return(1));
TraceStorage::Thread thread(16);
thread.upid = 1u;
@@ -2283,6 +2300,30 @@
context_.sorter->ExtractEventsForced();
}
+TEST_F(ProtoTraceParserTest, ParseEventWithClockIdButWithoutClockSnapshot) {
+ context_.sorter.reset(new TraceSorter(
+ &context_, std::numeric_limits<int64_t>::max() /*window size*/));
+
+ {
+ auto* packet = trace_.add_packet();
+ packet->set_timestamp(1000);
+ packet->set_timestamp_clock_id(3);
+ packet->set_trusted_packet_sequence_id(1);
+ auto* bundle = packet->set_chrome_events();
+ auto* metadata = bundle->add_metadata();
+ metadata->set_name("test");
+ metadata->set_int_value(23);
+ }
+
+ util::Status status = Tokenize();
+ EXPECT_TRUE(status.ok());
+ context_.sorter->ExtractEventsForced();
+
+ // Metadata should have created a raw event.
+ const auto& raw_events = storage_->raw_events();
+ EXPECT_EQ(raw_events.raw_event_count(), 1u);
+}
+
TEST_F(ProtoTraceParserTest, ParseChromeMetadataEventIntoRawTable) {
static const char kStringName[] = "string_name";
static const char kStringValue[] = "string_value";
@@ -2294,6 +2335,8 @@
{
auto* packet = trace_.add_packet();
+ packet->set_timestamp(1000);
+ packet->set_timestamp_clock_id(3);
packet->set_trusted_packet_sequence_id(1);
auto* bundle = packet->set_chrome_events();
auto* metadata = bundle->add_metadata();
@@ -2425,6 +2468,7 @@
Variadic::String(3))}));
}
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_ANDROID_PROBES)
TEST_F(ProtoTraceParserTest, AndroidPackagesList) {
auto* packet = trace_.add_packet();
auto* pkg_list = packet->set_packages_list();
@@ -2505,6 +2549,7 @@
false);
EXPECT_EQ(find_arg(second_set_id, "version_code").int_value, 43);
}
+#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_ANDROID_PROBES)
TEST_F(ProtoTraceParserTest, ParseCPUProfileSamplesIntoTable) {
{
diff --git a/src/trace_processor/importers/proto/proto_trace_tokenizer.cc b/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
new file mode 100644
index 0000000..8952957
--- /dev/null
+++ b/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2018 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/importers/proto/proto_trace_tokenizer.h"
+
+#include <string>
+
+#include <zlib.h>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/protozero/proto_decoder.h"
+#include "perfetto/protozero/proto_utils.h"
+#include "perfetto/trace_processor/status.h"
+#include "src/trace_processor/clock_tracker.h"
+#include "src/trace_processor/event_tracker.h"
+#include "src/trace_processor/importers/ftrace/ftrace_module.h"
+#include "src/trace_processor/importers/proto/packet_sequence_state.h"
+#include "src/trace_processor/importers/proto/proto_incremental_state.h"
+#include "src/trace_processor/importers/proto/track_event_module.h"
+#include "src/trace_processor/stats.h"
+#include "src/trace_processor/trace_sorter.h"
+#include "src/trace_processor/trace_storage.h"
+
+#include "protos/perfetto/config/trace_config.pbzero.h"
+#include "protos/perfetto/trace/clock_snapshot.pbzero.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
+#include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
+#include "protos/perfetto/trace/trace.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using protozero::proto_utils::MakeTagLengthDelimited;
+using protozero::proto_utils::ParseVarInt;
+
+namespace {
+
+constexpr uint8_t kTracePacketTag =
+ MakeTagLengthDelimited(protos::pbzero::Trace::kPacketFieldNumber);
+
+TraceBlobView Decompress(TraceBlobView input) {
+ uint8_t out[4096];
+ std::string s;
+
+ z_stream stream{};
+ stream.next_in = const_cast<uint8_t*>(input.data());
+ stream.avail_in = static_cast<unsigned int>(input.length());
+
+ if (inflateInit(&stream) != Z_OK)
+ return TraceBlobView(nullptr, 0, 0);
+
+ int ret;
+ do {
+ stream.next_out = out;
+ stream.avail_out = sizeof(out);
+ ret = inflate(&stream, Z_NO_FLUSH);
+ if (ret != Z_STREAM_END && ret != Z_OK)
+ return TraceBlobView(nullptr, 0, 0);
+ s.append(reinterpret_cast<char*>(out), sizeof(out) - stream.avail_out);
+ } while (ret != Z_STREAM_END);
+ inflateEnd(&stream);
+
+ std::unique_ptr<uint8_t[]> output(new uint8_t[s.size()]);
+ memcpy(output.get(), s.data(), s.size());
+ return TraceBlobView(std::move(output), 0, s.size());
+}
+
+} // namespace
+
+ProtoTraceTokenizer::ProtoTraceTokenizer(TraceProcessorContext* ctx)
+ : context_(ctx) {}
+ProtoTraceTokenizer::~ProtoTraceTokenizer() = default;
+
+util::Status ProtoTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> owned_buf,
+ size_t size) {
+ uint8_t* data = &owned_buf[0];
+ if (!partial_buf_.empty()) {
+ // It takes ~5 bytes for a proto preamble + the varint size.
+ const size_t kHeaderBytes = 5;
+ if (PERFETTO_UNLIKELY(partial_buf_.size() < kHeaderBytes)) {
+ size_t missing_len = std::min(kHeaderBytes - partial_buf_.size(), size);
+ partial_buf_.insert(partial_buf_.end(), &data[0], &data[missing_len]);
+ if (partial_buf_.size() < kHeaderBytes)
+ return util::OkStatus();
+ data += missing_len;
+ size -= missing_len;
+ }
+
+ // At this point we have enough data in |partial_buf_| to read at least the
+ // field header and know the size of the next TracePacket.
+ const uint8_t* pos = &partial_buf_[0];
+ uint8_t proto_field_tag = *pos;
+ uint64_t field_size = 0;
+ const uint8_t* next = ParseVarInt(++pos, &*partial_buf_.end(), &field_size);
+ bool parse_failed = next == pos;
+ pos = next;
+ if (proto_field_tag != kTracePacketTag || field_size == 0 || parse_failed) {
+ return util::ErrStatus(
+ "Failed parsing a TracePacket from the partial buffer");
+ }
+
+ // At this point we know how big the TracePacket is.
+ size_t hdr_size = static_cast<size_t>(pos - &partial_buf_[0]);
+ size_t size_incl_header = static_cast<size_t>(field_size + hdr_size);
+ PERFETTO_DCHECK(size_incl_header > partial_buf_.size());
+
+ // There is a good chance that between the |partial_buf_| and the new |data|
+ // of the current call we have enough bytes to parse a TracePacket.
+ if (partial_buf_.size() + size >= size_incl_header) {
+ // Create a new buffer for the whole TracePacket and copy into that:
+ // 1) The beginning of the TracePacket (including the proto header) from
+ // the partial buffer.
+ // 2) The rest of the TracePacket from the current |data| buffer (note
+ // that we might have consumed already a few bytes form |data| earlier
+ // in this function, hence we need to keep |off| into account).
+ std::unique_ptr<uint8_t[]> buf(new uint8_t[size_incl_header]);
+ memcpy(&buf[0], partial_buf_.data(), partial_buf_.size());
+ // |size_missing| is the number of bytes for the rest of the TracePacket
+ // in |data|.
+ size_t size_missing = size_incl_header - partial_buf_.size();
+ memcpy(&buf[partial_buf_.size()], &data[0], size_missing);
+ data += size_missing;
+ size -= size_missing;
+ partial_buf_.clear();
+ uint8_t* buf_start = &buf[0]; // Note that buf is std::moved below.
+ util::Status status =
+ ParseInternal(std::move(buf), buf_start, size_incl_header);
+ if (PERFETTO_UNLIKELY(!status.ok()))
+ return status;
+ } else {
+ partial_buf_.insert(partial_buf_.end(), data, &data[size]);
+ return util::OkStatus();
+ }
+ }
+ return ParseInternal(std::move(owned_buf), data, size);
+}
+
+util::Status ProtoTraceTokenizer::ParseInternal(
+ std::unique_ptr<uint8_t[]> owned_buf,
+ uint8_t* data,
+ size_t size) {
+ PERFETTO_DCHECK(data >= &owned_buf[0]);
+ const uint8_t* start = &owned_buf[0];
+ const size_t data_off = static_cast<size_t>(data - start);
+ TraceBlobView whole_buf(std::move(owned_buf), data_off, size);
+
+ protos::pbzero::Trace::Decoder decoder(data, size);
+ for (auto it = decoder.packet(); it; ++it) {
+ protozero::ConstBytes packet = *it;
+ size_t field_offset = whole_buf.offset_of(packet.data);
+ util::Status status =
+ ParsePacket(whole_buf.slice(field_offset, packet.size));
+ if (PERFETTO_UNLIKELY(!status.ok()))
+ return status;
+ }
+
+ const size_t bytes_left = decoder.bytes_left();
+ if (bytes_left > 0) {
+ PERFETTO_DCHECK(partial_buf_.empty());
+ partial_buf_.insert(partial_buf_.end(), &data[decoder.read_offset()],
+ &data[decoder.read_offset() + bytes_left]);
+ }
+ return util::OkStatus();
+}
+
+util::Status ProtoTraceTokenizer::ParsePacket(TraceBlobView packet) {
+ protos::pbzero::TracePacket::Decoder decoder(packet.data(), packet.length());
+ if (PERFETTO_UNLIKELY(decoder.bytes_left()))
+ return util::ErrStatus(
+ "Failed to parse proto packet fully; the trace is probably corrupt.");
+
+ auto timestamp =
+ decoder.has_timestamp()
+ ? static_cast<int64_t>(decoder.timestamp())
+ : std::max(latest_timestamp_, context_->sorter->max_timestamp());
+
+ const uint32_t seq_id = decoder.trusted_packet_sequence_id();
+
+ if ((decoder.has_chrome_events() || decoder.has_chrome_metadata()) &&
+ (!decoder.timestamp_clock_id() ||
+ decoder.timestamp_clock_id() ==
+ protos::pbzero::ClockSnapshot::Clock::MONOTONIC)) {
+ // Chrome event timestamps are in MONOTONIC domain, but may occur in traces
+ // where (a) no clock snapshots exist or (b) no clock_id is specified for
+ // their timestamps. Adjust to trace time if we have a clock snapshot.
+ // TODO(eseckler): Set timestamp_clock_id and emit ClockSnapshots in chrome
+ // and then remove this.
+ auto trace_ts = context_->clock_tracker->ToTraceTime(
+ protos::pbzero::ClockSnapshot::Clock::MONOTONIC, timestamp);
+ if (trace_ts.has_value())
+ timestamp = trace_ts.value();
+ } else if (decoder.timestamp_clock_id()) {
+ // If the TracePacket specifies a non-zero clock-id, translate the timestamp
+ // into the trace-time clock domain.
+ PERFETTO_DCHECK(decoder.has_timestamp());
+ ClockTracker::ClockId clock_id = decoder.timestamp_clock_id();
+ bool is_seq_scoped = ClockTracker::IsReservedSeqScopedClockId(clock_id);
+ if (is_seq_scoped) {
+ if (!seq_id) {
+ return util::ErrStatus(
+ "TracePacket specified a sequence-local clock id (%" PRIu32
+ ") but the TraceWriter's sequence_id is zero (the service is "
+ "probably too old)",
+ decoder.timestamp_clock_id());
+ }
+ clock_id = ClockTracker::SeqScopedClockIdToGlobal(
+ seq_id, decoder.timestamp_clock_id());
+ }
+ auto trace_ts = context_->clock_tracker->ToTraceTime(clock_id, timestamp);
+ if (!trace_ts.has_value()) {
+ // ToTraceTime() will increase the |clock_sync_failure| stat on failure.
+ static const char seq_extra_err[] =
+ " Because the clock id is sequence-scoped, the ClockSnapshot must be "
+ "emitted on the same TraceWriter sequence of the packet that refers "
+ "to that clock id.";
+ return util::ErrStatus(
+ "Failed to convert TracePacket's timestamp from clock_id=%" PRIu32
+ " seq_id=%" PRIu32
+ ". This is usually due to the lack of a prior ClockSnapshot proto.%s",
+ decoder.timestamp_clock_id(), seq_id,
+ is_seq_scoped ? seq_extra_err : "");
+ }
+ timestamp = trace_ts.value();
+ }
+ latest_timestamp_ = std::max(timestamp, latest_timestamp_);
+
+ auto* state = GetIncrementalStateForPacketSequence(
+ decoder.trusted_packet_sequence_id());
+
+ uint32_t sequence_flags = decoder.sequence_flags();
+
+ if (decoder.incremental_state_cleared() ||
+ sequence_flags &
+ protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
+ HandleIncrementalStateCleared(decoder);
+ } else if (decoder.previous_packet_dropped()) {
+ HandlePreviousPacketDropped(decoder);
+ }
+
+ if (decoder.sequence_flags() &
+ protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE) {
+ if (!seq_id) {
+ return util::ErrStatus(
+ "TracePacket specified SEQ_NEEDS_INCREMENTAL_STATE but the "
+ "TraceWriter's sequence_id is zero (the service is "
+ "probably too old)");
+ }
+
+ if (!state->IsIncrementalStateValid()) {
+ context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
+ return util::OkStatus();
+ }
+ }
+
+ if (decoder.has_clock_snapshot()) {
+ return ParseClockSnapshot(decoder.clock_snapshot(),
+ decoder.trusted_packet_sequence_id());
+ }
+
+ // TODO(eseckler): Parse TracePacketDefaults.
+
+ if (decoder.has_interned_data()) {
+ auto field = decoder.interned_data();
+ const size_t offset = packet.offset_of(field.data);
+ ParseInternedData(decoder, packet.slice(offset, field.size));
+ }
+
+ ModuleResult res = ModuleResult::Ignored();
+ res = context_->ftrace_module->TokenizePacket(decoder, &packet, timestamp,
+ state);
+ if (!res.ignored())
+ return res.ToStatus();
+
+ res = context_->track_event_module->TokenizePacket(decoder, &packet,
+ timestamp, state);
+ if (!res.ignored())
+ return res.ToStatus();
+
+ if (decoder.has_compressed_packets()) {
+ protozero::ConstBytes field = decoder.compressed_packets();
+ const size_t field_off = packet.offset_of(field.data);
+ TraceBlobView compressed_packets = packet.slice(field_off, field.size);
+ TraceBlobView packets = Decompress(std::move(compressed_packets));
+
+ const uint8_t* start = packets.data();
+ const uint8_t* end = packets.data() + packets.length();
+ const uint8_t* ptr = start;
+ while ((end - ptr) > 2) {
+ const uint8_t* packet_start = ptr;
+ if (PERFETTO_UNLIKELY(*ptr != kTracePacketTag))
+ return util::ErrStatus("Expected TracePacket tag");
+ uint64_t packet_size = 0;
+ ptr = ParseVarInt(++ptr, end, &packet_size);
+ size_t packet_offset = static_cast<size_t>(ptr - start);
+ ptr += packet_size;
+ if (PERFETTO_UNLIKELY((ptr - packet_start) < 2 || ptr > end))
+ return util::ErrStatus("Invalid packet size");
+ util::Status status = ParsePacket(
+ packets.slice(packet_offset, static_cast<size_t>(packet_size)));
+ if (PERFETTO_UNLIKELY(!status.ok()))
+ return status;
+ }
+
+ return util::OkStatus();
+ }
+
+ // If we're not forcing a full sort and this is a write_into_file trace, then
+ // use flush_period_ms as an indiciator for how big the sliding window for the
+ // sorter should be.
+ if (!context_->config.force_full_sort && decoder.has_trace_config()) {
+ auto config = decoder.trace_config();
+ protos::pbzero::TraceConfig::Decoder trace_config(config.data, config.size);
+
+ if (trace_config.write_into_file()) {
+ int64_t window_size_ns;
+ if (trace_config.has_flush_period_ms() &&
+ trace_config.flush_period_ms() > 0) {
+ // We use 2x the flush period as a margin of error to allow for any
+ // late flush responses to still be sorted correctly.
+ window_size_ns = static_cast<int64_t>(trace_config.flush_period_ms()) *
+ 2 * 1000 * 1000;
+ } else {
+ constexpr uint64_t kDefaultWindowNs =
+ 180 * 1000 * 1000 * 1000ULL; // 3 minutes.
+ PERFETTO_ELOG(
+ "It is strongly recommended to have flush_period_ms set when "
+ "write_into_file is turned on. You will likely have many dropped "
+ "events because of inability to sort the events correctly.");
+ window_size_ns = static_cast<int64_t>(kDefaultWindowNs);
+ }
+ context_->sorter->SetWindowSizeNs(window_size_ns);
+ }
+ }
+
+ // Use parent data and length because we want to parse this again
+ // later to get the exact type of the packet.
+ context_->sorter->PushTracePacket(timestamp, state, std::move(packet));
+
+ return util::OkStatus();
+}
+
+void ProtoTraceTokenizer::HandleIncrementalStateCleared(
+ const protos::pbzero::TracePacket::Decoder& packet_decoder) {
+ if (PERFETTO_UNLIKELY(!packet_decoder.has_trusted_packet_sequence_id())) {
+ PERFETTO_ELOG(
+ "incremental_state_cleared without trusted_packet_sequence_id");
+ context_->storage->IncrementStats(stats::interned_data_tokenizer_errors);
+ return;
+ }
+ GetIncrementalStateForPacketSequence(
+ packet_decoder.trusted_packet_sequence_id())
+ ->OnIncrementalStateCleared();
+}
+
+void ProtoTraceTokenizer::HandlePreviousPacketDropped(
+ const protos::pbzero::TracePacket::Decoder& packet_decoder) {
+ if (PERFETTO_UNLIKELY(!packet_decoder.has_trusted_packet_sequence_id())) {
+ PERFETTO_ELOG("previous_packet_dropped without trusted_packet_sequence_id");
+ context_->storage->IncrementStats(stats::interned_data_tokenizer_errors);
+ return;
+ }
+ GetIncrementalStateForPacketSequence(
+ packet_decoder.trusted_packet_sequence_id())
+ ->OnPacketLoss();
+}
+
+void ProtoTraceTokenizer::ParseInternedData(
+ const protos::pbzero::TracePacket::Decoder& packet_decoder,
+ TraceBlobView interned_data) {
+ if (PERFETTO_UNLIKELY(!packet_decoder.has_trusted_packet_sequence_id())) {
+ PERFETTO_ELOG("InternedData packet without trusted_packet_sequence_id");
+ context_->storage->IncrementStats(stats::interned_data_tokenizer_errors);
+ return;
+ }
+
+ auto* state = GetIncrementalStateForPacketSequence(
+ packet_decoder.trusted_packet_sequence_id());
+
+ // Don't parse interned data entries until incremental state is valid, because
+ // they could otherwise be associated with the wrong generation in the state.
+ if (!state->IsIncrementalStateValid()) {
+ context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
+ return;
+ }
+
+ // Store references to interned data submessages into the sequence's state.
+ protozero::ProtoDecoder decoder(interned_data.data(), interned_data.length());
+ for (protozero::Field f = decoder.ReadField(); f.valid();
+ f = decoder.ReadField()) {
+ auto bytes = f.as_bytes();
+ auto offset = interned_data.offset_of(bytes.data);
+ state->InternMessage(f.id(), interned_data.slice(offset, bytes.size));
+ }
+}
+
+util::Status ProtoTraceTokenizer::ParseClockSnapshot(ConstBytes blob,
+ uint32_t seq_id) {
+ std::map<ClockTracker::ClockId, int64_t> clock_map;
+ protos::pbzero::ClockSnapshot::Decoder evt(blob.data, blob.size);
+ for (auto it = evt.clocks(); it; ++it) {
+ protos::pbzero::ClockSnapshot::Clock::Decoder clk(*it);
+ ClockTracker::ClockId clock_id = clk.clock_id();
+ if (ClockTracker::IsReservedSeqScopedClockId(clk.clock_id())) {
+ if (!seq_id) {
+ return util::ErrStatus(
+ "ClockSnapshot packet is specifying a sequence-scoped clock id "
+ "(%" PRIu64 ") but the TracePacket sequence_id is zero",
+ clock_id);
+ }
+ clock_id = ClockTracker::SeqScopedClockIdToGlobal(seq_id, clk.clock_id());
+ }
+ clock_map[clock_id] = static_cast<int64_t>(clk.timestamp());
+ }
+ context_->clock_tracker->AddSnapshot(clock_map);
+ return util::OkStatus();
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/proto_trace_tokenizer.h b/src/trace_processor/importers/proto/proto_trace_tokenizer.h
similarity index 74%
rename from src/trace_processor/proto_trace_tokenizer.h
rename to src/trace_processor/importers/proto/proto_trace_tokenizer.h
index 40564f3..e86675e 100644
--- a/src/trace_processor/proto_trace_tokenizer.h
+++ b/src/trace_processor/importers/proto/proto_trace_tokenizer.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef SRC_TRACE_PROCESSOR_PROTO_TRACE_TOKENIZER_H_
-#define SRC_TRACE_PROCESSOR_PROTO_TRACE_TOKENIZER_H_
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_TOKENIZER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_TOKENIZER_H_
#include <stdint.h>
@@ -23,12 +23,10 @@
#include <vector>
#include "src/trace_processor/chunked_trace_reader.h"
-#include "src/trace_processor/proto_incremental_state.h"
+#include "src/trace_processor/importers/proto/proto_incremental_state.h"
+#include "src/trace_processor/trace_blob_view.h"
#include "src/trace_processor/trace_processor_impl.h"
-#include "protos/perfetto/trace/trace_packet.pbzero.h"
-#include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
-
namespace protozero {
struct ConstBytes;
}
@@ -36,8 +34,8 @@
namespace perfetto {
namespace trace_processor {
+class PacketSequenceState;
class TraceProcessorContext;
-class TraceBlobView;
class TraceSorter;
class TraceStorage;
@@ -65,17 +63,8 @@
void HandlePreviousPacketDropped(const protos::pbzero::TracePacket::Decoder&);
void ParseInternedData(const protos::pbzero::TracePacket::Decoder&,
TraceBlobView interned_data);
- void ParseTrackDescriptorPacket(const protos::pbzero::TracePacket::Decoder&);
- void ParseProcessDescriptorPacket(
- const protos::pbzero::TracePacket::Decoder&);
- void ParseThreadDescriptorPacket(const protos::pbzero::TracePacket::Decoder&);
- void ParseThreadDescriptor(const protos::pbzero::ThreadDescriptor::Decoder&);
- void ParseTrackEventPacket(const protos::pbzero::TracePacket::Decoder&,
- TraceBlobView packet,
- int64_t packet_timestamp);
-
- ProtoIncrementalState::PacketSequenceState*
- GetIncrementalStateForPacketSequence(uint32_t sequence_id) {
+ PacketSequenceState* GetIncrementalStateForPacketSequence(
+ uint32_t sequence_id) {
if (!incremental_state)
incremental_state.reset(new ProtoIncrementalState(context_));
return incremental_state->GetOrCreateStateForPacketSequence(sequence_id);
@@ -99,4 +88,4 @@
} // namespace trace_processor
} // namespace perfetto
-#endif // SRC_TRACE_PROCESSOR_PROTO_TRACE_TOKENIZER_H_
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_TOKENIZER_H_
diff --git a/src/trace_processor/importers/proto/system_probes_module.h b/src/trace_processor/importers/proto/system_probes_module.h
new file mode 100644
index 0000000..c09e69b
--- /dev/null
+++ b/src/trace_processor/importers/proto/system_probes_module.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_SYSTEM_PROBES_MODULE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_SYSTEM_PROBES_MODULE_H_
+
+#include "perfetto/base/build_config.h"
+#include "src/trace_processor/importers/proto/proto_importer_module.h"
+#include "src/trace_processor/importers/proto/system_probes_parser.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class SystraceProtoModule : public ProtoImporterModuleBase<PERFETTO_BUILDFLAG(
+ PERFETTO_TP_SYSTEM_PROBES)> {
+ public:
+ explicit SystraceProtoModule(TraceProcessorContext* context)
+ : ProtoImporterModuleBase(context), parser_(context) {}
+
+ ModuleResult ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp) {
+ if (decoder.has_process_tree()) {
+ parser_.ParseProcessTree(decoder.process_tree());
+ return ModuleResult::Handled();
+ }
+
+ if (decoder.has_process_stats()) {
+ parser_.ParseProcessStats(ttp.timestamp, decoder.process_stats());
+ return ModuleResult::Handled();
+ }
+
+ if (decoder.has_sys_stats()) {
+ parser_.ParseSysStats(ttp.timestamp, decoder.sys_stats());
+ return ModuleResult::Handled();
+ }
+
+ if (decoder.has_system_info()) {
+ parser_.ParseSystemInfo(decoder.system_info());
+ return ModuleResult::Handled();
+ }
+
+ return ModuleResult::Ignored();
+ }
+
+ private:
+ SystraceProtoParser parser_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_SYSTEM_PROBES_MODULE_H_
diff --git a/src/trace_processor/importers/proto/system_probes_parser.cc b/src/trace_processor/importers/proto/system_probes_parser.cc
new file mode 100644
index 0000000..b2787ff
--- /dev/null
+++ b/src/trace_processor/importers/proto/system_probes_parser.cc
@@ -0,0 +1,281 @@
+/*
+ * 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/importers/proto/system_probes_parser.h"
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/traced/sys_stats_counters.h"
+#include "perfetto/protozero/proto_decoder.h"
+#include "src/trace_processor/event_tracker.h"
+#include "src/trace_processor/process_tracker.h"
+#include "src/trace_processor/syscall_tracker.h"
+#include "src/trace_processor/trace_processor_context.h"
+
+#include "protos/perfetto/trace/ps/process_stats.pbzero.h"
+#include "protos/perfetto/trace/ps/process_tree.pbzero.h"
+#include "protos/perfetto/trace/sys_stats/sys_stats.pbzero.h"
+#include "protos/perfetto/trace/system_info.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+namespace {
+// kthreadd is the parent process for all kernel threads and always has
+// pid == 2 on Linux and Android.
+const uint32_t kKthreaddPid = 2;
+const char kKthreaddName[] = "kthreadd";
+} // namespace
+
+SystraceProtoParser::SystraceProtoParser(TraceProcessorContext* context)
+ : context_(context),
+ utid_name_id_(context->storage->InternString("utid")),
+ num_forks_name_id_(context->storage->InternString("num_forks")),
+ num_irq_total_name_id_(context->storage->InternString("num_irq_total")),
+ num_softirq_total_name_id_(
+ context->storage->InternString("num_softirq_total")),
+ num_irq_name_id_(context->storage->InternString("num_irq")),
+ num_softirq_name_id_(context->storage->InternString("num_softirq")),
+ cpu_times_user_ns_id_(
+ context->storage->InternString("cpu.times.user_ns")),
+ cpu_times_user_nice_ns_id_(
+ context->storage->InternString("cpu.times.user_nice_ns")),
+ cpu_times_system_mode_ns_id_(
+ context->storage->InternString("cpu.times.system_mode_ns")),
+ cpu_times_idle_ns_id_(
+ context->storage->InternString("cpu.times.idle_ns")),
+ cpu_times_io_wait_ns_id_(
+ context->storage->InternString("cpu.times.io_wait_ns")),
+ cpu_times_irq_ns_id_(context->storage->InternString("cpu.times.irq_ns")),
+ cpu_times_softirq_ns_id_(
+ context->storage->InternString("cpu.times.softirq_ns")),
+ oom_score_adj_id_(context->storage->InternString("oom_score_adj")) {
+ for (const auto& name : BuildMeminfoCounterNames()) {
+ meminfo_strs_id_.emplace_back(context->storage->InternString(name));
+ }
+ for (const auto& name : BuildVmstatCounterNames()) {
+ vmstat_strs_id_.emplace_back(context->storage->InternString(name));
+ }
+
+ using ProcessStats = protos::pbzero::ProcessStats;
+ proc_stats_process_names_[ProcessStats::Process::kVmSizeKbFieldNumber] =
+ context->storage->InternString("mem.virt");
+ proc_stats_process_names_[ProcessStats::Process::kVmRssKbFieldNumber] =
+ context->storage->InternString("mem.rss");
+ proc_stats_process_names_[ProcessStats::Process::kRssAnonKbFieldNumber] =
+ context->storage->InternString("mem.rss.anon");
+ proc_stats_process_names_[ProcessStats::Process::kRssFileKbFieldNumber] =
+ context->storage->InternString("mem.rss.file");
+ proc_stats_process_names_[ProcessStats::Process::kRssShmemKbFieldNumber] =
+ context->storage->InternString("mem.rss.shmem");
+ proc_stats_process_names_[ProcessStats::Process::kVmSwapKbFieldNumber] =
+ context->storage->InternString("mem.swap");
+ proc_stats_process_names_[ProcessStats::Process::kVmLockedKbFieldNumber] =
+ context->storage->InternString("mem.locked");
+ proc_stats_process_names_[ProcessStats::Process::kVmHwmKbFieldNumber] =
+ context->storage->InternString("mem.rss.watermark");
+ proc_stats_process_names_[ProcessStats::Process::kOomScoreAdjFieldNumber] =
+ oom_score_adj_id_;
+}
+
+void SystraceProtoParser::ParseSysStats(int64_t ts, ConstBytes blob) {
+ protos::pbzero::SysStats::Decoder sys_stats(blob.data, blob.size);
+
+ for (auto it = sys_stats.meminfo(); it; ++it) {
+ protos::pbzero::SysStats::MeminfoValue::Decoder mi(*it);
+ auto key = static_cast<size_t>(mi.key());
+ if (PERFETTO_UNLIKELY(key >= meminfo_strs_id_.size())) {
+ PERFETTO_ELOG("MemInfo key %zu is not recognized.", key);
+ context_->storage->IncrementStats(stats::meminfo_unknown_keys);
+ continue;
+ }
+ // /proc/meminfo counters are in kB, convert to bytes
+ context_->event_tracker->PushCounter(
+ ts, mi.value() * 1024L, meminfo_strs_id_[key], 0, RefType::kRefNoRef);
+ }
+
+ for (auto it = sys_stats.vmstat(); it; ++it) {
+ protos::pbzero::SysStats::VmstatValue::Decoder vm(*it);
+ auto key = static_cast<size_t>(vm.key());
+ if (PERFETTO_UNLIKELY(key >= vmstat_strs_id_.size())) {
+ PERFETTO_ELOG("VmStat key %zu is not recognized.", key);
+ context_->storage->IncrementStats(stats::vmstat_unknown_keys);
+ continue;
+ }
+ context_->event_tracker->PushCounter(ts, vm.value(), vmstat_strs_id_[key],
+ 0, RefType::kRefNoRef);
+ }
+
+ for (auto it = sys_stats.cpu_stat(); it; ++it) {
+ protos::pbzero::SysStats::CpuTimes::Decoder ct(*it);
+ if (PERFETTO_UNLIKELY(!ct.has_cpu_id())) {
+ PERFETTO_ELOG("CPU field not found in CpuTimes");
+ context_->storage->IncrementStats(stats::invalid_cpu_times);
+ continue;
+ }
+ context_->event_tracker->PushCounter(ts, ct.user_ns(),
+ cpu_times_user_ns_id_, ct.cpu_id(),
+ RefType::kRefCpuId);
+ context_->event_tracker->PushCounter(ts, ct.user_ice_ns(),
+ cpu_times_user_nice_ns_id_,
+ ct.cpu_id(), RefType::kRefCpuId);
+ context_->event_tracker->PushCounter(ts, ct.system_mode_ns(),
+ cpu_times_system_mode_ns_id_,
+ ct.cpu_id(), RefType::kRefCpuId);
+ context_->event_tracker->PushCounter(ts, ct.idle_ns(),
+ cpu_times_idle_ns_id_, ct.cpu_id(),
+ RefType::kRefCpuId);
+ context_->event_tracker->PushCounter(ts, ct.io_wait_ns(),
+ cpu_times_io_wait_ns_id_, ct.cpu_id(),
+ RefType::kRefCpuId);
+ context_->event_tracker->PushCounter(ts, ct.irq_ns(), cpu_times_irq_ns_id_,
+ ct.cpu_id(), RefType::kRefCpuId);
+ context_->event_tracker->PushCounter(ts, ct.softirq_ns(),
+ cpu_times_softirq_ns_id_, ct.cpu_id(),
+ RefType::kRefCpuId);
+ }
+
+ for (auto it = sys_stats.num_irq(); it; ++it) {
+ protos::pbzero::SysStats::InterruptCount::Decoder ic(*it);
+ context_->event_tracker->PushCounter(ts, ic.count(), num_irq_name_id_,
+ ic.irq(), RefType::kRefIrq);
+ }
+
+ for (auto it = sys_stats.num_softirq(); it; ++it) {
+ protos::pbzero::SysStats::InterruptCount::Decoder ic(*it);
+ context_->event_tracker->PushCounter(ts, ic.count(), num_softirq_name_id_,
+ ic.irq(), RefType::kRefSoftIrq);
+ }
+
+ if (sys_stats.has_num_forks()) {
+ context_->event_tracker->PushCounter(
+ ts, sys_stats.num_forks(), num_forks_name_id_, 0, RefType::kRefNoRef);
+ }
+
+ if (sys_stats.has_num_irq_total()) {
+ context_->event_tracker->PushCounter(ts, sys_stats.num_irq_total(),
+ num_irq_total_name_id_, 0,
+ RefType::kRefNoRef);
+ }
+
+ if (sys_stats.has_num_softirq_total()) {
+ context_->event_tracker->PushCounter(ts, sys_stats.num_softirq_total(),
+ num_softirq_total_name_id_, 0,
+ RefType::kRefNoRef);
+ }
+}
+
+void SystraceProtoParser::ParseProcessTree(ConstBytes blob) {
+ protos::pbzero::ProcessTree::Decoder ps(blob.data, blob.size);
+
+ for (auto it = ps.processes(); it; ++it) {
+ protos::pbzero::ProcessTree::Process::Decoder proc(*it);
+ if (!proc.has_cmdline())
+ continue;
+ auto pid = static_cast<uint32_t>(proc.pid());
+ auto ppid = static_cast<uint32_t>(proc.ppid());
+
+ // If the parent pid is kthreadd's pid, even though this pid is of a
+ // "process", we want to treat it as being a child thread of kthreadd.
+ if (ppid == kKthreaddPid) {
+ context_->process_tracker->SetProcessMetadata(kKthreaddPid, base::nullopt,
+ kKthreaddName);
+ context_->process_tracker->UpdateThread(pid, kKthreaddPid);
+ } else {
+ auto args = proc.cmdline();
+ base::StringView argv0 = args ? *args : base::StringView();
+ context_->process_tracker->SetProcessMetadata(pid, ppid, argv0);
+ }
+ }
+
+ for (auto it = ps.threads(); it; ++it) {
+ protos::pbzero::ProcessTree::Thread::Decoder thd(*it);
+ auto tid = static_cast<uint32_t>(thd.tid());
+ auto tgid = static_cast<uint32_t>(thd.tgid());
+ context_->process_tracker->UpdateThread(tid, tgid);
+
+ if (thd.has_name()) {
+ StringId threadNameId = context_->storage->InternString(thd.name());
+ context_->process_tracker->UpdateThreadName(tid, threadNameId);
+ }
+ }
+}
+
+void SystraceProtoParser::ParseProcessStats(int64_t ts, ConstBytes blob) {
+ protos::pbzero::ProcessStats::Decoder stats(blob.data, blob.size);
+ const auto kOomScoreAdjFieldNumber =
+ protos::pbzero::ProcessStats::Process::kOomScoreAdjFieldNumber;
+ for (auto it = stats.processes(); it; ++it) {
+ // Maps a process counter field it to its value.
+ // E.g., 4 := 1024 -> "mem.rss.anon" := 1024.
+ std::array<int64_t, kProcStatsProcessSize> counter_values{};
+ std::array<bool, kProcStatsProcessSize> has_counter{};
+
+ protozero::ProtoDecoder proc(*it);
+ uint32_t pid = 0;
+ for (auto fld = proc.ReadField(); fld.valid(); fld = proc.ReadField()) {
+ if (fld.id() == protos::pbzero::ProcessStats::Process::kPidFieldNumber) {
+ pid = fld.as_uint32();
+ continue;
+ }
+ bool is_counter_field = fld.id() < proc_stats_process_names_.size() &&
+ proc_stats_process_names_[fld.id()] != 0;
+ if (is_counter_field) {
+ // Memory counters are in KB, keep values in bytes in the trace
+ // processor.
+ counter_values[fld.id()] = fld.id() == kOomScoreAdjFieldNumber
+ ? fld.as_int64()
+ : fld.as_int64() * 1024;
+ has_counter[fld.id()] = true;
+ } else {
+ context_->storage->IncrementStats(stats::proc_stat_unknown_counters);
+ }
+ }
+
+ // Skip field_id 0 (invalid) and 1 (pid).
+ for (size_t field_id = 2; field_id < counter_values.size(); field_id++) {
+ if (!has_counter[field_id])
+ continue;
+
+ // Lookup the interned string id from the field name using the
+ // pre-cached |proc_stats_process_names_| map.
+ StringId name = proc_stats_process_names_[field_id];
+ int64_t value = counter_values[field_id];
+ UniquePid upid = context_->process_tracker->GetOrCreateProcess(pid);
+ context_->event_tracker->PushCounter(ts, value, name, upid,
+ RefType::kRefUpid);
+ }
+ }
+}
+
+void SystraceProtoParser::ParseSystemInfo(ConstBytes blob) {
+ protos::pbzero::SystemInfo::Decoder packet(blob.data, blob.size);
+ if (packet.has_utsname()) {
+ ConstBytes utsname_blob = packet.utsname();
+ protos::pbzero::Utsname::Decoder utsname(utsname_blob.data,
+ utsname_blob.size);
+ base::StringView machine = utsname.machine();
+ if (machine == "aarch64" || machine == "armv8l") {
+ context_->syscall_tracker->SetArchitecture(kAarch64);
+ } else if (machine == "x86_64") {
+ context_->syscall_tracker->SetArchitecture(kX86_64);
+ } else {
+ PERFETTO_ELOG("Unknown architecture %s", machine.ToStdString().c_str());
+ }
+ }
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/system_probes_parser.h b/src/trace_processor/importers/proto/system_probes_parser.h
new file mode 100644
index 0000000..713118e
--- /dev/null
+++ b/src/trace_processor/importers/proto/system_probes_parser.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_SYSTEM_PROBES_PARSER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_SYSTEM_PROBES_PARSER_H_
+
+#include <vector>
+
+#include "perfetto/protozero/field.h"
+#include "src/trace_processor/trace_storage.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class TraceProcessorContext;
+
+class SystraceProtoParser {
+ public:
+ using ConstBytes = protozero::ConstBytes;
+
+ explicit SystraceProtoParser(TraceProcessorContext*);
+
+ void ParseProcessTree(ConstBytes);
+ void ParseProcessStats(int64_t timestamp, ConstBytes);
+ void ParseSysStats(int64_t ts, ConstBytes);
+ void ParseSystemInfo(ConstBytes);
+
+ private:
+ TraceProcessorContext* const context_;
+
+ const StringId utid_name_id_;
+ const StringId num_forks_name_id_;
+ const StringId num_irq_total_name_id_;
+ const StringId num_softirq_total_name_id_;
+ const StringId num_irq_name_id_;
+ const StringId num_softirq_name_id_;
+ const StringId cpu_times_user_ns_id_;
+ const StringId cpu_times_user_nice_ns_id_;
+ const StringId cpu_times_system_mode_ns_id_;
+ const StringId cpu_times_idle_ns_id_;
+ const StringId cpu_times_io_wait_ns_id_;
+ const StringId cpu_times_irq_ns_id_;
+ const StringId cpu_times_softirq_ns_id_;
+ const StringId oom_score_adj_id_;
+ std::vector<StringId> meminfo_strs_id_;
+ std::vector<StringId> vmstat_strs_id_;
+
+ // Maps a proto field number for memcounters in ProcessStats::Process to
+ // their StringId. Keep kProcStatsProcessSize equal to 1 + max proto field
+ // id of ProcessStats::Process.
+ static constexpr size_t kProcStatsProcessSize = 11;
+ std::array<StringId, kProcStatsProcessSize> proc_stats_process_names_{};
+};
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_SYSTEM_PROBES_PARSER_H_
diff --git a/src/trace_processor/importers/proto/track_event_module.h b/src/trace_processor/importers/proto/track_event_module.h
index 1c66d34..b3b3299 100644
--- a/src/trace_processor/importers/proto/track_event_module.h
+++ b/src/trace_processor/importers/proto/track_event_module.h
@@ -19,6 +19,9 @@
#include "perfetto/base/build_config.h"
#include "src/trace_processor/importers/proto/proto_importer_module.h"
+#include "src/trace_processor/importers/proto/track_event_parser.h"
+#include "src/trace_processor/importers/proto/track_event_tokenizer.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
namespace perfetto {
namespace trace_processor {
@@ -26,20 +29,55 @@
class TrackEventModule : public ProtoImporterModuleBase</*IsEnabled=*/1> {
public:
explicit TrackEventModule(TraceProcessorContext* context)
- : ProtoImporterModuleBase(context) {}
+ : ProtoImporterModuleBase(context),
+ tokenizer_(context),
+ parser_(context) {}
- ModuleResult TokenizePacket(const protos::pbzero::TracePacket::Decoder&,
- TraceBlobView* /*packet*/,
- int64_t /*packet_timestamp*/) {
- // TODO(eseckler): implement.
+ ModuleResult TokenizePacket(
+ const protos::pbzero::TracePacket::Decoder& decoder,
+ TraceBlobView* packet,
+ int64_t packet_timestamp,
+ PacketSequenceState* state) {
+ if (decoder.has_track_descriptor()) {
+ tokenizer_.TokenizeTrackDescriptorPacket(decoder);
+ return ModuleResult::Handled();
+ }
+
+ if (decoder.has_track_event()) {
+ tokenizer_.TokenizeTrackEventPacket(state, decoder, packet,
+ packet_timestamp);
+ return ModuleResult::Handled();
+ }
+
+ // TODO(eseckler): Remove these once Chrome has switched fully over to
+ // TrackDescriptors.
+ if (decoder.has_thread_descriptor()) {
+ tokenizer_.TokenizeThreadDescriptorPacket(state, decoder);
+ return ModuleResult::Handled();
+ }
+ if (decoder.has_process_descriptor()) {
+ tokenizer_.TokenizeProcessDescriptorPacket(decoder);
+ return ModuleResult::Handled();
+ }
+
return ModuleResult::Ignored();
}
- ModuleResult ParsePacket(const protos::pbzero::TracePacket::Decoder&,
- const TimestampedTracePiece&) {
- // TODO(eseckler): implement.
+ ModuleResult ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp) {
+ if (decoder.has_track_event()) {
+ parser_.ParseTrackEvent(
+ ttp.timestamp, ttp.thread_timestamp, ttp.thread_instruction_count,
+ ttp.packet_sequence_state, ttp.packet_sequence_state_generation,
+ decoder.track_event());
+ return ModuleResult::Handled();
+ }
return ModuleResult::Ignored();
}
+
+ private:
+ TrackEventTokenizer tokenizer_;
+ TrackEventParser parser_;
};
} // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/track_event_parser.cc b/src/trace_processor/importers/proto/track_event_parser.cc
new file mode 100644
index 0000000..53a527b
--- /dev/null
+++ b/src/trace_processor/importers/proto/track_event_parser.cc
@@ -0,0 +1,893 @@
+/*
+ * 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/importers/proto/track_event_parser.h"
+
+#include <string>
+
+#include "perfetto/base/logging.h"
+#include "src/trace_processor/args_tracker.h"
+#include "src/trace_processor/importers/proto/packet_sequence_state.h"
+#include "src/trace_processor/process_tracker.h"
+#include "src/trace_processor/track_tracker.h"
+
+#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+#include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+#include "protos/perfetto/trace/track_event/log_message.pbzero.h"
+#include "protos/perfetto/trace/track_event/source_location.pbzero.h"
+#include "protos/perfetto/trace/track_event/task_execution.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+namespace {
+using protozero::ConstBytes;
+
+// Slices which have been opened but haven't been closed yet will be marked
+// with these placeholder values.
+constexpr int64_t kPendingThreadDuration = -1;
+constexpr int64_t kPendingThreadInstructionDelta = -1;
+} // namespace
+
+TrackEventParser::TrackEventParser(TraceProcessorContext* context)
+ : context_(context),
+ task_file_name_args_key_id_(
+ context->storage->InternString("task.posted_from.file_name")),
+ task_function_name_args_key_id_(
+ context->storage->InternString("task.posted_from.function_name")),
+ task_line_number_args_key_id_(
+ context->storage->InternString("task.posted_from.line_number")),
+ log_message_body_key_id_(
+ context->storage->InternString("track_event.log_message")),
+ raw_legacy_event_id_(
+ context->storage->InternString("track_event.legacy_event")),
+ legacy_event_category_key_id_(
+ context->storage->InternString("legacy_event.category")),
+ legacy_event_name_key_id_(
+ context->storage->InternString("legacy_event.name")),
+ legacy_event_phase_key_id_(
+ context->storage->InternString("legacy_event.phase")),
+ legacy_event_duration_ns_key_id_(
+ context->storage->InternString("legacy_event.duration_ns")),
+ legacy_event_thread_timestamp_ns_key_id_(
+ context->storage->InternString("legacy_event.thread_timestamp_ns")),
+ legacy_event_thread_duration_ns_key_id_(
+ context->storage->InternString("legacy_event.thread_duration_ns")),
+ legacy_event_thread_instruction_count_key_id_(
+ context->storage->InternString(
+ "legacy_event.thread_instruction_count")),
+ legacy_event_thread_instruction_delta_key_id_(
+ context->storage->InternString(
+ "legacy_event.thread_instruction_delta")),
+ legacy_event_use_async_tts_key_id_(
+ context->storage->InternString("legacy_event.use_async_tts")),
+ legacy_event_unscoped_id_key_id_(
+ context->storage->InternString("legacy_event.unscoped_id")),
+ legacy_event_global_id_key_id_(
+ context->storage->InternString("legacy_event.global_id")),
+ legacy_event_local_id_key_id_(
+ context->storage->InternString("legacy_event.local_id")),
+ legacy_event_id_scope_key_id_(
+ context->storage->InternString("legacy_event.id_scope")),
+ legacy_event_bind_id_key_id_(
+ context->storage->InternString("legacy_event.bind_id")),
+ legacy_event_bind_to_enclosing_key_id_(
+ context->storage->InternString("legacy_event.bind_to_enclosing")),
+ legacy_event_flow_direction_key_id_(
+ context->storage->InternString("legacy_event.flow_direction")),
+ flow_direction_value_in_id_(context->storage->InternString("in")),
+ flow_direction_value_out_id_(context->storage->InternString("out")),
+ flow_direction_value_inout_id_(context->storage->InternString("inout")) {}
+
+void TrackEventParser::ParseTrackEvent(int64_t ts,
+ int64_t tts,
+ int64_t ticount,
+ PacketSequenceState* sequence_state,
+ size_t sequence_state_generation,
+ ConstBytes blob) {
+ using LegacyEvent = protos::pbzero::TrackEvent::LegacyEvent;
+
+ protos::pbzero::TrackEvent::Decoder event(blob.data, blob.size);
+
+ const auto legacy_event_blob = event.legacy_event();
+ LegacyEvent::Decoder legacy_event(legacy_event_blob.data,
+ legacy_event_blob.size);
+
+ // TODO(eseckler): This legacy event field will eventually be replaced by
+ // fields in TrackEvent itself.
+ if (PERFETTO_UNLIKELY(!event.type() && !legacy_event.has_phase())) {
+ context_->storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG("TrackEvent without type or phase");
+ return;
+ }
+
+ ProcessTracker* procs = context_->process_tracker.get();
+ TraceStorage* storage = context_->storage.get();
+ TrackTracker* track_tracker = context_->track_tracker.get();
+ SliceTracker* slice_tracker = context_->slice_tracker.get();
+
+ std::vector<uint64_t> category_iids;
+ for (auto it = event.category_iids(); it; ++it) {
+ category_iids.push_back(*it);
+ }
+ std::vector<protozero::ConstChars> category_strings;
+ for (auto it = event.categories(); it; ++it) {
+ category_strings.push_back(*it);
+ }
+
+ StringId category_id = 0;
+
+ // If there's a single category, we can avoid building a concatenated
+ // string.
+ if (PERFETTO_LIKELY(category_iids.size() == 1 && category_strings.empty())) {
+ auto* decoder = sequence_state->LookupInternedMessage<
+ protos::pbzero::InternedData::kEventCategoriesFieldNumber,
+ protos::pbzero::EventCategory>(sequence_state_generation,
+ category_iids[0]);
+ if (decoder)
+ category_id = storage->InternString(decoder->name());
+ } else if (category_iids.empty() && category_strings.size() == 1) {
+ category_id = storage->InternString(category_strings[0]);
+ } else if (category_iids.size() + category_strings.size() > 1) {
+ // We concatenate the category strings together since we currently only
+ // support a single "cat" column.
+ // TODO(eseckler): Support multi-category events in the table schema.
+ std::string categories;
+ for (uint64_t iid : category_iids) {
+ auto* decoder = sequence_state->LookupInternedMessage<
+ protos::pbzero::InternedData::kEventCategoriesFieldNumber,
+ protos::pbzero::EventCategory>(sequence_state_generation, iid);
+ if (!decoder)
+ continue;
+ base::StringView name = decoder->name();
+ if (!categories.empty())
+ categories.append(",");
+ categories.append(name.data(), name.size());
+ }
+ for (const protozero::ConstChars& cat : category_strings) {
+ if (!categories.empty())
+ categories.append(",");
+ categories.append(cat.data, cat.size);
+ }
+ if (!categories.empty())
+ category_id = storage->InternString(base::StringView(categories));
+ }
+
+ StringId name_id = 0;
+
+ uint64_t name_iid = event.name_iid();
+ if (!name_iid)
+ name_iid = legacy_event.name_iid();
+
+ if (PERFETTO_LIKELY(name_iid)) {
+ auto* decoder = sequence_state->LookupInternedMessage<
+ protos::pbzero::InternedData::kEventNamesFieldNumber,
+ protos::pbzero::EventName>(sequence_state_generation, name_iid);
+ if (decoder)
+ name_id = storage->InternString(decoder->name());
+ } else if (event.has_name()) {
+ name_id = storage->InternString(event.name());
+ }
+
+ // TODO(eseckler): Also consider track_uuid from TrackEventDefaults.
+ // Fall back to the default descriptor track (uuid 0).
+ uint64_t track_uuid = event.has_track_uuid() ? event.track_uuid() : 0u;
+ TrackId track_id;
+ base::Optional<UniqueTid> utid;
+ base::Optional<UniqueTid> upid;
+
+ // Determine track from track_uuid specified in either TrackEvent or
+ // TrackEventDefaults. If none is set, fall back to the track specified by the
+ // sequence's (or event's) pid + tid or a default track.
+ if (track_uuid) {
+ base::Optional<TrackId> opt_track_id =
+ track_tracker->GetDescriptorTrack(track_uuid);
+ if (!opt_track_id) {
+ storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG("TrackEvent with unknown track_uuid %" PRIu64, track_uuid);
+ return;
+ }
+ track_id = *opt_track_id;
+
+ auto thread_track_row =
+ context_->storage->thread_track_table().id().IndexOf(
+ SqlValue::Long(track_id));
+ if (thread_track_row) {
+ utid = storage->thread_track_table().utid()[*thread_track_row];
+ upid = storage->GetThread(*utid).upid;
+ } else {
+ auto process_track_row =
+ context_->storage->process_track_table().id().IndexOf(
+ SqlValue::Long(track_id));
+ if (process_track_row)
+ upid = storage->process_track_table().upid()[*process_track_row];
+ }
+ } else if (sequence_state->pid_and_tid_valid() ||
+ (legacy_event.has_pid_override() &&
+ legacy_event.has_tid_override())) {
+ uint32_t pid = static_cast<uint32_t>(sequence_state->pid());
+ uint32_t tid = static_cast<uint32_t>(sequence_state->tid());
+ if (legacy_event.has_pid_override())
+ pid = static_cast<uint32_t>(legacy_event.pid_override());
+ if (legacy_event.has_tid_override())
+ tid = static_cast<uint32_t>(legacy_event.tid_override());
+
+ utid = procs->UpdateThread(tid, pid);
+ upid = storage->GetThread(*utid).upid;
+ track_id = track_tracker->GetOrCreateDescriptorTrackForThread(*utid);
+ } else {
+ track_id = track_tracker->GetOrCreateDefaultDescriptorTrack();
+ }
+
+ // TODO(eseckler): Replace phase with type and remove handling of
+ // legacy_event.phase() once it is no longer used by producers.
+ int32_t phase = 0;
+ if (legacy_event.has_phase()) {
+ phase = legacy_event.phase();
+
+ switch (phase) {
+ case 'b':
+ case 'e':
+ case 'n': {
+ // Intern tracks for legacy async events based on legacy event ids.
+ int64_t source_id = 0;
+ bool source_id_is_process_scoped = false;
+ if (legacy_event.has_unscoped_id()) {
+ source_id = static_cast<int64_t>(legacy_event.unscoped_id());
+ } else if (legacy_event.has_global_id()) {
+ source_id = static_cast<int64_t>(legacy_event.global_id());
+ } else if (legacy_event.has_local_id()) {
+ if (!upid) {
+ storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG(
+ "TrackEvent with local_id without process association");
+ return;
+ }
+
+ source_id = static_cast<int64_t>(legacy_event.local_id());
+ source_id_is_process_scoped = true;
+ } else {
+ storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG("Async LegacyEvent without ID");
+ return;
+ }
+
+ // Catapult treats nestable async events of different categories with
+ // the same ID as separate tracks. We replicate the same behavior here.
+ StringId id_scope = category_id;
+ if (legacy_event.has_id_scope()) {
+ std::string concat = storage->GetString(category_id).ToStdString() +
+ ":" + legacy_event.id_scope().ToStdString();
+ id_scope = storage->InternString(base::StringView(concat));
+ }
+
+ track_id = context_->track_tracker->InternLegacyChromeAsyncTrack(
+ name_id, upid ? *upid : 0, source_id, source_id_is_process_scoped,
+ id_scope);
+ break;
+ }
+ case 'i':
+ case 'I': {
+ // Intern tracks for global or process-scoped legacy instant events.
+ switch (legacy_event.instant_event_scope()) {
+ case LegacyEvent::SCOPE_UNSPECIFIED:
+ case LegacyEvent::SCOPE_THREAD:
+ // Thread-scoped legacy instant events already have the right track
+ // based on the tid/pid of the sequence.
+ if (!utid) {
+ storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG(
+ "Thread-scoped instant event without thread association");
+ return;
+ }
+ break;
+ case LegacyEvent::SCOPE_GLOBAL:
+ track_id = context_->track_tracker
+ ->GetOrCreateLegacyChromeGlobalInstantTrack();
+ break;
+ case LegacyEvent::SCOPE_PROCESS:
+ if (!upid) {
+ storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG(
+ "Process-scoped instant event without process association");
+ return;
+ }
+
+ track_id =
+ context_->track_tracker->InternLegacyChromeProcessInstantTrack(
+ *upid);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ } else {
+ switch (event.type()) {
+ case protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN:
+ phase = utid ? 'B' : 'b';
+ break;
+ case protos::pbzero::TrackEvent::TYPE_SLICE_END:
+ phase = utid ? 'E' : 'e';
+ break;
+ case protos::pbzero::TrackEvent::TYPE_INSTANT:
+ phase = utid ? 'i' : 'n';
+ break;
+ default:
+ PERFETTO_FATAL("unexpected event type %d", event.type());
+ return;
+ }
+ }
+
+ auto args_callback = [this, &event, &legacy_event, &sequence_state,
+ sequence_state_generation, ts,
+ utid](ArgsTracker* args_tracker, RowId row_id) {
+ for (auto it = event.debug_annotations(); it; ++it) {
+ ParseDebugAnnotationArgs(*it, sequence_state, sequence_state_generation,
+ args_tracker, row_id);
+ }
+
+ if (event.has_task_execution()) {
+ ParseTaskExecutionArgs(event.task_execution(), sequence_state,
+ sequence_state_generation, args_tracker, row_id);
+ }
+
+ if (event.has_log_message()) {
+ ParseLogMessage(event.log_message(), sequence_state,
+ sequence_state_generation, ts, utid, args_tracker,
+ row_id);
+ }
+
+ // TODO(eseckler): Parse legacy flow events into flow events table once we
+ // have a design for it.
+ if (legacy_event.has_bind_id()) {
+ args_tracker->AddArg(row_id, legacy_event_bind_id_key_id_,
+ legacy_event_bind_id_key_id_,
+ Variadic::UnsignedInteger(legacy_event.bind_id()));
+ }
+
+ if (legacy_event.bind_to_enclosing()) {
+ args_tracker->AddArg(row_id, legacy_event_bind_to_enclosing_key_id_,
+ legacy_event_bind_to_enclosing_key_id_,
+ Variadic::Boolean(true));
+ }
+
+ if (legacy_event.flow_direction()) {
+ StringId value;
+ switch (legacy_event.flow_direction()) {
+ case protos::pbzero::TrackEvent::LegacyEvent::FLOW_IN:
+ value = flow_direction_value_in_id_;
+ break;
+ case protos::pbzero::TrackEvent::LegacyEvent::FLOW_OUT:
+ value = flow_direction_value_out_id_;
+ break;
+ case protos::pbzero::TrackEvent::LegacyEvent::FLOW_INOUT:
+ value = flow_direction_value_inout_id_;
+ break;
+ default:
+ PERFETTO_FATAL("Unknown flow direction: %d",
+ legacy_event.flow_direction());
+ break;
+ }
+ args_tracker->AddArg(row_id, legacy_event_flow_direction_key_id_,
+ legacy_event_flow_direction_key_id_,
+ Variadic::String(value));
+ }
+ };
+
+ switch (static_cast<char>(phase)) {
+ case 'B': { // TRACE_EVENT_PHASE_BEGIN.
+ if (!utid) {
+ storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG("TrackEvent with phase B without thread association");
+ return;
+ }
+
+ auto opt_slice_id =
+ slice_tracker->Begin(ts, track_id, *utid, RefType::kRefUtid,
+ category_id, name_id, args_callback);
+ if (opt_slice_id.has_value()) {
+ auto* thread_slices = storage->mutable_thread_slices();
+ PERFETTO_DCHECK(!thread_slices->slice_count() ||
+ thread_slices->slice_ids().back() <
+ opt_slice_id.value());
+ thread_slices->AddThreadSlice(opt_slice_id.value(), tts,
+ kPendingThreadDuration, ticount,
+ kPendingThreadInstructionDelta);
+ }
+ break;
+ }
+ case 'E': { // TRACE_EVENT_PHASE_END.
+ if (!utid) {
+ storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG("TrackEvent with phase E without thread association");
+ return;
+ }
+
+ auto opt_slice_id =
+ slice_tracker->End(ts, track_id, category_id, name_id, args_callback);
+ if (opt_slice_id.has_value()) {
+ auto* thread_slices = storage->mutable_thread_slices();
+ thread_slices->UpdateThreadDeltasForSliceId(opt_slice_id.value(), tts,
+ ticount);
+ }
+ break;
+ }
+ case 'X': { // TRACE_EVENT_PHASE_COMPLETE.
+ if (!utid) {
+ storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG("TrackEvent with phase X without thread association");
+ return;
+ }
+
+ auto duration_ns = legacy_event.duration_us() * 1000;
+ if (duration_ns < 0)
+ return;
+ auto opt_slice_id = slice_tracker->Scoped(
+ ts, track_id, *utid, RefType::kRefUtid, category_id, name_id,
+ duration_ns, args_callback);
+ if (opt_slice_id.has_value()) {
+ auto* thread_slices = storage->mutable_thread_slices();
+ PERFETTO_DCHECK(!thread_slices->slice_count() ||
+ thread_slices->slice_ids().back() <
+ opt_slice_id.value());
+ auto thread_duration_ns = legacy_event.thread_duration_us() * 1000;
+ thread_slices->AddThreadSlice(opt_slice_id.value(), tts,
+ thread_duration_ns, ticount,
+ legacy_event.thread_instruction_delta());
+ }
+ break;
+ }
+ case 'i':
+ case 'I': { // TRACE_EVENT_PHASE_INSTANT.
+ // Handle instant events as slices with zero duration, so that they end
+ // up nested underneath their parent slices.
+ int64_t duration_ns = 0;
+ int64_t tidelta = 0;
+
+ switch (legacy_event.instant_event_scope()) {
+ case LegacyEvent::SCOPE_UNSPECIFIED:
+ case LegacyEvent::SCOPE_THREAD: {
+ // TODO(lalitm): Associate thread slices with track instead.
+ auto opt_slice_id = slice_tracker->Scoped(
+ ts, track_id, *utid, RefType::kRefUtid, category_id, name_id,
+ duration_ns, args_callback);
+ if (opt_slice_id.has_value()) {
+ auto* thread_slices = storage->mutable_thread_slices();
+ PERFETTO_DCHECK(!thread_slices->slice_count() ||
+ thread_slices->slice_ids().back() <
+ opt_slice_id.value());
+ thread_slices->AddThreadSlice(opt_slice_id.value(), tts,
+ duration_ns, ticount, tidelta);
+ }
+ break;
+ }
+ case LegacyEvent::SCOPE_GLOBAL: {
+ slice_tracker->Scoped(ts, track_id, /*ref=*/0, RefType::kRefNoRef,
+ category_id, name_id, duration_ns,
+ args_callback);
+ break;
+ }
+ case LegacyEvent::SCOPE_PROCESS: {
+ slice_tracker->Scoped(ts, track_id, *upid, RefType::kRefUpid,
+ category_id, name_id, duration_ns,
+ args_callback);
+ break;
+ }
+ default: {
+ PERFETTO_FATAL("Unknown instant event scope: %u",
+ legacy_event.instant_event_scope());
+ break;
+ }
+ }
+ break;
+ }
+ case 'b': { // TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN
+ auto opt_slice_id =
+ slice_tracker->Begin(ts, track_id, track_id, RefType::kRefTrack,
+ category_id, name_id, args_callback);
+ // For the time beeing, we only create vtrack slice rows if we need to
+ // store thread timestamps/counters.
+ if (legacy_event.use_async_tts() && opt_slice_id.has_value()) {
+ auto* vtrack_slices = storage->mutable_virtual_track_slices();
+ PERFETTO_DCHECK(!vtrack_slices->slice_count() ||
+ vtrack_slices->slice_ids().back() <
+ opt_slice_id.value());
+ vtrack_slices->AddVirtualTrackSlice(opt_slice_id.value(), tts,
+ kPendingThreadDuration, ticount,
+ kPendingThreadInstructionDelta);
+ }
+ break;
+ }
+ case 'e': { // TRACE_EVENT_PHASE_NESTABLE_ASYNC_END
+ auto opt_slice_id =
+ slice_tracker->End(ts, track_id, category_id, name_id, args_callback);
+ if (legacy_event.use_async_tts() && opt_slice_id.has_value()) {
+ auto* vtrack_slices = storage->mutable_virtual_track_slices();
+ vtrack_slices->UpdateThreadDeltasForSliceId(opt_slice_id.value(), tts,
+ ticount);
+ }
+ break;
+ }
+ case 'n': { // TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT
+ // Handle instant events as slices with zero duration, so that they end up
+ // nested underneath their parent slices.
+ int64_t duration_ns = 0;
+ int64_t tidelta = 0;
+ auto opt_slice_id = slice_tracker->Scoped(
+ ts, track_id, track_id, RefType::kRefTrack, category_id, name_id,
+ duration_ns, args_callback);
+ if (legacy_event.use_async_tts() && opt_slice_id.has_value()) {
+ auto* vtrack_slices = storage->mutable_virtual_track_slices();
+ PERFETTO_DCHECK(!vtrack_slices->slice_count() ||
+ vtrack_slices->slice_ids().back() <
+ opt_slice_id.value());
+ vtrack_slices->AddVirtualTrackSlice(opt_slice_id.value(), tts,
+ duration_ns, ticount, tidelta);
+ }
+ break;
+ }
+ case 'M': { // TRACE_EVENT_PHASE_METADATA (process and thread names).
+ // Parse process and thread names from correspondingly named events.
+ // TODO(eseckler): Also consider names from process/thread descriptors.
+ NullTermStringView event_name = storage->GetString(name_id);
+ PERFETTO_DCHECK(event_name.data());
+ if (strcmp(event_name.c_str(), "thread_name") == 0) {
+ if (!utid) {
+ storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG(
+ "thread_name metadata event without thread association");
+ return;
+ }
+
+ auto it = event.debug_annotations();
+ if (!it)
+ break;
+ protos::pbzero::DebugAnnotation::Decoder annotation(*it);
+ auto thread_name = annotation.string_value();
+ if (!thread_name.size)
+ break;
+ auto thread_name_id = storage->InternString(thread_name);
+ procs->SetThreadName(*utid, thread_name_id);
+ break;
+ }
+ if (strcmp(event_name.c_str(), "process_name") == 0) {
+ if (!upid) {
+ storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG(
+ "process_name metadata event without process association");
+ return;
+ }
+
+ auto it = event.debug_annotations();
+ if (!it)
+ break;
+ protos::pbzero::DebugAnnotation::Decoder annotation(*it);
+ auto process_name = annotation.string_value();
+ if (!process_name.size)
+ break;
+ procs->SetProcessMetadata(storage->GetProcess(*upid).pid, base::nullopt,
+ process_name);
+ break;
+ }
+ // Other metadata events are proxied via the raw table for JSON export.
+ ParseLegacyEventAsRawEvent(ts, tts, ticount, utid, category_id, name_id,
+ legacy_event, args_callback);
+ break;
+ }
+ default: {
+ // Other events are proxied via the raw table for JSON export.
+ ParseLegacyEventAsRawEvent(ts, tts, ticount, utid, category_id, name_id,
+ legacy_event, args_callback);
+ }
+ }
+}
+
+void TrackEventParser::ParseLegacyEventAsRawEvent(
+ int64_t ts,
+ int64_t tts,
+ int64_t ticount,
+ base::Optional<UniqueTid> utid,
+ StringId category_id,
+ StringId name_id,
+ const protos::pbzero::TrackEvent::LegacyEvent::Decoder& legacy_event,
+ SliceTracker::SetArgsCallback args_callback) {
+ if (!utid) {
+ context_->storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG("raw legacy event without thread association");
+ return;
+ }
+
+ RowId row_id = context_->storage->mutable_raw_events()->AddRawEvent(
+ ts, raw_legacy_event_id_, 0, *utid);
+ ArgsTracker args(context_);
+ args.AddArg(row_id, legacy_event_category_key_id_,
+ legacy_event_category_key_id_, Variadic::String(category_id));
+ args.AddArg(row_id, legacy_event_name_key_id_, legacy_event_name_key_id_,
+ Variadic::String(name_id));
+
+ std::string phase_string(1, static_cast<char>(legacy_event.phase()));
+ StringId phase_id = context_->storage->InternString(phase_string.c_str());
+ args.AddArg(row_id, legacy_event_phase_key_id_, legacy_event_phase_key_id_,
+ Variadic::String(phase_id));
+
+ if (legacy_event.has_duration_us()) {
+ args.AddArg(row_id, legacy_event_duration_ns_key_id_,
+ legacy_event_duration_ns_key_id_,
+ Variadic::Integer(legacy_event.duration_us() * 1000));
+ }
+
+ if (tts) {
+ args.AddArg(row_id, legacy_event_thread_timestamp_ns_key_id_,
+ legacy_event_thread_timestamp_ns_key_id_,
+ Variadic::Integer(tts));
+ if (legacy_event.has_thread_duration_us()) {
+ args.AddArg(row_id, legacy_event_thread_duration_ns_key_id_,
+ legacy_event_thread_duration_ns_key_id_,
+ Variadic::Integer(legacy_event.thread_duration_us() * 1000));
+ }
+ }
+
+ if (ticount) {
+ args.AddArg(row_id, legacy_event_thread_instruction_count_key_id_,
+ legacy_event_thread_instruction_count_key_id_,
+ Variadic::Integer(tts));
+ if (legacy_event.has_thread_instruction_delta()) {
+ args.AddArg(row_id, legacy_event_thread_instruction_delta_key_id_,
+ legacy_event_thread_instruction_delta_key_id_,
+ Variadic::Integer(legacy_event.thread_instruction_delta()));
+ }
+ }
+
+ if (legacy_event.use_async_tts()) {
+ args.AddArg(row_id, legacy_event_use_async_tts_key_id_,
+ legacy_event_use_async_tts_key_id_, Variadic::Boolean(true));
+ }
+
+ bool has_id = false;
+ if (legacy_event.has_unscoped_id()) {
+ // Unscoped ids are either global or local depending on the phase. Pass them
+ // through as unscoped IDs to JSON export to preserve this behavior.
+ args.AddArg(row_id, legacy_event_unscoped_id_key_id_,
+ legacy_event_unscoped_id_key_id_,
+ Variadic::UnsignedInteger(legacy_event.unscoped_id()));
+ has_id = true;
+ } else if (legacy_event.has_global_id()) {
+ args.AddArg(row_id, legacy_event_global_id_key_id_,
+ legacy_event_global_id_key_id_,
+ Variadic::UnsignedInteger(legacy_event.global_id()));
+ has_id = true;
+ } else if (legacy_event.has_local_id()) {
+ args.AddArg(row_id, legacy_event_local_id_key_id_,
+ legacy_event_local_id_key_id_,
+ Variadic::UnsignedInteger(legacy_event.local_id()));
+ has_id = true;
+ }
+
+ if (has_id && legacy_event.has_id_scope() && legacy_event.id_scope().size) {
+ args.AddArg(row_id, legacy_event_id_scope_key_id_,
+ legacy_event_id_scope_key_id_,
+ Variadic::String(
+ context_->storage->InternString(legacy_event.id_scope())));
+ }
+
+ // No need to parse legacy_event.instant_event_scope() because we import
+ // instant events into the slice table.
+
+ args_callback(&args, row_id);
+}
+
+void TrackEventParser::ParseDebugAnnotationArgs(
+ ConstBytes debug_annotation,
+ PacketSequenceState* sequence_state,
+ size_t sequence_state_generation,
+ ArgsTracker* args_tracker,
+ RowId row_id) {
+ TraceStorage* storage = context_->storage.get();
+
+ protos::pbzero::DebugAnnotation::Decoder annotation(debug_annotation.data,
+ debug_annotation.size);
+
+ StringId name_id = 0;
+
+ uint64_t name_iid = annotation.name_iid();
+ if (PERFETTO_LIKELY(name_iid)) {
+ auto* decoder = sequence_state->LookupInternedMessage<
+ protos::pbzero::InternedData::kDebugAnnotationNamesFieldNumber,
+ protos::pbzero::DebugAnnotationName>(sequence_state_generation,
+ name_iid);
+ if (!decoder)
+ return;
+
+ std::string name_prefixed = "debug." + decoder->name().ToStdString();
+ name_id = storage->InternString(base::StringView(name_prefixed));
+ } else if (annotation.has_name()) {
+ name_id = storage->InternString(annotation.name());
+ } else {
+ context_->storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG("Debug annotation without name");
+ return;
+ }
+
+ if (annotation.has_bool_value()) {
+ args_tracker->AddArg(row_id, name_id, name_id,
+ Variadic::Boolean(annotation.bool_value()));
+ } else if (annotation.has_uint_value()) {
+ args_tracker->AddArg(row_id, name_id, name_id,
+ Variadic::UnsignedInteger(annotation.uint_value()));
+ } else if (annotation.has_int_value()) {
+ args_tracker->AddArg(row_id, name_id, name_id,
+ Variadic::Integer(annotation.int_value()));
+ } else if (annotation.has_double_value()) {
+ args_tracker->AddArg(row_id, name_id, name_id,
+ Variadic::Real(annotation.double_value()));
+ } else if (annotation.has_string_value()) {
+ args_tracker->AddArg(
+ row_id, name_id, name_id,
+ Variadic::String(storage->InternString(annotation.string_value())));
+ } else if (annotation.has_pointer_value()) {
+ args_tracker->AddArg(row_id, name_id, name_id,
+ Variadic::Pointer(annotation.pointer_value()));
+ } else if (annotation.has_legacy_json_value()) {
+ args_tracker->AddArg(
+ row_id, name_id, name_id,
+ Variadic::Json(storage->InternString(annotation.legacy_json_value())));
+ } else if (annotation.has_nested_value()) {
+ auto name = storage->GetString(name_id);
+ ParseNestedValueArgs(annotation.nested_value(), name, name, args_tracker,
+ row_id);
+ }
+}
+
+void TrackEventParser::ParseNestedValueArgs(ConstBytes nested_value,
+ base::StringView flat_key,
+ base::StringView key,
+ ArgsTracker* args_tracker,
+ RowId row_id) {
+ protos::pbzero::DebugAnnotation::NestedValue::Decoder value(
+ nested_value.data, nested_value.size);
+ switch (value.nested_type()) {
+ case protos::pbzero::DebugAnnotation::NestedValue::UNSPECIFIED: {
+ auto flat_key_id = context_->storage->InternString(flat_key);
+ auto key_id = context_->storage->InternString(key);
+ // Leaf value.
+ if (value.has_bool_value()) {
+ args_tracker->AddArg(row_id, flat_key_id, key_id,
+ Variadic::Boolean(value.bool_value()));
+ } else if (value.has_int_value()) {
+ args_tracker->AddArg(row_id, flat_key_id, key_id,
+ Variadic::Integer(value.int_value()));
+ } else if (value.has_double_value()) {
+ args_tracker->AddArg(row_id, flat_key_id, key_id,
+ Variadic::Real(value.double_value()));
+ } else if (value.has_string_value()) {
+ args_tracker->AddArg(row_id, flat_key_id, key_id,
+ Variadic::String(context_->storage->InternString(
+ value.string_value())));
+ }
+ break;
+ }
+ case protos::pbzero::DebugAnnotation::NestedValue::DICT: {
+ auto key_it = value.dict_keys();
+ auto value_it = value.dict_values();
+ for (; key_it && value_it; ++key_it, ++value_it) {
+ std::string child_name = (*key_it).ToStdString();
+ std::string child_flat_key = flat_key.ToStdString() + "." + child_name;
+ std::string child_key = key.ToStdString() + "." + child_name;
+ ParseNestedValueArgs(*value_it, base::StringView(child_flat_key),
+ base::StringView(child_key), args_tracker, row_id);
+ }
+ break;
+ }
+ case protos::pbzero::DebugAnnotation::NestedValue::ARRAY: {
+ int child_index = 0;
+ std::string child_flat_key = flat_key.ToStdString();
+ for (auto value_it = value.array_values(); value_it;
+ ++value_it, ++child_index) {
+ std::string child_key =
+ key.ToStdString() + "[" + std::to_string(child_index) + "]";
+ ParseNestedValueArgs(*value_it, base::StringView(child_flat_key),
+ base::StringView(child_key), args_tracker, row_id);
+ }
+ break;
+ }
+ }
+}
+
+void TrackEventParser::ParseTaskExecutionArgs(
+ ConstBytes task_execution,
+ PacketSequenceState* sequence_state,
+ size_t sequence_state_generation,
+ ArgsTracker* args_tracker,
+ RowId row) {
+ protos::pbzero::TaskExecution::Decoder task(task_execution.data,
+ task_execution.size);
+ uint64_t iid = task.posted_from_iid();
+ if (!iid)
+ return;
+
+ auto* decoder = sequence_state->LookupInternedMessage<
+ protos::pbzero::InternedData::kSourceLocationsFieldNumber,
+ protos::pbzero::SourceLocation>(sequence_state_generation, iid);
+ if (!decoder)
+ return;
+
+ StringId file_name_id = 0;
+ StringId function_name_id = 0;
+ uint32_t line_number = 0;
+
+ TraceStorage* storage = context_->storage.get();
+ file_name_id = storage->InternString(decoder->file_name());
+ function_name_id = storage->InternString(decoder->function_name());
+ line_number = decoder->line_number();
+
+ args_tracker->AddArg(row, task_file_name_args_key_id_,
+ task_file_name_args_key_id_,
+ Variadic::String(file_name_id));
+ args_tracker->AddArg(row, task_function_name_args_key_id_,
+ task_function_name_args_key_id_,
+ Variadic::String(function_name_id));
+
+ args_tracker->AddArg(row, task_line_number_args_key_id_,
+ task_line_number_args_key_id_,
+ Variadic::UnsignedInteger(line_number));
+}
+
+void TrackEventParser::ParseLogMessage(ConstBytes blob,
+ PacketSequenceState* sequence_state,
+ size_t sequence_state_generation,
+ int64_t ts,
+ base::Optional<UniqueTid> utid,
+ ArgsTracker* args_tracker,
+ RowId row) {
+ if (!utid) {
+ context_->storage->IncrementStats(stats::track_event_parser_errors);
+ PERFETTO_DLOG("LogMessage without thread association");
+ return;
+ }
+
+ protos::pbzero::LogMessage::Decoder message(blob.data, blob.size);
+
+ TraceStorage* storage = context_->storage.get();
+
+ StringId log_message_id = 0;
+
+ auto* decoder = sequence_state->LookupInternedMessage<
+ protos::pbzero::InternedData::kLogMessageBodyFieldNumber,
+ protos::pbzero::LogMessageBody>(sequence_state_generation,
+ message.body_iid());
+ if (!decoder)
+ return;
+
+ log_message_id = storage->InternString(decoder->body());
+
+ // TODO(nicomazz): LogMessage also contains the source of the message (file
+ // and line number). Android logs doesn't support this so far.
+ context_->storage->mutable_android_log()->AddLogEvent(
+ ts, *utid,
+ /*priority*/ 0,
+ /*tag_id*/ 0, // TODO(nicomazz): Abuse tag_id to display
+ // "file_name:line_number".
+ log_message_id);
+
+ args_tracker->AddArg(row, log_message_body_key_id_, log_message_body_key_id_,
+ Variadic::String(log_message_id));
+ // TODO(nicomazz): Add the source location as an argument.
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/track_event_parser.h b/src/trace_processor/importers/proto/track_event_parser.h
new file mode 100644
index 0000000..7e39eb1
--- /dev/null
+++ b/src/trace_processor/importers/proto/track_event_parser.h
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_TRACK_EVENT_PARSER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_TRACK_EVENT_PARSER_H_
+
+#include "src/trace_processor/slice_tracker.h"
+#include "src/trace_processor/trace_storage.h"
+
+#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class PacketSequenceState;
+class TraceProcessorContext;
+
+class TrackEventParser {
+ public:
+ explicit TrackEventParser(TraceProcessorContext* context);
+
+ void ParseTrackEvent(int64_t ts,
+ int64_t tts,
+ int64_t ticount,
+ PacketSequenceState*,
+ size_t sequence_state_generation,
+ protozero::ConstBytes);
+ void ParseLegacyEventAsRawEvent(
+ int64_t ts,
+ int64_t tts,
+ int64_t ticount,
+ base::Optional<UniqueTid> utid,
+ StringId category_id,
+ StringId name_id,
+ const protos::pbzero::TrackEvent::LegacyEvent::Decoder& legacy_event,
+ SliceTracker::SetArgsCallback args_callback);
+ void ParseDebugAnnotationArgs(protozero::ConstBytes debug_annotation,
+ PacketSequenceState*,
+ size_t sequence_state_generation,
+ ArgsTracker* args_tracker,
+ RowId row);
+ void ParseNestedValueArgs(protozero::ConstBytes nested_value,
+ base::StringView flat_key,
+ base::StringView key,
+ ArgsTracker* args_tracker,
+ RowId row);
+ void ParseTaskExecutionArgs(protozero::ConstBytes task_execution,
+ PacketSequenceState*,
+ size_t sequence_state_generation,
+ ArgsTracker* args_tracker,
+ RowId row);
+ void ParseLogMessage(protozero::ConstBytes,
+ PacketSequenceState*,
+ size_t sequence_state_generation,
+ int64_t,
+ base::Optional<UniqueTid>,
+ ArgsTracker*,
+ RowId);
+
+ private:
+ TraceProcessorContext* context_;
+
+ const StringId task_file_name_args_key_id_;
+ const StringId task_function_name_args_key_id_;
+ const StringId task_line_number_args_key_id_;
+ const StringId log_message_body_key_id_;
+ const StringId raw_legacy_event_id_;
+ const StringId legacy_event_category_key_id_;
+ const StringId legacy_event_name_key_id_;
+ const StringId legacy_event_phase_key_id_;
+ const StringId legacy_event_duration_ns_key_id_;
+ const StringId legacy_event_thread_timestamp_ns_key_id_;
+ const StringId legacy_event_thread_duration_ns_key_id_;
+ const StringId legacy_event_thread_instruction_count_key_id_;
+ const StringId legacy_event_thread_instruction_delta_key_id_;
+ const StringId legacy_event_use_async_tts_key_id_;
+ const StringId legacy_event_unscoped_id_key_id_;
+ const StringId legacy_event_global_id_key_id_;
+ const StringId legacy_event_local_id_key_id_;
+ const StringId legacy_event_id_scope_key_id_;
+ const StringId legacy_event_bind_id_key_id_;
+ const StringId legacy_event_bind_to_enclosing_key_id_;
+ const StringId legacy_event_flow_direction_key_id_;
+ const StringId flow_direction_value_in_id_;
+ const StringId flow_direction_value_out_id_;
+ const StringId flow_direction_value_inout_id_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_TRACK_EVENT_PARSER_H_
diff --git a/src/trace_processor/importers/proto/track_event_tokenizer.cc b/src/trace_processor/importers/proto/track_event_tokenizer.cc
new file mode 100644
index 0000000..57df3a5
--- /dev/null
+++ b/src/trace_processor/importers/proto/track_event_tokenizer.cc
@@ -0,0 +1,338 @@
+/*
+ * 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/importers/proto/track_event_tokenizer.h"
+
+#include "perfetto/base/logging.h"
+#include "perfetto/protozero/proto_decoder.h"
+#include "src/trace_processor/clock_tracker.h"
+#include "src/trace_processor/importers/proto/packet_sequence_state.h"
+#include "src/trace_processor/importers/proto/proto_trace_tokenizer.h"
+#include "src/trace_processor/process_tracker.h"
+#include "src/trace_processor/stats.h"
+#include "src/trace_processor/trace_blob_view.h"
+#include "src/trace_processor/trace_sorter.h"
+#include "src/trace_processor/trace_storage.h"
+#include "src/trace_processor/track_tracker.h"
+
+#include "protos/perfetto/trace/clock_snapshot.pbzero.h"
+#include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
+#include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
+#include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
+#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+void TrackEventTokenizer::TokenizeTrackDescriptorPacket(
+ const protos::pbzero::TracePacket::Decoder& packet_decoder) {
+ auto track_descriptor_field = packet_decoder.track_descriptor();
+ protos::pbzero::TrackDescriptor::Decoder track_descriptor_decoder(
+ track_descriptor_field.data, track_descriptor_field.size);
+
+ if (!track_descriptor_decoder.has_uuid()) {
+ PERFETTO_ELOG("TrackDescriptor packet without trusted_packet_sequence_id");
+ context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
+ return;
+ }
+
+ base::Optional<UniquePid> upid;
+ base::Optional<UniqueTid> utid;
+
+ if (track_descriptor_decoder.has_process()) {
+ auto process_descriptor_field = track_descriptor_decoder.process();
+ protos::pbzero::ProcessDescriptor::Decoder process_descriptor_decoder(
+ process_descriptor_field.data, process_descriptor_field.size);
+
+ // TODO(eseckler): Also parse process name / type here.
+
+ upid = context_->process_tracker->GetOrCreateProcess(
+ static_cast<uint32_t>(process_descriptor_decoder.pid()));
+ }
+
+ if (track_descriptor_decoder.has_thread()) {
+ auto thread_descriptor_field = track_descriptor_decoder.thread();
+ protos::pbzero::ThreadDescriptor::Decoder thread_descriptor_decoder(
+ thread_descriptor_field.data, thread_descriptor_field.size);
+
+ TokenizeThreadDescriptor(thread_descriptor_decoder);
+ utid = context_->process_tracker->UpdateThread(
+ static_cast<uint32_t>(thread_descriptor_decoder.tid()),
+ static_cast<uint32_t>(thread_descriptor_decoder.pid()));
+ upid = *context_->storage->GetThread(*utid).upid;
+ }
+
+ StringId name_id =
+ context_->storage->InternString(track_descriptor_decoder.name());
+
+ context_->track_tracker->UpdateDescriptorTrack(
+ track_descriptor_decoder.uuid(), name_id, upid, utid);
+}
+
+void TrackEventTokenizer::TokenizeProcessDescriptorPacket(
+ const protos::pbzero::TracePacket::Decoder& packet_decoder) {
+ protos::pbzero::ProcessDescriptor::Decoder process_descriptor_decoder(
+ packet_decoder.process_descriptor());
+ if (!process_descriptor_decoder.has_chrome_process_type())
+ return;
+ base::StringView name = "Unknown";
+ switch (process_descriptor_decoder.chrome_process_type()) {
+ case protos::pbzero::ProcessDescriptor::PROCESS_BROWSER:
+ name = "Browser";
+ break;
+ case protos::pbzero::ProcessDescriptor::PROCESS_RENDERER:
+ name = "Renderer";
+ break;
+ case protos::pbzero::ProcessDescriptor::PROCESS_UTILITY:
+ name = "Utility";
+ break;
+ case protos::pbzero::ProcessDescriptor::PROCESS_ZYGOTE:
+ name = "Zygote";
+ break;
+ case protos::pbzero::ProcessDescriptor::PROCESS_SANDBOX_HELPER:
+ name = "SandboxHelper";
+ break;
+ case protos::pbzero::ProcessDescriptor::PROCESS_GPU:
+ name = "Gpu";
+ break;
+ case protos::pbzero::ProcessDescriptor::PROCESS_PPAPI_PLUGIN:
+ name = "PpapiPlugin";
+ break;
+ case protos::pbzero::ProcessDescriptor::PROCESS_PPAPI_BROKER:
+ name = "PpapiBroker";
+ break;
+ }
+ context_->process_tracker->SetProcessMetadata(
+ static_cast<uint32_t>(process_descriptor_decoder.pid()), base::nullopt,
+ name);
+}
+
+void TrackEventTokenizer::TokenizeThreadDescriptorPacket(
+ PacketSequenceState* state,
+ const protos::pbzero::TracePacket::Decoder& packet_decoder) {
+ if (PERFETTO_UNLIKELY(!packet_decoder.has_trusted_packet_sequence_id())) {
+ PERFETTO_ELOG("ThreadDescriptor packet without trusted_packet_sequence_id");
+ context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
+ return;
+ }
+
+ // TrackEvents will be ignored while incremental state is invalid. As a
+ // consequence, we should also ignore any ThreadDescriptors received in this
+ // state. Otherwise, any delta-encoded timestamps would be calculated
+ // incorrectly once we move out of the packet loss state. Instead, wait until
+ // the first subsequent descriptor after incremental state is cleared.
+ if (!state->IsIncrementalStateValid()) {
+ context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
+ return;
+ }
+
+ auto thread_descriptor_field = packet_decoder.thread_descriptor();
+ protos::pbzero::ThreadDescriptor::Decoder thread_descriptor_decoder(
+ thread_descriptor_field.data, thread_descriptor_field.size);
+
+ state->SetThreadDescriptor(
+ thread_descriptor_decoder.pid(), thread_descriptor_decoder.tid(),
+ thread_descriptor_decoder.reference_timestamp_us() * 1000,
+ thread_descriptor_decoder.reference_thread_time_us() * 1000,
+ thread_descriptor_decoder.reference_thread_instruction_count());
+
+ TokenizeThreadDescriptor(thread_descriptor_decoder);
+}
+
+void TrackEventTokenizer::TokenizeThreadDescriptor(
+ const protos::pbzero::ThreadDescriptor::Decoder&
+ thread_descriptor_decoder) {
+ base::StringView name;
+ if (thread_descriptor_decoder.has_thread_name()) {
+ name = thread_descriptor_decoder.thread_name();
+ } else if (thread_descriptor_decoder.has_chrome_thread_type()) {
+ using protos::pbzero::ThreadDescriptor;
+ switch (thread_descriptor_decoder.chrome_thread_type()) {
+ case ThreadDescriptor::CHROME_THREAD_MAIN:
+ name = "CrProcessMain";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_IO:
+ name = "ChromeIOThread";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_POOL_FG_WORKER:
+ name = "ThreadPoolForegroundWorker&";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_POOL_BG_WORKER:
+ name = "ThreadPoolBackgroundWorker&";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_POOL_FB_BLOCKING:
+ name = "ThreadPoolSingleThreadForegroundBlocking&";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_POOL_BG_BLOCKING:
+ name = "ThreadPoolSingleThreadBackgroundBlocking&";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_POOL_SERVICE:
+ name = "ThreadPoolService";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_COMPOSITOR_WORKER:
+ name = "CompositorTileWorker&";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_COMPOSITOR:
+ name = "Compositor";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_VIZ_COMPOSITOR:
+ name = "VizCompositorThread";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_SERVICE_WORKER:
+ name = "ServiceWorkerThread&";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_MEMORY_INFRA:
+ name = "MemoryInfra";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_SAMPLING_PROFILER:
+ name = "StackSamplingProfiler";
+ break;
+ case ThreadDescriptor::CHROME_THREAD_UNSPECIFIED:
+ name = "ChromeUnspecified";
+ break;
+ }
+ }
+
+ if (!name.empty()) {
+ auto thread_name_id = context_->storage->InternString(name);
+ ProcessTracker* procs = context_->process_tracker.get();
+ procs->SetThreadName(
+ procs->UpdateThread(
+ static_cast<uint32_t>(thread_descriptor_decoder.tid()),
+ static_cast<uint32_t>(thread_descriptor_decoder.pid())),
+ thread_name_id);
+ }
+}
+
+void TrackEventTokenizer::TokenizeTrackEventPacket(
+ PacketSequenceState* state,
+ const protos::pbzero::TracePacket::Decoder& packet_decoder,
+ TraceBlobView* packet,
+ int64_t packet_timestamp) {
+ constexpr auto kTimestampDeltaUsFieldNumber =
+ protos::pbzero::TrackEvent::kTimestampDeltaUsFieldNumber;
+ constexpr auto kTimestampAbsoluteUsFieldNumber =
+ protos::pbzero::TrackEvent::kTimestampAbsoluteUsFieldNumber;
+ constexpr auto kThreadTimeDeltaUsFieldNumber =
+ protos::pbzero::TrackEvent::kThreadTimeDeltaUsFieldNumber;
+ constexpr auto kThreadTimeAbsoluteUsFieldNumber =
+ protos::pbzero::TrackEvent::kThreadTimeAbsoluteUsFieldNumber;
+ constexpr auto kThreadInstructionCountDeltaFieldNumber =
+ protos::pbzero::TrackEvent::kThreadInstructionCountDeltaFieldNumber;
+ constexpr auto kThreadInstructionCountAbsoluteFieldNumber =
+ protos::pbzero::TrackEvent::kThreadInstructionCountAbsoluteFieldNumber;
+
+ if (PERFETTO_UNLIKELY(!packet_decoder.has_trusted_packet_sequence_id())) {
+ PERFETTO_ELOG("TrackEvent packet without trusted_packet_sequence_id");
+ context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
+ return;
+ }
+
+ // TODO(eseckler): For now, TrackEvents can only be parsed correctly while
+ // incremental state for their sequence is valid, because chromium doesn't set
+ // SEQ_NEEDS_INCREMENTAL_STATE yet. Remove this once it does.
+ if (!state->IsIncrementalStateValid()) {
+ context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
+ return;
+ }
+
+ auto field = packet_decoder.track_event();
+ protozero::ProtoDecoder event_decoder(field.data, field.size);
+
+ int64_t timestamp;
+ int64_t thread_timestamp = 0;
+ int64_t thread_instructions = 0;
+
+ // TODO(eseckler): Remove handling of timestamps relative to ThreadDescriptors
+ // once all producers have switched to clock-domain timestamps (e.g.
+ // TracePacket's timestamp).
+
+ if (auto ts_delta_field =
+ event_decoder.FindField(kTimestampDeltaUsFieldNumber)) {
+ // Delta timestamps require a valid ThreadDescriptor packet since the last
+ // packet loss.
+ if (!state->track_event_timestamps_valid()) {
+ context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
+ return;
+ }
+ timestamp = state->IncrementAndGetTrackEventTimeNs(
+ ts_delta_field.as_int64() * 1000);
+
+ // Legacy TrackEvent timestamp fields are in MONOTONIC domain. Adjust to
+ // trace time if we have a clock snapshot.
+ auto trace_ts = context_->clock_tracker->ToTraceTime(
+ protos::pbzero::ClockSnapshot::Clock::MONOTONIC, timestamp);
+ if (trace_ts.has_value())
+ timestamp = trace_ts.value();
+ } else if (auto ts_absolute_field =
+ event_decoder.FindField(kTimestampAbsoluteUsFieldNumber)) {
+ // One-off absolute timestamps don't affect delta computation.
+ timestamp = ts_absolute_field.as_int64() * 1000;
+
+ // Legacy TrackEvent timestamp fields are in MONOTONIC domain. Adjust to
+ // trace time if we have a clock snapshot.
+ auto trace_ts = context_->clock_tracker->ToTraceTime(
+ protos::pbzero::ClockSnapshot::Clock::MONOTONIC, timestamp);
+ if (trace_ts.has_value())
+ timestamp = trace_ts.value();
+ } else if (packet_decoder.has_timestamp()) {
+ timestamp = packet_timestamp;
+ } else {
+ PERFETTO_ELOG("TrackEvent without timestamp");
+ context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
+ return;
+ }
+
+ if (auto tt_delta_field =
+ event_decoder.FindField(kThreadTimeDeltaUsFieldNumber)) {
+ // Delta timestamps require a valid ThreadDescriptor packet since the last
+ // packet loss.
+ if (!state->track_event_timestamps_valid()) {
+ context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
+ return;
+ }
+ thread_timestamp = state->IncrementAndGetTrackEventThreadTimeNs(
+ tt_delta_field.as_int64() * 1000);
+ } else if (auto tt_absolute_field =
+ event_decoder.FindField(kThreadTimeAbsoluteUsFieldNumber)) {
+ // One-off absolute timestamps don't affect delta computation.
+ thread_timestamp = tt_absolute_field.as_int64() * 1000;
+ }
+
+ if (auto ti_delta_field =
+ event_decoder.FindField(kThreadInstructionCountDeltaFieldNumber)) {
+ // Delta timestamps require a valid ThreadDescriptor packet since the last
+ // packet loss.
+ if (!state->track_event_timestamps_valid()) {
+ context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
+ return;
+ }
+ thread_instructions =
+ state->IncrementAndGetTrackEventThreadInstructionCount(
+ ti_delta_field.as_int64());
+ } else if (auto ti_absolute_field = event_decoder.FindField(
+ kThreadInstructionCountAbsoluteFieldNumber)) {
+ // One-off absolute timestamps don't affect delta computation.
+ thread_instructions = ti_absolute_field.as_int64();
+ }
+
+ context_->sorter->PushTrackEventPacket(timestamp, thread_timestamp,
+ thread_instructions, state,
+ std::move(*packet));
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/track_event_tokenizer.h b/src/trace_processor/importers/proto/track_event_tokenizer.h
new file mode 100644
index 0000000..32e3446
--- /dev/null
+++ b/src/trace_processor/importers/proto/track_event_tokenizer.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_TRACK_EVENT_TOKENIZER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_TRACK_EVENT_TOKENIZER_H_
+
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class PacketSequenceState;
+class TraceProcessorContext;
+class TraceBlobView;
+
+class TrackEventTokenizer {
+ public:
+ explicit TrackEventTokenizer(TraceProcessorContext* context)
+ : context_(context) {}
+
+ void TokenizeTrackDescriptorPacket(
+ const protos::pbzero::TracePacket::Decoder&);
+ void TokenizeProcessDescriptorPacket(
+ const protos::pbzero::TracePacket::Decoder&);
+ void TokenizeThreadDescriptorPacket(
+ PacketSequenceState* state,
+ const protos::pbzero::TracePacket::Decoder&);
+ void TokenizeThreadDescriptor(
+ const protos::pbzero::ThreadDescriptor::Decoder&);
+ void TokenizeTrackEventPacket(PacketSequenceState* state,
+ const protos::pbzero::TracePacket::Decoder&,
+ TraceBlobView* packet,
+ int64_t packet_timestamp);
+
+ private:
+ TraceProcessorContext* context_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_TRACK_EVENT_TOKENIZER_H_
diff --git a/src/trace_processor/importers/systrace/systrace_parser.h b/src/trace_processor/importers/systrace/systrace_parser.h
index a002fc6..569efd0 100644
--- a/src/trace_processor/importers/systrace/systrace_parser.h
+++ b/src/trace_processor/importers/systrace/systrace_parser.h
@@ -21,6 +21,8 @@
#include "src/trace_processor/trace_processor_context.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/string_view.h"
#include "src/trace_processor/trace_storage.h"
@@ -126,12 +128,8 @@
tgid_length++;
}
- if (tgid_length == 0) {
- out->tgid = 0;
- } else {
- std::string tgid_str(s + 2, tgid_length);
- out->tgid = static_cast<uint32_t>(std::stoi(tgid_str.c_str()));
- }
+ std::string tgid_str(s + 2, tgid_length);
+ out->tgid = base::StringToUInt32(tgid_str).value_or(0);
out->phase = ph;
switch (ph) {
@@ -165,8 +163,14 @@
size_t value_len = len - value_index;
if (value_len == 0)
return SystraceParseResult::kFailure;
+ if (*(s + value_index + value_len - 1) == '\n')
+ value_len--;
std::string value_str(s + value_index, value_len);
- out->value = std::stod(value_str.c_str());
+ base::Optional<double> maybe_value = base::StringToDouble(value_str);
+ if (!maybe_value.has_value()) {
+ return SystraceParseResult::kFailure;
+ }
+ out->value = maybe_value.value();
return SystraceParseResult::kSuccess;
}
default:
diff --git a/src/trace_processor/importers/systrace/systrace_trace_parser.cc b/src/trace_processor/importers/systrace/systrace_trace_parser.cc
index be0d2f8..f1d9c6c 100644
--- a/src/trace_processor/importers/systrace/systrace_trace_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_trace_parser.cc
@@ -75,7 +75,10 @@
: ParseState::kSystrace;
}
- const char kSystraceStart[] =
+ // There can be multiple trace data sections in an HTML trace, we want to
+ // ignore any that don't contain systrace data. In the future it would be
+ // good to also parse the process dump section.
+ const char kTraceDataSection[] =
R"(<script class="trace-data" type="application/text">)";
auto start_it = partial_buf_.begin();
for (;;) {
@@ -84,13 +87,20 @@
break;
std::string buffer(start_it, line_it);
+
if (state_ == ParseState::kHtmlBeforeSystrace) {
- if (base::Contains(buffer, kSystraceStart)) {
+ if (base::Contains(buffer, kTraceDataSection)) {
+ state_ = ParseState::kTraceDataSection;
+ }
+ } else if (state_ == ParseState::kTraceDataSection) {
+ if (base::StartsWith(buffer, "#")) {
state_ = ParseState::kSystrace;
+ } else if (base::Contains(buffer, R"(</script>)")) {
+ state_ = ParseState::kHtmlBeforeSystrace;
}
} else if (state_ == ParseState::kSystrace) {
if (base::Contains(buffer, R"(</script>)")) {
- state_ = kEndOfSystrace;
+ state_ = ParseState::kEndOfSystrace;
break;
} else if (!base::StartsWith(buffer, "#")) {
ParseSingleSystraceEvent(buffer);
@@ -115,7 +125,6 @@
//
// However, sometimes the tgid can be missing and buffer looks like this:
// <idle>-0 [000] ...2 0.002188: task_newtask: pid=1 ...
-
size_t task_start;
size_t task_length;
std::tie<size_t, size_t>(task_start, task_length) = FindTask(buffer);
@@ -134,29 +143,40 @@
return util::Status("Could not find [ in " + buffer);
}
- auto pid_end = has_tgid ? cpu_idx : tgid_idx;
+ auto pid_end = has_tgid ? tgid_idx : cpu_idx;
std::string pid_str = SubstrTrim(buffer, task_idx + 1, pid_end);
- auto pid = static_cast<uint32_t>(std::stoi(pid_str));
+ base::Optional<uint32_t> maybe_pid = base::StringToUInt32(pid_str);
+ if (!maybe_pid.has_value()) {
+ return util::Status("Could not convert pid " + pid_str);
+ }
+ uint32_t pid = maybe_pid.value();
context_->process_tracker->GetOrCreateThread(pid);
if (has_tgid) {
auto tgid_end = buffer.find(')', tgid_idx + 1);
std::string tgid_str = SubstrTrim(buffer, tgid_idx + 1, tgid_end);
- if (tgid_str != "-----") {
- context_->process_tracker->UpdateThread(
- pid, static_cast<uint32_t>(std::stoi(tgid_str)));
+ base::Optional<uint32_t> tgid = base::StringToUInt32(tgid_str);
+ if (tgid) {
+ context_->process_tracker->UpdateThread(pid, tgid.value());
}
}
auto cpu_end = buffer.find(']', cpu_idx + 1);
std::string cpu_str = SubstrTrim(buffer, cpu_idx + 1, cpu_end);
- auto cpu = static_cast<uint32_t>(std::stoi(cpu_str));
+ base::Optional<uint32_t> maybe_cpu = base::StringToUInt32(cpu_str);
+ if (!maybe_cpu.has_value()) {
+ return util::Status("Could not convert cpu " + cpu_str);
+ }
+ uint32_t cpu = maybe_cpu.value();
auto ts_idx = buffer.find(' ', cpu_end + 2);
auto ts_end = buffer.find(':', ts_idx + 1);
std::string ts_str = SubstrTrim(buffer, ts_idx + 1, ts_end);
- auto ts_float = std::stod(ts_str) * 1e9;
- auto ts = static_cast<int64_t>(ts_float);
+ base::Optional<double> maybe_ts = base::StringToDouble(ts_str);
+ if (!maybe_ts.has_value()) {
+ return util::Status("Could not convert ts");
+ }
+ int64_t ts = static_cast<int64_t>(maybe_ts.value() * 1e9);
auto fn_idx = buffer.find(':', ts_end + 2);
std::string fn = SubstrTrim(buffer, ts_end + 2, fn_idx);
@@ -181,34 +201,48 @@
int64_t prev_state =
ftrace_utils::TaskState(prev_state_str.c_str()).raw_state();
- auto prev_pid = std::stoi(args["prev_pid"]);
+ auto prev_pid = base::StringToUInt32(args["prev_pid"]);
auto prev_comm = base::StringView(args["prev_comm"]);
- auto prev_prio = std::stoi(args["prev_prio"]);
- auto next_pid = std::stoi(args["next_pid"]);
+ auto prev_prio = base::StringToInt32(args["prev_prio"]);
+ auto next_pid = base::StringToUInt32(args["next_pid"]);
auto next_comm = base::StringView(args["next_comm"]);
- auto next_prio = std::stoi(args["next_prio"]);
+ auto next_prio = base::StringToInt32(args["next_prio"]);
+
+ if (!(prev_pid.has_value() && prev_prio.has_value() &&
+ next_pid.has_value() && next_prio.has_value())) {
+ return util::Status("Could not parse sched_switch");
+ }
context_->sched_tracker->PushSchedSwitch(
- static_cast<uint32_t>(cpu), ts, static_cast<uint32_t>(prev_pid),
- prev_comm, prev_prio, prev_state, static_cast<uint32_t>(next_pid),
- next_comm, next_prio);
+ cpu, ts, prev_pid.value(), prev_comm, prev_prio.value(), prev_state,
+ next_pid.value(), next_comm, next_prio.value());
} else if (fn == "tracing_mark_write" || fn == "0" || fn == "print") {
context_->systrace_parser->ParsePrintEvent(ts, pid, args_str.c_str());
} else if (fn == "sched_wakeup") {
auto comm = args["comm"];
- uint32_t wakee_pid = static_cast<uint32_t>(std::stoi(args["pid"]));
+ base::Optional<uint32_t> wakee_pid = base::StringToUInt32(args["pid"]);
+ if (!wakee_pid.has_value()) {
+ return util::Status("Could not convert wakee_pid");
+ }
StringId name_id = context_->storage->InternString(base::StringView(comm));
auto wakee_utid =
- context_->process_tracker->UpdateThreadName(wakee_pid, name_id);
+ context_->process_tracker->UpdateThreadName(wakee_pid.value(), name_id);
context_->event_tracker->PushInstant(ts, sched_wakeup_name_id_,
0 /* value */, wakee_utid,
RefType::kRefUtid);
} else if (fn == "cpu_idle") {
- auto new_state = static_cast<double>(std::stoul(args["state"]));
- uint32_t event_cpu = static_cast<uint32_t>(std::stoi(args["cpu_id"]));
- context_->event_tracker->PushCounter(ts, new_state, cpu_idle_name_id_,
- event_cpu, RefType::kRefCpuId);
+ base::Optional<uint32_t> event_cpu = base::StringToUInt32(args["cpu_id"]);
+ base::Optional<double> new_state = base::StringToDouble(args["state"]);
+ if (!event_cpu.has_value()) {
+ return util::Status("Could not convert event cpu");
+ }
+ if (!event_cpu.has_value()) {
+ return util::Status("Could not convert state");
+ }
+ context_->event_tracker->PushCounter(ts, new_state.value(),
+ cpu_idle_name_id_, event_cpu.value(),
+ RefType::kRefCpuId);
}
return util::OkStatus();
diff --git a/src/trace_processor/importers/systrace/systrace_trace_parser.h b/src/trace_processor/importers/systrace/systrace_trace_parser.h
index 5703ec8..cbc6ccb 100644
--- a/src/trace_processor/importers/systrace/systrace_trace_parser.h
+++ b/src/trace_processor/importers/systrace/systrace_trace_parser.h
@@ -39,6 +39,7 @@
enum ParseState {
kBeforeParse,
kHtmlBeforeSystrace,
+ kTraceDataSection,
kSystrace,
kEndOfSystrace,
};
diff --git a/src/trace_processor/metrics/android/android_lmk.sql b/src/trace_processor/metrics/android/android_lmk.sql
index 56ad63c..253a7cf 100644
--- a/src/trace_processor/metrics/android/android_lmk.sql
+++ b/src/trace_processor/metrics/android/android_lmk.sql
@@ -55,5 +55,6 @@
'count', count
))
FROM lmk_counts
+ WHERE score IS NOT NULL
)
);
diff --git a/src/trace_processor/process_tracker.cc b/src/trace_processor/process_tracker.cc
index 39b5afb..0dc7693 100644
--- a/src/trace_processor/process_tracker.cc
+++ b/src/trace_processor/process_tracker.cc
@@ -89,6 +89,11 @@
return utid;
}
+void ProcessTracker::SetThreadName(UniqueTid utid, StringId thread_name_id) {
+ TraceStorage::Thread* thread = context_->storage->GetMutableThread(utid);
+ thread->name_id = thread_name_id;
+}
+
UniqueTid ProcessTracker::UpdateThread(uint32_t tid, uint32_t pid) {
auto tids_pair = tids_.equal_range(tid);
diff --git a/src/trace_processor/process_tracker.h b/src/trace_processor/process_tracker.h
index 970843f..6aee798 100644
--- a/src/trace_processor/process_tracker.h
+++ b/src/trace_processor/process_tracker.h
@@ -68,6 +68,9 @@
// the thread_name_id.
virtual UniqueTid UpdateThreadName(uint32_t tid, StringId thread_name_id);
+ // Assigns a new name to a thread uniquely identified by its utid.
+ virtual void SetThreadName(UniqueTid utid, StringId thread_name_id);
+
// Called when a thread is seen the process tree. Retrieves the matching utid
// for the tid and the matching upid for the tgid and stores both.
// Virtual for testing.
diff --git a/src/trace_processor/proto_incremental_state.h b/src/trace_processor/proto_incremental_state.h
deleted file mode 100644
index 7dbfdf3..0000000
--- a/src/trace_processor/proto_incremental_state.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_PROTO_INCREMENTAL_STATE_H_
-#define SRC_TRACE_PROCESSOR_PROTO_INCREMENTAL_STATE_H_
-
-#include <stdint.h>
-#include <string.h>
-
-#include <map>
-#include <unordered_map>
-#include <vector>
-
-#include "perfetto/protozero/proto_decoder.h"
-#include "src/trace_processor/stack_profile_tracker.h"
-#include "src/trace_processor/trace_blob_view.h"
-#include "src/trace_processor/trace_processor_context.h"
-#include "src/trace_processor/trace_storage.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-struct DefaultFieldName;
-struct BuildIdFieldName;
-struct MappingPathsFieldName;
-struct FunctionNamesFieldName;
-struct VulkanAnnotationsFieldName;
-
-#if PERFETTO_DCHECK_IS_ON() && defined(__GNUC__)
-// When called from GetOrCreateDecoder(), __PRETTY_FUNCTION__ (supported by GCC
-// + clang) should include the stringified name of the MessageType.
-#define PERFETTO_TYPE_IDENTIFIER __PRETTY_FUNCTION__
-#else // PERFETTO_DCHECK_IS_ON() && defined(__GNUC__)
-#define PERFETTO_TYPE_IDENTIFIER nullptr
-#endif // PERFETTO_DCHECK_IS_ON() && defined(__GNUC__)
-
-// Stores per-packet-sequence incremental state during trace parsing, such as
-// reference timestamps for delta timestamp calculation and interned messages.
-class ProtoIncrementalState {
- public:
- ProtoIncrementalState(TraceProcessorContext* context) : context_(context) {}
-
- // Entry in an interning index, refers to the interned message.
- struct InternedMessageView {
- InternedMessageView(TraceBlobView msg) : message(std::move(msg)) {}
-
- template <typename MessageType>
- typename MessageType::Decoder* GetOrCreateDecoder() {
- if (!decoder) {
- // Lazy init the decoder and save it away, so that we don't have to
- // reparse the message every time we access the interning entry.
- decoder = std::unique_ptr<void, std::function<void(void*)>>(
- new typename MessageType::Decoder(message.data(), message.length()),
- [](void* obj) {
- delete reinterpret_cast<typename MessageType::Decoder*>(obj);
- });
- decoder_type = PERFETTO_TYPE_IDENTIFIER;
- }
- // Verify that the type of the decoder didn't change.
- if (PERFETTO_TYPE_IDENTIFIER &&
- strcmp(decoder_type,
- // GCC complains if this arg can be null.
- PERFETTO_TYPE_IDENTIFIER ? PERFETTO_TYPE_IDENTIFIER : "") !=
- 0) {
- PERFETTO_FATAL(
- "Interning entry accessed under different types! previous type: "
- "%s. new type: %s.",
- decoder_type, __PRETTY_FUNCTION__);
- }
- return reinterpret_cast<typename MessageType::Decoder*>(decoder.get());
- }
-
- TraceBlobView message;
- std::unique_ptr<void, std::function<void(void*)>> decoder;
-
- private:
- const char* decoder_type = nullptr;
- };
-
- using InternedMessageMap =
- std::unordered_map<uint64_t /*iid*/, InternedMessageView>;
- using InternedFieldMap =
- std::unordered_map<uint32_t /*field_id*/, InternedMessageMap>;
- using InternedDataGenerationList = std::vector<InternedFieldMap>;
-
- class PacketSequenceState {
- public:
- PacketSequenceState(TraceProcessorContext* context)
- : context_(context), stack_profile_tracker_(context) {
- interned_data_.emplace_back();
- }
-
- int64_t IncrementAndGetTrackEventTimeNs(int64_t delta_ns) {
- PERFETTO_DCHECK(track_event_timestamps_valid());
- track_event_timestamp_ns_ += delta_ns;
- return track_event_timestamp_ns_;
- }
-
- int64_t IncrementAndGetTrackEventThreadTimeNs(int64_t delta_ns) {
- PERFETTO_DCHECK(track_event_timestamps_valid());
- track_event_thread_timestamp_ns_ += delta_ns;
- return track_event_thread_timestamp_ns_;
- }
-
- int64_t IncrementAndGetTrackEventThreadInstructionCount(int64_t delta) {
- PERFETTO_DCHECK(track_event_timestamps_valid());
- track_event_thread_instruction_count_ += delta;
- return track_event_thread_instruction_count_;
- }
-
- void OnPacketLoss() {
- packet_loss_ = true;
- track_event_timestamps_valid_ = false;
- }
-
- void OnIncrementalStateCleared() {
- packet_loss_ = false;
- interned_data_.emplace_back(); // Bump generation number
- }
-
- void SetThreadDescriptor(int32_t pid,
- int32_t tid,
- int64_t timestamp_ns,
- int64_t thread_timestamp_ns,
- int64_t thread_instruction_count) {
- track_event_timestamps_valid_ = true;
- pid_and_tid_valid_ = true;
- pid_ = pid;
- tid_ = tid;
- track_event_timestamp_ns_ = timestamp_ns;
- track_event_thread_timestamp_ns_ = thread_timestamp_ns;
- track_event_thread_instruction_count_ = thread_instruction_count;
- }
-
- bool IsIncrementalStateValid() const { return !packet_loss_; }
-
- StackProfileTracker& stack_profile_tracker() {
- return stack_profile_tracker_;
- }
-
- // Returns the index of the current generation in the
- // InternedDataGenerationList.
- size_t current_generation() const { return interned_data_.size() - 1; }
-
- bool track_event_timestamps_valid() const {
- return track_event_timestamps_valid_;
- }
-
- bool pid_and_tid_valid() const { return pid_and_tid_valid_; }
-
- int32_t pid() const { return pid_; }
- int32_t tid() const { return tid_; }
-
- void InternMessage(uint32_t field_id, TraceBlobView message) {
- constexpr auto kIidFieldNumber = 1;
-
- uint64_t iid = 0;
- auto message_start = message.data();
- auto message_size = message.length();
- protozero::ProtoDecoder decoder(message_start, message_size);
-
- auto field = decoder.FindField(kIidFieldNumber);
- if (PERFETTO_UNLIKELY(!field)) {
- PERFETTO_DLOG("Interned message without interning_id");
- context_->storage->IncrementStats(
- stats::interned_data_tokenizer_errors);
- return;
- }
- iid = field.as_uint64();
-
- auto* map = &interned_data_.back()[field_id];
- auto res = map->emplace(iid, InternedMessageView(std::move(message)));
-
- // If a message with this ID is already interned in the same generation,
- // its data should not have changed (this is forbidden by the InternedData
- // proto).
- // TODO(eseckler): This DCHECK assumes that the message is encoded the
- // same way if it is re-emitted.
- PERFETTO_DCHECK(res.second ||
- (res.first->second.message.length() == message_size &&
- memcmp(res.first->second.message.data(), message_start,
- message_size) == 0));
- }
-
- template <uint32_t FieldId, typename MessageType>
- typename MessageType::Decoder* LookupInternedMessage(size_t generation,
- uint64_t iid) {
- PERFETTO_CHECK(generation <= interned_data_.size());
- auto* field_map = &interned_data_[generation];
- auto field_it = field_map->find(FieldId);
- if (field_it != field_map->end()) {
- auto* message_map = &field_it->second;
- auto it = message_map->find(iid);
- if (it != message_map->end()) {
- return it->second.GetOrCreateDecoder<MessageType>();
- }
- }
- context_->storage->IncrementStats(stats::interned_data_tokenizer_errors);
- PERFETTO_DLOG("Could not find interning entry for field ID %" PRIu32
- ", generation %zu, and IID %" PRIu64,
- FieldId, generation, iid);
- return nullptr;
- }
-
- private:
- TraceProcessorContext* context_;
-
- // If true, incremental state on the sequence is considered invalid until we
- // see the next packet with incremental_state_cleared. We assume that we
- // missed some packets at the beginning of the trace.
- bool packet_loss_ = true;
-
- // We can only consider TrackEvent delta timestamps to be correct after we
- // have observed a thread descriptor (since the last packet loss).
- bool track_event_timestamps_valid_ = false;
-
- // |pid_| and |tid_| are only valid after we parsed at least one
- // ThreadDescriptor packet on the sequence.
- bool pid_and_tid_valid_ = false;
-
- // Process/thread ID of the packet sequence set by a ThreadDescriptor
- // packet. Used as default values for TrackEvents that don't specify a
- // pid/tid override. Only valid after |pid_and_tid_valid_| is set to true.
- int32_t pid_ = 0;
- int32_t tid_ = 0;
-
- // Current wall/thread timestamps/counters used as reference for the next
- // TrackEvent delta timestamp.
- int64_t track_event_timestamp_ns_ = 0;
- int64_t track_event_thread_timestamp_ns_ = 0;
- int64_t track_event_thread_instruction_count_ = 0;
-
- InternedDataGenerationList interned_data_;
- StackProfileTracker stack_profile_tracker_;
- };
-
- // Returns the PacketSequenceState for the packet sequence with the given id.
- // If this is a new sequence which we haven't tracked before, initializes and
- // inserts a new PacketSequenceState into the state map.
- PacketSequenceState* GetOrCreateStateForPacketSequence(uint32_t sequence_id) {
- auto& ptr = packet_sequence_states_[sequence_id];
- if (!ptr)
- ptr.reset(new PacketSequenceState(context_));
- return ptr.get();
- }
-
- private:
- // Stores unique_ptrs to ensure that pointers to a PacketSequenceState remain
- // valid even if the map rehashes.
- std::map<uint32_t, std::unique_ptr<PacketSequenceState>>
- packet_sequence_states_;
-
- TraceProcessorContext* context_;
-};
-
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_PROTO_INCREMENTAL_STATE_H_
diff --git a/src/trace_processor/proto_trace_parser.cc b/src/trace_processor/proto_trace_parser.cc
deleted file mode 100644
index 42daa08..0000000
--- a/src/trace_processor/proto_trace_parser.cc
+++ /dev/null
@@ -1,2091 +0,0 @@
-/*
- * Copyright (C) 2018 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/proto_trace_parser.h"
-
-#include <inttypes.h>
-#include <string.h>
-
-#include <string>
-
-#include "perfetto/base/logging.h"
-#include "perfetto/ext/base/metatrace_events.h"
-#include "perfetto/ext/base/string_utils.h"
-#include "perfetto/ext/base/string_view.h"
-#include "perfetto/ext/base/string_writer.h"
-#include "perfetto/ext/base/utils.h"
-#include "perfetto/ext/traced/sys_stats_counters.h"
-#include "perfetto/protozero/proto_decoder.h"
-#include "perfetto/trace_processor/status.h"
-#include "src/trace_processor/args_tracker.h"
-#include "src/trace_processor/clock_tracker.h"
-#include "src/trace_processor/event_tracker.h"
-#include "src/trace_processor/heap_graph_tracker.h"
-#include "src/trace_processor/heap_profile_tracker.h"
-#include "src/trace_processor/importers/ftrace/ftrace_module.h"
-#include "src/trace_processor/importers/proto/track_event_module.h"
-#include "src/trace_processor/importers/systrace/systrace_parser.h"
-#include "src/trace_processor/metadata.h"
-#include "src/trace_processor/process_tracker.h"
-#include "src/trace_processor/proto_incremental_state.h"
-#include "src/trace_processor/stack_profile_tracker.h"
-#include "src/trace_processor/syscall_tracker.h"
-#include "src/trace_processor/timestamped_trace_piece.h"
-#include "src/trace_processor/trace_processor_context.h"
-#include "src/trace_processor/track_tracker.h"
-#include "src/trace_processor/variadic.h"
-
-#include "protos/perfetto/common/android_log_constants.pbzero.h"
-#include "protos/perfetto/common/trace_stats.pbzero.h"
-#include "protos/perfetto/config/trace_config.pbzero.h"
-#include "protos/perfetto/trace/android/android_log.pbzero.h"
-#include "protos/perfetto/trace/android/packages_list.pbzero.h"
-#include "protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h"
-#include "protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h"
-#include "protos/perfetto/trace/clock_snapshot.pbzero.h"
-#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
-#include "protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h"
-#include "protos/perfetto/trace/power/battery_counters.pbzero.h"
-#include "protos/perfetto/trace/power/power_rails.pbzero.h"
-#include "protos/perfetto/trace/profiling/heap_graph.pbzero.h"
-#include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
-#include "protos/perfetto/trace/profiling/profile_packet.pbzero.h"
-#include "protos/perfetto/trace/ps/process_stats.pbzero.h"
-#include "protos/perfetto/trace/ps/process_tree.pbzero.h"
-#include "protos/perfetto/trace/sys_stats/sys_stats.pbzero.h"
-#include "protos/perfetto/trace/system_info.pbzero.h"
-#include "protos/perfetto/trace/trace.pbzero.h"
-#include "protos/perfetto/trace/trace_packet.pbzero.h"
-#include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
-#include "protos/perfetto/trace/track_event/log_message.pbzero.h"
-#include "protos/perfetto/trace/track_event/source_location.pbzero.h"
-#include "protos/perfetto/trace/track_event/task_execution.pbzero.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-namespace {
-
-// kthreadd is the parent process for all kernel threads and always has
-// pid == 2 on Linux and Android.
-const uint32_t kKthreaddPid = 2;
-const char kKthreaddName[] = "kthreadd";
-
-using protozero::ProtoDecoder;
-
-StackProfileTracker::SourceMapping MakeSourceMapping(
- const protos::pbzero::Mapping::Decoder& entry) {
- StackProfileTracker::SourceMapping src_mapping{};
- src_mapping.build_id = entry.build_id();
- src_mapping.exact_offset = entry.exact_offset();
- src_mapping.start_offset = entry.start_offset();
- src_mapping.start = entry.start();
- src_mapping.end = entry.end();
- src_mapping.load_bias = entry.load_bias();
- for (auto path_string_id_it = entry.path_string_ids(); path_string_id_it;
- ++path_string_id_it)
- src_mapping.name_ids.emplace_back(*path_string_id_it);
- return src_mapping;
-}
-
-StackProfileTracker::SourceFrame MakeSourceFrame(
- const protos::pbzero::Frame::Decoder& entry) {
- StackProfileTracker::SourceFrame src_frame;
- src_frame.name_id = entry.function_name_id();
- src_frame.mapping_id = entry.mapping_id();
- src_frame.rel_pc = entry.rel_pc();
- return src_frame;
-}
-
-StackProfileTracker::SourceCallstack MakeSourceCallstack(
- const protos::pbzero::Callstack::Decoder& entry) {
- StackProfileTracker::SourceCallstack src_callstack;
- for (auto frame_it = entry.frame_ids(); frame_it; ++frame_it)
- src_callstack.emplace_back(*frame_it);
- return src_callstack;
-}
-
-class ProfilePacketInternLookup : public StackProfileTracker::InternLookup {
- public:
- ProfilePacketInternLookup(
- ProtoIncrementalState::PacketSequenceState* seq_state,
- size_t seq_state_generation)
- : seq_state_(seq_state), seq_state_generation_(seq_state_generation) {}
-
- base::Optional<base::StringView> GetString(
- StackProfileTracker::SourceStringId iid,
- StackProfileTracker::InternedStringType type) const override {
- protos::pbzero::InternedString::Decoder* decoder = nullptr;
- switch (type) {
- case StackProfileTracker::InternedStringType::kBuildId:
- decoder = seq_state_->LookupInternedMessage<
- protos::pbzero::InternedData::kBuildIdsFieldNumber,
- protos::pbzero::InternedString>(seq_state_generation_, iid);
- break;
- case StackProfileTracker::InternedStringType::kFunctionName:
- decoder = seq_state_->LookupInternedMessage<
- protos::pbzero::InternedData::kFunctionNamesFieldNumber,
- protos::pbzero::InternedString>(seq_state_generation_, iid);
- break;
- case StackProfileTracker::InternedStringType::kMappingPath:
- decoder = seq_state_->LookupInternedMessage<
- protos::pbzero::InternedData::kMappingPathsFieldNumber,
- protos::pbzero::InternedString>(seq_state_generation_, iid);
- break;
- }
- if (!decoder)
- return base::nullopt;
- return base::StringView(reinterpret_cast<const char*>(decoder->str().data),
- decoder->str().size);
- }
-
- base::Optional<StackProfileTracker::SourceMapping> GetMapping(
- StackProfileTracker::SourceMappingId iid) const override {
- auto* decoder = seq_state_->LookupInternedMessage<
- protos::pbzero::InternedData::kMappingsFieldNumber,
- protos::pbzero::Mapping>(seq_state_generation_, iid);
- if (!decoder)
- return base::nullopt;
- return MakeSourceMapping(*decoder);
- }
-
- base::Optional<StackProfileTracker::SourceFrame> GetFrame(
- StackProfileTracker::SourceFrameId iid) const override {
- auto* decoder = seq_state_->LookupInternedMessage<
- protos::pbzero::InternedData::kFramesFieldNumber,
- protos::pbzero::Frame>(seq_state_generation_, iid);
- if (!decoder)
- return base::nullopt;
- return MakeSourceFrame(*decoder);
- }
-
- base::Optional<StackProfileTracker::SourceCallstack> GetCallstack(
- StackProfileTracker::SourceCallstackId iid) const override {
- auto* decoder = seq_state_->LookupInternedMessage<
- protos::pbzero::InternedData::kCallstacksFieldNumber,
- protos::pbzero::Callstack>(seq_state_generation_, iid);
- if (!decoder)
- return base::nullopt;
- return MakeSourceCallstack(*decoder);
- }
-
- private:
- ProtoIncrementalState::PacketSequenceState* seq_state_;
- size_t seq_state_generation_;
-};
-
-namespace {
-// Slices which have been opened but haven't been closed yet will be marked
-// with these placeholder values.
-constexpr int64_t kPendingThreadDuration = -1;
-constexpr int64_t kPendingThreadInstructionDelta = -1;
-} // namespace
-
-const char* HeapGraphRootTypeToString(int32_t type) {
- switch (type) {
- case protos::pbzero::HeapGraphRoot::ROOT_UNKNOWN:
- return "ROOT_UNKNOWN";
- case protos::pbzero::HeapGraphRoot::ROOT_JNI_GLOBAL:
- return "ROOT_JNI_GLOBAL";
- case protos::pbzero::HeapGraphRoot::ROOT_JNI_LOCAL:
- return "ROOT_JNI_LOCAL";
- case protos::pbzero::HeapGraphRoot::ROOT_JAVA_FRAME:
- return "ROOT_JAVA_FRAME";
- case protos::pbzero::HeapGraphRoot::ROOT_NATIVE_STACK:
- return "ROOT_NATIVE_STACK";
- case protos::pbzero::HeapGraphRoot::ROOT_STICKY_CLASS:
- return "ROOT_STICKY_CLASS";
- case protos::pbzero::HeapGraphRoot::ROOT_THREAD_BLOCK:
- return "ROOT_THREAD_BLOCK";
- case protos::pbzero::HeapGraphRoot::ROOT_MONITOR_USED:
- return "ROOT_MONITOR_USED";
- case protos::pbzero::HeapGraphRoot::ROOT_THREAD_OBJECT:
- return "ROOT_THREAD_OBJECT";
- case protos::pbzero::HeapGraphRoot::ROOT_INTERNED_STRING:
- return "ROOT_INTERNED_STRING";
- case protos::pbzero::HeapGraphRoot::ROOT_FINALIZING:
- return "ROOT_FINALIZING";
- case protos::pbzero::HeapGraphRoot::ROOT_DEBUGGER:
- return "ROOT_DEBUGGER";
- case protos::pbzero::HeapGraphRoot::ROOT_REFERENCE_CLEANUP:
- return "ROOT_REFERENCE_CLEANUP";
- case protos::pbzero::HeapGraphRoot::ROOT_VM_INTERNAL:
- return "ROOT_VM_INTERNAL";
- case protos::pbzero::HeapGraphRoot::ROOT_JNI_MONITOR:
- return "ROOT_JNI_MONITOR";
- default:
- return "ROOT_UNKNOWN";
- }
-}
-
-} // namespace
-
-ProtoTraceParser::ProtoTraceParser(TraceProcessorContext* context)
- : context_(context),
- graphics_event_parser_(new GraphicsEventParser(context_)),
- utid_name_id_(context->storage->InternString("utid")),
- num_forks_name_id_(context->storage->InternString("num_forks")),
- num_irq_total_name_id_(context->storage->InternString("num_irq_total")),
- num_softirq_total_name_id_(
- context->storage->InternString("num_softirq_total")),
- num_irq_name_id_(context->storage->InternString("num_irq")),
- num_softirq_name_id_(context->storage->InternString("num_softirq")),
- cpu_times_user_ns_id_(
- context->storage->InternString("cpu.times.user_ns")),
- cpu_times_user_nice_ns_id_(
- context->storage->InternString("cpu.times.user_nice_ns")),
- cpu_times_system_mode_ns_id_(
- context->storage->InternString("cpu.times.system_mode_ns")),
- cpu_times_idle_ns_id_(
- context->storage->InternString("cpu.times.idle_ns")),
- cpu_times_io_wait_ns_id_(
- context->storage->InternString("cpu.times.io_wait_ns")),
- cpu_times_irq_ns_id_(context->storage->InternString("cpu.times.irq_ns")),
- cpu_times_softirq_ns_id_(
- context->storage->InternString("cpu.times.softirq_ns")),
- batt_charge_id_(context->storage->InternString("batt.charge_uah")),
- batt_capacity_id_(context->storage->InternString("batt.capacity_pct")),
- batt_current_id_(context->storage->InternString("batt.current_ua")),
- batt_current_avg_id_(
- context->storage->InternString("batt.current.avg_ua")),
- oom_score_adj_id_(context->storage->InternString("oom_score_adj")),
- metatrace_id_(context->storage->InternString("metatrace")),
- task_file_name_args_key_id_(
- context->storage->InternString("task.posted_from.file_name")),
- task_function_name_args_key_id_(
- context->storage->InternString("task.posted_from.function_name")),
- task_line_number_args_key_id_(
- context->storage->InternString("task.posted_from.line_number")),
- log_message_body_key_id_(
- context->storage->InternString("track_event.log_message")),
- data_name_id_(context->storage->InternString("data")),
- raw_chrome_metadata_event_id_(
- context->storage->InternString("chrome_event.metadata")),
- raw_chrome_legacy_system_trace_event_id_(
- context->storage->InternString("chrome_event.legacy_system_trace")),
- raw_chrome_legacy_user_trace_event_id_(
- context->storage->InternString("chrome_event.legacy_user_trace")),
- raw_legacy_event_id_(
- context->storage->InternString("track_event.legacy_event")),
- legacy_event_category_key_id_(
- context->storage->InternString("legacy_event.category")),
- legacy_event_name_key_id_(
- context->storage->InternString("legacy_event.name")),
- legacy_event_phase_key_id_(
- context->storage->InternString("legacy_event.phase")),
- legacy_event_duration_ns_key_id_(
- context->storage->InternString("legacy_event.duration_ns")),
- legacy_event_thread_timestamp_ns_key_id_(
- context->storage->InternString("legacy_event.thread_timestamp_ns")),
- legacy_event_thread_duration_ns_key_id_(
- context->storage->InternString("legacy_event.thread_duration_ns")),
- legacy_event_thread_instruction_count_key_id_(
- context->storage->InternString(
- "legacy_event.thread_instruction_count")),
- legacy_event_thread_instruction_delta_key_id_(
- context->storage->InternString(
- "legacy_event.thread_instruction_delta")),
- legacy_event_use_async_tts_key_id_(
- context->storage->InternString("legacy_event.use_async_tts")),
- legacy_event_unscoped_id_key_id_(
- context->storage->InternString("legacy_event.unscoped_id")),
- legacy_event_global_id_key_id_(
- context->storage->InternString("legacy_event.global_id")),
- legacy_event_local_id_key_id_(
- context->storage->InternString("legacy_event.local_id")),
- legacy_event_id_scope_key_id_(
- context->storage->InternString("legacy_event.id_scope")),
- legacy_event_bind_id_key_id_(
- context->storage->InternString("legacy_event.bind_id")),
- legacy_event_bind_to_enclosing_key_id_(
- context->storage->InternString("legacy_event.bind_to_enclosing")),
- legacy_event_flow_direction_key_id_(
- context->storage->InternString("legacy_event.flow_direction")),
- flow_direction_value_in_id_(context->storage->InternString("in")),
- flow_direction_value_out_id_(context->storage->InternString("out")),
- flow_direction_value_inout_id_(context->storage->InternString("inout")) {
- for (const auto& name : BuildMeminfoCounterNames()) {
- meminfo_strs_id_.emplace_back(context->storage->InternString(name));
- }
- for (const auto& name : BuildVmstatCounterNames()) {
- vmstat_strs_id_.emplace_back(context->storage->InternString(name));
- }
-
- using ProcessStats = protos::pbzero::ProcessStats;
- proc_stats_process_names_[ProcessStats::Process::kVmSizeKbFieldNumber] =
- context->storage->InternString("mem.virt");
- proc_stats_process_names_[ProcessStats::Process::kVmRssKbFieldNumber] =
- context->storage->InternString("mem.rss");
- proc_stats_process_names_[ProcessStats::Process::kRssAnonKbFieldNumber] =
- context->storage->InternString("mem.rss.anon");
- proc_stats_process_names_[ProcessStats::Process::kRssFileKbFieldNumber] =
- context->storage->InternString("mem.rss.file");
- proc_stats_process_names_[ProcessStats::Process::kRssShmemKbFieldNumber] =
- context->storage->InternString("mem.rss.shmem");
- proc_stats_process_names_[ProcessStats::Process::kVmSwapKbFieldNumber] =
- context->storage->InternString("mem.swap");
- proc_stats_process_names_[ProcessStats::Process::kVmLockedKbFieldNumber] =
- context->storage->InternString("mem.locked");
- proc_stats_process_names_[ProcessStats::Process::kVmHwmKbFieldNumber] =
- context->storage->InternString("mem.rss.watermark");
- proc_stats_process_names_[ProcessStats::Process::kOomScoreAdjFieldNumber] =
- oom_score_adj_id_;
-
- // TODO(140860736): Once we support null values for
- // stack_profile_frame.symbol_set_id remove this hack
- context_->storage->mutable_symbol_table()->Insert({0, 0, 0, 0});
-}
-
-ProtoTraceParser::~ProtoTraceParser() = default;
-
-void ProtoTraceParser::ParseTracePacket(int64_t ts, TimestampedTracePiece ttp) {
- PERFETTO_DCHECK(ttp.json_value == nullptr);
-
- const TraceBlobView& blob = ttp.blob_view;
- protos::pbzero::TracePacket::Decoder packet(blob.data(), blob.length());
-
- ParseTracePacketImpl(ts, std::move(ttp), packet);
-
- // TODO(lalitm): maybe move this to the flush method in the trace processor
- // once we have it. This may reduce performance in the ArgsTracker though so
- // needs to be handled carefully.
- context_->args_tracker->Flush();
- PERFETTO_DCHECK(!packet.bytes_left());
-}
-
-void ProtoTraceParser::ParseTracePacketImpl(
- int64_t ts,
- TimestampedTracePiece ttp,
- const protos::pbzero::TracePacket::Decoder& packet) {
- // TODO(eseckler): Propagate statuses from modules.
- if (!context_->ftrace_module->ParsePacket(packet, ttp).ignored())
- return;
-
- if (!context_->track_event_module->ParsePacket(packet, ttp).ignored())
- return;
-
- if (packet.has_process_tree())
- ParseProcessTree(packet.process_tree());
-
- if (packet.has_process_stats())
- ParseProcessStats(ts, packet.process_stats());
-
- if (packet.has_sys_stats())
- ParseSysStats(ts, packet.sys_stats());
-
- if (packet.has_battery())
- ParseBatteryCounters(ts, packet.battery());
-
- if (packet.has_power_rails())
- ParsePowerRails(ts, packet.power_rails());
-
- if (packet.has_trace_stats())
- ParseTraceStats(packet.trace_stats());
-
- if (packet.has_android_log())
- ParseAndroidLogPacket(packet.android_log());
-
- if (packet.has_profile_packet()) {
- ParseProfilePacket(ts, ttp.packet_sequence_state,
- ttp.packet_sequence_state_generation,
- packet.profile_packet());
- }
-
- if (packet.has_streaming_profile_packet()) {
- ParseStreamingProfilePacket(ttp.packet_sequence_state,
- ttp.packet_sequence_state_generation,
- packet.streaming_profile_packet());
- }
-
- if (packet.has_system_info())
- ParseSystemInfo(packet.system_info());
-
- if (packet.has_track_event()) {
- ParseTrackEvent(ts, ttp.thread_timestamp, ttp.thread_instruction_count,
- ttp.packet_sequence_state,
- ttp.packet_sequence_state_generation, packet.track_event());
- }
-
- if (packet.has_chrome_benchmark_metadata()) {
- ParseChromeBenchmarkMetadata(packet.chrome_benchmark_metadata());
- }
-
- if (packet.has_chrome_events()) {
- ParseChromeEvents(ts, packet.chrome_events());
- }
-
- if (packet.has_perfetto_metatrace()) {
- ParseMetatraceEvent(ts, packet.perfetto_metatrace());
- }
-
- if (packet.has_gpu_counter_event()) {
- graphics_event_parser_->ParseGpuCounterEvent(ts,
- packet.gpu_counter_event());
- }
-
- if (packet.has_gpu_render_stage_event()) {
- graphics_event_parser_->ParseGpuRenderStageEvent(
- ts, packet.gpu_render_stage_event());
- }
-
- if (packet.has_trace_config()) {
- ParseTraceConfig(packet.trace_config());
- }
-
- if (packet.has_gpu_log()) {
- graphics_event_parser_->ParseGpuLog(ts, packet.gpu_log());
- }
-
- if (packet.has_packages_list()) {
- ParseAndroidPackagesList(packet.packages_list());
- }
-
- if (packet.has_graphics_frame_event()) {
- graphics_event_parser_->ParseGraphicsFrameEvent(
- ts, packet.graphics_frame_event());
- }
-
- if (packet.has_module_symbols()) {
- ParseModuleSymbols(packet.module_symbols());
- }
-
- if (packet.has_heap_graph()) {
- ParseHeapGraph(ts, packet.heap_graph());
- }
-
- if (packet.has_vulkan_memory_event()) {
- graphics_event_parser_->ParseVulkanMemoryEvent(
- packet.vulkan_memory_event());
- }
-}
-
-void ProtoTraceParser::ParseSysStats(int64_t ts, ConstBytes blob) {
- protos::pbzero::SysStats::Decoder sys_stats(blob.data, blob.size);
-
- for (auto it = sys_stats.meminfo(); it; ++it) {
- protos::pbzero::SysStats::MeminfoValue::Decoder mi(*it);
- auto key = static_cast<size_t>(mi.key());
- if (PERFETTO_UNLIKELY(key >= meminfo_strs_id_.size())) {
- PERFETTO_ELOG("MemInfo key %zu is not recognized.", key);
- context_->storage->IncrementStats(stats::meminfo_unknown_keys);
- continue;
- }
- // /proc/meminfo counters are in kB, convert to bytes
- context_->event_tracker->PushCounter(
- ts, mi.value() * 1024L, meminfo_strs_id_[key], 0, RefType::kRefNoRef);
- }
-
- for (auto it = sys_stats.vmstat(); it; ++it) {
- protos::pbzero::SysStats::VmstatValue::Decoder vm(*it);
- auto key = static_cast<size_t>(vm.key());
- if (PERFETTO_UNLIKELY(key >= vmstat_strs_id_.size())) {
- PERFETTO_ELOG("VmStat key %zu is not recognized.", key);
- context_->storage->IncrementStats(stats::vmstat_unknown_keys);
- continue;
- }
- context_->event_tracker->PushCounter(ts, vm.value(), vmstat_strs_id_[key],
- 0, RefType::kRefNoRef);
- }
-
- for (auto it = sys_stats.cpu_stat(); it; ++it) {
- protos::pbzero::SysStats::CpuTimes::Decoder ct(*it);
- if (PERFETTO_UNLIKELY(!ct.has_cpu_id())) {
- PERFETTO_ELOG("CPU field not found in CpuTimes");
- context_->storage->IncrementStats(stats::invalid_cpu_times);
- continue;
- }
- context_->event_tracker->PushCounter(ts, ct.user_ns(),
- cpu_times_user_ns_id_, ct.cpu_id(),
- RefType::kRefCpuId);
- context_->event_tracker->PushCounter(ts, ct.user_ice_ns(),
- cpu_times_user_nice_ns_id_,
- ct.cpu_id(), RefType::kRefCpuId);
- context_->event_tracker->PushCounter(ts, ct.system_mode_ns(),
- cpu_times_system_mode_ns_id_,
- ct.cpu_id(), RefType::kRefCpuId);
- context_->event_tracker->PushCounter(ts, ct.idle_ns(),
- cpu_times_idle_ns_id_, ct.cpu_id(),
- RefType::kRefCpuId);
- context_->event_tracker->PushCounter(ts, ct.io_wait_ns(),
- cpu_times_io_wait_ns_id_, ct.cpu_id(),
- RefType::kRefCpuId);
- context_->event_tracker->PushCounter(ts, ct.irq_ns(), cpu_times_irq_ns_id_,
- ct.cpu_id(), RefType::kRefCpuId);
- context_->event_tracker->PushCounter(ts, ct.softirq_ns(),
- cpu_times_softirq_ns_id_, ct.cpu_id(),
- RefType::kRefCpuId);
- }
-
- for (auto it = sys_stats.num_irq(); it; ++it) {
- protos::pbzero::SysStats::InterruptCount::Decoder ic(*it);
- context_->event_tracker->PushCounter(ts, ic.count(), num_irq_name_id_,
- ic.irq(), RefType::kRefIrq);
- }
-
- for (auto it = sys_stats.num_softirq(); it; ++it) {
- protos::pbzero::SysStats::InterruptCount::Decoder ic(*it);
- context_->event_tracker->PushCounter(ts, ic.count(), num_softirq_name_id_,
- ic.irq(), RefType::kRefSoftIrq);
- }
-
- if (sys_stats.has_num_forks()) {
- context_->event_tracker->PushCounter(
- ts, sys_stats.num_forks(), num_forks_name_id_, 0, RefType::kRefNoRef);
- }
-
- if (sys_stats.has_num_irq_total()) {
- context_->event_tracker->PushCounter(ts, sys_stats.num_irq_total(),
- num_irq_total_name_id_, 0,
- RefType::kRefNoRef);
- }
-
- if (sys_stats.has_num_softirq_total()) {
- context_->event_tracker->PushCounter(ts, sys_stats.num_softirq_total(),
- num_softirq_total_name_id_, 0,
- RefType::kRefNoRef);
- }
-}
-
-void ProtoTraceParser::ParseProcessTree(ConstBytes blob) {
- protos::pbzero::ProcessTree::Decoder ps(blob.data, blob.size);
-
- for (auto it = ps.processes(); it; ++it) {
- protos::pbzero::ProcessTree::Process::Decoder proc(*it);
- if (!proc.has_cmdline())
- continue;
- auto pid = static_cast<uint32_t>(proc.pid());
- auto ppid = static_cast<uint32_t>(proc.ppid());
-
- // If the parent pid is kthreadd's pid, even though this pid is of a
- // "process", we want to treat it as being a child thread of kthreadd.
- if (ppid == kKthreaddPid) {
- context_->process_tracker->SetProcessMetadata(kKthreaddPid, base::nullopt,
- kKthreaddName);
- context_->process_tracker->UpdateThread(pid, kKthreaddPid);
- } else {
- auto args = proc.cmdline();
- base::StringView argv0 = args ? *args : base::StringView();
- context_->process_tracker->SetProcessMetadata(pid, ppid, argv0);
- }
- }
-
- for (auto it = ps.threads(); it; ++it) {
- protos::pbzero::ProcessTree::Thread::Decoder thd(*it);
- auto tid = static_cast<uint32_t>(thd.tid());
- auto tgid = static_cast<uint32_t>(thd.tgid());
- context_->process_tracker->UpdateThread(tid, tgid);
-
- if (thd.has_name()) {
- StringId threadNameId = context_->storage->InternString(thd.name());
- context_->process_tracker->UpdateThreadName(tid, threadNameId);
- }
- }
-}
-
-void ProtoTraceParser::ParseProcessStats(int64_t ts, ConstBytes blob) {
- protos::pbzero::ProcessStats::Decoder stats(blob.data, blob.size);
- const auto kOomScoreAdjFieldNumber =
- protos::pbzero::ProcessStats::Process::kOomScoreAdjFieldNumber;
- for (auto it = stats.processes(); it; ++it) {
- // Maps a process counter field it to its value.
- // E.g., 4 := 1024 -> "mem.rss.anon" := 1024.
- std::array<int64_t, kProcStatsProcessSize> counter_values{};
- std::array<bool, kProcStatsProcessSize> has_counter{};
-
- ProtoDecoder proc(*it);
- uint32_t pid = 0;
- for (auto fld = proc.ReadField(); fld.valid(); fld = proc.ReadField()) {
- if (fld.id() == protos::pbzero::ProcessStats::Process::kPidFieldNumber) {
- pid = fld.as_uint32();
- continue;
- }
- bool is_counter_field = fld.id() < proc_stats_process_names_.size() &&
- proc_stats_process_names_[fld.id()] != 0;
- if (is_counter_field) {
- // Memory counters are in KB, keep values in bytes in the trace
- // processor.
- counter_values[fld.id()] = fld.id() == kOomScoreAdjFieldNumber
- ? fld.as_int64()
- : fld.as_int64() * 1024;
- has_counter[fld.id()] = true;
- } else {
- context_->storage->IncrementStats(stats::proc_stat_unknown_counters);
- }
- }
-
- // Skip field_id 0 (invalid) and 1 (pid).
- for (size_t field_id = 2; field_id < counter_values.size(); field_id++) {
- if (!has_counter[field_id])
- continue;
-
- // Lookup the interned string id from the field name using the
- // pre-cached |proc_stats_process_names_| map.
- StringId name = proc_stats_process_names_[field_id];
- int64_t value = counter_values[field_id];
- UniquePid upid = context_->process_tracker->GetOrCreateProcess(pid);
- context_->event_tracker->PushCounter(ts, value, name, upid,
- RefType::kRefUpid);
- }
- }
-}
-
-void ProtoTraceParser::ParseFtracePacket(uint32_t cpu,
- int64_t /*ts*/,
- TimestampedTracePiece ttp) {
- PERFETTO_DCHECK(ttp.json_value == nullptr);
-
- ModuleResult res = context_->ftrace_module->ParseFtracePacket(cpu, ttp);
- PERFETTO_DCHECK(!res.ignored());
- // TODO(eseckler): Propagate status.
- if (!res.ok()) {
- PERFETTO_ELOG("%s", res.message().c_str());
- }
-
- // TODO(lalitm): maybe move this to the flush method in the trace processor
- // once we have it. This may reduce performance in the ArgsTracker though so
- // needs to be handled carefully.
- context_->args_tracker->Flush();
-}
-
-void ProtoTraceParser::ParseBatteryCounters(int64_t ts, ConstBytes blob) {
- protos::pbzero::BatteryCounters::Decoder evt(blob.data, blob.size);
- if (evt.has_charge_counter_uah()) {
- context_->event_tracker->PushCounter(
- ts, evt.charge_counter_uah(), batt_charge_id_, 0, RefType::kRefNoRef);
- }
- if (evt.has_capacity_percent()) {
- context_->event_tracker->PushCounter(
- ts, static_cast<double>(evt.capacity_percent()), batt_capacity_id_, 0,
- RefType::kRefNoRef);
- }
- if (evt.has_current_ua()) {
- context_->event_tracker->PushCounter(ts, evt.current_ua(), batt_current_id_,
- 0, RefType::kRefNoRef);
- }
- if (evt.has_current_avg_ua()) {
- context_->event_tracker->PushCounter(
- ts, evt.current_avg_ua(), batt_current_avg_id_, 0, RefType::kRefNoRef);
- }
-}
-
-void ProtoTraceParser::ParsePowerRails(int64_t ts, ConstBytes blob) {
- protos::pbzero::PowerRails::Decoder evt(blob.data, blob.size);
- if (evt.has_rail_descriptor()) {
- for (auto it = evt.rail_descriptor(); it; ++it) {
- protos::pbzero::PowerRails::RailDescriptor::Decoder desc(*it);
- uint32_t idx = desc.index();
- if (PERFETTO_UNLIKELY(idx > 256)) {
- PERFETTO_DLOG("Skipping excessively large power_rail index %" PRIu32,
- idx);
- continue;
- }
- if (power_rails_strs_id_.size() <= idx)
- power_rails_strs_id_.resize(idx + 1);
- char counter_name[255];
- snprintf(counter_name, sizeof(counter_name), "power.%.*s_uws",
- int(desc.rail_name().size), desc.rail_name().data);
- power_rails_strs_id_[idx] = context_->storage->InternString(counter_name);
- }
- }
-
- if (evt.has_energy_data()) {
- for (auto it = evt.energy_data(); it; ++it) {
- protos::pbzero::PowerRails::EnergyData::Decoder desc(*it);
- if (desc.index() < power_rails_strs_id_.size()) {
- int64_t actual_ts =
- desc.has_timestamp_ms()
- ? static_cast<int64_t>(desc.timestamp_ms()) * 1000000
- : ts;
- context_->event_tracker->PushCounter(actual_ts, desc.energy(),
- power_rails_strs_id_[desc.index()],
- 0, RefType::kRefNoRef);
- } else {
- context_->storage->IncrementStats(stats::power_rail_unknown_index);
- }
- }
- }
-}
-
-void ProtoTraceParser::ParseAndroidLogPacket(ConstBytes blob) {
- protos::pbzero::AndroidLogPacket::Decoder packet(blob.data, blob.size);
- for (auto it = packet.events(); it; ++it)
- ParseAndroidLogEvent(*it);
-
- if (packet.has_stats())
- ParseAndroidLogStats(packet.stats());
-}
-
-void ProtoTraceParser::ParseAndroidLogEvent(ConstBytes blob) {
- // TODO(primiano): Add events and non-stringified fields to the "raw" table.
- protos::pbzero::AndroidLogPacket::LogEvent::Decoder evt(blob.data, blob.size);
- int64_t ts = static_cast<int64_t>(evt.timestamp());
- uint32_t pid = static_cast<uint32_t>(evt.pid());
- uint32_t tid = static_cast<uint32_t>(evt.tid());
- uint8_t prio = static_cast<uint8_t>(evt.prio());
- StringId tag_id = context_->storage->InternString(
- evt.has_tag() ? evt.tag() : base::StringView());
- StringId msg_id = context_->storage->InternString(
- evt.has_message() ? evt.message() : base::StringView());
-
- char arg_msg[4096];
- char* arg_str = &arg_msg[0];
- *arg_str = '\0';
- auto arg_avail = [&arg_msg, &arg_str]() {
- return sizeof(arg_msg) - static_cast<size_t>(arg_str - arg_msg);
- };
- for (auto it = evt.args(); it; ++it) {
- protos::pbzero::AndroidLogPacket::LogEvent::Arg::Decoder arg(*it);
- if (!arg.has_name())
- continue;
- arg_str +=
- snprintf(arg_str, arg_avail(),
- " %.*s=", static_cast<int>(arg.name().size), arg.name().data);
- if (arg.has_string_value()) {
- arg_str += snprintf(arg_str, arg_avail(), "\"%.*s\"",
- static_cast<int>(arg.string_value().size),
- arg.string_value().data);
- } else if (arg.has_int_value()) {
- arg_str += snprintf(arg_str, arg_avail(), "%" PRId64, arg.int_value());
- } else if (arg.has_float_value()) {
- arg_str += snprintf(arg_str, arg_avail(), "%f",
- static_cast<double>(arg.float_value()));
- }
- }
-
- if (prio == 0)
- prio = protos::pbzero::AndroidLogPriority::PRIO_INFO;
-
- if (arg_str != &arg_msg[0]) {
- PERFETTO_DCHECK(msg_id.is_null());
- // Skip the first space char (" foo=1 bar=2" -> "foo=1 bar=2").
- msg_id = context_->storage->InternString(&arg_msg[1]);
- }
- UniquePid utid = tid ? context_->process_tracker->UpdateThread(tid, pid) : 0;
- base::Optional<int64_t> opt_trace_time = context_->clock_tracker->ToTraceTime(
- protos::pbzero::ClockSnapshot::Clock::REALTIME, ts);
- if (!opt_trace_time)
- return;
-
- // Log events are NOT required to be sorted by trace_time. The virtual table
- // will take care of sorting on-demand.
- context_->storage->mutable_android_log()->AddLogEvent(
- opt_trace_time.value(), utid, prio, tag_id, msg_id);
-}
-
-void ProtoTraceParser::ParseAndroidLogStats(ConstBytes blob) {
- protos::pbzero::AndroidLogPacket::Stats::Decoder evt(blob.data, blob.size);
- if (evt.has_num_failed()) {
- context_->storage->SetStats(stats::android_log_num_failed,
- static_cast<int64_t>(evt.num_failed()));
- }
-
- if (evt.has_num_skipped()) {
- context_->storage->SetStats(stats::android_log_num_skipped,
- static_cast<int64_t>(evt.num_skipped()));
- }
-
- if (evt.has_num_total()) {
- context_->storage->SetStats(stats::android_log_num_total,
- static_cast<int64_t>(evt.num_total()));
- }
-}
-
-void ProtoTraceParser::ParseTraceStats(ConstBytes blob) {
- protos::pbzero::TraceStats::Decoder evt(blob.data, blob.size);
- auto* storage = context_->storage.get();
- storage->SetStats(stats::traced_producers_connected,
- static_cast<int64_t>(evt.producers_connected()));
- storage->SetStats(stats::traced_data_sources_registered,
- static_cast<int64_t>(evt.data_sources_registered()));
- storage->SetStats(stats::traced_data_sources_seen,
- static_cast<int64_t>(evt.data_sources_seen()));
- storage->SetStats(stats::traced_tracing_sessions,
- static_cast<int64_t>(evt.tracing_sessions()));
- storage->SetStats(stats::traced_total_buffers,
- static_cast<int64_t>(evt.total_buffers()));
- storage->SetStats(stats::traced_chunks_discarded,
- static_cast<int64_t>(evt.chunks_discarded()));
- storage->SetStats(stats::traced_patches_discarded,
- static_cast<int64_t>(evt.patches_discarded()));
-
- int buf_num = 0;
- for (auto it = evt.buffer_stats(); it; ++it, ++buf_num) {
- protos::pbzero::TraceStats::BufferStats::Decoder buf(*it);
- storage->SetIndexedStats(stats::traced_buf_buffer_size, buf_num,
- static_cast<int64_t>(buf.buffer_size()));
- storage->SetIndexedStats(stats::traced_buf_bytes_written, buf_num,
- static_cast<int64_t>(buf.bytes_written()));
- storage->SetIndexedStats(stats::traced_buf_bytes_overwritten, buf_num,
- static_cast<int64_t>(buf.bytes_overwritten()));
- storage->SetIndexedStats(stats::traced_buf_bytes_read, buf_num,
- static_cast<int64_t>(buf.bytes_read()));
- storage->SetIndexedStats(stats::traced_buf_padding_bytes_written, buf_num,
- static_cast<int64_t>(buf.padding_bytes_written()));
- storage->SetIndexedStats(stats::traced_buf_padding_bytes_cleared, buf_num,
- static_cast<int64_t>(buf.padding_bytes_cleared()));
- storage->SetIndexedStats(stats::traced_buf_chunks_written, buf_num,
- static_cast<int64_t>(buf.chunks_written()));
- storage->SetIndexedStats(stats::traced_buf_chunks_rewritten, buf_num,
- static_cast<int64_t>(buf.chunks_rewritten()));
- storage->SetIndexedStats(stats::traced_buf_chunks_overwritten, buf_num,
- static_cast<int64_t>(buf.chunks_overwritten()));
- storage->SetIndexedStats(stats::traced_buf_chunks_discarded, buf_num,
- static_cast<int64_t>(buf.chunks_discarded()));
- storage->SetIndexedStats(stats::traced_buf_chunks_read, buf_num,
- static_cast<int64_t>(buf.chunks_read()));
- storage->SetIndexedStats(
- stats::traced_buf_chunks_committed_out_of_order, buf_num,
- static_cast<int64_t>(buf.chunks_committed_out_of_order()));
- storage->SetIndexedStats(stats::traced_buf_write_wrap_count, buf_num,
- static_cast<int64_t>(buf.write_wrap_count()));
- storage->SetIndexedStats(stats::traced_buf_patches_succeeded, buf_num,
- static_cast<int64_t>(buf.patches_succeeded()));
- storage->SetIndexedStats(stats::traced_buf_patches_failed, buf_num,
- static_cast<int64_t>(buf.patches_failed()));
- storage->SetIndexedStats(stats::traced_buf_readaheads_succeeded, buf_num,
- static_cast<int64_t>(buf.readaheads_succeeded()));
- storage->SetIndexedStats(stats::traced_buf_readaheads_failed, buf_num,
- static_cast<int64_t>(buf.readaheads_failed()));
- storage->SetIndexedStats(
- stats::traced_buf_trace_writer_packet_loss, buf_num,
- static_cast<int64_t>(buf.trace_writer_packet_loss()));
- }
-}
-
-void ProtoTraceParser::ParseProfilePacket(
- int64_t,
- ProtoIncrementalState::PacketSequenceState* sequence_state,
- size_t sequence_state_generation,
- ConstBytes blob) {
- protos::pbzero::ProfilePacket::Decoder packet(blob.data, blob.size);
- context_->heap_profile_tracker->SetProfilePacketIndex(packet.index());
-
- for (auto it = packet.strings(); it; ++it) {
- protos::pbzero::InternedString::Decoder entry(*it);
-
- const char* str = reinterpret_cast<const char*>(entry.str().data);
- auto str_view = base::StringView(str, entry.str().size);
- sequence_state->stack_profile_tracker().AddString(entry.iid(), str_view);
- }
-
- for (auto it = packet.mappings(); it; ++it) {
- protos::pbzero::Mapping::Decoder entry(*it);
- StackProfileTracker::SourceMapping src_mapping = MakeSourceMapping(entry);
- sequence_state->stack_profile_tracker().AddMapping(entry.iid(),
- src_mapping);
- }
-
- for (auto it = packet.frames(); it; ++it) {
- protos::pbzero::Frame::Decoder entry(*it);
- StackProfileTracker::SourceFrame src_frame = MakeSourceFrame(entry);
- sequence_state->stack_profile_tracker().AddFrame(entry.iid(), src_frame);
- }
-
- for (auto it = packet.callstacks(); it; ++it) {
- protos::pbzero::Callstack::Decoder entry(*it);
- StackProfileTracker::SourceCallstack src_callstack =
- MakeSourceCallstack(entry);
- sequence_state->stack_profile_tracker().AddCallstack(entry.iid(),
- src_callstack);
- }
-
- for (auto it = packet.process_dumps(); it; ++it) {
- protos::pbzero::ProfilePacket::ProcessHeapSamples::Decoder entry(*it);
-
- int pid = static_cast<int>(entry.pid());
-
- if (entry.buffer_corrupted())
- context_->storage->IncrementIndexedStats(
- stats::heapprofd_buffer_corrupted, pid);
- if (entry.buffer_overran())
- context_->storage->IncrementIndexedStats(stats::heapprofd_buffer_overran,
- pid);
- if (entry.rejected_concurrent())
- context_->storage->IncrementIndexedStats(
- stats::heapprofd_rejected_concurrent, pid);
-
- for (auto sample_it = entry.samples(); sample_it; ++sample_it) {
- protos::pbzero::ProfilePacket::HeapSample::Decoder sample(*sample_it);
-
- HeapProfileTracker::SourceAllocation src_allocation;
- src_allocation.pid = entry.pid();
- src_allocation.timestamp = static_cast<int64_t>(entry.timestamp());
- src_allocation.callstack_id = sample.callstack_id();
- src_allocation.self_allocated = sample.self_allocated();
- src_allocation.self_freed = sample.self_freed();
- src_allocation.alloc_count = sample.alloc_count();
- src_allocation.free_count = sample.free_count();
-
- context_->heap_profile_tracker->StoreAllocation(src_allocation);
- }
- }
- if (!packet.continued()) {
- PERFETTO_CHECK(sequence_state);
- ProfilePacketInternLookup intern_lookup(sequence_state,
- sequence_state_generation);
- context_->heap_profile_tracker->FinalizeProfile(
- &sequence_state->stack_profile_tracker(), &intern_lookup);
- }
-}
-
-void ProtoTraceParser::ParseStreamingProfilePacket(
- ProtoIncrementalState::PacketSequenceState* sequence_state,
- size_t sequence_state_generation,
- ConstBytes blob) {
- protos::pbzero::StreamingProfilePacket::Decoder packet(blob.data, blob.size);
-
- ProcessTracker* procs = context_->process_tracker.get();
- TraceStorage* storage = context_->storage.get();
- StackProfileTracker& stack_profile_tracker =
- sequence_state->stack_profile_tracker();
- ProfilePacketInternLookup intern_lookup(sequence_state,
- sequence_state_generation);
-
- uint32_t pid = static_cast<uint32_t>(sequence_state->pid());
- uint32_t tid = static_cast<uint32_t>(sequence_state->tid());
- UniqueTid utid = procs->UpdateThread(tid, pid);
-
- auto timestamp_it = packet.timestamp_delta_us();
- for (auto callstack_it = packet.callstack_iid(); callstack_it;
- ++callstack_it, ++timestamp_it) {
- if (!timestamp_it) {
- context_->storage->IncrementStats(stats::stackprofile_parser_error);
- PERFETTO_ELOG(
- "StreamingProfilePacket has less callstack IDs than timestamps!");
- break;
- }
-
- auto maybe_callstack_id =
- stack_profile_tracker.FindCallstack(*callstack_it, &intern_lookup);
- if (!maybe_callstack_id) {
- context_->storage->IncrementStats(stats::stackprofile_parser_error);
- PERFETTO_ELOG("StreamingProfilePacket referencing invalid callstack!");
- continue;
- }
-
- int64_t callstack_id = *maybe_callstack_id;
-
- TraceStorage::CpuProfileStackSamples::Row sample_row{
- sequence_state->IncrementAndGetTrackEventTimeNs(*timestamp_it),
- callstack_id, utid};
- storage->mutable_cpu_profile_stack_samples()->Insert(sample_row);
- }
-}
-
-void ProtoTraceParser::ParseSystemInfo(ConstBytes blob) {
- protos::pbzero::SystemInfo::Decoder packet(blob.data, blob.size);
- if (packet.has_utsname()) {
- ConstBytes utsname_blob = packet.utsname();
- protos::pbzero::Utsname::Decoder utsname(utsname_blob.data,
- utsname_blob.size);
- base::StringView machine = utsname.machine();
- if (machine == "aarch64" || machine == "armv8l") {
- context_->syscall_tracker->SetArchitecture(kAarch64);
- } else if (machine == "x86_64") {
- context_->syscall_tracker->SetArchitecture(kX86_64);
- } else {
- PERFETTO_ELOG("Unknown architecture %s", machine.ToStdString().c_str());
- }
- }
-}
-
-void ProtoTraceParser::ParseTrackEvent(
- int64_t ts,
- int64_t tts,
- int64_t ticount,
- ProtoIncrementalState::PacketSequenceState* sequence_state,
- size_t sequence_state_generation,
- ConstBytes blob) {
- using LegacyEvent = protos::pbzero::TrackEvent::LegacyEvent;
-
- protos::pbzero::TrackEvent::Decoder event(blob.data, blob.size);
-
- const auto legacy_event_blob = event.legacy_event();
- LegacyEvent::Decoder legacy_event(legacy_event_blob.data,
- legacy_event_blob.size);
-
- // TODO(eseckler): This legacy event field will eventually be replaced by
- // fields in TrackEvent itself.
- if (PERFETTO_UNLIKELY(!event.type() && !legacy_event.has_phase())) {
- context_->storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG("TrackEvent without type or phase");
- return;
- }
-
- ProcessTracker* procs = context_->process_tracker.get();
- TraceStorage* storage = context_->storage.get();
- TrackTracker* track_tracker = context_->track_tracker.get();
- SliceTracker* slice_tracker = context_->slice_tracker.get();
-
- std::vector<uint64_t> category_iids;
- for (auto it = event.category_iids(); it; ++it) {
- category_iids.push_back(*it);
- }
- std::vector<protozero::ConstChars> category_strings;
- for (auto it = event.categories(); it; ++it) {
- category_strings.push_back(*it);
- }
-
- StringId category_id = 0;
-
- // If there's a single category, we can avoid building a concatenated
- // string.
- if (PERFETTO_LIKELY(category_iids.size() == 1 && category_strings.empty())) {
- auto* decoder = sequence_state->LookupInternedMessage<
- protos::pbzero::InternedData::kEventCategoriesFieldNumber,
- protos::pbzero::EventCategory>(sequence_state_generation,
- category_iids[0]);
- if (decoder)
- category_id = storage->InternString(decoder->name());
- } else if (category_iids.empty() && category_strings.size() == 1) {
- category_id = storage->InternString(category_strings[0]);
- } else if (category_iids.size() + category_strings.size() > 1) {
- // We concatenate the category strings together since we currently only
- // support a single "cat" column.
- // TODO(eseckler): Support multi-category events in the table schema.
- std::string categories;
- for (uint64_t iid : category_iids) {
- auto* decoder = sequence_state->LookupInternedMessage<
- protos::pbzero::InternedData::kEventCategoriesFieldNumber,
- protos::pbzero::EventCategory>(sequence_state_generation, iid);
- if (!decoder)
- continue;
- base::StringView name = decoder->name();
- if (!categories.empty())
- categories.append(",");
- categories.append(name.data(), name.size());
- }
- for (const protozero::ConstChars& cat : category_strings) {
- if (!categories.empty())
- categories.append(",");
- categories.append(cat.data, cat.size);
- }
- if (!categories.empty())
- category_id = storage->InternString(base::StringView(categories));
- }
-
- StringId name_id = 0;
-
- uint64_t name_iid = event.name_iid();
- if (!name_iid)
- name_iid = legacy_event.name_iid();
-
- if (PERFETTO_LIKELY(name_iid)) {
- auto* decoder = sequence_state->LookupInternedMessage<
- protos::pbzero::InternedData::kEventNamesFieldNumber,
- protos::pbzero::EventName>(sequence_state_generation, name_iid);
- if (decoder)
- name_id = storage->InternString(decoder->name());
- } else if (event.has_name()) {
- name_id = storage->InternString(event.name());
- }
-
- // TODO(eseckler): Also consider track_uuid from TrackEventDefaults.
- // Fall back to the default descriptor track (uuid 0).
- uint64_t track_uuid = event.has_track_uuid() ? event.track_uuid() : 0u;
- TrackId track_id;
- base::Optional<UniqueTid> utid;
- base::Optional<UniqueTid> upid;
-
- // Determine track from track_uuid specified in either TrackEvent or
- // TrackEventDefaults. If none is set, fall back to the track specified by the
- // sequence's (or event's) pid + tid or a default track.
- if (track_uuid) {
- base::Optional<TrackId> opt_track_id =
- track_tracker->GetDescriptorTrack(track_uuid);
- if (!opt_track_id) {
- storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG("TrackEvent with unknown track_uuid %" PRIu64, track_uuid);
- return;
- }
- track_id = *opt_track_id;
-
- auto thread_track_row =
- context_->storage->thread_track_table().id().IndexOf(
- SqlValue::Long(track_id));
- if (thread_track_row) {
- utid = storage->thread_track_table().utid()[*thread_track_row];
- upid = storage->GetThread(*utid).upid;
- } else {
- auto process_track_row =
- context_->storage->process_track_table().id().IndexOf(
- SqlValue::Long(track_id));
- if (process_track_row)
- upid = storage->process_track_table().upid()[*process_track_row];
- }
- } else if (sequence_state->pid_and_tid_valid() ||
- (legacy_event.has_pid_override() &&
- legacy_event.has_tid_override())) {
- uint32_t pid = static_cast<uint32_t>(sequence_state->pid());
- uint32_t tid = static_cast<uint32_t>(sequence_state->tid());
- if (legacy_event.has_pid_override())
- pid = static_cast<uint32_t>(legacy_event.pid_override());
- if (legacy_event.has_tid_override())
- tid = static_cast<uint32_t>(legacy_event.tid_override());
-
- utid = procs->UpdateThread(tid, pid);
- upid = storage->GetThread(*utid).upid;
- track_id = track_tracker->GetOrCreateDescriptorTrackForThread(*utid);
- } else {
- track_id = track_tracker->GetOrCreateDefaultDescriptorTrack();
- }
-
- // TODO(eseckler): Replace phase with type and remove handling of
- // legacy_event.phase() once it is no longer used by producers.
- int32_t phase = 0;
- if (legacy_event.has_phase()) {
- phase = legacy_event.phase();
-
- switch (phase) {
- case 'b':
- case 'e':
- case 'n': {
- // Intern tracks for legacy async events based on legacy event ids.
- int64_t source_id = 0;
- bool source_id_is_process_scoped = false;
- if (legacy_event.has_unscoped_id()) {
- source_id = static_cast<int64_t>(legacy_event.unscoped_id());
- } else if (legacy_event.has_global_id()) {
- source_id = static_cast<int64_t>(legacy_event.global_id());
- } else if (legacy_event.has_local_id()) {
- if (!upid) {
- storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG(
- "TrackEvent with local_id without process association");
- return;
- }
-
- source_id = static_cast<int64_t>(legacy_event.local_id());
- source_id_is_process_scoped = true;
- } else {
- storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG("Async LegacyEvent without ID");
- return;
- }
-
- // Catapult treats nestable async events of different categories with
- // the same ID as separate tracks. We replicate the same behavior here.
- StringId id_scope = category_id;
- if (legacy_event.has_id_scope()) {
- std::string concat = storage->GetString(category_id).ToStdString() +
- ":" + legacy_event.id_scope().ToStdString();
- id_scope = storage->InternString(base::StringView(concat));
- }
-
- track_id = context_->track_tracker->InternLegacyChromeAsyncTrack(
- name_id, upid ? *upid : 0, source_id, source_id_is_process_scoped,
- id_scope);
- break;
- }
- case 'i':
- case 'I': {
- // Intern tracks for global or process-scoped legacy instant events.
- switch (legacy_event.instant_event_scope()) {
- case LegacyEvent::SCOPE_UNSPECIFIED:
- case LegacyEvent::SCOPE_THREAD:
- // Thread-scoped legacy instant events already have the right track
- // based on the tid/pid of the sequence.
- if (!utid) {
- storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG(
- "Thread-scoped instant event without thread association");
- return;
- }
- break;
- case LegacyEvent::SCOPE_GLOBAL:
- track_id = context_->track_tracker
- ->GetOrCreateLegacyChromeGlobalInstantTrack();
- break;
- case LegacyEvent::SCOPE_PROCESS:
- if (!upid) {
- storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG(
- "Process-scoped instant event without process association");
- return;
- }
-
- track_id =
- context_->track_tracker->InternLegacyChromeProcessInstantTrack(
- *upid);
- break;
- }
- break;
- }
- default:
- break;
- }
- } else {
- switch (event.type()) {
- case protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN:
- phase = utid ? 'B' : 'b';
- break;
- case protos::pbzero::TrackEvent::TYPE_SLICE_END:
- phase = utid ? 'E' : 'e';
- break;
- case protos::pbzero::TrackEvent::TYPE_INSTANT:
- phase = utid ? 'i' : 'n';
- break;
- default:
- PERFETTO_FATAL("unexpected event type %d", event.type());
- return;
- }
- }
-
- auto args_callback = [this, &event, &legacy_event, &sequence_state,
- sequence_state_generation, ts,
- utid](ArgsTracker* args_tracker, RowId row_id) {
- for (auto it = event.debug_annotations(); it; ++it) {
- ParseDebugAnnotationArgs(*it, sequence_state, sequence_state_generation,
- args_tracker, row_id);
- }
-
- if (event.has_task_execution()) {
- ParseTaskExecutionArgs(event.task_execution(), sequence_state,
- sequence_state_generation, args_tracker, row_id);
- }
-
- if (event.has_log_message()) {
- ParseLogMessage(event.log_message(), sequence_state,
- sequence_state_generation, ts, utid, args_tracker,
- row_id);
- }
-
- // TODO(eseckler): Parse legacy flow events into flow events table once we
- // have a design for it.
- if (legacy_event.has_bind_id()) {
- args_tracker->AddArg(row_id, legacy_event_bind_id_key_id_,
- legacy_event_bind_id_key_id_,
- Variadic::UnsignedInteger(legacy_event.bind_id()));
- }
-
- if (legacy_event.bind_to_enclosing()) {
- args_tracker->AddArg(row_id, legacy_event_bind_to_enclosing_key_id_,
- legacy_event_bind_to_enclosing_key_id_,
- Variadic::Boolean(true));
- }
-
- if (legacy_event.flow_direction()) {
- StringId value;
- switch (legacy_event.flow_direction()) {
- case protos::pbzero::TrackEvent::LegacyEvent::FLOW_IN:
- value = flow_direction_value_in_id_;
- break;
- case protos::pbzero::TrackEvent::LegacyEvent::FLOW_OUT:
- value = flow_direction_value_out_id_;
- break;
- case protos::pbzero::TrackEvent::LegacyEvent::FLOW_INOUT:
- value = flow_direction_value_inout_id_;
- break;
- default:
- PERFETTO_FATAL("Unknown flow direction: %d",
- legacy_event.flow_direction());
- break;
- }
- args_tracker->AddArg(row_id, legacy_event_flow_direction_key_id_,
- legacy_event_flow_direction_key_id_,
- Variadic::String(value));
- }
- };
-
- switch (static_cast<char>(phase)) {
- case 'B': { // TRACE_EVENT_PHASE_BEGIN.
- if (!utid) {
- storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG("TrackEvent with phase B without thread association");
- return;
- }
-
- auto opt_slice_id =
- slice_tracker->Begin(ts, track_id, *utid, RefType::kRefUtid,
- category_id, name_id, args_callback);
- if (opt_slice_id.has_value()) {
- auto* thread_slices = storage->mutable_thread_slices();
- PERFETTO_DCHECK(!thread_slices->slice_count() ||
- thread_slices->slice_ids().back() <
- opt_slice_id.value());
- thread_slices->AddThreadSlice(opt_slice_id.value(), tts,
- kPendingThreadDuration, ticount,
- kPendingThreadInstructionDelta);
- }
- break;
- }
- case 'E': { // TRACE_EVENT_PHASE_END.
- if (!utid) {
- storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG("TrackEvent with phase E without thread association");
- return;
- }
-
- auto opt_slice_id =
- slice_tracker->End(ts, track_id, category_id, name_id, args_callback);
- if (opt_slice_id.has_value()) {
- auto* thread_slices = storage->mutable_thread_slices();
- thread_slices->UpdateThreadDeltasForSliceId(opt_slice_id.value(), tts,
- ticount);
- }
- break;
- }
- case 'X': { // TRACE_EVENT_PHASE_COMPLETE.
- if (!utid) {
- storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG("TrackEvent with phase X without thread association");
- return;
- }
-
- auto duration_ns = legacy_event.duration_us() * 1000;
- if (duration_ns < 0)
- return;
- auto opt_slice_id = slice_tracker->Scoped(
- ts, track_id, *utid, RefType::kRefUtid, category_id, name_id,
- duration_ns, args_callback);
- if (opt_slice_id.has_value()) {
- auto* thread_slices = storage->mutable_thread_slices();
- PERFETTO_DCHECK(!thread_slices->slice_count() ||
- thread_slices->slice_ids().back() <
- opt_slice_id.value());
- auto thread_duration_ns = legacy_event.thread_duration_us() * 1000;
- thread_slices->AddThreadSlice(opt_slice_id.value(), tts,
- thread_duration_ns, ticount,
- legacy_event.thread_instruction_delta());
- }
- break;
- }
- case 'i':
- case 'I': { // TRACE_EVENT_PHASE_INSTANT.
- // Handle instant events as slices with zero duration, so that they end
- // up nested underneath their parent slices.
- int64_t duration_ns = 0;
- int64_t tidelta = 0;
-
- switch (legacy_event.instant_event_scope()) {
- case LegacyEvent::SCOPE_UNSPECIFIED:
- case LegacyEvent::SCOPE_THREAD: {
- // TODO(lalitm): Associate thread slices with track instead.
- auto opt_slice_id = slice_tracker->Scoped(
- ts, track_id, *utid, RefType::kRefUtid, category_id, name_id,
- duration_ns, args_callback);
- if (opt_slice_id.has_value()) {
- auto* thread_slices = storage->mutable_thread_slices();
- PERFETTO_DCHECK(!thread_slices->slice_count() ||
- thread_slices->slice_ids().back() <
- opt_slice_id.value());
- thread_slices->AddThreadSlice(opt_slice_id.value(), tts,
- duration_ns, ticount, tidelta);
- }
- break;
- }
- case LegacyEvent::SCOPE_GLOBAL: {
- slice_tracker->Scoped(ts, track_id, /*ref=*/0, RefType::kRefNoRef,
- category_id, name_id, duration_ns,
- args_callback);
- break;
- }
- case LegacyEvent::SCOPE_PROCESS: {
- slice_tracker->Scoped(ts, track_id, *upid, RefType::kRefUpid,
- category_id, name_id, duration_ns,
- args_callback);
- break;
- }
- default: {
- PERFETTO_FATAL("Unknown instant event scope: %u",
- legacy_event.instant_event_scope());
- break;
- }
- }
- break;
- }
- case 'b': { // TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN
- auto opt_slice_id =
- slice_tracker->Begin(ts, track_id, track_id, RefType::kRefTrack,
- category_id, name_id, args_callback);
- // For the time beeing, we only create vtrack slice rows if we need to
- // store thread timestamps/counters.
- if (legacy_event.use_async_tts() && opt_slice_id.has_value()) {
- auto* vtrack_slices = storage->mutable_virtual_track_slices();
- PERFETTO_DCHECK(!vtrack_slices->slice_count() ||
- vtrack_slices->slice_ids().back() <
- opt_slice_id.value());
- vtrack_slices->AddVirtualTrackSlice(opt_slice_id.value(), tts,
- kPendingThreadDuration, ticount,
- kPendingThreadInstructionDelta);
- }
- break;
- }
- case 'e': { // TRACE_EVENT_PHASE_NESTABLE_ASYNC_END
- auto opt_slice_id =
- slice_tracker->End(ts, track_id, category_id, name_id, args_callback);
- if (legacy_event.use_async_tts() && opt_slice_id.has_value()) {
- auto* vtrack_slices = storage->mutable_virtual_track_slices();
- vtrack_slices->UpdateThreadDeltasForSliceId(opt_slice_id.value(), tts,
- ticount);
- }
- break;
- }
- case 'n': { // TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT
- // Handle instant events as slices with zero duration, so that they end up
- // nested underneath their parent slices.
- int64_t duration_ns = 0;
- int64_t tidelta = 0;
- auto opt_slice_id = slice_tracker->Scoped(
- ts, track_id, track_id, RefType::kRefTrack, category_id, name_id,
- duration_ns, args_callback);
- if (legacy_event.use_async_tts() && opt_slice_id.has_value()) {
- auto* vtrack_slices = storage->mutable_virtual_track_slices();
- PERFETTO_DCHECK(!vtrack_slices->slice_count() ||
- vtrack_slices->slice_ids().back() <
- opt_slice_id.value());
- vtrack_slices->AddVirtualTrackSlice(opt_slice_id.value(), tts,
- duration_ns, ticount, tidelta);
- }
- break;
- }
- case 'M': { // TRACE_EVENT_PHASE_METADATA (process and thread names).
- // Parse process and thread names from correspondingly named events.
- // TODO(eseckler): Also consider names from process/thread descriptors.
- NullTermStringView event_name = storage->GetString(name_id);
- PERFETTO_DCHECK(event_name.data());
- if (strcmp(event_name.c_str(), "thread_name") == 0) {
- if (!utid) {
- storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG(
- "thread_name metadata event without thread association");
- return;
- }
-
- auto it = event.debug_annotations();
- if (!it)
- break;
- protos::pbzero::DebugAnnotation::Decoder annotation(*it);
- auto thread_name = annotation.string_value();
- if (!thread_name.size)
- break;
- auto thread_name_id = storage->InternString(thread_name);
- procs->UpdateThreadName(storage->GetThread(*utid).tid, thread_name_id);
- break;
- }
- if (strcmp(event_name.c_str(), "process_name") == 0) {
- if (!upid) {
- storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG(
- "process_name metadata event without process association");
- return;
- }
-
- auto it = event.debug_annotations();
- if (!it)
- break;
- protos::pbzero::DebugAnnotation::Decoder annotation(*it);
- auto process_name = annotation.string_value();
- if (!process_name.size)
- break;
- procs->SetProcessMetadata(storage->GetProcess(*upid).pid, base::nullopt,
- process_name);
- break;
- }
- // Other metadata events are proxied via the raw table for JSON export.
- ParseLegacyEventAsRawEvent(ts, tts, ticount, utid, category_id, name_id,
- legacy_event, args_callback);
- break;
- }
- default: {
- // Other events are proxied via the raw table for JSON export.
- ParseLegacyEventAsRawEvent(ts, tts, ticount, utid, category_id, name_id,
- legacy_event, args_callback);
- }
- }
-}
-
-void ProtoTraceParser::ParseLegacyEventAsRawEvent(
- int64_t ts,
- int64_t tts,
- int64_t ticount,
- base::Optional<UniqueTid> utid,
- StringId category_id,
- StringId name_id,
- const protos::pbzero::TrackEvent::LegacyEvent::Decoder& legacy_event,
- SliceTracker::SetArgsCallback args_callback) {
- if (!utid) {
- context_->storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG("raw legacy event without thread association");
- return;
- }
-
- RowId row_id = context_->storage->mutable_raw_events()->AddRawEvent(
- ts, raw_legacy_event_id_, 0, *utid);
- ArgsTracker args(context_);
- args.AddArg(row_id, legacy_event_category_key_id_,
- legacy_event_category_key_id_, Variadic::String(category_id));
- args.AddArg(row_id, legacy_event_name_key_id_, legacy_event_name_key_id_,
- Variadic::String(name_id));
-
- std::string phase_string(1, static_cast<char>(legacy_event.phase()));
- StringId phase_id = context_->storage->InternString(phase_string.c_str());
- args.AddArg(row_id, legacy_event_phase_key_id_, legacy_event_phase_key_id_,
- Variadic::String(phase_id));
-
- if (legacy_event.has_duration_us()) {
- args.AddArg(row_id, legacy_event_duration_ns_key_id_,
- legacy_event_duration_ns_key_id_,
- Variadic::Integer(legacy_event.duration_us() * 1000));
- }
-
- if (tts) {
- args.AddArg(row_id, legacy_event_thread_timestamp_ns_key_id_,
- legacy_event_thread_timestamp_ns_key_id_,
- Variadic::Integer(tts));
- if (legacy_event.has_thread_duration_us()) {
- args.AddArg(row_id, legacy_event_thread_duration_ns_key_id_,
- legacy_event_thread_duration_ns_key_id_,
- Variadic::Integer(legacy_event.thread_duration_us() * 1000));
- }
- }
-
- if (ticount) {
- args.AddArg(row_id, legacy_event_thread_instruction_count_key_id_,
- legacy_event_thread_instruction_count_key_id_,
- Variadic::Integer(tts));
- if (legacy_event.has_thread_instruction_delta()) {
- args.AddArg(row_id, legacy_event_thread_instruction_delta_key_id_,
- legacy_event_thread_instruction_delta_key_id_,
- Variadic::Integer(legacy_event.thread_instruction_delta()));
- }
- }
-
- if (legacy_event.use_async_tts()) {
- args.AddArg(row_id, legacy_event_use_async_tts_key_id_,
- legacy_event_use_async_tts_key_id_, Variadic::Boolean(true));
- }
-
- bool has_id = false;
- if (legacy_event.has_unscoped_id()) {
- // Unscoped ids are either global or local depending on the phase. Pass them
- // through as unscoped IDs to JSON export to preserve this behavior.
- args.AddArg(row_id, legacy_event_unscoped_id_key_id_,
- legacy_event_unscoped_id_key_id_,
- Variadic::UnsignedInteger(legacy_event.unscoped_id()));
- has_id = true;
- } else if (legacy_event.has_global_id()) {
- args.AddArg(row_id, legacy_event_global_id_key_id_,
- legacy_event_global_id_key_id_,
- Variadic::UnsignedInteger(legacy_event.global_id()));
- has_id = true;
- } else if (legacy_event.has_local_id()) {
- args.AddArg(row_id, legacy_event_local_id_key_id_,
- legacy_event_local_id_key_id_,
- Variadic::UnsignedInteger(legacy_event.local_id()));
- has_id = true;
- }
-
- if (has_id && legacy_event.has_id_scope() && legacy_event.id_scope().size) {
- args.AddArg(row_id, legacy_event_id_scope_key_id_,
- legacy_event_id_scope_key_id_,
- Variadic::String(
- context_->storage->InternString(legacy_event.id_scope())));
- }
-
- // No need to parse legacy_event.instant_event_scope() because we import
- // instant events into the slice table.
-
- args_callback(&args, row_id);
-}
-
-void ProtoTraceParser::ParseDebugAnnotationArgs(
- ConstBytes debug_annotation,
- ProtoIncrementalState::PacketSequenceState* sequence_state,
- size_t sequence_state_generation,
- ArgsTracker* args_tracker,
- RowId row_id) {
- TraceStorage* storage = context_->storage.get();
-
- protos::pbzero::DebugAnnotation::Decoder annotation(debug_annotation.data,
- debug_annotation.size);
-
- StringId name_id = 0;
-
- uint64_t name_iid = annotation.name_iid();
- if (PERFETTO_LIKELY(name_iid)) {
- auto* decoder = sequence_state->LookupInternedMessage<
- protos::pbzero::InternedData::kDebugAnnotationNamesFieldNumber,
- protos::pbzero::DebugAnnotationName>(sequence_state_generation,
- name_iid);
- if (!decoder)
- return;
-
- std::string name_prefixed = "debug." + decoder->name().ToStdString();
- name_id = storage->InternString(base::StringView(name_prefixed));
- } else if (annotation.has_name()) {
- name_id = storage->InternString(annotation.name());
- } else {
- context_->storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG("Debug annotation without name");
- return;
- }
-
- if (annotation.has_bool_value()) {
- args_tracker->AddArg(row_id, name_id, name_id,
- Variadic::Boolean(annotation.bool_value()));
- } else if (annotation.has_uint_value()) {
- args_tracker->AddArg(row_id, name_id, name_id,
- Variadic::UnsignedInteger(annotation.uint_value()));
- } else if (annotation.has_int_value()) {
- args_tracker->AddArg(row_id, name_id, name_id,
- Variadic::Integer(annotation.int_value()));
- } else if (annotation.has_double_value()) {
- args_tracker->AddArg(row_id, name_id, name_id,
- Variadic::Real(annotation.double_value()));
- } else if (annotation.has_string_value()) {
- args_tracker->AddArg(
- row_id, name_id, name_id,
- Variadic::String(storage->InternString(annotation.string_value())));
- } else if (annotation.has_pointer_value()) {
- args_tracker->AddArg(row_id, name_id, name_id,
- Variadic::Pointer(annotation.pointer_value()));
- } else if (annotation.has_legacy_json_value()) {
- args_tracker->AddArg(
- row_id, name_id, name_id,
- Variadic::Json(storage->InternString(annotation.legacy_json_value())));
- } else if (annotation.has_nested_value()) {
- auto name = storage->GetString(name_id);
- ParseNestedValueArgs(annotation.nested_value(), name, name, args_tracker,
- row_id);
- }
-}
-
-void ProtoTraceParser::ParseNestedValueArgs(ConstBytes nested_value,
- base::StringView flat_key,
- base::StringView key,
- ArgsTracker* args_tracker,
- RowId row_id) {
- protos::pbzero::DebugAnnotation::NestedValue::Decoder value(
- nested_value.data, nested_value.size);
- switch (value.nested_type()) {
- case protos::pbzero::DebugAnnotation::NestedValue::UNSPECIFIED: {
- auto flat_key_id = context_->storage->InternString(flat_key);
- auto key_id = context_->storage->InternString(key);
- // Leaf value.
- if (value.has_bool_value()) {
- args_tracker->AddArg(row_id, flat_key_id, key_id,
- Variadic::Boolean(value.bool_value()));
- } else if (value.has_int_value()) {
- args_tracker->AddArg(row_id, flat_key_id, key_id,
- Variadic::Integer(value.int_value()));
- } else if (value.has_double_value()) {
- args_tracker->AddArg(row_id, flat_key_id, key_id,
- Variadic::Real(value.double_value()));
- } else if (value.has_string_value()) {
- args_tracker->AddArg(row_id, flat_key_id, key_id,
- Variadic::String(context_->storage->InternString(
- value.string_value())));
- }
- break;
- }
- case protos::pbzero::DebugAnnotation::NestedValue::DICT: {
- auto key_it = value.dict_keys();
- auto value_it = value.dict_values();
- for (; key_it && value_it; ++key_it, ++value_it) {
- std::string child_name = (*key_it).ToStdString();
- std::string child_flat_key = flat_key.ToStdString() + "." + child_name;
- std::string child_key = key.ToStdString() + "." + child_name;
- ParseNestedValueArgs(*value_it, base::StringView(child_flat_key),
- base::StringView(child_key), args_tracker, row_id);
- }
- break;
- }
- case protos::pbzero::DebugAnnotation::NestedValue::ARRAY: {
- int child_index = 0;
- std::string child_flat_key = flat_key.ToStdString();
- for (auto value_it = value.array_values(); value_it;
- ++value_it, ++child_index) {
- std::string child_key =
- key.ToStdString() + "[" + std::to_string(child_index) + "]";
- ParseNestedValueArgs(*value_it, base::StringView(child_flat_key),
- base::StringView(child_key), args_tracker, row_id);
- }
- break;
- }
- }
-}
-
-void ProtoTraceParser::ParseTaskExecutionArgs(
- ConstBytes task_execution,
- ProtoIncrementalState::PacketSequenceState* sequence_state,
- size_t sequence_state_generation,
- ArgsTracker* args_tracker,
- RowId row) {
- protos::pbzero::TaskExecution::Decoder task(task_execution.data,
- task_execution.size);
- uint64_t iid = task.posted_from_iid();
- if (!iid)
- return;
-
- auto* decoder = sequence_state->LookupInternedMessage<
- protos::pbzero::InternedData::kSourceLocationsFieldNumber,
- protos::pbzero::SourceLocation>(sequence_state_generation, iid);
- if (!decoder)
- return;
-
- StringId file_name_id = 0;
- StringId function_name_id = 0;
- uint32_t line_number = 0;
-
- TraceStorage* storage = context_->storage.get();
- file_name_id = storage->InternString(decoder->file_name());
- function_name_id = storage->InternString(decoder->function_name());
- line_number = decoder->line_number();
-
- args_tracker->AddArg(row, task_file_name_args_key_id_,
- task_file_name_args_key_id_,
- Variadic::String(file_name_id));
- args_tracker->AddArg(row, task_function_name_args_key_id_,
- task_function_name_args_key_id_,
- Variadic::String(function_name_id));
-
- args_tracker->AddArg(row, task_line_number_args_key_id_,
- task_line_number_args_key_id_,
- Variadic::UnsignedInteger(line_number));
-}
-
-void ProtoTraceParser::ParseLogMessage(
- ConstBytes blob,
- ProtoIncrementalState::PacketSequenceState* sequence_state,
- size_t sequence_state_generation,
- int64_t ts,
- base::Optional<UniqueTid> utid,
- ArgsTracker* args_tracker,
- RowId row) {
- if (!utid) {
- context_->storage->IncrementStats(stats::track_event_parser_errors);
- PERFETTO_DLOG("LogMessage without thread association");
- return;
- }
-
- protos::pbzero::LogMessage::Decoder message(blob.data, blob.size);
-
- TraceStorage* storage = context_->storage.get();
-
- StringId log_message_id = 0;
-
- auto* decoder = sequence_state->LookupInternedMessage<
- protos::pbzero::InternedData::kLogMessageBodyFieldNumber,
- protos::pbzero::LogMessageBody>(sequence_state_generation,
- message.body_iid());
- if (!decoder)
- return;
-
- log_message_id = storage->InternString(decoder->body());
-
- // TODO(nicomazz): LogMessage also contains the source of the message (file
- // and line number). Android logs doesn't support this so far.
- context_->storage->mutable_android_log()->AddLogEvent(
- ts, *utid,
- /*priority*/ 0,
- /*tag_id*/ 0, // TODO(nicomazz): Abuse tag_id to display
- // "file_name:line_number".
- log_message_id);
-
- args_tracker->AddArg(row, log_message_body_key_id_, log_message_body_key_id_,
- Variadic::String(log_message_id));
- // TODO(nicomazz): Add the source location as an argument.
-}
-
-void ProtoTraceParser::ParseChromeBenchmarkMetadata(ConstBytes blob) {
- TraceStorage* storage = context_->storage.get();
- protos::pbzero::ChromeBenchmarkMetadata::Decoder packet(blob.data, blob.size);
- if (packet.has_benchmark_name()) {
- auto benchmark_name_id = storage->InternString(packet.benchmark_name());
- storage->SetMetadata(metadata::benchmark_name,
- Variadic::String(benchmark_name_id));
- }
- if (packet.has_benchmark_description()) {
- auto benchmark_description_id =
- storage->InternString(packet.benchmark_description());
- storage->SetMetadata(metadata::benchmark_description,
- Variadic::String(benchmark_description_id));
- }
- if (packet.has_label()) {
- auto label_id = storage->InternString(packet.label());
- storage->SetMetadata(metadata::benchmark_label, Variadic::String(label_id));
- }
- if (packet.has_story_name()) {
- auto story_name_id = storage->InternString(packet.story_name());
- storage->SetMetadata(metadata::benchmark_story_name,
- Variadic::String(story_name_id));
- }
- for (auto it = packet.story_tags(); it; ++it) {
- auto story_tag_id = storage->InternString(*it);
- storage->AppendMetadata(metadata::benchmark_story_tags,
- Variadic::String(story_tag_id));
- }
- if (packet.has_benchmark_start_time_us()) {
- storage->SetMetadata(metadata::benchmark_start_time_us,
- Variadic::Integer(packet.benchmark_start_time_us()));
- }
- if (packet.has_story_run_time_us()) {
- storage->SetMetadata(metadata::benchmark_story_run_time_us,
- Variadic::Integer(packet.story_run_time_us()));
- }
- if (packet.has_story_run_index()) {
- storage->SetMetadata(metadata::benchmark_story_run_index,
- Variadic::Integer(packet.story_run_index()));
- }
- if (packet.has_had_failures()) {
- storage->SetMetadata(metadata::benchmark_had_failures,
- Variadic::Integer(packet.had_failures()));
- }
-}
-
-void ProtoTraceParser::ParseChromeEvents(int64_t ts, ConstBytes blob) {
- TraceStorage* storage = context_->storage.get();
- protos::pbzero::ChromeEventBundle::Decoder bundle(blob.data, blob.size);
- ArgsTracker args(context_);
- if (bundle.has_metadata()) {
- RowId row_id = storage->mutable_raw_events()->AddRawEvent(
- ts, raw_chrome_metadata_event_id_, 0, 0);
-
- // Metadata is proxied via a special event in the raw table to JSON export.
- for (auto it = bundle.metadata(); it; ++it) {
- protos::pbzero::ChromeMetadata::Decoder metadata(*it);
- StringId name_id = storage->InternString(metadata.name());
- Variadic value;
- if (metadata.has_string_value()) {
- value =
- Variadic::String(storage->InternString(metadata.string_value()));
- } else if (metadata.has_int_value()) {
- value = Variadic::Integer(metadata.int_value());
- } else if (metadata.has_bool_value()) {
- value = Variadic::Integer(metadata.bool_value());
- } else if (metadata.has_json_value()) {
- value = Variadic::Json(storage->InternString(metadata.json_value()));
- } else {
- PERFETTO_FATAL("Empty ChromeMetadata message");
- }
- args.AddArg(row_id, name_id, name_id, value);
- }
- }
-
- if (bundle.has_legacy_ftrace_output()) {
- RowId row_id = storage->mutable_raw_events()->AddRawEvent(
- ts, raw_chrome_legacy_system_trace_event_id_, 0, 0);
-
- std::string data;
- for (auto it = bundle.legacy_ftrace_output(); it; ++it) {
- data += (*it).ToStdString();
- }
- Variadic value =
- Variadic::String(storage->InternString(base::StringView(data)));
- args.AddArg(row_id, data_name_id_, data_name_id_, value);
- }
-
- if (bundle.has_legacy_json_trace()) {
- for (auto it = bundle.legacy_json_trace(); it; ++it) {
- protos::pbzero::ChromeLegacyJsonTrace::Decoder legacy_trace(*it);
- if (legacy_trace.type() !=
- protos::pbzero::ChromeLegacyJsonTrace::USER_TRACE) {
- continue;
- }
- RowId row_id = storage->mutable_raw_events()->AddRawEvent(
- ts, raw_chrome_legacy_user_trace_event_id_, 0, 0);
- Variadic value =
- Variadic::String(storage->InternString(legacy_trace.data()));
- args.AddArg(row_id, data_name_id_, data_name_id_, value);
- }
- }
-}
-
-void ProtoTraceParser::ParseMetatraceEvent(int64_t ts, ConstBytes blob) {
- protos::pbzero::PerfettoMetatrace::Decoder event(blob.data, blob.size);
- auto utid = context_->process_tracker->GetOrCreateThread(event.thread_id());
-
- StringId cat_id = metatrace_id_;
- StringId name_id = 0;
- char fallback[64];
-
- if (event.has_event_id()) {
- auto eid = event.event_id();
- if (eid < metatrace::EVENTS_MAX) {
- name_id = context_->storage->InternString(metatrace::kEventNames[eid]);
- } else {
- sprintf(fallback, "Event %d", eid);
- name_id = context_->storage->InternString(fallback);
- }
- TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
- context_->slice_tracker->Scoped(ts, track_id, utid, RefType::kRefUtid,
- cat_id, name_id, event.event_duration_ns());
- } else if (event.has_counter_id()) {
- auto cid = event.counter_id();
- if (cid < metatrace::COUNTERS_MAX) {
- name_id = context_->storage->InternString(metatrace::kCounterNames[cid]);
- } else {
- sprintf(fallback, "Counter %d", cid);
- name_id = context_->storage->InternString(fallback);
- }
- context_->event_tracker->PushCounter(ts, event.counter_value(), name_id,
- utid, RefType::kRefUtid);
- }
-
- if (event.has_overruns())
- context_->storage->IncrementStats(stats::metatrace_overruns);
-}
-
-void ProtoTraceParser::ParseTraceConfig(ConstBytes blob) {
- protos::pbzero::TraceConfig::Decoder trace_config(blob.data, blob.size);
- if (trace_config.has_statsd_metadata()) {
- ParseStatsdMetadata(trace_config.statsd_metadata());
- }
-}
-
-void ProtoTraceParser::ParseStatsdMetadata(ConstBytes blob) {
- protos::pbzero::TraceConfig::StatsdMetadata::Decoder metadata(blob.data,
- blob.size);
- if (metadata.has_triggering_subscription_id()) {
- context_->storage->SetMetadata(
- metadata::statsd_triggering_subscription_id,
- Variadic::Integer(metadata.triggering_subscription_id()));
- }
-}
-
-void ProtoTraceParser::ParseAndroidPackagesList(ConstBytes blob) {
- protos::pbzero::PackagesList::Decoder pkg_list(blob.data, blob.size);
- context_->storage->SetStats(stats::packages_list_has_read_errors,
- pkg_list.read_error());
- context_->storage->SetStats(stats::packages_list_has_parse_errors,
- pkg_list.parse_error());
-
- // Insert the package info into arg sets (one set per package), with the arg
- // set ids collected in the Metadata table, under
- // metadata::android_packages_list key type.
- for (auto it = pkg_list.packages(); it; ++it) {
- // Insert a placeholder metadata entry, which will be overwritten by the
- // arg_set_id when the arg tracker is flushed.
- RowId row_id = context_->storage->AppendMetadata(
- metadata::android_packages_list, Variadic::Integer(0));
-
- auto add_arg = [this, row_id](base::StringView name, Variadic value) {
- StringId key_id = context_->storage->InternString(name);
- context_->args_tracker->AddArg(row_id, key_id, key_id, value);
- };
- protos::pbzero::PackagesList_PackageInfo::Decoder pkg(*it);
- add_arg("name",
- Variadic::String(context_->storage->InternString(pkg.name())));
- add_arg("uid", Variadic::UnsignedInteger(pkg.uid()));
- add_arg("debuggable", Variadic::Boolean(pkg.debuggable()));
- add_arg("profileable_from_shell",
- Variadic::Boolean(pkg.profileable_from_shell()));
- add_arg("version_code", Variadic::Integer(pkg.version_code()));
- }
-}
-
-void ProtoTraceParser::ParseModuleSymbols(ConstBytes blob) {
- protos::pbzero::ModuleSymbols::Decoder module_symbols(blob.data, blob.size);
- std::string hex_build_id = base::ToHex(module_symbols.build_id().data,
- module_symbols.build_id().size);
- auto mapping_rows =
- context_->storage->stack_profile_mappings().FindMappingRow(
- context_->storage->InternString(module_symbols.path()),
- context_->storage->InternString(base::StringView(hex_build_id)));
- if (mapping_rows.empty()) {
- context_->storage->IncrementStats(stats::stackprofile_invalid_mapping_id);
- return;
- }
- for (auto addr_it = module_symbols.address_symbols(); addr_it; ++addr_it) {
- protos::pbzero::AddressSymbols::Decoder address_symbols(*addr_it);
-
- ssize_t frame_row = -1;
- for (int64_t mapping_row : mapping_rows) {
- frame_row = context_->storage->stack_profile_frames().FindFrameRow(
- static_cast<size_t>(mapping_row), address_symbols.address());
- if (frame_row != -1)
- break;
- }
- if (frame_row == -1) {
- context_->storage->IncrementStats(stats::stackprofile_invalid_frame_id);
- continue;
- }
- uint32_t symbol_set_id = context_->storage->symbol_table().size();
- context_->storage->mutable_stack_profile_frames()->SetSymbolSetId(
- static_cast<size_t>(frame_row), symbol_set_id);
- for (auto line_it = address_symbols.lines(); line_it; ++line_it) {
- protos::pbzero::Line::Decoder line(*line_it);
- context_->storage->mutable_symbol_table()->Insert(
- {symbol_set_id, context_->storage->InternString(line.function_name()),
- context_->storage->InternString(line.source_file_name()),
- line.line_number()});
- }
- }
-}
-
-void ProtoTraceParser::ParseHeapGraph(int64_t ts, ConstBytes blob) {
- protos::pbzero::HeapGraph::Decoder heap_graph(blob.data, blob.size);
- UniquePid upid = context_->process_tracker->GetOrCreateProcess(
- static_cast<uint32_t>(heap_graph.pid()));
- context_->heap_graph_tracker->SetPacketIndex(heap_graph.index());
- for (auto it = heap_graph.objects(); it; ++it) {
- protos::pbzero::HeapGraphObject::Decoder object(*it);
- HeapGraphTracker::SourceObject obj;
- obj.object_id = object.id();
- obj.self_size = object.self_size();
- obj.type_id = object.type_id();
- auto ref_field_ids_it = object.reference_field_id();
- auto ref_object_ids_it = object.reference_object_id();
- for (; ref_field_ids_it && ref_object_ids_it;
- ++ref_field_ids_it, ++ref_object_ids_it) {
- HeapGraphTracker::SourceObject::Reference ref;
- ref.field_name_id = *ref_field_ids_it;
- ref.owned_object_id = *ref_object_ids_it;
- obj.references.emplace_back(std::move(ref));
- }
-
- if (ref_field_ids_it || ref_object_ids_it) {
- context_->storage->IncrementIndexedStats(stats::heap_graph_missing_packet,
- static_cast<int>(upid));
- continue;
- }
- context_->heap_graph_tracker->AddObject(upid, ts, std::move(obj));
- }
- for (auto it = heap_graph.type_names(); it; ++it) {
- protos::pbzero::InternedString::Decoder entry(*it);
- const char* str = reinterpret_cast<const char*>(entry.str().data);
- auto str_view = base::StringView(str, entry.str().size);
-
- context_->heap_graph_tracker->AddInternedTypeName(
- entry.iid(), context_->storage->InternString(str_view));
- }
- for (auto it = heap_graph.field_names(); it; ++it) {
- protos::pbzero::InternedString::Decoder entry(*it);
- const char* str = reinterpret_cast<const char*>(entry.str().data);
- auto str_view = base::StringView(str, entry.str().size);
-
- context_->heap_graph_tracker->AddInternedFieldName(
- entry.iid(), context_->storage->InternString(str_view));
- }
- for (auto it = heap_graph.roots(); it; ++it) {
- protos::pbzero::HeapGraphRoot::Decoder entry(*it);
- const char* str = HeapGraphRootTypeToString(entry.root_type());
- auto str_view = base::StringView(str);
-
- HeapGraphTracker::SourceRoot src_root;
- src_root.root_type = context_->storage->InternString(str_view);
- for (auto obj_it = entry.object_ids(); obj_it; ++obj_it)
- src_root.object_ids.emplace_back(*obj_it);
- context_->heap_graph_tracker->AddRoot(upid, ts, std::move(src_root));
- }
- if (!heap_graph.continued()) {
- context_->heap_graph_tracker->FinalizeProfile();
- }
-}
-
-} // namespace trace_processor
-} // namespace perfetto
diff --git a/src/trace_processor/proto_trace_parser.h b/src/trace_processor/proto_trace_parser.h
deleted file mode 100644
index 1ed2ac7..0000000
--- a/src/trace_processor/proto_trace_parser.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2018 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_PROTO_TRACE_PARSER_H_
-#define SRC_TRACE_PROCESSOR_PROTO_TRACE_PARSER_H_
-
-#include <stdint.h>
-
-#include <array>
-#include <memory>
-
-#include "perfetto/ext/base/optional.h"
-#include "perfetto/ext/base/string_view.h"
-#include "perfetto/protozero/field.h"
-#include "src/trace_processor/graphics_event_parser.h"
-#include "src/trace_processor/proto_incremental_state.h"
-#include "src/trace_processor/slice_tracker.h"
-#include "src/trace_processor/timestamped_trace_piece.h"
-#include "src/trace_processor/trace_blob_view.h"
-#include "src/trace_processor/trace_parser.h"
-#include "src/trace_processor/trace_storage.h"
-
-#include "protos/perfetto/trace/trace_packet.pbzero.h"
-#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-class ArgsTracker;
-class TraceProcessorContext;
-
-class ProtoTraceParser : public TraceParser {
- public:
- using ConstBytes = protozero::ConstBytes;
- explicit ProtoTraceParser(TraceProcessorContext*);
- ~ProtoTraceParser() override;
-
- // TraceParser implementation.
- void ParseTracePacket(int64_t timestamp, TimestampedTracePiece) override;
- void ParseFtracePacket(uint32_t cpu,
- int64_t timestamp,
- TimestampedTracePiece) override;
-
- void ParseTracePacketImpl(int64_t ts,
- TimestampedTracePiece,
- const protos::pbzero::TracePacket::Decoder&);
-
- void ParseProcessTree(ConstBytes);
- void ParseProcessStats(int64_t timestamp, ConstBytes);
- void ParseSysStats(int64_t ts, ConstBytes);
- void ParseBatteryCounters(int64_t ts, ConstBytes);
- void ParsePowerRails(int64_t ts, ConstBytes);
- void ParseAndroidLogPacket(ConstBytes);
- void ParseAndroidLogEvent(ConstBytes);
- void ParseAndroidLogStats(ConstBytes);
- void ParseTraceStats(ConstBytes);
- void ParseProfilePacket(int64_t ts,
- ProtoIncrementalState::PacketSequenceState*,
- size_t sequence_state_generation,
- ConstBytes);
- void ParseStreamingProfilePacket(ProtoIncrementalState::PacketSequenceState*,
- size_t sequence_state_generation,
- ConstBytes);
- void ParseSystemInfo(ConstBytes);
- void ParseTrackEvent(int64_t ts,
- int64_t tts,
- int64_t ticount,
- ProtoIncrementalState::PacketSequenceState*,
- size_t sequence_state_generation,
- ConstBytes);
- void ParseLegacyEventAsRawEvent(
- int64_t ts,
- int64_t tts,
- int64_t ticount,
- base::Optional<UniqueTid> utid,
- StringId category_id,
- StringId name_id,
- const protos::pbzero::TrackEvent::LegacyEvent::Decoder& legacy_event,
- SliceTracker::SetArgsCallback args_callback);
- void ParseDebugAnnotationArgs(ConstBytes debug_annotation,
- ProtoIncrementalState::PacketSequenceState*,
- size_t sequence_state_generation,
- ArgsTracker* args_tracker,
- RowId row);
- void ParseNestedValueArgs(ConstBytes nested_value,
- base::StringView flat_key,
- base::StringView key,
- ArgsTracker* args_tracker,
- RowId row);
- void ParseTaskExecutionArgs(ConstBytes task_execution,
- ProtoIncrementalState::PacketSequenceState*,
- size_t sequence_state_generation,
- ArgsTracker* args_tracker,
- RowId row);
- void ParseChromeBenchmarkMetadata(ConstBytes);
- void ParseChromeEvents(int64_t ts, ConstBytes);
- void ParseMetatraceEvent(int64_t ts, ConstBytes);
- void ParseTraceConfig(ConstBytes);
- void ParseStatsdMetadata(ConstBytes);
- void ParseAndroidPackagesList(ConstBytes);
- void ParseLogMessage(ConstBytes,
- ProtoIncrementalState::PacketSequenceState*,
- size_t sequence_state_generation,
- int64_t,
- base::Optional<UniqueTid>,
- ArgsTracker*,
- RowId);
- void ParseModuleSymbols(ConstBytes);
- void ParseHeapGraph(int64_t ts, ConstBytes);
-
- private:
- TraceProcessorContext* context_;
- std::unique_ptr<GraphicsEventParser> graphics_event_parser_;
-
- const StringId utid_name_id_;
- const StringId num_forks_name_id_;
- const StringId num_irq_total_name_id_;
- const StringId num_softirq_total_name_id_;
- const StringId num_irq_name_id_;
- const StringId num_softirq_name_id_;
- const StringId cpu_times_user_ns_id_;
- const StringId cpu_times_user_nice_ns_id_;
- const StringId cpu_times_system_mode_ns_id_;
- const StringId cpu_times_idle_ns_id_;
- const StringId cpu_times_io_wait_ns_id_;
- const StringId cpu_times_irq_ns_id_;
- const StringId cpu_times_softirq_ns_id_;
- const StringId batt_charge_id_;
- const StringId batt_capacity_id_;
- const StringId batt_current_id_;
- const StringId batt_current_avg_id_;
- const StringId oom_score_adj_id_;
- const StringId metatrace_id_;
- const StringId task_file_name_args_key_id_;
- const StringId task_function_name_args_key_id_;
- const StringId task_line_number_args_key_id_;
- const StringId log_message_body_key_id_;
- const StringId data_name_id_;
- const StringId raw_chrome_metadata_event_id_;
- const StringId raw_chrome_legacy_system_trace_event_id_;
- const StringId raw_chrome_legacy_user_trace_event_id_;
- const StringId raw_legacy_event_id_;
- const StringId legacy_event_category_key_id_;
- const StringId legacy_event_name_key_id_;
- const StringId legacy_event_phase_key_id_;
- const StringId legacy_event_duration_ns_key_id_;
- const StringId legacy_event_thread_timestamp_ns_key_id_;
- const StringId legacy_event_thread_duration_ns_key_id_;
- const StringId legacy_event_thread_instruction_count_key_id_;
- const StringId legacy_event_thread_instruction_delta_key_id_;
- const StringId legacy_event_use_async_tts_key_id_;
- const StringId legacy_event_unscoped_id_key_id_;
- const StringId legacy_event_global_id_key_id_;
- const StringId legacy_event_local_id_key_id_;
- const StringId legacy_event_id_scope_key_id_;
- const StringId legacy_event_bind_id_key_id_;
- const StringId legacy_event_bind_to_enclosing_key_id_;
- const StringId legacy_event_flow_direction_key_id_;
- const StringId flow_direction_value_in_id_;
- const StringId flow_direction_value_out_id_;
- const StringId flow_direction_value_inout_id_;
- std::vector<StringId> meminfo_strs_id_;
- std::vector<StringId> vmstat_strs_id_;
- std::vector<StringId> power_rails_strs_id_;
-
- // Maps a proto field number for memcounters in ProcessStats::Process to
- // their StringId. Keep kProcStatsProcessSize equal to 1 + max proto field
- // id of ProcessStats::Process.
- static constexpr size_t kProcStatsProcessSize = 11;
- std::array<StringId, kProcStatsProcessSize> proc_stats_process_names_{};
-};
-
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_PROTO_TRACE_PARSER_H_
diff --git a/src/trace_processor/proto_trace_tokenizer.cc b/src/trace_processor/proto_trace_tokenizer.cc
deleted file mode 100644
index 379573b..0000000
--- a/src/trace_processor/proto_trace_tokenizer.cc
+++ /dev/null
@@ -1,755 +0,0 @@
-/*
- * Copyright (C) 2018 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/proto_trace_tokenizer.h"
-
-#include <string>
-
-#include <zlib.h>
-
-#include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
-#include "perfetto/ext/base/string_view.h"
-#include "perfetto/ext/base/utils.h"
-#include "perfetto/protozero/proto_decoder.h"
-#include "perfetto/protozero/proto_utils.h"
-#include "perfetto/trace_processor/status.h"
-#include "src/trace_processor/clock_tracker.h"
-#include "src/trace_processor/event_tracker.h"
-#include "src/trace_processor/importers/ftrace/ftrace_module.h"
-#include "src/trace_processor/importers/proto/track_event_module.h"
-#include "src/trace_processor/process_tracker.h"
-#include "src/trace_processor/proto_incremental_state.h"
-#include "src/trace_processor/stats.h"
-#include "src/trace_processor/trace_blob_view.h"
-#include "src/trace_processor/trace_sorter.h"
-#include "src/trace_processor/trace_storage.h"
-#include "src/trace_processor/track_tracker.h"
-
-#include "protos/perfetto/config/trace_config.pbzero.h"
-#include "protos/perfetto/trace/clock_snapshot.pbzero.h"
-#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
-#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
-#include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
-#include "protos/perfetto/trace/trace.pbzero.h"
-#include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
-#include "protos/perfetto/trace/track_event/source_location.pbzero.h"
-#include "protos/perfetto/trace/track_event/task_execution.pbzero.h"
-#include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
-#include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
-#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-using protozero::ProtoDecoder;
-using protozero::proto_utils::MakeTagLengthDelimited;
-using protozero::proto_utils::ParseVarInt;
-
-namespace {
-
-constexpr uint8_t kTracePacketTag =
- MakeTagLengthDelimited(protos::pbzero::Trace::kPacketFieldNumber);
-
-TraceBlobView Decompress(TraceBlobView input) {
- uint8_t out[4096];
- std::string s;
-
- z_stream stream{};
- stream.next_in = const_cast<uint8_t*>(input.data());
- stream.avail_in = static_cast<unsigned int>(input.length());
-
- if (inflateInit(&stream) != Z_OK)
- return TraceBlobView(nullptr, 0, 0);
-
- int ret;
- do {
- stream.next_out = out;
- stream.avail_out = sizeof(out);
- ret = inflate(&stream, Z_NO_FLUSH);
- if (ret != Z_STREAM_END && ret != Z_OK)
- return TraceBlobView(nullptr, 0, 0);
- s.append(reinterpret_cast<char*>(out), sizeof(out) - stream.avail_out);
- } while (ret != Z_STREAM_END);
- inflateEnd(&stream);
-
- std::unique_ptr<uint8_t[]> output(new uint8_t[s.size()]);
- memcpy(output.get(), s.data(), s.size());
- return TraceBlobView(std::move(output), 0, s.size());
-}
-
-} // namespace
-
-ProtoTraceTokenizer::ProtoTraceTokenizer(TraceProcessorContext* ctx)
- : context_(ctx) {}
-ProtoTraceTokenizer::~ProtoTraceTokenizer() = default;
-
-util::Status ProtoTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> owned_buf,
- size_t size) {
- uint8_t* data = &owned_buf[0];
- if (!partial_buf_.empty()) {
- // It takes ~5 bytes for a proto preamble + the varint size.
- const size_t kHeaderBytes = 5;
- if (PERFETTO_UNLIKELY(partial_buf_.size() < kHeaderBytes)) {
- size_t missing_len = std::min(kHeaderBytes - partial_buf_.size(), size);
- partial_buf_.insert(partial_buf_.end(), &data[0], &data[missing_len]);
- if (partial_buf_.size() < kHeaderBytes)
- return util::OkStatus();
- data += missing_len;
- size -= missing_len;
- }
-
- // At this point we have enough data in |partial_buf_| to read at least the
- // field header and know the size of the next TracePacket.
- const uint8_t* pos = &partial_buf_[0];
- uint8_t proto_field_tag = *pos;
- uint64_t field_size = 0;
- const uint8_t* next = ParseVarInt(++pos, &*partial_buf_.end(), &field_size);
- bool parse_failed = next == pos;
- pos = next;
- if (proto_field_tag != kTracePacketTag || field_size == 0 || parse_failed) {
- return util::ErrStatus(
- "Failed parsing a TracePacket from the partial buffer");
- }
-
- // At this point we know how big the TracePacket is.
- size_t hdr_size = static_cast<size_t>(pos - &partial_buf_[0]);
- size_t size_incl_header = static_cast<size_t>(field_size + hdr_size);
- PERFETTO_DCHECK(size_incl_header > partial_buf_.size());
-
- // There is a good chance that between the |partial_buf_| and the new |data|
- // of the current call we have enough bytes to parse a TracePacket.
- if (partial_buf_.size() + size >= size_incl_header) {
- // Create a new buffer for the whole TracePacket and copy into that:
- // 1) The beginning of the TracePacket (including the proto header) from
- // the partial buffer.
- // 2) The rest of the TracePacket from the current |data| buffer (note
- // that we might have consumed already a few bytes form |data| earlier
- // in this function, hence we need to keep |off| into account).
- std::unique_ptr<uint8_t[]> buf(new uint8_t[size_incl_header]);
- memcpy(&buf[0], partial_buf_.data(), partial_buf_.size());
- // |size_missing| is the number of bytes for the rest of the TracePacket
- // in |data|.
- size_t size_missing = size_incl_header - partial_buf_.size();
- memcpy(&buf[partial_buf_.size()], &data[0], size_missing);
- data += size_missing;
- size -= size_missing;
- partial_buf_.clear();
- uint8_t* buf_start = &buf[0]; // Note that buf is std::moved below.
- util::Status status =
- ParseInternal(std::move(buf), buf_start, size_incl_header);
- if (PERFETTO_UNLIKELY(!status.ok()))
- return status;
- } else {
- partial_buf_.insert(partial_buf_.end(), data, &data[size]);
- return util::OkStatus();
- }
- }
- return ParseInternal(std::move(owned_buf), data, size);
-}
-
-util::Status ProtoTraceTokenizer::ParseInternal(
- std::unique_ptr<uint8_t[]> owned_buf,
- uint8_t* data,
- size_t size) {
- PERFETTO_DCHECK(data >= &owned_buf[0]);
- const uint8_t* start = &owned_buf[0];
- const size_t data_off = static_cast<size_t>(data - start);
- TraceBlobView whole_buf(std::move(owned_buf), data_off, size);
-
- protos::pbzero::Trace::Decoder decoder(data, size);
- for (auto it = decoder.packet(); it; ++it) {
- protozero::ConstBytes packet = *it;
- size_t field_offset = whole_buf.offset_of(packet.data);
- util::Status status =
- ParsePacket(whole_buf.slice(field_offset, packet.size));
- if (PERFETTO_UNLIKELY(!status.ok()))
- return status;
- }
-
- const size_t bytes_left = decoder.bytes_left();
- if (bytes_left > 0) {
- PERFETTO_DCHECK(partial_buf_.empty());
- partial_buf_.insert(partial_buf_.end(), &data[decoder.read_offset()],
- &data[decoder.read_offset() + bytes_left]);
- }
- return util::OkStatus();
-}
-
-util::Status ProtoTraceTokenizer::ParsePacket(TraceBlobView packet) {
- protos::pbzero::TracePacket::Decoder decoder(packet.data(), packet.length());
- if (PERFETTO_UNLIKELY(decoder.bytes_left()))
- return util::ErrStatus(
- "Failed to parse proto packet fully; the trace is probably corrupt.");
-
- auto timestamp =
- decoder.has_timestamp()
- ? static_cast<int64_t>(decoder.timestamp())
- : std::max(latest_timestamp_, context_->sorter->max_timestamp());
-
- const uint32_t seq_id = decoder.trusted_packet_sequence_id();
-
- // If the TracePacket specifies a non-zero clock-id, translate the timestamp
- // into the trace-time clock domain.
- if (decoder.timestamp_clock_id()) {
- PERFETTO_DCHECK(decoder.has_timestamp());
- ClockTracker::ClockId clock_id = decoder.timestamp_clock_id();
- bool is_seq_scoped = ClockTracker::IsReservedSeqScopedClockId(clock_id);
- if (is_seq_scoped) {
- if (!seq_id) {
- return util::ErrStatus(
- "TracePacket specified a sequence-local clock id (%" PRIu32
- ") but the TraceWriter's sequence_id is zero (the service is "
- "probably too old)",
- decoder.timestamp_clock_id());
- }
- clock_id = ClockTracker::SeqScopedClockIdToGlobal(
- seq_id, decoder.timestamp_clock_id());
- }
- auto trace_ts = context_->clock_tracker->ToTraceTime(clock_id, timestamp);
- if (!trace_ts.has_value()) {
- // ToTraceTime() will increase the |clock_sync_failure| stat on failure.
- static const char seq_extra_err[] =
- " Because the clock id is sequence-scoped, the ClockSnapshot must be "
- "emitted on the same TraceWriter sequence of the packet that refers "
- "to that clock id.";
- return util::ErrStatus(
- "Failed to convert TracePacket's timestamp from clock_id=%" PRIu32
- " seq_id=%" PRIu32
- ". This is usually due to the lack of a prior ClockSnapshot proto.%s",
- decoder.timestamp_clock_id(), seq_id,
- is_seq_scoped ? seq_extra_err : "");
- }
- timestamp = trace_ts.value();
- } else if (decoder.has_chrome_events() || decoder.has_chrome_metadata()) {
- // Chrome timestamps are in MONOTONIC domain. Adjust to trace time if we
- // have a clock snapshot.
- // TODO(eseckler): Set timestamp_clock_id in chrome and then remove this.
- auto trace_ts = context_->clock_tracker->ToTraceTime(
- protos::pbzero::ClockSnapshot::Clock::MONOTONIC, timestamp);
- if (trace_ts.has_value())
- timestamp = trace_ts.value();
- }
- latest_timestamp_ = std::max(timestamp, latest_timestamp_);
-
- auto* state = GetIncrementalStateForPacketSequence(
- decoder.trusted_packet_sequence_id());
-
- uint32_t sequence_flags = decoder.sequence_flags();
-
- if (decoder.incremental_state_cleared() ||
- sequence_flags &
- protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
- HandleIncrementalStateCleared(decoder);
- } else if (decoder.previous_packet_dropped()) {
- HandlePreviousPacketDropped(decoder);
- }
-
- if (decoder.sequence_flags() &
- protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE) {
- if (!seq_id) {
- return util::ErrStatus(
- "TracePacket specified SEQ_NEEDS_INCREMENTAL_STATE but the "
- "TraceWriter's sequence_id is zero (the service is "
- "probably too old)");
- }
-
- if (!state->IsIncrementalStateValid()) {
- context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
- return util::OkStatus();
- }
- }
-
- if (decoder.has_clock_snapshot()) {
- return ParseClockSnapshot(decoder.clock_snapshot(),
- decoder.trusted_packet_sequence_id());
- }
-
- // TODO(eseckler): Parse TracePacketDefaults.
-
- if (decoder.has_interned_data()) {
- auto field = decoder.interned_data();
- const size_t offset = packet.offset_of(field.data);
- ParseInternedData(decoder, packet.slice(offset, field.size));
- }
-
- ModuleResult res = ModuleResult::Ignored();
- res = context_->ftrace_module->TokenizePacket(decoder, &packet, timestamp);
- if (!res.ignored())
- return res.ToStatus();
-
- res =
- context_->track_event_module->TokenizePacket(decoder, &packet, timestamp);
- if (!res.ignored())
- return res.ToStatus();
-
- if (decoder.has_track_descriptor()) {
- ParseTrackDescriptorPacket(decoder);
- return util::OkStatus();
- }
-
- if (decoder.has_track_event()) {
- ParseTrackEventPacket(decoder, std::move(packet), timestamp);
- return util::OkStatus();
- }
-
- // TODO(eseckler): Remove this once Chrome has switched fully over to
- // TrackDescriptors.
- if (decoder.has_thread_descriptor()) {
- ParseThreadDescriptorPacket(decoder);
- return util::OkStatus();
- }
- if (decoder.has_process_descriptor()) {
- ParseProcessDescriptorPacket(decoder);
- return util::OkStatus();
- }
-
- if (decoder.has_compressed_packets()) {
- protozero::ConstBytes field = decoder.compressed_packets();
- const size_t field_off = packet.offset_of(field.data);
- TraceBlobView compressed_packets = packet.slice(field_off, field.size);
- TraceBlobView packets = Decompress(std::move(compressed_packets));
-
- const uint8_t* start = packets.data();
- const uint8_t* end = packets.data() + packets.length();
- const uint8_t* ptr = start;
- while ((end - ptr) > 2) {
- const uint8_t* packet_start = ptr;
- if (PERFETTO_UNLIKELY(*ptr != kTracePacketTag))
- return util::ErrStatus("Expected TracePacket tag");
- uint64_t packet_size = 0;
- ptr = ParseVarInt(++ptr, end, &packet_size);
- size_t packet_offset = static_cast<size_t>(ptr - start);
- ptr += packet_size;
- if (PERFETTO_UNLIKELY((ptr - packet_start) < 2 || ptr > end))
- return util::ErrStatus("Invalid packet size");
- util::Status status = ParsePacket(
- packets.slice(packet_offset, static_cast<size_t>(packet_size)));
- if (PERFETTO_UNLIKELY(!status.ok()))
- return status;
- }
-
- return util::OkStatus();
- }
-
- if (decoder.has_trace_config()) {
- auto config = decoder.trace_config();
- protos::pbzero::TraceConfig::Decoder trace_config(config.data, config.size);
-
- if (trace_config.write_into_file()) {
- int64_t window_size_ns;
- if (trace_config.has_flush_period_ms() &&
- trace_config.flush_period_ms() > 0) {
- // We use 2x the flush period as a margin of error to allow for any
- // late flush responses to still be sorted correctly.
- window_size_ns = static_cast<int64_t>(trace_config.flush_period_ms()) *
- 2 * 1000 * 1000;
- } else {
- constexpr uint64_t kDefaultWindowNs =
- 180 * 1000 * 1000 * 1000ULL; // 3 minutes.
- PERFETTO_ELOG(
- "It is strongly recommended to have flush_period_ms set when "
- "write_into_file is turned on. You will likely have many dropped "
- "events because of inability to sort the events correctly.");
- window_size_ns = static_cast<int64_t>(kDefaultWindowNs);
- }
- context_->sorter->SetWindowSizeNs(window_size_ns);
- }
- }
-
- // Use parent data and length because we want to parse this again
- // later to get the exact type of the packet.
- context_->sorter->PushTracePacket(timestamp, state, std::move(packet));
-
- return util::OkStatus();
-}
-
-void ProtoTraceTokenizer::HandleIncrementalStateCleared(
- const protos::pbzero::TracePacket::Decoder& packet_decoder) {
- if (PERFETTO_UNLIKELY(!packet_decoder.has_trusted_packet_sequence_id())) {
- PERFETTO_ELOG(
- "incremental_state_cleared without trusted_packet_sequence_id");
- context_->storage->IncrementStats(stats::interned_data_tokenizer_errors);
- return;
- }
- GetIncrementalStateForPacketSequence(
- packet_decoder.trusted_packet_sequence_id())
- ->OnIncrementalStateCleared();
-}
-
-void ProtoTraceTokenizer::HandlePreviousPacketDropped(
- const protos::pbzero::TracePacket::Decoder& packet_decoder) {
- if (PERFETTO_UNLIKELY(!packet_decoder.has_trusted_packet_sequence_id())) {
- PERFETTO_ELOG("previous_packet_dropped without trusted_packet_sequence_id");
- context_->storage->IncrementStats(stats::interned_data_tokenizer_errors);
- return;
- }
- GetIncrementalStateForPacketSequence(
- packet_decoder.trusted_packet_sequence_id())
- ->OnPacketLoss();
-}
-
-void ProtoTraceTokenizer::ParseInternedData(
- const protos::pbzero::TracePacket::Decoder& packet_decoder,
- TraceBlobView interned_data) {
- if (PERFETTO_UNLIKELY(!packet_decoder.has_trusted_packet_sequence_id())) {
- PERFETTO_ELOG("InternedData packet without trusted_packet_sequence_id");
- context_->storage->IncrementStats(stats::interned_data_tokenizer_errors);
- return;
- }
-
- auto* state = GetIncrementalStateForPacketSequence(
- packet_decoder.trusted_packet_sequence_id());
-
- // Don't parse interned data entries until incremental state is valid, because
- // they could otherwise be associated with the wrong generation in the state.
- if (!state->IsIncrementalStateValid()) {
- context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
- return;
- }
-
- // Store references to interned data submessages into the sequence's state.
- protozero::ProtoDecoder decoder(interned_data.data(), interned_data.length());
- for (protozero::Field f = decoder.ReadField(); f.valid();
- f = decoder.ReadField()) {
- auto bytes = f.as_bytes();
- auto offset = interned_data.offset_of(bytes.data);
- state->InternMessage(f.id(), interned_data.slice(offset, bytes.size));
- }
-}
-
-void ProtoTraceTokenizer::ParseTrackDescriptorPacket(
- const protos::pbzero::TracePacket::Decoder& packet_decoder) {
- auto track_descriptor_field = packet_decoder.track_descriptor();
- protos::pbzero::TrackDescriptor::Decoder track_descriptor_decoder(
- track_descriptor_field.data, track_descriptor_field.size);
-
- if (!track_descriptor_decoder.has_uuid()) {
- PERFETTO_ELOG("TrackDescriptor packet without trusted_packet_sequence_id");
- context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
- return;
- }
-
- base::Optional<UniquePid> upid;
- base::Optional<UniqueTid> utid;
-
- if (track_descriptor_decoder.has_process()) {
- auto process_descriptor_field = track_descriptor_decoder.process();
- protos::pbzero::ProcessDescriptor::Decoder process_descriptor_decoder(
- process_descriptor_field.data, process_descriptor_field.size);
-
- // TODO(eseckler): Also parse process name / type here.
-
- upid = context_->process_tracker->GetOrCreateProcess(
- static_cast<uint32_t>(process_descriptor_decoder.pid()));
- }
-
- if (track_descriptor_decoder.has_thread()) {
- auto thread_descriptor_field = track_descriptor_decoder.thread();
- protos::pbzero::ThreadDescriptor::Decoder thread_descriptor_decoder(
- thread_descriptor_field.data, thread_descriptor_field.size);
-
- ParseThreadDescriptor(thread_descriptor_decoder);
- utid = context_->process_tracker->UpdateThread(
- static_cast<uint32_t>(thread_descriptor_decoder.tid()),
- static_cast<uint32_t>(thread_descriptor_decoder.pid()));
- upid = *context_->storage->GetThread(*utid).upid;
- }
-
- StringId name_id =
- context_->storage->InternString(track_descriptor_decoder.name());
-
- context_->track_tracker->UpdateDescriptorTrack(
- track_descriptor_decoder.uuid(), name_id, upid, utid);
-}
-
-void ProtoTraceTokenizer::ParseProcessDescriptorPacket(
- const protos::pbzero::TracePacket::Decoder& packet_decoder) {
- protos::pbzero::ProcessDescriptor::Decoder process_descriptor_decoder(
- packet_decoder.process_descriptor());
- if (!process_descriptor_decoder.has_chrome_process_type())
- return;
- base::StringView name = "Unknown";
- switch (process_descriptor_decoder.chrome_process_type()) {
- case protos::pbzero::ProcessDescriptor::PROCESS_BROWSER:
- name = "Browser";
- break;
- case protos::pbzero::ProcessDescriptor::PROCESS_RENDERER:
- name = "Renderer";
- break;
- case protos::pbzero::ProcessDescriptor::PROCESS_UTILITY:
- name = "Utility";
- break;
- case protos::pbzero::ProcessDescriptor::PROCESS_ZYGOTE:
- name = "Zygote";
- break;
- case protos::pbzero::ProcessDescriptor::PROCESS_SANDBOX_HELPER:
- name = "SandboxHelper";
- break;
- case protos::pbzero::ProcessDescriptor::PROCESS_GPU:
- name = "Gpu";
- break;
- case protos::pbzero::ProcessDescriptor::PROCESS_PPAPI_PLUGIN:
- name = "PpapiPlugin";
- break;
- case protos::pbzero::ProcessDescriptor::PROCESS_PPAPI_BROKER:
- name = "PpapiBroker";
- break;
- }
- context_->process_tracker->SetProcessMetadata(
- static_cast<uint32_t>(process_descriptor_decoder.pid()), base::nullopt,
- name);
-}
-
-void ProtoTraceTokenizer::ParseThreadDescriptorPacket(
- const protos::pbzero::TracePacket::Decoder& packet_decoder) {
- if (PERFETTO_UNLIKELY(!packet_decoder.has_trusted_packet_sequence_id())) {
- PERFETTO_ELOG("ThreadDescriptor packet without trusted_packet_sequence_id");
- context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
- return;
- }
-
- auto* state = GetIncrementalStateForPacketSequence(
- packet_decoder.trusted_packet_sequence_id());
-
- // TrackEvents will be ignored while incremental state is invalid. As a
- // consequence, we should also ignore any ThreadDescriptors received in this
- // state. Otherwise, any delta-encoded timestamps would be calculated
- // incorrectly once we move out of the packet loss state. Instead, wait until
- // the first subsequent descriptor after incremental state is cleared.
- if (!state->IsIncrementalStateValid()) {
- context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
- return;
- }
-
- auto thread_descriptor_field = packet_decoder.thread_descriptor();
- protos::pbzero::ThreadDescriptor::Decoder thread_descriptor_decoder(
- thread_descriptor_field.data, thread_descriptor_field.size);
-
- state->SetThreadDescriptor(
- thread_descriptor_decoder.pid(), thread_descriptor_decoder.tid(),
- thread_descriptor_decoder.reference_timestamp_us() * 1000,
- thread_descriptor_decoder.reference_thread_time_us() * 1000,
- thread_descriptor_decoder.reference_thread_instruction_count());
-
- ParseThreadDescriptor(thread_descriptor_decoder);
-}
-
-void ProtoTraceTokenizer::ParseThreadDescriptor(
- const protos::pbzero::ThreadDescriptor::Decoder&
- thread_descriptor_decoder) {
- base::StringView name;
- if (thread_descriptor_decoder.has_thread_name()) {
- name = thread_descriptor_decoder.thread_name();
- } else if (thread_descriptor_decoder.has_chrome_thread_type()) {
- using protos::pbzero::ThreadDescriptor;
- switch (thread_descriptor_decoder.chrome_thread_type()) {
- case ThreadDescriptor::CHROME_THREAD_MAIN:
- name = "CrProcessMain";
- break;
- case ThreadDescriptor::CHROME_THREAD_IO:
- name = "ChromeIOThread";
- break;
- case ThreadDescriptor::CHROME_THREAD_POOL_FG_WORKER:
- name = "ThreadPoolForegroundWorker&";
- break;
- case ThreadDescriptor::CHROME_THREAD_POOL_BG_WORKER:
- name = "ThreadPoolBackgroundWorker&";
- break;
- case ThreadDescriptor::CHROME_THREAD_POOL_FB_BLOCKING:
- name = "ThreadPoolSingleThreadForegroundBlocking&";
- break;
- case ThreadDescriptor::CHROME_THREAD_POOL_BG_BLOCKING:
- name = "ThreadPoolSingleThreadBackgroundBlocking&";
- break;
- case ThreadDescriptor::CHROME_THREAD_POOL_SERVICE:
- name = "ThreadPoolService";
- break;
- case ThreadDescriptor::CHROME_THREAD_COMPOSITOR_WORKER:
- name = "CompositorTileWorker&";
- break;
- case ThreadDescriptor::CHROME_THREAD_COMPOSITOR:
- name = "Compositor";
- break;
- case ThreadDescriptor::CHROME_THREAD_VIZ_COMPOSITOR:
- name = "VizCompositorThread";
- break;
- case ThreadDescriptor::CHROME_THREAD_SERVICE_WORKER:
- name = "ServiceWorkerThread&";
- break;
- case ThreadDescriptor::CHROME_THREAD_MEMORY_INFRA:
- name = "MemoryInfra";
- break;
- case ThreadDescriptor::CHROME_THREAD_SAMPLING_PROFILER:
- name = "StackSamplingProfiler";
- break;
- case ThreadDescriptor::CHROME_THREAD_UNSPECIFIED:
- name = "ChromeUnspecified";
- break;
- }
- }
-
- if (!name.empty()) {
- auto thread_name_id = context_->storage->InternString(name);
- ProcessTracker* procs = context_->process_tracker.get();
- procs->UpdateThreadName(
- static_cast<uint32_t>(thread_descriptor_decoder.tid()), thread_name_id);
- }
-}
-
-util::Status ProtoTraceTokenizer::ParseClockSnapshot(ConstBytes blob,
- uint32_t seq_id) {
- std::map<ClockTracker::ClockId, int64_t> clock_map;
- protos::pbzero::ClockSnapshot::Decoder evt(blob.data, blob.size);
- for (auto it = evt.clocks(); it; ++it) {
- protos::pbzero::ClockSnapshot::Clock::Decoder clk(*it);
- ClockTracker::ClockId clock_id = clk.clock_id();
- if (ClockTracker::IsReservedSeqScopedClockId(clk.clock_id())) {
- if (!seq_id) {
- return util::ErrStatus(
- "ClockSnapshot packet is specifying a sequence-scoped clock id "
- "(%" PRIu64 ") but the TracePacket sequence_id is zero",
- clock_id);
- }
- clock_id = ClockTracker::SeqScopedClockIdToGlobal(seq_id, clk.clock_id());
- }
- clock_map[clock_id] = static_cast<int64_t>(clk.timestamp());
- }
- context_->clock_tracker->AddSnapshot(clock_map);
- return util::OkStatus();
-}
-
-void ProtoTraceTokenizer::ParseTrackEventPacket(
- const protos::pbzero::TracePacket::Decoder& packet_decoder,
- TraceBlobView packet,
- int64_t packet_timestamp) {
- constexpr auto kTimestampDeltaUsFieldNumber =
- protos::pbzero::TrackEvent::kTimestampDeltaUsFieldNumber;
- constexpr auto kTimestampAbsoluteUsFieldNumber =
- protos::pbzero::TrackEvent::kTimestampAbsoluteUsFieldNumber;
- constexpr auto kThreadTimeDeltaUsFieldNumber =
- protos::pbzero::TrackEvent::kThreadTimeDeltaUsFieldNumber;
- constexpr auto kThreadTimeAbsoluteUsFieldNumber =
- protos::pbzero::TrackEvent::kThreadTimeAbsoluteUsFieldNumber;
- constexpr auto kThreadInstructionCountDeltaFieldNumber =
- protos::pbzero::TrackEvent::kThreadInstructionCountDeltaFieldNumber;
- constexpr auto kThreadInstructionCountAbsoluteFieldNumber =
- protos::pbzero::TrackEvent::kThreadInstructionCountAbsoluteFieldNumber;
-
- if (PERFETTO_UNLIKELY(!packet_decoder.has_trusted_packet_sequence_id())) {
- PERFETTO_ELOG("TrackEvent packet without trusted_packet_sequence_id");
- context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
- return;
- }
-
- auto* state = GetIncrementalStateForPacketSequence(
- packet_decoder.trusted_packet_sequence_id());
-
- // TODO(eseckler): For now, TrackEvents can only be parsed correctly while
- // incremental state for their sequence is valid, because chromium doesn't set
- // SEQ_NEEDS_INCREMENTAL_STATE yet. Remove this once it does.
- if (!state->IsIncrementalStateValid()) {
- context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
- return;
- }
-
- auto field = packet_decoder.track_event();
- ProtoDecoder event_decoder(field.data, field.size);
-
- int64_t timestamp;
- int64_t thread_timestamp = 0;
- int64_t thread_instructions = 0;
-
- // TODO(eseckler): Remove handling of timestamps relative to ThreadDescriptors
- // once all producers have switched to clock-domain timestamps (e.g.
- // TracePacket's timestamp).
-
- if (auto ts_delta_field =
- event_decoder.FindField(kTimestampDeltaUsFieldNumber)) {
- // Delta timestamps require a valid ThreadDescriptor packet since the last
- // packet loss.
- if (!state->track_event_timestamps_valid()) {
- context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
- return;
- }
- timestamp = state->IncrementAndGetTrackEventTimeNs(
- ts_delta_field.as_int64() * 1000);
-
- // Legacy TrackEvent timestamp fields are in MONOTONIC domain. Adjust to
- // trace time if we have a clock snapshot.
- auto trace_ts = context_->clock_tracker->ToTraceTime(
- protos::pbzero::ClockSnapshot::Clock::MONOTONIC, timestamp);
- if (trace_ts.has_value())
- timestamp = trace_ts.value();
- } else if (auto ts_absolute_field =
- event_decoder.FindField(kTimestampAbsoluteUsFieldNumber)) {
- // One-off absolute timestamps don't affect delta computation.
- timestamp = ts_absolute_field.as_int64() * 1000;
-
- // Legacy TrackEvent timestamp fields are in MONOTONIC domain. Adjust to
- // trace time if we have a clock snapshot.
- auto trace_ts = context_->clock_tracker->ToTraceTime(
- protos::pbzero::ClockSnapshot::Clock::MONOTONIC, timestamp);
- if (trace_ts.has_value())
- timestamp = trace_ts.value();
- } else if (packet_decoder.has_timestamp()) {
- timestamp = packet_timestamp;
- } else {
- PERFETTO_ELOG("TrackEvent without timestamp");
- context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
- return;
- }
-
- if (auto tt_delta_field =
- event_decoder.FindField(kThreadTimeDeltaUsFieldNumber)) {
- // Delta timestamps require a valid ThreadDescriptor packet since the last
- // packet loss.
- if (!state->track_event_timestamps_valid()) {
- context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
- return;
- }
- thread_timestamp = state->IncrementAndGetTrackEventThreadTimeNs(
- tt_delta_field.as_int64() * 1000);
- } else if (auto tt_absolute_field =
- event_decoder.FindField(kThreadTimeAbsoluteUsFieldNumber)) {
- // One-off absolute timestamps don't affect delta computation.
- thread_timestamp = tt_absolute_field.as_int64() * 1000;
- }
-
- if (auto ti_delta_field =
- event_decoder.FindField(kThreadInstructionCountDeltaFieldNumber)) {
- // Delta timestamps require a valid ThreadDescriptor packet since the last
- // packet loss.
- if (!state->track_event_timestamps_valid()) {
- context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
- return;
- }
- thread_instructions =
- state->IncrementAndGetTrackEventThreadInstructionCount(
- ti_delta_field.as_int64());
- } else if (auto ti_absolute_field = event_decoder.FindField(
- kThreadInstructionCountAbsoluteFieldNumber)) {
- // One-off absolute timestamps don't affect delta computation.
- thread_instructions = ti_absolute_field.as_int64();
- }
-
- context_->sorter->PushTrackEventPacket(timestamp, thread_timestamp,
- thread_instructions, state,
- std::move(packet));
-}
-
-} // namespace trace_processor
-} // namespace perfetto
diff --git a/src/trace_processor/rpc.cc b/src/trace_processor/rpc.cc
new file mode 100644
index 0000000..e84df1c
--- /dev/null
+++ b/src/trace_processor/rpc.cc
@@ -0,0 +1,191 @@
+/*
+ * 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/rpc.h"
+
+#include <vector>
+
+#include "perfetto/base/time.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "perfetto/trace_processor/trace_processor.h"
+#include "protos/perfetto/trace_processor/raw_query.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using ColumnValues = protos::pbzero::RawQueryResult::ColumnValues;
+using ColumnDesc = protos::pbzero::RawQueryResult::ColumnDesc;
+
+// Writes a "Loading trace ..." update every N bytes.
+constexpr size_t kProgressUpdateBytes = 50 * 1000 * 1000;
+
+Rpc::~Rpc() = default;
+
+util::Status Rpc::LoadTrace(const uint8_t* data, size_t len, bool eof) {
+ if (eof_) {
+ // Reset the trace processor state if this is either the first call ever or
+ // if another trace has been previously fully loaded.
+ trace_processor_ = TraceProcessor::CreateInstance(Config());
+ bytes_parsed_ = bytes_last_progress_ = 0;
+ t_parse_started_ = base::GetWallTimeNs().count();
+ }
+ eof_ = eof;
+ bytes_parsed_ += len;
+ if (eof || bytes_parsed_ - bytes_last_progress_ > kProgressUpdateBytes) {
+ bytes_last_progress_ = bytes_parsed_;
+ auto t_load_s = (base::GetWallTimeNs().count() - t_parse_started_) / 1e9;
+ fprintf(stderr, "\rLoading trace %.2f MB (%.1f MB/s)%s",
+ bytes_parsed_ / 1e6, bytes_parsed_ / 1e6 / t_load_s,
+ (eof ? "\n" : ""));
+ fflush(stderr);
+ }
+ util::Status res;
+ if (len) {
+ // TraceProcessor needs take ownership of the memory chunk.
+ std::unique_ptr<uint8_t[]> data_copy(new uint8_t[len]);
+ memcpy(data_copy.get(), data, len);
+ res = trace_processor_->Parse(std::move(data_copy), len);
+ }
+ if (eof)
+ trace_processor_->NotifyEndOfFile();
+ return res;
+}
+
+std::vector<uint8_t> Rpc::RawQuery(const uint8_t* args, size_t len) {
+ protozero::HeapBuffered<protos::pbzero::RawQueryResult> result;
+ protos::pbzero::RawQueryArgs::Decoder query(args, len);
+ std::string sql_query = query.sql_query().ToStdString();
+ PERFETTO_DLOG("[RPC] RawQuery < %s", sql_query.c_str());
+ auto it = trace_processor_->ExecuteQuery(sql_query.c_str());
+
+ // This vector contains a standalone protozero message per column. The problem
+ // it's solving is the following: (i) sqlite iterators are row-based; (ii) the
+ // RawQueryResult proto is column-based (that was a poor design choice we
+ // should revisit at some point); (iii) the protozero API doesn't allow to
+ // begin a new nested message before the previous one is completed.
+ // In order to avoid the interleaved-writing, we write each column in a
+ // dedicated heap buffer and then we merge all the column data at the end,
+ // after having iterated all rows.
+ std::vector<protozero::HeapBuffered<ColumnValues>> cols(it.ColumnCount());
+
+ // This constexpr is to avoid ODR-use of protozero constants which are only
+ // declared but not defined. Putting directly UNKONWN in the vector ctor
+ // causes a linker error in the WASM toolchain.
+ static constexpr auto kUnknown = ColumnDesc::UNKNOWN;
+ std::vector<ColumnDesc::Type> col_types(it.ColumnCount(), kUnknown);
+ uint32_t rows = 0;
+
+ for (; it.Next(); ++rows) {
+ for (uint32_t col_idx = 0; col_idx < it.ColumnCount(); ++col_idx) {
+ auto& col = cols[col_idx];
+ auto& col_type = col_types[col_idx];
+
+ using SqlValue = trace_processor::SqlValue;
+ auto cell = it.Get(col_idx);
+ if (col_type == ColumnDesc::UNKNOWN) {
+ switch (cell.type) {
+ case SqlValue::Type::kLong:
+ col_type = ColumnDesc::LONG;
+ break;
+ case SqlValue::Type::kString:
+ col_type = ColumnDesc::STRING;
+ break;
+ case SqlValue::Type::kDouble:
+ col_type = ColumnDesc::DOUBLE;
+ break;
+ case SqlValue::Type::kBytes:
+ col_type = ColumnDesc::STRING;
+ break;
+ case SqlValue::Type::kNull:
+ break;
+ }
+ }
+
+ // If either the column type is null or we still don't know the type,
+ // just add null values to all the columns.
+ if (cell.type == SqlValue::Type::kNull ||
+ col_type == ColumnDesc::UNKNOWN) {
+ col->add_long_values(0);
+ col->add_string_values("[NULL]");
+ col->add_double_values(0);
+ col->add_is_nulls(true);
+ continue;
+ }
+
+ // Cast the sqlite value to the type of the column.
+ switch (col_type) {
+ case ColumnDesc::LONG:
+ PERFETTO_CHECK(cell.type == SqlValue::Type::kLong ||
+ cell.type == SqlValue::Type::kDouble);
+ if (cell.type == SqlValue::Type::kLong) {
+ col->add_long_values(cell.long_value);
+ } else /* if (cell.type == SqlValue::Type::kDouble) */ {
+ col->add_long_values(static_cast<int64_t>(cell.double_value));
+ }
+ col->add_is_nulls(false);
+ break;
+ case ColumnDesc::STRING: {
+ if (cell.type == SqlValue::Type::kBytes) {
+ col->add_string_values("<bytes>");
+ } else {
+ PERFETTO_CHECK(cell.type == SqlValue::Type::kString);
+ col->add_string_values(cell.string_value);
+ }
+ col->add_is_nulls(false);
+ break;
+ }
+ case ColumnDesc::DOUBLE:
+ PERFETTO_CHECK(cell.type == SqlValue::Type::kLong ||
+ cell.type == SqlValue::Type::kDouble);
+ if (cell.type == SqlValue::Type::kLong) {
+ col->add_double_values(static_cast<double>(cell.long_value));
+ } else /* if (cell.type == SqlValue::Type::kDouble) */ {
+ col->add_double_values(cell.double_value);
+ }
+ col->add_is_nulls(false);
+ break;
+ case ColumnDesc::UNKNOWN:
+ PERFETTO_FATAL("Handled in if statement above.");
+ }
+ } // for(col)
+ } // for(row)
+
+ // Write the column descriptors.
+ for (uint32_t col_idx = 0; col_idx < it.ColumnCount(); ++col_idx) {
+ auto* descriptor = result->add_column_descriptors();
+ std::string col_name = it.GetColumName(col_idx);
+ descriptor->set_name(col_name.data(), col_name.size());
+ descriptor->set_type(col_types[col_idx]);
+ }
+
+ // Merge the column values.
+ for (uint32_t col_idx = 0; col_idx < it.ColumnCount(); ++col_idx) {
+ std::vector<uint8_t> col_data = cols[col_idx].SerializeAsArray();
+ result->AppendBytes(protos::pbzero::RawQueryResult::kColumnsFieldNumber,
+ col_data.data(), col_data.size());
+ }
+
+ util::Status status = it.Status();
+ result->set_num_records(rows);
+ if (!status.ok())
+ result->set_error(status.c_message());
+ PERFETTO_DLOG("[RPC] RawQuery > %d rows (err: %d)", rows, !status.ok());
+
+ return result.SerializeAsArray();
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/rpc.h b/src/trace_processor/rpc.h
new file mode 100644
index 0000000..4ce3e32
--- /dev/null
+++ b/src/trace_processor/rpc.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_RPC_H_
+#define SRC_TRACE_PROCESSOR_RPC_H_
+
+#include <memory>
+#include <vector>
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "perfetto/trace_processor/status.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class TraceProcessor;
+
+// This class handles the binary {,un}marshalling for the Trace Processor RPC
+// API (see protos/perfetto/trace_processor/trace_processor.proto).
+// This is to deal with cases where the client of the trace processor is not
+// some in-process C++ code but a remote process:
+// There are two use cases of this:
+// 1. The JS<>WASM interop for the web-based UI.
+// 2. The HTTP RPC mode of trace_processor_shell that allows the UI to talk
+// to a native trace processor instead of the bundled WASM one.
+// This class has (a subset of) the same methods of the public TraceProcessor
+// interface, but the methods just take and return proto-encoded binary buffers.
+// This class does NOT define how the transport works (e.g. HTTP vs WASM interop
+// calls), it just deals with {,un}marshalling.
+// This class internally creates and owns a TraceProcessor instance, which
+// lifetime is tied to the lifetime of the Rpc instance.
+class Rpc {
+ public:
+ ~Rpc();
+
+ // Loads a trace into the trace processor. Chunked loading is supported for
+ // avoid buffering multi-GB traces in memory.
+ // Args:
+ // (data, len): a protobuf-encoded buffer for of a Trace, or just a portion
+ // of it (if eof=false). In the case of eof=false, the passed buffer does
+ // NOT need to be chunked on TracePacket boundaries. The internals deal
+ // with stitching packets together. This is to allow clients to easily chunk
+ // large trace files with fixed arbitrary chunk sizes.
+ // eof: if true, this is the last chunk of the trace. The TraceProcessor
+ // will flush its internal state and reflect all the data ingested until now
+ // into the SQL tables. A further call to LoadTrace() after eof=true will
+ // completely reset the TraceProcessor state and restart from scratch.
+ util::Status LoadTrace(const uint8_t* data, size_t len, bool eof = true);
+
+ // Executes a SQL query and returns the results.
+ // Args: RawQueryArgs proto-encoded bytes.
+ // Returns: RawQueryResult proto-encoded bytes.
+ // See protos/perfetto/trace_processor/raw_query.proto for the proto schema.
+ // If the query fails the |error| RawQueryResult.field is set accordingly
+ std::vector<uint8_t> RawQuery(const uint8_t* args, size_t len);
+
+ private:
+ std::unique_ptr<TraceProcessor> trace_processor_;
+ bool eof_ = true; // Reset when calling LoadTrace(..., eof).
+ int64_t t_parse_started_ = 0;
+ size_t bytes_last_progress_ = 0;
+ size_t bytes_parsed_ = 0;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_RPC_H_
diff --git a/src/trace_processor/tables/BUILD.gn b/src/trace_processor/tables/BUILD.gn
index ab79c88..10f5289 100644
--- a/src/trace_processor/tables/BUILD.gn
+++ b/src/trace_processor/tables/BUILD.gn
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import("../../../gn/test.gni")
+
source_set("tables") {
sources = [
"macros.h",
@@ -38,3 +40,17 @@
"../../../gn:gtest_and_gmock",
]
}
+
+if (enable_perfetto_benchmarks) {
+ source_set("benchmarks") {
+ testonly = true
+ deps = [
+ ":tables",
+ "../../../gn:benchmark",
+ "../../../gn:default_deps",
+ ]
+ sources = [
+ "macros_benchmark.cc",
+ ]
+ }
+}
diff --git a/src/trace_processor/tables/macros_benchmark.cc b/src/trace_processor/tables/macros_benchmark.cc
new file mode 100644
index 0000000..0d5a657
--- /dev/null
+++ b/src/trace_processor/tables/macros_benchmark.cc
@@ -0,0 +1,90 @@
+// 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 <random>
+
+#include <benchmark/benchmark.h>
+
+#include "src/trace_processor/tables/macros.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+
+#define PERFETTO_TP_TEST_TABLE(NAME, PARENT, C) \
+ NAME(TestTable, "test_table") \
+ PERFETTO_TP_ROOT_TABLE(PARENT, C) \
+ C(uint32_t, a)
+
+PERFETTO_TP_TABLE(PERFETTO_TP_TEST_TABLE);
+
+} // namespace
+} // namespace trace_processor
+} // namespace perfetto
+
+using perfetto::trace_processor::SqlValue;
+using perfetto::trace_processor::StringPool;
+using perfetto::trace_processor::TestTable;
+
+static void BM_TableInsert(benchmark::State& state) {
+ StringPool pool;
+ TestTable table(&pool, nullptr);
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(table.Insert({}));
+ }
+}
+BENCHMARK(BM_TableInsert);
+
+static void BM_TableFilterIdColumn(benchmark::State& state) {
+ StringPool pool;
+ TestTable table(&pool, nullptr);
+
+ uint32_t size = static_cast<uint32_t>(state.range(0));
+ for (uint32_t i = 0; i < size; ++i)
+ table.Insert({});
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(table.Filter({table.id().eq(SqlValue::Long(30))}));
+ }
+}
+BENCHMARK(BM_TableFilterIdColumn)
+ ->RangeMultiplier(8)
+ ->Range(1024, 2 * 1024 * 1024);
+
+static void BM_TableFilterEqMatchMany(benchmark::State& state) {
+ StringPool pool;
+ TestTable table(&pool, nullptr);
+
+ // We want the number of partitions to be significantly less than the size of
+ // the RowMap. This matches the setup of columns like track_id in the event
+ // table where there are a large number of events but a much smaller number of
+ // tracks all those events are associated with.
+ uint32_t size = static_cast<uint32_t>(state.range(0));
+ uint32_t partitions = size / 1024;
+
+ constexpr uint32_t kRandomSeed = 42;
+ std::minstd_rand0 rnd_engine(kRandomSeed);
+ for (uint32_t i = 0; i < size; ++i) {
+ TestTable::Row row(static_cast<uint32_t>(rnd_engine() % partitions));
+ table.Insert(row);
+ }
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(table.Filter({table.a().eq(SqlValue::Long(0))}));
+ }
+}
+BENCHMARK(BM_TableFilterEqMatchMany)
+ ->RangeMultiplier(8)
+ ->Range(1024, 2 * 1024 * 1024);
diff --git a/src/trace_processor/timestamped_trace_piece.h b/src/trace_processor/timestamped_trace_piece.h
index ac3fd26..dded81b 100644
--- a/src/trace_processor/timestamped_trace_piece.h
+++ b/src/trace_processor/timestamped_trace_piece.h
@@ -20,7 +20,7 @@
#include "perfetto/base/build_config.h"
#include "perfetto/trace_processor/basic_types.h"
#include "src/trace_processor/importers/fuchsia/fuchsia_provider_view.h"
-#include "src/trace_processor/proto_incremental_state.h"
+#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/trace_blob_view.h"
#include "src/trace_processor/trace_processor_context.h"
#include "src/trace_processor/trace_storage.h"
@@ -65,11 +65,10 @@
// A TimestampedTracePiece is (usually a reference to) a piece of a trace that
// is sorted by TraceSorter.
struct TimestampedTracePiece {
- TimestampedTracePiece(
- int64_t ts,
- uint64_t idx,
- TraceBlobView tbv,
- ProtoIncrementalState::PacketSequenceState* sequence_state)
+ TimestampedTracePiece(int64_t ts,
+ uint64_t idx,
+ TraceBlobView tbv,
+ PacketSequenceState* sequence_state)
: TimestampedTracePiece(ts,
/*thread_ts=*/0,
/*thread_instructions=*/0,
@@ -120,13 +119,12 @@
/*sequence_state=*/nullptr,
InlineEvent{}) {}
- TimestampedTracePiece(
- int64_t ts,
- int64_t thread_ts,
- int64_t thread_instructions,
- uint64_t idx,
- TraceBlobView tbv,
- ProtoIncrementalState::PacketSequenceState* sequence_state)
+ TimestampedTracePiece(int64_t ts,
+ int64_t thread_ts,
+ int64_t thread_instructions,
+ uint64_t idx,
+ TraceBlobView tbv,
+ PacketSequenceState* sequence_state)
: TimestampedTracePiece(ts,
thread_ts,
thread_instructions,
@@ -148,16 +146,15 @@
/*sequence_state=*/nullptr,
inline_evt) {}
- TimestampedTracePiece(
- int64_t ts,
- int64_t thread_ts,
- int64_t thread_instructions,
- uint64_t idx,
- TraceBlobView tbv,
- std::unique_ptr<Json::Value> value,
- std::unique_ptr<FuchsiaProviderView> fpv,
- ProtoIncrementalState::PacketSequenceState* sequence_state,
- InlineEvent inline_evt)
+ TimestampedTracePiece(int64_t ts,
+ int64_t thread_ts,
+ int64_t thread_instructions,
+ uint64_t idx,
+ TraceBlobView tbv,
+ std::unique_ptr<Json::Value> value,
+ std::unique_ptr<FuchsiaProviderView> fpv,
+ PacketSequenceState* sequence_state,
+ InlineEvent inline_evt)
: json_value(std::move(value)),
fuchsia_provider_view(std::move(fpv)),
packet_sequence_state(sequence_state),
@@ -186,7 +183,7 @@
std::unique_ptr<Json::Value> json_value;
std::unique_ptr<FuchsiaProviderView> fuchsia_provider_view;
- ProtoIncrementalState::PacketSequenceState* packet_sequence_state;
+ PacketSequenceState* packet_sequence_state;
size_t packet_sequence_state_generation;
int64_t timestamp;
diff --git a/src/trace_processor/trace_database_integrationtest.cc b/src/trace_processor/trace_database_integrationtest.cc
index 84e357f..0392c85 100644
--- a/src/trace_processor/trace_database_integrationtest.cc
+++ b/src/trace_processor/trace_database_integrationtest.cc
@@ -175,6 +175,10 @@
ASSERT_TRUE(LoadTrace("clusterfuzz_15252", 4096).ok());
}
+TEST_F(TraceProcessorIntegrationTest, Clusterfuzz17805) {
+ ASSERT_TRUE(LoadTrace("clusterfuzz_17805", 4096).ok());
+}
+
} // namespace
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/trace_processor_context.cc b/src/trace_processor/trace_processor_context.cc
index e5bd1ca..cb4e2a2 100644
--- a/src/trace_processor/trace_processor_context.cc
+++ b/src/trace_processor/trace_processor_context.cc
@@ -25,10 +25,13 @@
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
#include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
#include "src/trace_processor/importers/json/json_trace_parser.h"
+#include "src/trace_processor/importers/proto/android_probes_module.h"
+#include "src/trace_processor/importers/proto/graphics_event_module.h"
+#include "src/trace_processor/importers/proto/proto_trace_parser.h"
+#include "src/trace_processor/importers/proto/system_probes_module.h"
#include "src/trace_processor/importers/proto/track_event_module.h"
#include "src/trace_processor/importers/systrace/systrace_parser.h"
#include "src/trace_processor/process_tracker.h"
-#include "src/trace_processor/proto_trace_parser.h"
#include "src/trace_processor/slice_tracker.h"
#include "src/trace_processor/stack_profile_tracker.h"
#include "src/trace_processor/syscall_tracker.h"
diff --git a/src/trace_processor/trace_processor_context.h b/src/trace_processor/trace_processor_context.h
index 2f6c9db..51f9d90 100644
--- a/src/trace_processor/trace_processor_context.h
+++ b/src/trace_processor/trace_processor_context.h
@@ -25,24 +25,27 @@
namespace perfetto {
namespace trace_processor {
+class AndroidProbesModule;
class ArgsTracker;
class ChunkedTraceReader;
class ClockTracker;
class EventTracker;
class FtraceModule;
+class GraphicsEventModule;
class HeapGraphTracker;
class HeapProfileTracker;
-class VulkanMemoryTracker;
class ProcessTracker;
class SchedEventTracker;
class SliceTracker;
class SyscallTracker;
+class SystraceProtoModule;
class SystraceParser;
class TraceParser;
class TraceStorage;
class TraceSorter;
class TrackEventModule;
class TrackTracker;
+class VulkanMemoryTracker;
class TraceProcessorContext {
public:
@@ -70,6 +73,11 @@
std::unique_ptr<ProtoImporterModule<FtraceModule>> ftrace_module;
std::unique_ptr<ProtoImporterModule<TrackEventModule>> track_event_module;
+ std::unique_ptr<ProtoImporterModule<SystraceProtoModule>> systrace_module;
+ std::unique_ptr<ProtoImporterModule<AndroidProbesModule>>
+ android_probes_module;
+ std::unique_ptr<ProtoImporterModule<GraphicsEventModule>>
+ graphics_event_module;
};
} // namespace trace_processor
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index eeec130..90f274f 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -40,7 +40,11 @@
#include "src/trace_processor/heap_profile_tracker.h"
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
#include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
+#include "src/trace_processor/importers/proto/android_probes_module.h"
+#include "src/trace_processor/importers/proto/graphics_event_module.h"
#include "src/trace_processor/importers/proto/proto_importer_module.h"
+#include "src/trace_processor/importers/proto/proto_trace_tokenizer.h"
+#include "src/trace_processor/importers/proto/system_probes_module.h"
#include "src/trace_processor/importers/proto/track_event_module.h"
#include "src/trace_processor/importers/systrace/systrace_parser.h"
#include "src/trace_processor/importers/systrace/systrace_trace_parser.h"
@@ -48,7 +52,6 @@
#include "src/trace_processor/metadata_table.h"
#include "src/trace_processor/process_table.h"
#include "src/trace_processor/process_tracker.h"
-#include "src/trace_processor/proto_trace_tokenizer.h"
#include "src/trace_processor/raw_table.h"
#include "src/trace_processor/sched_slice_table.h"
#include "src/trace_processor/slice_table.h"
@@ -229,14 +232,10 @@
}
}
- json::ResultCode result = json::ExportJson(storage, output);
- switch (result) {
- case json::kResultOk:
- return;
- case json::kResultWrongRefType:
- sqlite3_result_error(ctx, "Encountered a slice with unsupported ref type",
- -1);
- return;
+ util::Status result = json::ExportJson(storage, output);
+ if (!result.ok()) {
+ sqlite3_result_error(ctx, result.message().c_str(), -1);
+ return;
}
}
@@ -345,6 +344,12 @@
new ProtoImporterModule<FtraceModule>(&context_));
context_.track_event_module.reset(
new ProtoImporterModule<TrackEventModule>(&context_));
+ context_.systrace_module.reset(
+ new ProtoImporterModule<SystraceProtoModule>(&context_));
+ context_.android_probes_module.reset(
+ new ProtoImporterModule<AndroidProbesModule>(&context_));
+ context_.graphics_event_module.reset(
+ new ProtoImporterModule<GraphicsEventModule>(&context_));
#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
CreateJsonExportFunction(this->context_.storage.get(), db);
diff --git a/src/trace_processor/trace_processor_impl.h b/src/trace_processor/trace_processor_impl.h
index a9cea90..0f61c2b 100644
--- a/src/trace_processor/trace_processor_impl.h
+++ b/src/trace_processor/trace_processor_impl.h
@@ -67,6 +67,8 @@
void InterruptQuery() override;
+ TraceProcessorContext* context() { return &context_; }
+
private:
// Needed for iterators to be able to delete themselves from the vector.
friend class IteratorImpl;
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index e86f220..c113e95 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -329,6 +329,7 @@
kBinaryProto,
kTextProto,
kJson,
+ kNone,
};
int RunMetrics(const std::vector<std::string>& metric_names,
@@ -340,6 +341,9 @@
PERFETTO_ELOG("Error when computing metrics: %s", status.c_message());
return 1;
}
+ if (format == OutputFormat::kNone) {
+ return 0;
+ }
if (format == OutputFormat::kBinaryProto) {
fwrite(metric_result.data(), sizeof(uint8_t), metric_result.size(), stdout);
return 0;
@@ -365,6 +369,7 @@
break;
}
case OutputFormat::kBinaryProto:
+ case OutputFormat::kNone:
PERFETTO_FATAL("Unsupported output format.");
}
return 0;
@@ -631,6 +636,7 @@
std::string trace_file_path;
bool launch_shell = false;
bool wide = false;
+ bool force_full_sort = false;
};
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
@@ -685,6 +691,9 @@
the file will only be written if the
execution is successful.
-q, --query-file FILE Read and execute an SQL query from a file.
+ If used with --run-metrics, the query is
+ executed after the selected metrics and
+ the metrics output is suppressed.
-i, --interactive Starts interactive mode even after a query
file is specified with -q or
--run-metrics.
@@ -701,7 +710,10 @@
--extra-metrics PATH Registers all SQL files at the given path
to the trace processor and extends the
builtin metrics proto with
- $PATH/metrics-ext.proto.)",
+ $PATH/metrics-ext.proto.
+ --full-sort Forces the trace processor into performing
+ a full sort ignoring any windowing
+ logic.)",
argv[0]);
}
@@ -711,6 +723,7 @@
OPT_RUN_METRICS = 1000,
OPT_METRICS_OUTPUT,
OPT_EXTRA_METRICS,
+ OPT_FORCE_FULL_SORT,
};
static const struct option long_options[] = {
@@ -725,6 +738,7 @@
{"run-metrics", required_argument, nullptr, OPT_RUN_METRICS},
{"metrics-output", required_argument, nullptr, OPT_METRICS_OUTPUT},
{"extra-metrics", required_argument, nullptr, OPT_EXTRA_METRICS},
+ {"full-sort", no_argument, nullptr, OPT_FORCE_FULL_SORT},
{nullptr, 0, nullptr, 0}};
bool explicit_interactive = false;
@@ -786,6 +800,11 @@
continue;
}
+ if (option == OPT_FORCE_FULL_SORT) {
+ command_line_options.force_full_sort = true;
+ continue;
+ }
+
PrintUsage(argv);
exit(option == 'h' ? 0 : 1);
}
@@ -856,6 +875,8 @@
// Load the trace file into the trace processor.
Config config;
+ config.force_full_sort = options.force_full_sort;
+
std::unique_ptr<TraceProcessor> tp = TraceProcessor::CreateInstance(config);
auto t_load_start = base::GetWallTimeNs();
@@ -955,7 +976,9 @@
}
OutputFormat format;
- if (options.metric_output == "binary") {
+ if (!options.query_file_path.empty()) {
+ format = OutputFormat::kNone;
+ } else if (options.metric_output == "binary") {
format = OutputFormat::kBinaryProto;
} else if (options.metric_output == "json") {
format = OutputFormat::kJson;
@@ -969,24 +992,24 @@
}
if (ret)
return ret;
- } else {
- // If we were given a query file, load contents
- std::vector<std::string> queries;
- if (!options.query_file_path.empty()) {
- base::ScopedFstream file(fopen(options.query_file_path.c_str(), "r"));
- if (!file) {
- PERFETTO_ELOG("Could not open query file (path: %s)",
- options.query_file_path.c_str());
- return 1;
- }
- if (!LoadQueries(file.get(), &queries)) {
- return 1;
- }
- }
+ }
- if (!RunQueryAndPrintResult(queries, stdout)) {
+ // If we were given a query file, load contents
+ std::vector<std::string> queries;
+ if (!options.query_file_path.empty()) {
+ base::ScopedFstream file(fopen(options.query_file_path.c_str(), "r"));
+ if (!file) {
+ PERFETTO_ELOG("Could not open query file (path: %s)",
+ options.query_file_path.c_str());
return 1;
}
+ if (!LoadQueries(file.get(), &queries)) {
+ return 1;
+ }
+ }
+
+ if (!RunQueryAndPrintResult(queries, stdout)) {
+ return 1;
}
if (!options.sqlite_file_path.empty()) {
diff --git a/src/trace_processor/trace_sorter.cc b/src/trace_processor/trace_sorter.cc
index 6209890..49cd78e 100644
--- a/src/trace_processor/trace_sorter.cc
+++ b/src/trace_processor/trace_sorter.cc
@@ -18,7 +18,7 @@
#include <utility>
#include "perfetto/ext/base/utils.h"
-#include "src/trace_processor/proto_trace_parser.h"
+#include "src/trace_processor/importers/proto/proto_trace_parser.h"
#include "src/trace_processor/trace_sorter.h"
namespace perfetto {
diff --git a/src/trace_processor/trace_sorter.h b/src/trace_processor/trace_sorter.h
index 6320fad..82f5acd 100644
--- a/src/trace_processor/trace_sorter.h
+++ b/src/trace_processor/trace_sorter.h
@@ -21,7 +21,6 @@
#include "perfetto/ext/base/circular_queue.h"
#include "perfetto/trace_processor/basic_types.h"
-#include "src/trace_processor/proto_incremental_state.h"
#include "src/trace_processor/timestamped_trace_piece.h"
#include "src/trace_processor/trace_blob_view.h"
#include "src/trace_processor/trace_processor_context.h"
@@ -35,6 +34,7 @@
namespace trace_processor {
class FuchsiaProviderView;
+class PacketSequenceState;
// This class takes care of sorting events parsed from the trace stream in
// arbitrary order and pushing them to the next pipeline stages (parsing) in
@@ -68,7 +68,7 @@
TraceSorter(TraceProcessorContext*, int64_t window_size_ns);
inline void PushTracePacket(int64_t timestamp,
- ProtoIncrementalState::PacketSequenceState* state,
+ PacketSequenceState* state,
TraceBlobView packet) {
DCHECK_ftrace_batch_cpu(kNoBatch);
auto* queue = GetQueue(0);
@@ -124,12 +124,11 @@
TimestampedTracePiece(timestamp, packet_idx_++, inline_event));
}
- inline void PushTrackEventPacket(
- int64_t timestamp,
- int64_t thread_time,
- int64_t thread_instruction_count,
- ProtoIncrementalState::PacketSequenceState* state,
- TraceBlobView packet) {
+ inline void PushTrackEventPacket(int64_t timestamp,
+ int64_t thread_time,
+ int64_t thread_instruction_count,
+ PacketSequenceState* state,
+ TraceBlobView packet) {
auto* queue = GetQueue(0);
queue->Append(TimestampedTracePiece(timestamp, thread_time,
thread_instruction_count, packet_idx_++,
diff --git a/src/trace_processor/trace_sorter_unittest.cc b/src/trace_processor/trace_sorter_unittest.cc
index da93c61..fa0a34a 100644
--- a/src/trace_processor/trace_sorter_unittest.cc
+++ b/src/trace_processor/trace_sorter_unittest.cc
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "src/trace_processor/proto_trace_parser.h"
+#include "src/trace_processor/importers/proto/proto_trace_parser.h"
#include <map>
#include <random>
diff --git a/src/trace_processor/track_tracker.cc b/src/trace_processor/track_tracker.cc
index 44837f6..f04bd34 100644
--- a/src/trace_processor/track_tracker.cc
+++ b/src/trace_processor/track_tracker.cc
@@ -142,6 +142,10 @@
row.upid = upid;
auto id = context_->storage->mutable_process_track_table()->Insert(row);
chrome_process_instant_tracks_[upid] = id;
+
+ RowId row_id = TraceStorage::CreateRowId(TableId::kTrack, id);
+ context_->args_tracker->AddArg(row_id, source_key_, source_key_,
+ Variadic::String(chrome_source_));
return id;
}
@@ -149,6 +153,11 @@
if (!chrome_global_instant_track_id_) {
chrome_global_instant_track_id_ =
context_->storage->mutable_track_table()->Insert({});
+
+ RowId row_id = TraceStorage::CreateRowId(TableId::kTrack,
+ *chrome_global_instant_track_id_);
+ context_->args_tracker->AddArg(row_id, source_key_, source_key_,
+ Variadic::String(chrome_source_));
}
return *chrome_global_instant_track_id_;
}
diff --git a/src/trace_processor/wasm_bridge.cc b/src/trace_processor/wasm_bridge.cc
index b5a1e58..a09385c 100644
--- a/src/trace_processor/wasm_bridge.cc
+++ b/src/trace_processor/wasm_bridge.cc
@@ -20,8 +20,7 @@
#include "perfetto/base/logging.h"
#include "perfetto/trace_processor/trace_processor.h"
-
-#include "protos/perfetto/trace_processor/raw_query.pb.h"
+#include "src/trace_processor/rpc.h"
namespace perfetto {
namespace trace_processor {
@@ -41,7 +40,7 @@
uint32_t /*len*/);
namespace {
-TraceProcessor* g_trace_processor;
+Rpc* g_trace_processor_rpc;
ReplyFunction g_reply;
} // namespace
// +---------------------------------------------------------------------------+
@@ -52,8 +51,7 @@
void EMSCRIPTEN_KEEPALIVE Initialize(ReplyFunction);
void Initialize(ReplyFunction reply_function) {
PERFETTO_ILOG("Initializing WASM bridge");
- Config config;
- g_trace_processor = TraceProcessor::CreateInstance(config).release();
+ g_trace_processor_rpc = new Rpc();
g_reply = reply_function;
}
@@ -61,14 +59,10 @@
const uint8_t*,
uint32_t);
void trace_processor_parse(RequestID id, const uint8_t* data, size_t size) {
- // TODO(primiano): This copy is extremely unfortunate. Ideally there should be
- // a way to take the Blob coming from JS (either from FileReader or from th
- // fetch() stream) and move into WASM.
+ // TODO(primiano): LoadTrace() makes a copy of the data, which is unfortunate.
+ // Ideally there should be a way to take the Blob coming from JS and move it.
// See https://github.com/WebAssembly/design/issues/1162.
- std::unique_ptr<uint8_t[]> buf(new uint8_t[size]);
- memcpy(buf.get(), data, size);
-
- util::Status status = g_trace_processor->Parse(std::move(buf), size);
+ auto status = g_trace_processor_rpc->LoadTrace(data, size, /*eof=*/false);
if (status.ok()) {
g_reply(id, true, "", 0);
} else {
@@ -84,7 +78,7 @@
uint32_t);
void trace_processor_notifyEof(RequestID id, const uint8_t*, uint32_t size) {
PERFETTO_DCHECK(!size);
- g_trace_processor->NotifyEndOfFile();
+ g_trace_processor_rpc->LoadTrace(nullptr, 0, /*eof=*/true);
g_reply(id, true, "", 0);
}
@@ -94,110 +88,11 @@
void trace_processor_rawQuery(RequestID id,
const uint8_t* query_data,
int len) {
- protos::RawQueryArgs query;
- bool parsed = query.ParseFromArray(query_data, len);
- if (!parsed) {
- std::string err = "Failed to parse input request";
- g_reply(id, false, err.data(), err.size());
- return;
- }
+ std::vector<uint8_t> res =
+ g_trace_processor_rpc->RawQuery(query_data, static_cast<size_t>(len));
- using ColumnDesc = protos::RawQueryResult::ColumnDesc;
- protos::RawQueryResult result;
- auto it = g_trace_processor->ExecuteQuery(query.sql_query().c_str());
- for (uint32_t col = 0; col < it.ColumnCount(); ++col) {
- // Setup the descriptors.
- auto* descriptor = result.add_column_descriptors();
- descriptor->set_name(it.GetColumName(col));
- descriptor->set_type(ColumnDesc::UNKNOWN);
-
- // Add an empty column.
- result.add_columns();
- }
-
- for (uint32_t rows = 0; it.Next(); ++rows) {
- for (uint32_t col = 0; col < it.ColumnCount(); ++col) {
- auto* column = result.mutable_columns(static_cast<int>(col));
- auto* desc = result.mutable_column_descriptors(static_cast<int>(col));
-
- using SqlValue = trace_processor::SqlValue;
- auto cell = it.Get(col);
- if (desc->type() == ColumnDesc::UNKNOWN) {
- switch (cell.type) {
- case SqlValue::Type::kLong:
- desc->set_type(ColumnDesc::LONG);
- break;
- case SqlValue::Type::kString:
- desc->set_type(ColumnDesc::STRING);
- break;
- case SqlValue::Type::kDouble:
- desc->set_type(ColumnDesc::DOUBLE);
- break;
- case SqlValue::Type::kNull:
- break;
- case SqlValue::Type::kBytes:
- desc->set_type(ColumnDesc::STRING);
- break;
- }
- }
-
- // If either the column type is null or we still don't know the type,
- // just add null values to all the columns.
- if (cell.type == SqlValue::Type::kNull ||
- desc->type() == ColumnDesc::UNKNOWN) {
- column->add_long_values(0);
- column->add_string_values("[NULL]");
- column->add_double_values(0);
- column->add_is_nulls(true);
- continue;
- }
-
- // Cast the sqlite value to the type of the column.
- switch (desc->type()) {
- case ColumnDesc::LONG:
- PERFETTO_CHECK(cell.type == SqlValue::Type::kLong ||
- cell.type == SqlValue::Type::kDouble);
- if (cell.type == SqlValue::Type::kLong) {
- column->add_long_values(cell.long_value);
- } else /* if (cell.type == SqlValue::Type::kDouble) */ {
- column->add_long_values(static_cast<int64_t>(cell.double_value));
- }
- column->add_is_nulls(false);
- break;
- case ColumnDesc::STRING: {
- if (cell.type == SqlValue::Type::kBytes) {
- column->add_string_values("<bytes>");
- } else {
- PERFETTO_CHECK(cell.type == SqlValue::Type::kString);
- column->add_string_values(cell.string_value);
- }
- column->add_is_nulls(false);
- break;
- }
- case ColumnDesc::DOUBLE:
- PERFETTO_CHECK(cell.type == SqlValue::Type::kLong ||
- cell.type == SqlValue::Type::kDouble);
- if (cell.type == SqlValue::Type::kLong) {
- column->add_double_values(static_cast<double>(cell.long_value));
- } else /* if (cell.type == SqlValue::Type::kDouble) */ {
- column->add_double_values(cell.double_value);
- }
- column->add_is_nulls(false);
- break;
- case ColumnDesc::UNKNOWN:
- PERFETTO_FATAL("Handled in if statement above.");
- }
- }
- result.set_num_records(rows + 1);
- }
- util::Status status = it.Status();
- if (!status.ok()) {
- result.set_error(status.message());
- }
-
- std::string encoded;
- result.SerializeToString(&encoded);
- g_reply(id, true, encoded.data(), static_cast<uint32_t>(encoded.size()));
+ g_reply(id, true, reinterpret_cast<const char*>(res.data()),
+ static_cast<uint32_t>(res.size()));
}
} // extern "C"
diff --git a/src/traced/probes/android_log/android_log_data_source.cc b/src/traced/probes/android_log/android_log_data_source.cc
index 73e84db..c49bec6 100644
--- a/src/traced/probes/android_log/android_log_data_source.cc
+++ b/src/traced/probes/android_log/android_log_data_source.cc
@@ -148,7 +148,8 @@
}
base::UnixSocketRaw AndroidLogDataSource::ConnectLogdrSocket() {
- auto socket = base::UnixSocketRaw::CreateMayFail(base::SockType::kSeqPacket);
+ auto socket = base::UnixSocketRaw::CreateMayFail(base::SockFamily::kUnix,
+ base::SockType::kSeqPacket);
if (!socket || !socket.Connect(kLogdrSocket)) {
PERFETTO_PLOG("Failed to connect to %s", kLogdrSocket);
return base::UnixSocketRaw();
diff --git a/src/traced/probes/android_log/android_log_data_source_unittest.cc b/src/traced/probes/android_log/android_log_data_source_unittest.cc
index ee38ced..1c90204 100644
--- a/src/traced/probes/android_log/android_log_data_source_unittest.cc
+++ b/src/traced/probes/android_log/android_log_data_source_unittest.cc
@@ -62,8 +62,8 @@
base::UnixSocketRaw recv_sock;
// In theory this should be a kSeqPacket. We use kDgram here so that the
// test can run also on MacOS (which doesn't support SOCK_SEQPACKET).
- const auto kSockType = base::SockType::kDgram;
- std::tie(send_sock, recv_sock) = base::UnixSocketRaw::CreatePair(kSockType);
+ std::tie(send_sock, recv_sock) = base::UnixSocketRaw::CreatePair(
+ base::SockFamily::kUnix, base::SockType::kDgram);
ASSERT_TRUE(send_sock);
ASSERT_TRUE(recv_sock);
diff --git a/src/tracing/BUILD.gn b/src/tracing/BUILD.gn
index e426793..aca11d7 100644
--- a/src/tracing/BUILD.gn
+++ b/src/tracing/BUILD.gn
@@ -231,6 +231,8 @@
source_set("client_api") {
deps = [
":common",
+ "../../include/perfetto/tracing/core",
+ "../../protos/perfetto/config:lite",
"../base",
"../tracing",
]
@@ -244,9 +246,10 @@
"internal/in_process_tracing_backend.h",
"internal/tracing_muxer_impl.cc",
"internal/tracing_muxer_impl.h",
+ "internal/track_event_internal.cc",
"platform.cc",
"tracing.cc",
- "track_event.cc",
+ "track_event_category_registry.cc",
"virtual_destructors.cc",
]
@@ -276,6 +279,10 @@
]
sources = [
"api_integrationtest.cc",
+ "test/tracing_module.cc",
+ "test/tracing_module.h",
+ "test/tracing_module2.cc",
+ "test/tracing_module_categories.h",
]
}
}
diff --git a/src/tracing/api_integrationtest.cc b/src/tracing/api_integrationtest.cc
index 2e1d402..d11359c 100644
--- a/src/tracing/api_integrationtest.cc
+++ b/src/tracing/api_integrationtest.cc
@@ -32,18 +32,28 @@
// Deliberately not pulling any non-public perfetto header to spot accidental
// header public -> non-public dependency while building this file.
-// This is the only header allowed here, see comments in api_test_support.h.
+// These two are the only headers allowed here, see comments in
+// api_test_support.h.
#include "src/tracing/test/api_test_support.h"
+#include "src/tracing/test/tracing_module.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "perfetto/tracing/core/trace_config.h"
+// Trace categories used in the tests.
+PERFETTO_DEFINE_CATEGORIES(PERFETTO_CATEGORY(test),
+ PERFETTO_CATEGORY(foo),
+ PERFETTO_CATEGORY(bar));
+PERFETTO_TRACK_EVENT_STATIC_STORAGE();
+
namespace {
using ::testing::_;
+using ::testing::HasSubstr;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::NiceMock;
+using ::testing::Not;
using ::testing::Property;
using ::testing::StrEq;
@@ -109,6 +119,42 @@
void OnStop(const StopArgs&) override {}
};
+// Used to verify that track event data sources in different namespaces register
+// themselves correctly in the muxer.
+class MockTracingMuxer : public perfetto::internal::TracingMuxer {
+ public:
+ struct DataSource {
+ const perfetto::DataSourceDescriptor dsd;
+ perfetto::internal::DataSourceStaticState* static_state;
+ };
+
+ MockTracingMuxer() : TracingMuxer(nullptr), prev_instance_(instance_) {
+ instance_ = this;
+ }
+ ~MockTracingMuxer() override { instance_ = prev_instance_; }
+
+ bool RegisterDataSource(
+ const perfetto::DataSourceDescriptor& dsd,
+ DataSourceFactory,
+ perfetto::internal::DataSourceStaticState* static_state) override {
+ data_sources.emplace_back(DataSource{dsd, static_state});
+ return true;
+ }
+
+ std::unique_ptr<perfetto::TraceWriterBase> CreateTraceWriter(
+ perfetto::internal::DataSourceState*,
+ perfetto::BufferExhaustedPolicy) override {
+ return nullptr;
+ }
+
+ void DestroyStoppedTraceWritersForCurrentThread() override {}
+
+ std::vector<DataSource> data_sources;
+
+ private:
+ TracingMuxer* prev_instance_;
+};
+
struct TestIncrementalState {
TestIncrementalState() { constructed = true; }
// Note: a virtual destructor is not required for incremental state.
@@ -122,9 +168,14 @@
bool TestIncrementalState::constructed;
bool TestIncrementalState::destroyed;
+struct TestIncrementalDataSourceTraits
+ : public perfetto::DefaultDataSourceTraits {
+ using IncrementalStateType = TestIncrementalState;
+};
+
class TestIncrementalDataSource
: public perfetto::DataSource<TestIncrementalDataSource,
- TestIncrementalState> {
+ TestIncrementalDataSourceTraits> {
public:
void OnSetup(const SetupArgs&) override {}
void OnStart(const StartArgs&) override {}
@@ -156,6 +207,7 @@
perfetto::Tracing::Initialize(args);
was_initialized = true;
RegisterDataSource<MockDataSource>("my_data_source");
+ perfetto::TrackEvent::Register();
}
// Make sure our data source always has a valid handle.
data_sources_["my_data_source"];
@@ -225,8 +277,10 @@
// Test fixtures
// -------------
-TEST_F(PerfettoApiTest, TrackEvent) {
- perfetto::TrackEvent::Initialize(/* TODO(skyostil): Register categories */);
+TEST_F(PerfettoApiTest, TrackEventStartStopAndDestroy) {
+ // This test used to cause a use after free as the tracing session got
+ // destroyed. It needed to be run approximately 2000 times to catch it so test
+ // with --gtest_repeat=3000 (less if running under GDB).
// Setup the trace config.
perfetto::TraceConfig cfg;
@@ -235,14 +289,59 @@
auto* ds_cfg = cfg.add_data_sources()->mutable_config();
ds_cfg->set_name("track_event");
ds_cfg->set_legacy_config("test");
+ // Create five new trace sessions.
+ std::vector<std::unique_ptr<perfetto::TracingSession>> sessions;
+ for (size_t i = 0; i < 5; ++i) {
+ sessions.push_back(
+ perfetto::Tracing::NewTrace(perfetto::BackendType::kInProcessBackend));
+ sessions[i]->Setup(cfg);
+ sessions[i]->Start();
+ sessions[i]->Stop();
+ }
+}
+
+TEST_F(PerfettoApiTest, TrackEventStartStopAndStopBlocking) {
+ // This test used to cause a deadlock (due to StopBlocking() after the session
+ // already stopped). This usually occurred within 1 or 2 runs of the test so
+ // use --gtest_repeat=10
+
+ // Setup the trace config.
+ perfetto::TraceConfig cfg;
+ cfg.set_duration_ms(500);
+ cfg.add_buffers()->set_size_kb(1024);
+ auto* ds_cfg = cfg.add_data_sources()->mutable_config();
+ ds_cfg->set_name("track_event");
+ ds_cfg->set_legacy_config("test");
+ // Create five new trace sessions.
+ std::vector<std::unique_ptr<perfetto::TracingSession>> sessions;
+ for (size_t i = 0; i < 5; ++i) {
+ sessions.push_back(
+ perfetto::Tracing::NewTrace(perfetto::BackendType::kInProcessBackend));
+ sessions[i]->Setup(cfg);
+ sessions[i]->Start();
+ sessions[i]->Stop();
+ }
+ for (auto& session : sessions) {
+ session->StopBlocking();
+ }
+}
+
+TEST_F(PerfettoApiTest, TrackEvent) {
+ // Setup the trace config.
+ perfetto::TraceConfig cfg;
+ cfg.set_duration_ms(500);
+ cfg.add_buffers()->set_size_kb(1024);
+ auto* ds_cfg = cfg.add_data_sources()->mutable_config();
+ ds_cfg->set_name("track_event");
+ ds_cfg->set_legacy_config("test");
// Create a new trace session.
auto* tracing_session = NewTrace(cfg);
tracing_session->get()->StartBlocking();
// Emit one complete track event.
- perfetto::TrackEvent::Begin("test", "TestEvent");
- perfetto::TrackEvent::End("test");
+ TRACE_EVENT_BEGIN("test", "TestEvent");
+ TRACE_EVENT_END("test");
perfetto::TrackEvent::Flush();
tracing_session->on_stop.Wait();
@@ -260,7 +359,7 @@
bool end_found = false;
bool process_descriptor_found = false;
bool thread_descriptor_found = false;
- auto now = perfetto::TrackEvent::GetTimeNs();
+ auto now = perfetto::test::GetWallTimeNs();
uint32_t sequence_id = 0;
int32_t cur_pid = perfetto::test::GetCurrentProcessId();
for (const auto& packet : trace.packet()) {
@@ -330,6 +429,194 @@
EXPECT_TRUE(end_found);
}
+TEST_F(PerfettoApiTest, TrackEventCategories) {
+ // Setup the trace config.
+ perfetto::TraceConfig cfg;
+ cfg.set_duration_ms(500);
+ cfg.add_buffers()->set_size_kb(1024);
+ auto* ds_cfg = cfg.add_data_sources()->mutable_config();
+ ds_cfg->set_name("track_event");
+ ds_cfg->set_legacy_config("bar");
+
+ // Create a new trace session.
+ auto* tracing_session = NewTrace(cfg);
+ tracing_session->get()->StartBlocking();
+
+ // Emit some track events.
+ TRACE_EVENT_BEGIN("foo", "NotEnabled");
+ TRACE_EVENT_END("foo");
+ TRACE_EVENT_BEGIN("bar", "Enabled");
+ TRACE_EVENT_END("bar");
+
+ tracing_session->get()->StopBlocking();
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+ std::string trace(raw_trace.data(), raw_trace.size());
+ // TODO(skyostil): Come up with a nicer way to verify trace contents.
+ EXPECT_THAT(trace, HasSubstr("Enabled"));
+ EXPECT_THAT(trace, Not(HasSubstr("NotEnabled")));
+}
+
+TEST_F(PerfettoApiTest, TrackEventRegistrationWithModule) {
+ MockTracingMuxer muxer;
+
+ // Each track event namespace registers its own data source.
+ perfetto::TrackEvent::Register();
+ EXPECT_EQ(1u, muxer.data_sources.size());
+
+ tracing_module::InitializeCategories();
+ EXPECT_EQ(2u, muxer.data_sources.size());
+
+ // Both data sources have the same name but distinct static data (i.e.,
+ // individual instance states).
+ EXPECT_EQ("track_event", muxer.data_sources[0].dsd.name());
+ EXPECT_EQ("track_event", muxer.data_sources[1].dsd.name());
+ EXPECT_NE(muxer.data_sources[0].static_state,
+ muxer.data_sources[1].static_state);
+}
+
+TEST_F(PerfettoApiTest, TrackEventSharedIncrementalState) {
+ tracing_module::InitializeCategories();
+
+ // Setup the trace config.
+ perfetto::TraceConfig cfg;
+ cfg.set_duration_ms(500);
+ cfg.add_buffers()->set_size_kb(1024);
+ auto* ds_cfg = cfg.add_data_sources()->mutable_config();
+ ds_cfg->set_name("track_event");
+ auto* tracing_session = NewTrace(cfg);
+ tracing_session->get()->StartBlocking();
+
+ perfetto::internal::TrackEventIncrementalState* main_state = nullptr;
+ perfetto::TrackEvent::Trace(
+ [&main_state](perfetto::TrackEvent::TraceContext ctx) {
+ main_state = ctx.GetIncrementalState();
+ });
+ perfetto::internal::TrackEventIncrementalState* module_state =
+ tracing_module::GetIncrementalState();
+
+ // Both track event data sources should use the same incremental state (thanks
+ // to sharing TLS).
+ EXPECT_NE(nullptr, main_state);
+ EXPECT_EQ(main_state, module_state);
+ tracing_session->get()->StopBlocking();
+}
+
+TEST_F(PerfettoApiTest, TrackEventCategoriesWithModule) {
+ // Check that categories defined in two different category registries are
+ // enabled and disabled correctly.
+ tracing_module::InitializeCategories();
+
+ // Setup the trace config.
+ perfetto::TraceConfig cfg;
+ cfg.set_duration_ms(500);
+ cfg.add_buffers()->set_size_kb(1024);
+ auto* ds_cfg = cfg.add_data_sources()->mutable_config();
+ ds_cfg->set_name("track_event");
+
+ // Only the "foo" category is enabled. It also exists both locally and in the
+ // existing module.
+ ds_cfg->set_legacy_config("foo");
+
+ // Create a new trace session.
+ auto* tracing_session = NewTrace(cfg);
+ tracing_session->get()->StartBlocking();
+
+ // Emit some track events locally and from the test module.
+ TRACE_EVENT_BEGIN("foo", "FooEventFromMain");
+ TRACE_EVENT_END("foo");
+ tracing_module::EmitTrackEvents();
+ tracing_module::EmitTrackEvents2();
+ TRACE_EVENT_BEGIN("bar", "DisabledEventFromMain");
+ TRACE_EVENT_END("bar");
+
+ tracing_session->get()->StopBlocking();
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+ std::string trace(raw_trace.data(), raw_trace.size());
+ EXPECT_THAT(trace, HasSubstr("FooEventFromMain"));
+ EXPECT_THAT(trace, Not(HasSubstr("DisabledEventFromMain")));
+ EXPECT_THAT(trace, HasSubstr("FooEventFromModule"));
+ EXPECT_THAT(trace, Not(HasSubstr("DisabledEventFromModule")));
+ EXPECT_THAT(trace, HasSubstr("FooEventFromModule2"));
+ EXPECT_THAT(trace, Not(HasSubstr("DisabledEventFromModule2")));
+
+ perfetto::protos::Trace parsed_trace;
+ ASSERT_TRUE(
+ parsed_trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
+
+ uint32_t sequence_id = 0;
+ for (const auto& packet : parsed_trace.packet()) {
+ if (!packet.has_track_event())
+ continue;
+
+ // Make sure we only see track events on one sequence. This means all track
+ // event modules are sharing the same trace writer (by using the same TLS
+ // index).
+ if (packet.trusted_packet_sequence_id()) {
+ if (!sequence_id)
+ sequence_id = packet.trusted_packet_sequence_id();
+ EXPECT_EQ(sequence_id, packet.trusted_packet_sequence_id());
+ }
+ }
+}
+
+TEST_F(PerfettoApiTest, TrackEventConcurrentSessions) {
+ // Check that categories that are enabled and disabled in two parallel tracing
+ // sessions don't interfere.
+
+ // Setup the trace config.
+ perfetto::TraceConfig cfg;
+ cfg.set_duration_ms(500);
+ cfg.add_buffers()->set_size_kb(1024);
+ auto* ds_cfg = cfg.add_data_sources()->mutable_config();
+ ds_cfg->set_name("track_event");
+
+ // Session #1 enables the "foo" category.
+ ds_cfg->set_legacy_config("foo");
+ auto* tracing_session = NewTrace(cfg);
+ tracing_session->get()->StartBlocking();
+
+ // Session #2 enables the "bar" category.
+ ds_cfg->set_legacy_config("bar");
+ auto* tracing_session2 = NewTrace(cfg);
+ tracing_session2->get()->StartBlocking();
+
+ // Emit some track events under both categories.
+ TRACE_EVENT_BEGIN("foo", "Session1_First");
+ TRACE_EVENT_END("foo");
+ TRACE_EVENT_BEGIN("bar", "Session2_First");
+ TRACE_EVENT_END("bar");
+
+ tracing_session->get()->StopBlocking();
+ TRACE_EVENT_BEGIN("foo", "Session1_Second");
+ TRACE_EVENT_END("foo");
+ TRACE_EVENT_BEGIN("bar", "Session2_Second");
+ TRACE_EVENT_END("bar");
+
+ tracing_session2->get()->StopBlocking();
+ TRACE_EVENT_BEGIN("foo", "Session1_Third");
+ TRACE_EVENT_END("foo");
+ TRACE_EVENT_BEGIN("bar", "Session2_Third");
+ TRACE_EVENT_END("bar");
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+ std::string trace(raw_trace.data(), raw_trace.size());
+ EXPECT_THAT(trace, HasSubstr("Session1_First"));
+ EXPECT_THAT(trace, Not(HasSubstr("Session1_Second")));
+ EXPECT_THAT(trace, Not(HasSubstr("Session1_Third")));
+ EXPECT_THAT(trace, Not(HasSubstr("Session2_First")));
+ EXPECT_THAT(trace, Not(HasSubstr("Session2_Second")));
+ EXPECT_THAT(trace, Not(HasSubstr("Session2_Third")));
+
+ std::vector<char> raw_trace2 = tracing_session2->get()->ReadTraceBlocking();
+ std::string trace2(raw_trace2.data(), raw_trace2.size());
+ EXPECT_THAT(trace2, Not(HasSubstr("Session1_First")));
+ EXPECT_THAT(trace2, Not(HasSubstr("Session1_Second")));
+ EXPECT_THAT(trace2, Not(HasSubstr("Session1_Third")));
+ EXPECT_THAT(trace2, HasSubstr("Session2_First"));
+ EXPECT_THAT(trace2, HasSubstr("Session2_Second"));
+ EXPECT_THAT(trace2, Not(HasSubstr("Session2_Third")));
+}
+
TEST_F(PerfettoApiTest, OneDataSourceOneEvent) {
auto* data_source = &data_sources_["my_data_source"];
@@ -347,6 +634,9 @@
MockDataSource::Trace([](MockDataSource::TraceContext) {
FAIL() << "Should not be called because the trace was not started";
});
+ MockDataSource::CallIfEnabled([](uint32_t) {
+ FAIL() << "Should not be called because the trace was not started";
+ });
tracing_session->get()->Start();
data_source->on_setup.Wait();
@@ -369,6 +659,12 @@
packet = ctx.NewTracePacket();
});
+ uint32_t active_instances = 0;
+ MockDataSource::CallIfEnabled([&active_instances](uint32_t instances) {
+ active_instances = instances;
+ });
+ EXPECT_EQ(1u, active_instances);
+
data_source->on_stop.Wait();
tracing_session->on_stop.Wait();
EXPECT_EQ(trace_lambda_calls, 1);
@@ -376,6 +672,9 @@
MockDataSource::Trace([](MockDataSource::TraceContext) {
FAIL() << "Should not be called because the trace is now stopped";
});
+ MockDataSource::CallIfEnabled([](uint32_t) {
+ FAIL() << "Should not be called because the trace is now stopped";
+ });
std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
ASSERT_GE(raw_trace.size(), 0u);
@@ -687,4 +986,4 @@
PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(MockDataSource);
PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(MockDataSource2);
PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(TestIncrementalDataSource,
- TestIncrementalState);
+ TestIncrementalDataSourceTraits);
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index dfd73db..fa2d1d1 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -252,7 +252,15 @@
new ConsumerEndpointImpl(this, task_runner_, consumer, uid));
auto it_and_inserted = consumers_.emplace(endpoint.get());
PERFETTO_DCHECK(it_and_inserted.second);
- task_runner_->PostTask(std::bind(&Consumer::OnConnect, endpoint->consumer_));
+ // Consumer might go away before we're able to send the connect notification,
+ // if that is the case just bail out.
+ auto weak_ptr = endpoint->GetWeakPtr();
+ task_runner_->PostTask([weak_ptr] {
+ if (!weak_ptr) {
+ return;
+ }
+ weak_ptr->consumer_->OnConnect();
+ });
return std::unique_ptr<ConsumerEndpoint>(std::move(endpoint));
}
diff --git a/src/tracing/internal/tracing_muxer_impl.cc b/src/tracing/internal/tracing_muxer_impl.cc
index 5f8dd4f..1ce6f93 100644
--- a/src/tracing/internal/tracing_muxer_impl.cc
+++ b/src/tracing/internal/tracing_muxer_impl.cc
@@ -24,6 +24,7 @@
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
+#include "perfetto/ext/base/hash.h"
#include "perfetto/ext/base/thread_checker.h"
#include "perfetto/ext/base/waitable_event.h"
#include "perfetto/ext/tracing/core/trace_packet.h"
@@ -36,6 +37,7 @@
#include "perfetto/tracing/trace_writer_base.h"
#include "perfetto/tracing/tracing.h"
#include "perfetto/tracing/tracing_backend.h"
+#include "protos/perfetto/config/trace_config.pb.h"
#include "src/tracing/internal/in_process_tracing_backend.h"
#include "src/tracing/internal/system_tracing_backend.h"
@@ -55,6 +57,17 @@
mutable std::function<void()> async_stop_closure;
};
+uint64_t ComputeConfigHash(const DataSourceConfig& config) {
+ base::Hash hasher;
+ perfetto::protos::DataSourceConfig config_proto;
+ config.ToProto(&config_proto);
+ std::string config_bytes;
+ bool serialized = config_proto.SerializeToString(&config_bytes);
+ PERFETTO_DCHECK(serialized);
+ hasher.Update(&config_bytes[0], config_bytes.size());
+ return hasher.digest();
+}
+
} // namespace
// ----- Begin of TracingMuxerImpl::ProducerImpl
@@ -164,6 +177,26 @@
connected_ = false;
// TODO notify the client somehow.
+
+ // Notify the muxer that it is safe to destroy |this|. This is needed because
+ // the ConsumerEndpoint stored in |service_| requires that |this| be safe to
+ // access until OnDisconnect() is called.
+ muxer_->OnConsumerDisconnected(this);
+}
+
+void TracingMuxerImpl::ConsumerImpl::Disconnect() {
+ // This is weird and deserves a comment.
+ //
+ // When we called the ConnectConsumer method on the service it returns
+ // us a ConsumerEndpoint which we stored in |service_|, however this
+ // ConsumerEndpoint holds a pointer to the ConsumerImpl pointed to by
+ // |this|. Part of the API contract to TracingService::ConnectConsumer is that
+ // the ConsumerImpl pointer has to be valid until the
+ // ConsumerImpl::OnDisconnect method is called. Therefore we reset the
+ // ConsumerEndpoint |service_|. Eventually this will call
+ // ConsumerImpl::OnDisconnect and we will inform the muxer it is safe to
+ // call the destructor of |this|.
+ service_.reset();
}
void TracingMuxerImpl::ConsumerImpl::OnTracingDisabled() {
@@ -441,7 +474,7 @@
static std::atomic<uint32_t> last_id{};
uint32_t new_index = last_id++;
- if (new_index >= kMaxDataSources - 1) {
+ if (new_index >= kMaxDataSources) {
PERFETTO_DLOG(
"RegisterDataSource failed: too many data sources already registered");
return false;
@@ -473,12 +506,39 @@
PERFETTO_DCHECK_THREAD(thread_checker_);
PERFETTO_DLOG("Setting up data source %" PRIu64 " %s", instance_id,
cfg.name().c_str());
+ uint64_t config_hash = ComputeConfigHash(cfg);
for (const auto& rds : data_sources_) {
if (rds.descriptor.name() != cfg.name())
continue;
-
DataSourceStaticState& static_state = *rds.static_state;
+
+ // If this data source is already active for this exact config, don't start
+ // another instance. This happens when we have several data sources with the
+ // same name, in which case the service sends one SetupDataSource event for
+ // each one. Since we can't map which event maps to which data source, we
+ // ensure each event only starts one data source instance.
+ // TODO(skyostil): Register a unique id with each data source to the service
+ // to disambiguate.
+ bool active_for_config = false;
+ for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+ if (!static_state.TryGet(i))
+ continue;
+ auto* internal_state =
+ reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
+ if (internal_state->backend_id == backend_id &&
+ internal_state->config_hash == config_hash) {
+ active_for_config = true;
+ break;
+ }
+ }
+ if (active_for_config) {
+ PERFETTO_DLOG(
+ "Data source %s is already active with this config, skipping",
+ cfg.name().c_str());
+ continue;
+ }
+
for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
// Find a free slot.
if (static_state.TryGet(i))
@@ -495,14 +555,16 @@
internal_state->data_source_instance_id = instance_id;
internal_state->buffer_id =
static_cast<internal::BufferId>(cfg.target_buffer());
+ internal_state->config_hash = config_hash;
internal_state->data_source = rds.factory();
// This must be made at the end. See matching acquire-load in
// DataSource::Trace().
- static_state.valid_instances.fetch_or(1 << i, std::memory_order_acq_rel);
+ static_state.valid_instances.fetch_or(1 << i, std::memory_order_release);
DataSourceBase::SetupArgs setup_args;
setup_args.config = &cfg;
+ setup_args.internal_instance_index = i;
internal_state->data_source->OnSetup(setup_args);
return;
}
@@ -510,6 +572,7 @@
"Maximum number of data source instances exhausted. "
"Dropping data source %" PRIu64,
instance_id);
+ break;
}
}
@@ -525,9 +588,12 @@
return;
}
+ DataSourceBase::StartArgs start_args{};
+ start_args.internal_instance_index = ds.instance_idx;
+
std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
ds.internal_state->trace_lambda_enabled = true;
- ds.internal_state->data_source->OnStart(DataSourceBase::StartArgs{});
+ ds.internal_state->data_source->OnStart(start_args);
}
// Called by the service of one of the backends.
@@ -544,6 +610,7 @@
}
StopArgsImpl stop_args{};
+ stop_args.internal_instance_index = ds.instance_idx;
stop_args.async_stop_closure = [this, backend_id, instance_id] {
// TracingMuxerImpl is long lived, capturing |this| is okay.
// The notification closure can be moved out of the StopArgs by the
@@ -611,12 +678,12 @@
// Iterate across all possible data source types.
auto cur_generation = generation_.load(std::memory_order_acquire);
auto* root_tls = GetOrCreateTracingTLS();
- for (size_t ds_idx = 0; ds_idx < kMaxDataSources; ds_idx++) {
+
+ auto destroy_stopped_instances = [](DataSourceThreadLocalState& tls) {
// |tls| has a vector of per-data-source-instance thread-local state.
- DataSourceThreadLocalState& tls = root_tls->data_sources_tls[ds_idx];
DataSourceStaticState* static_state = tls.static_state;
if (!static_state)
- continue; // Slot not used.
+ return; // Slot not used.
// Iterate across all possible instances for this data source.
for (uint32_t inst = 0; inst < kMaxDataSourceInstances; inst++) {
@@ -633,7 +700,14 @@
// The DataSource instance has been destroyed or recycled.
ds_tls.Reset(); // Will also destroy the |ds_tls.trace_writer|.
}
+ };
+
+ for (size_t ds_idx = 0; ds_idx < kMaxDataSources; ds_idx++) {
+ // |tls| has a vector of per-data-source-instance thread-local state.
+ DataSourceThreadLocalState& tls = root_tls->data_sources_tls[ds_idx];
+ destroy_stopped_instances(tls);
}
+ destroy_stopped_instances(root_tls->track_event_tls);
root_tls->generation = cur_generation;
}
@@ -721,11 +795,6 @@
if (!consumer)
return;
- if (!consumer->trace_config_) {
- PERFETTO_ELOG("Must call Setup(config) and Start() first");
- return;
- }
-
if (consumer->start_pending_) {
// If the session hasn't started yet, wait until it does before stopping.
consumer->stop_pending_ = true;
@@ -737,6 +806,9 @@
// If the session was already stopped (e.g., it failed to start), don't try
// stopping again.
consumer->NotifyStopComplete();
+ } else if (!consumer->trace_config_) {
+ PERFETTO_ELOG("Must call Setup(config) and Start() first");
+ return;
} else {
consumer->service_->DisableTracing();
}
@@ -748,12 +820,29 @@
TracingSessionGlobalID session_id) {
PERFETTO_DCHECK_THREAD(thread_checker_);
for (RegisteredBackend& backend : backends_) {
- auto pred = [session_id](const std::unique_ptr<ConsumerImpl>& consumer) {
- return consumer->session_id_ == session_id;
- };
- backend.consumers.erase(std::remove_if(backend.consumers.begin(),
- backend.consumers.end(), pred),
- backend.consumers.end());
+ // We need to find the consumer (if any) and call Disconnect as we destroy
+ // the tracing session. We can't call Disconnect() inside this for loop
+ // because in the in-process case this will end up to a synchronous call to
+ // OnConsumerDisconnect which will invalidate all the iterators to
+ // |backend.consumers|.
+ ConsumerImpl* consumer = nullptr;
+ for (auto& con : backend.consumers) {
+ if (con->session_id_ == session_id) {
+ consumer = con.get();
+ break;
+ }
+ }
+ if (consumer) {
+ // We broke out of the loop above on the assumption that each backend will
+ // only have a single consumer per session. This DCHECK ensures that
+ // this is the case.
+ PERFETTO_DCHECK(
+ std::count_if(backend.consumers.begin(), backend.consumers.end(),
+ [session_id](const std::unique_ptr<ConsumerImpl>& con) {
+ return con->session_id_ == session_id;
+ }) == 1u);
+ consumer->Disconnect();
+ }
}
}
@@ -774,13 +863,27 @@
PERFETTO_DCHECK_THREAD(thread_checker_);
for (RegisteredBackend& backend : backends_) {
for (auto& consumer : backend.consumers) {
- if (consumer->session_id_ == session_id)
+ if (consumer->session_id_ == session_id) {
+ PERFETTO_DCHECK(consumer->service_);
return consumer.get();
+ }
}
}
return nullptr;
}
+void TracingMuxerImpl::OnConsumerDisconnected(ConsumerImpl* consumer) {
+ PERFETTO_DCHECK_THREAD(thread_checker_);
+ for (RegisteredBackend& backend : backends_) {
+ auto pred = [consumer](const std::unique_ptr<ConsumerImpl>& con) {
+ return con.get() == consumer;
+ };
+ backend.consumers.erase(std::remove_if(backend.consumers.begin(),
+ backend.consumers.end(), pred),
+ backend.consumers.end());
+ }
+}
+
TracingMuxerImpl::FindDataSourceRes TracingMuxerImpl::FindDataSource(
TracingBackendId backend_id,
DataSourceInstanceID instance_id) {
diff --git a/src/tracing/internal/tracing_muxer_impl.h b/src/tracing/internal/tracing_muxer_impl.h
index 522b5cb..1f0f8be 100644
--- a/src/tracing/internal/tracing_muxer_impl.h
+++ b/src/tracing/internal/tracing_muxer_impl.h
@@ -195,6 +195,9 @@
void NotifyStartComplete();
void NotifyStopComplete();
+ // Will eventually inform the |muxer_| when it is safe to remove |this|.
+ void Disconnect();
+
TracingMuxerImpl* const muxer_;
TracingBackendId const backend_id_;
TracingSessionGlobalID const session_id_;
@@ -283,6 +286,7 @@
explicit TracingMuxerImpl(const TracingInitArgs&);
void Initialize(const TracingInitArgs& args);
ConsumerImpl* FindConsumer(TracingSessionGlobalID session_id);
+ void OnConsumerDisconnected(ConsumerImpl* consumer);
struct FindDataSourceRes {
FindDataSourceRes() = default;
diff --git a/src/tracing/track_event.cc b/src/tracing/internal/track_event_internal.cc
similarity index 63%
rename from src/tracing/track_event.cc
rename to src/tracing/internal/track_event_internal.cc
index 88411b9..b797e08 100644
--- a/src/tracing/track_event.cc
+++ b/src/tracing/internal/track_event_internal.cc
@@ -14,16 +14,16 @@
* limitations under the License.
*/
-#include "perfetto/tracing/track_event.h"
+#include "perfetto/tracing/internal/track_event_internal.h"
+#include "perfetto/base/time.h"
#include "perfetto/ext/base/proc_utils.h"
#include "perfetto/ext/base/thread_utils.h"
-#include "perfetto/tracing/core/data_source_descriptor.h"
-#include "perfetto/tracing/data_source.h"
+#include "perfetto/tracing/core/data_source_config.h"
+#include "perfetto/tracing/track_event_category_registry.h"
#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
#include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
#include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
-#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
namespace perfetto {
namespace internal {
@@ -31,6 +31,11 @@
std::atomic<perfetto::base::PlatformThreadID> g_main_thread;
+uint64_t GetTimeNs() {
+ // TODO(skyostil): Consider using boot time where available.
+ return static_cast<uint64_t>(perfetto::base::GetWallTimeNs().count());
+}
+
uint64_t GetNameIidOrZero(std::unordered_map<const char*, uint64_t>& name_map,
const char* name) {
auto it = name_map.find(name);
@@ -39,27 +44,84 @@
return it->second;
}
+// static
+void WriteSequenceDescriptors(TrackEventTraceContext* ctx, uint64_t timestamp) {
+ if (perfetto::base::GetThreadId() == g_main_thread) {
+ auto packet = ctx->NewTracePacket();
+ packet->set_timestamp(timestamp);
+ packet->set_incremental_state_cleared(true);
+ auto pd = packet->set_process_descriptor();
+ pd->set_pid(static_cast<int32_t>(base::GetProcessId()));
+ // TODO(skyostil): Record command line.
+ }
+ {
+ auto packet = ctx->NewTracePacket();
+ packet->set_timestamp(timestamp);
+ auto td = packet->set_thread_descriptor();
+ td->set_pid(static_cast<int32_t>(base::GetProcessId()));
+ td->set_tid(static_cast<int32_t>(perfetto::base::GetThreadId()));
+ }
+}
+
} // namespace
-void TrackEventDataSource::OnSetup(const SetupArgs&) {}
-void TrackEventDataSource::OnStart(const StartArgs&) {}
-void TrackEventDataSource::OnStop(const StopArgs&) {}
+TrackEventTraceContext::TrackEventTraceContext(
+ TrackEventIncrementalState* incremental_state,
+ TracePacketCreator new_trace_packet)
+ : incremental_state_(incremental_state),
+ new_trace_packet_(std::move(new_trace_packet)) {}
+
+TrackEventTraceContext::TracePacketHandle
+TrackEventTraceContext::NewTracePacket() {
+ return new_trace_packet_();
+}
// static
-void TrackEventDataSource::WriteEventImpl(
- internal::TrackEventDataSource::TraceContext ctx,
+void TrackEventInternal::Initialize() {
+ if (!g_main_thread)
+ g_main_thread = perfetto::base::GetThreadId();
+}
+
+// static
+void TrackEventInternal::EnableTracing(
+ const TrackEventCategoryRegistry& registry,
+ const DataSourceConfig& config,
+ uint32_t instance_index) {
+ for (size_t i = 0; i < registry.category_count(); i++) {
+ // TODO(skyostil): Support the full category config syntax instead of
+ // just strict matching.
+ // TODO(skyostil): Support comma-separated categories.
+ if (config.legacy_config().empty() ||
+ config.legacy_config() == registry.GetCategory(i)->name) {
+ registry.EnableCategoryForInstance(i, instance_index);
+ }
+ }
+}
+
+// static
+void TrackEventInternal::DisableTracing(
+ const TrackEventCategoryRegistry& registry,
+ uint32_t instance_index) {
+ for (size_t i = 0; i < registry.category_count(); i++)
+ registry.DisableCategoryForInstance(i, instance_index);
+}
+
+// static
+void TrackEventInternal::WriteEvent(
+ TrackEventTraceContext* ctx,
const char* category,
const char* name,
perfetto::protos::pbzero::TrackEvent::Type type) {
PERFETTO_DCHECK(category);
- auto timestamp = TrackEvent::GetTimeNs();
+ PERFETTO_DCHECK(g_main_thread);
+ auto timestamp = GetTimeNs();
- auto* incr_state = ctx.GetIncrementalState();
+ auto* incr_state = ctx->incremental_state();
if (incr_state->was_cleared) {
incr_state->was_cleared = false;
- WriteSequenceDescriptors(&ctx, timestamp);
+ WriteSequenceDescriptors(ctx, timestamp);
}
- auto packet = ctx.NewTracePacket();
+ auto packet = ctx->NewTracePacket();
packet->set_timestamp(timestamp);
// We assume that |category| and |name| point to strings with static lifetime.
@@ -94,39 +156,5 @@
}
}
-// static
-void TrackEventDataSource::WriteSequenceDescriptors(
- internal::TrackEventDataSource::TraceContext* ctx,
- uint64_t timestamp) {
- if (perfetto::base::GetThreadId() == g_main_thread) {
- auto packet = ctx->NewTracePacket();
- packet->set_timestamp(timestamp);
- packet->set_incremental_state_cleared(true);
- auto pd = packet->set_process_descriptor();
- pd->set_pid(static_cast<int32_t>(base::GetProcessId()));
- // TODO(skyostil): Record command line.
- }
- {
- auto packet = ctx->NewTracePacket();
- packet->set_timestamp(timestamp);
- auto td = packet->set_thread_descriptor();
- td->set_pid(static_cast<int32_t>(base::GetProcessId()));
- td->set_tid(static_cast<int32_t>(perfetto::base::GetThreadId()));
- }
-}
-
} // namespace internal
-
-// static
-void TrackEvent::Initialize() {
- internal::g_main_thread = perfetto::base::GetThreadId();
- DataSourceDescriptor dsd;
- dsd.set_name("track_event");
- internal::TrackEventDataSource::Register(dsd);
-}
-
} // namespace perfetto
-
-PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(
- perfetto::internal::TrackEventDataSource,
- perfetto::internal::TrackEventIncrementalState);
diff --git a/src/tracing/test/api_test_support.cc b/src/tracing/test/api_test_support.cc
index 73f1fae..ce49407 100644
--- a/src/tracing/test/api_test_support.cc
+++ b/src/tracing/test/api_test_support.cc
@@ -16,6 +16,7 @@
#include "src/tracing/test/api_test_support.h"
+#include "perfetto/base/time.h"
#include "perfetto/ext/base/proc_utils.h"
namespace perfetto {
@@ -25,5 +26,9 @@
return static_cast<int32_t>(base::GetProcessId());
}
+uint64_t GetWallTimeNs() {
+ return static_cast<uint64_t>(perfetto::base::GetWallTimeNs().count());
+}
+
} // namespace test
} // namespace perfetto
diff --git a/src/tracing/test/api_test_support.h b/src/tracing/test/api_test_support.h
index 9409caf..d85b9ec 100644
--- a/src/tracing/test/api_test_support.h
+++ b/src/tracing/test/api_test_support.h
@@ -32,6 +32,7 @@
namespace test {
int32_t GetCurrentProcessId();
+uint64_t GetWallTimeNs();
} // namespace test
} // namespace perfetto
diff --git a/src/tracing/test/tracing_module.cc b/src/tracing/test/tracing_module.cc
new file mode 100644
index 0000000..68a31cc
--- /dev/null
+++ b/src/tracing/test/tracing_module.cc
@@ -0,0 +1,60 @@
+/*
+ * 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/tracing/test/tracing_module.h"
+
+#include "src/tracing/test/tracing_module_categories.h"
+
+#include <stdio.h>
+
+// This file is for checking that multiple sets of trace event categories can be
+// combined into the same program.
+
+PERFETTO_TRACK_EVENT_STATIC_STORAGE();
+
+namespace tracing_module {
+
+void InitializeCategories() {
+ TrackEvent::Register();
+}
+
+void EmitTrackEvents() {
+ TRACE_EVENT_BEGIN("cat1", "DisabledEventFromModule");
+ TRACE_EVENT_END("cat1");
+ TRACE_EVENT_BEGIN("cat4", "DisabledEventFromModule");
+ TRACE_EVENT_END("cat4");
+ TRACE_EVENT_BEGIN("cat9", "DisabledEventFromModule");
+ TRACE_EVENT_END("cat9");
+ TRACE_EVENT_BEGIN("foo", "FooEventFromModule");
+ TRACE_EVENT_END("foo");
+}
+
+perfetto::internal::TrackEventIncrementalState* GetIncrementalState() {
+ perfetto::internal::TrackEventIncrementalState* state = nullptr;
+ TrackEvent::Trace([&state](TrackEvent::TraceContext ctx) {
+ state = ctx.GetIncrementalState();
+ });
+ return state;
+}
+
+void FunctionWithOneTrackEvent() {
+ TRACE_EVENT_BEGIN("cat1", "DisabledEventFromModule");
+ // Simulates the non-tracing work of this function, which should take priority
+ // over the above trace event in terms of instruction scheduling.
+ puts("Hello");
+}
+
+} // namespace tracing_module
diff --git a/src/tracing/test/tracing_module.h b/src/tracing/test/tracing_module.h
new file mode 100644
index 0000000..ce9af43
--- /dev/null
+++ b/src/tracing/test/tracing_module.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACING_TEST_TRACING_MODULE_H_
+#define SRC_TRACING_TEST_TRACING_MODULE_H_
+
+// Note: No non-client API header includes are allowed here.
+
+namespace perfetto {
+namespace internal {
+struct TrackEventIncrementalState;
+} // namespace internal
+} // namespace perfetto
+
+namespace tracing_module {
+
+void InitializeCategories();
+void EmitTrackEvents();
+void EmitTrackEvents2();
+perfetto::internal::TrackEventIncrementalState* GetIncrementalState();
+
+// This function is used to check the instruction size overhead of a single
+// track event.
+void FunctionWithOneTrackEvent();
+
+} // namespace tracing_module
+
+#endif // SRC_TRACING_TEST_TRACING_MODULE_H_
diff --git a/src/tracing/test/tracing_module2.cc b/src/tracing/test/tracing_module2.cc
new file mode 100644
index 0000000..e907d71
--- /dev/null
+++ b/src/tracing/test/tracing_module2.cc
@@ -0,0 +1,39 @@
+/*
+ * 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/tracing/test/tracing_module.h"
+
+#include "src/tracing/test/tracing_module_categories.h"
+
+#include <stdio.h>
+
+// This file checks that one track event category list can be shared by two
+// compilation units.
+
+namespace tracing_module {
+
+void EmitTrackEvents2() {
+ TRACE_EVENT_BEGIN("cat1", "DisabledEventFromModule2");
+ TRACE_EVENT_END("cat1");
+ TRACE_EVENT_BEGIN("cat4", "DisabledEventFromModule2");
+ TRACE_EVENT_END("cat4");
+ TRACE_EVENT_BEGIN("cat9", "DisabledEventFromModule2");
+ TRACE_EVENT_END("cat9");
+ TRACE_EVENT_BEGIN("foo", "FooEventFromModule2");
+ TRACE_EVENT_END("foo");
+}
+
+} // namespace tracing_module
diff --git a/src/tracing/test/tracing_module_categories.h b/src/tracing/test/tracing_module_categories.h
new file mode 100644
index 0000000..f776894
--- /dev/null
+++ b/src/tracing/test/tracing_module_categories.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACING_TEST_TRACING_MODULE_CATEGORIES_H_
+#define SRC_TRACING_TEST_TRACING_MODULE_CATEGORIES_H_
+
+// This header defines the tracing categories (and track event data source) used
+// in the external tracing test module. These categories are distinct from the
+// ones defined in api_integrationtest.cc, but events for both sets of
+// categories can be written to the same trace writer.
+
+#define PERFETTO_TRACK_EVENT_NAMESPACE tracing_module
+
+#include "perfetto/tracing.h"
+
+PERFETTO_DEFINE_CATEGORIES(PERFETTO_CATEGORY(cat1),
+ PERFETTO_CATEGORY(cat2),
+ PERFETTO_CATEGORY(cat3),
+ PERFETTO_CATEGORY(cat4),
+ PERFETTO_CATEGORY(cat5),
+ PERFETTO_CATEGORY(cat6),
+ PERFETTO_CATEGORY(cat7),
+ PERFETTO_CATEGORY(cat8),
+ PERFETTO_CATEGORY(cat9),
+ PERFETTO_CATEGORY(foo));
+
+#endif // SRC_TRACING_TEST_TRACING_MODULE_CATEGORIES_H_
diff --git a/src/tracing/track_event_category_registry.cc b/src/tracing/track_event_category_registry.cc
new file mode 100644
index 0000000..e64fa3b
--- /dev/null
+++ b/src/tracing/track_event_category_registry.cc
@@ -0,0 +1,49 @@
+/*
+ * 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 "perfetto/tracing/track_event_category_registry.h"
+
+namespace perfetto {
+namespace internal {
+
+const TrackEventCategory* TrackEventCategoryRegistry::GetCategory(
+ size_t index) const {
+ PERFETTO_DCHECK(index < category_count_);
+ return &categories_[index];
+}
+
+void TrackEventCategoryRegistry::EnableCategoryForInstance(
+ size_t category_index,
+ uint32_t instance_index) const {
+ PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
+ PERFETTO_DCHECK(category_index < category_count_);
+ // Matches the acquire_load in DataSource::Trace().
+ state_storage_[category_index].fetch_or(
+ static_cast<uint8_t>(1u << instance_index), std::memory_order_release);
+}
+
+void TrackEventCategoryRegistry::DisableCategoryForInstance(
+ size_t category_index,
+ uint32_t instance_index) const {
+ PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
+ PERFETTO_DCHECK(category_index < category_count_);
+ // Matches the acquire_load in DataSource::Trace().
+ state_storage_[category_index].fetch_and(
+ static_cast<uint8_t>(~(1u << instance_index)), std::memory_order_release);
+}
+
+} // namespace internal
+} // namespace perfetto
diff --git a/test/producer_socket_fuzzer.cc b/test/producer_socket_fuzzer.cc
index 430b2de..ac7227f 100644
--- a/test/producer_socket_fuzzer.cc
+++ b/test/producer_socket_fuzzer.cc
@@ -63,7 +63,8 @@
data, size, task_runner.CreateCheckpoint("data_sent"));
std::unique_ptr<base::UnixSocket> sock = base::UnixSocket::Connect(
- helper.GetProducerSocketName(), &fake_event_listener, &task_runner);
+ helper.GetProducerSocketName(), &fake_event_listener, &task_runner,
+ base::SockFamily::kUnix, base::SockType::kStream);
task_runner.RunUntilCheckpoint("data_sent");
return 0;
diff --git a/test/synth_common.py b/test/synth_common.py
index 656faab..3383b81 100644
--- a/test/synth_common.py
+++ b/test/synth_common.py
@@ -294,6 +294,35 @@
buffer_event.type = event_type
buffer_event.duration_ns = duration
+ def add_thread_track_descriptor(self,
+ ps,
+ ts,
+ uuid,
+ pid,
+ tid,
+ thread_name,
+ inc_state_cleared=False):
+ packet = self.add_packet()
+ packet.trusted_packet_sequence_id = ps
+ packet.timestamp = ts
+ if inc_state_cleared:
+ packet.incremental_state_cleared = True
+ track = packet.track_descriptor
+ track.uuid = uuid
+ track.thread.pid = pid
+ track.thread.tid = tid
+ track.thread.thread_name = thread_name
+
+ def add_track_event(self, ps, ts, track_uuid, cat, name, type):
+ packet = self.add_packet()
+ packet.trusted_packet_sequence_id = ps
+ packet.timestamp = ts
+ event = packet.track_event
+ event.track_uuid = track_uuid
+ event.categories.append(cat)
+ event.name = name
+ event.type = type
+
def create_trace():
parser = argparse.ArgumentParser()
diff --git a/test/trace_processor/index b/test/trace_processor/index
index 7b9ef11..2669011 100644
--- a/test/trace_processor/index
+++ b/test/trace_processor/index
@@ -68,6 +68,8 @@
# Power rails
../data/power_rails.pb power_rails.sql power_rails_power_rails.out
+power_rail_custom_clock.textproto power_rail_event.sql power_rail_event_power_rail_custom_clock.out
+
# Android userspace async slices
android_async_slice.textproto process_track_slices.sql process_track_slices_android_async_slice.out
@@ -135,3 +137,10 @@
heap_graph.textproto heap_graph_object.sql heap_graph_object.out
heap_graph.textproto heap_graph_reference.sql heap_graph_reference.out
+
+# TrackEvent tests.
+track_event_same_tids.py process_tracking.sql track_event_same_tids_threads.out
+track_event_same_tids.py track_event_slices.sql track_event_same_tids_slices.out
+
+# Parsing of an html file with systrace data inside
+../data/systrace.html systrace_html.sql systrace_html.out
diff --git a/test/trace_processor/power_rail_custom_clock.textproto b/test/trace_processor/power_rail_custom_clock.textproto
new file mode 100644
index 0000000..c7eeb09
--- /dev/null
+++ b/test/trace_processor/power_rail_custom_clock.textproto
@@ -0,0 +1,57 @@
+packet {
+ clock_snapshot {
+ clocks {
+ clock_id: 6
+ timestamp: 101000002
+ }
+ clocks {
+ clock_id: 128
+ timestamp: 2
+ }
+ }
+ timestamp: 101000002
+}
+packet {
+ power_rails {
+ rail_descriptor {
+ index: 4
+ rail_name: "test_rail"
+ subsys_name: "test_subsys"
+ sampling_rate: 1023
+ }
+ }
+}
+packet {
+ timestamp: 3000000
+ power_rails {
+ energy_data {
+ index: 4
+ energy: 333
+ }
+ }
+ timestamp_clock_id: 128
+}
+packet {
+ timestamp: 5000000
+ power_rails {
+ energy_data {
+ index: 4
+ energy: 666
+ }
+ }
+ timestamp_clock_id: 128
+}
+packet {
+ power_rails {
+ energy_data {
+ index: 4
+ timestamp_ms: 106
+ energy: 999
+ }
+ energy_data {
+ index: 4
+ timestamp_ms: 109
+ energy: 0
+ }
+ }
+}
diff --git a/test/trace_processor/power_rail_event.sql b/test/trace_processor/power_rail_event.sql
new file mode 100644
index 0000000..0082ac3
--- /dev/null
+++ b/test/trace_processor/power_rail_event.sql
@@ -0,0 +1,4 @@
+select ts, value
+from counters
+where name like "power.%"
+limit 20
diff --git a/test/trace_processor/power_rail_event_power_rail_custom_clock.out b/test/trace_processor/power_rail_event_power_rail_custom_clock.out
new file mode 100644
index 0000000..4c222eb
--- /dev/null
+++ b/test/trace_processor/power_rail_event_power_rail_custom_clock.out
@@ -0,0 +1,5 @@
+"ts","value"
+104000000,333.000000
+106000000,666.000000
+106000000,999.000000
+109000000,0.000000
diff --git a/test/trace_processor/systrace_html.out b/test/trace_processor/systrace_html.out
new file mode 100644
index 0000000..9d9b86b
--- /dev/null
+++ b/test/trace_processor/systrace_html.out
@@ -0,0 +1,3527 @@
+"ts","cpu","dur","ts_end","utid","end_state","priority","row_id","upid","name","tid","start_ts","end_ts"
+6824711826708000,6,352000,6824711827060000,0,"R",120,17179869190,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711826810000,0,15054000,6824711841864000,0,"R",120,17179869193,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711826907000,3,380000,6824711827287000,0,"R",120,17179869197,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711827018000,1,27430000,6824711854448000,0,"R",120,17179869199,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711827068000,6,32000,6824711827100000,0,"R",120,17179869202,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711827085000,2,1808000,6824711828893000,0,"R",120,17179869203,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711827104000,6,9000,6824711827113000,0,"R",120,17179869205,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711827143000,7,13961000,6824711841104000,0,"R",120,17179869208,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711827144000,6,1680000,6824711828824000,0,"R",120,17179869209,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711827183000,4,899199000,6824712726382000,0,"R",120,17179869210,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711828825000,3,15722000,6824711844547000,0,"R",120,17179869216,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711828886000,6,64000,6824711828950000,0,"R",120,17179869218,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711828985000,6,4000,6824711828989000,0,"R",120,17179869222,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711828998000,6,102000,6824711829100000,0,"R",120,17179869225,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711829134000,6,38000,6824711829172000,0,"R",120,17179869227,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711829211000,6,11000,6824711829222000,0,"R",120,17179869230,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711829255000,6,40000,6824711829295000,0,"R",120,17179869233,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711829327000,6,75000,6824711829402000,0,"R",120,17179869236,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711829421000,6,16000,6824711829437000,0,"R",120,17179869239,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711829444000,6,452000,6824711829896000,0,"R",120,17179869241,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711829559000,2,4671000,6824711834230000,0,"R",120,17179869243,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711829912000,6,3511000,6824711833423000,0,"R",120,17179869245,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711833450000,6,7442000,6824711840892000,0,"R",120,17179869251,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711834256000,2,5778000,6824711840034000,0,"R",120,17179869254,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711834507000,5,6564000,6824711841071000,0,"R",120,17179869255,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711840216000,2,1649000,6824711841865000,0,"R",120,17179869258,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711841082000,5,5691000,6824711846773000,0,"R",120,17179869263,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711841098000,6,3082000,6824711844180000,0,"R",120,17179869264,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711841137000,7,290852000,6824712131989000,0,"R",120,17179869268,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711842025000,0,12144000,6824711854169000,0,"R",120,17179869271,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711844270000,2,2752000,6824711847022000,0,"R",120,17179869279,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711844275000,6,572000,6824711844847000,0,"R",120,17179869280,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711844719000,3,2190000,6824711846909000,0,"R",120,17179869282,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711844860000,6,1757000,6824711846617000,0,"R",120,17179869284,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711846808000,5,88282000,6824711935090000,0,"R",120,17179869290,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711846815000,6,7290000,6824711854105000,0,"R",120,17179869291,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711847036000,3,3496000,6824711850532000,0,"R",120,17179869295,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711847350000,2,8611000,6824711855961000,0,"R",120,17179869296,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711850582000,3,24018000,6824711874600000,0,"R",120,17179869298,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711854125000,6,6654000,6824711860779000,0,"R",120,17179869301,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711854289000,0,462000,6824711854751000,0,"R",120,17179869303,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711854852000,1,326000,6824711855178000,0,"R",120,17179869306,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711855078000,0,471000,6824711855549000,0,"R",120,17179869307,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711855357000,1,545000,6824711855902000,0,"R",120,17179869309,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711855821000,0,1794000,6824711857615000,0,"R",120,17179869311,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711856033000,2,5351000,6824711861384000,0,"R",120,17179869314,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711857673000,1,347000,6824711858020000,0,"R",120,17179869316,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711857865000,0,426000,6824711858291000,0,"R",120,17179869317,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711858171000,1,29595000,6824711887766000,0,"R",120,17179869319,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711858370000,0,1693000,6824711860063000,0,"R",120,17179869321,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711860111000,0,5836000,6824711865947000,0,"R",120,17179869323,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711861302000,6,12006000,6824711873308000,0,"R",120,17179869330,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711861841000,2,27907000,6824711889748000,0,"R",120,17179869332,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711866132000,0,889000,6824711867021000,0,"R",120,17179869335,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711867068000,0,702000,6824711867770000,0,"R",120,17179869337,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711867840000,0,4623000,6824711872463000,0,"R",120,17179869339,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711872515000,0,868000,6824711873383000,0,"R",120,17179869341,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711873376000,6,665000,6824711874041000,0,"R",120,17179869343,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711873756000,0,6329000,6824711880085000,0,"R",120,17179869348,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711874518000,6,672000,6824711875190000,0,"R",120,17179869350,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711874738000,3,920000,6824711875658000,0,"R",120,17179869352,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711875397000,6,667000,6824711876064000,0,"R",120,17179869354,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711875744000,3,729000,6824711876473000,0,"R",120,17179869356,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711876266000,6,110000,6824711876376000,0,"R",120,17179869358,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711876472000,6,704000,6824711877176000,0,"R",120,17179869360,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711876544000,3,783000,6824711877327000,0,"R",120,17179869362,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711877301000,6,678000,6824711877979000,0,"R",120,17179869364,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711877470000,3,716000,6824711878186000,0,"R",120,17179869366,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711878177000,6,472000,6824711878649000,0,"R",120,17179869368,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711878379000,3,469000,6824711878848000,0,"R",120,17179869370,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711878831000,6,446000,6824711879277000,0,"R",120,17179869372,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711878988000,3,666000,6824711879654000,0,"R",120,17179869374,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711879438000,6,112000,6824711879550000,0,"R",120,17179869376,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711879632000,6,169000,6824711879801000,0,"R",120,17179869378,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711879836000,3,398000,6824711880234000,0,"R",120,17179869381,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711879993000,6,231000,6824711880224000,0,"R",120,17179869382,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711880297000,0,6382000,6824711886679000,0,"R",120,17179869387,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711880298000,3,94000,6824711880392000,0,"R",120,17179869388,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711880367000,6,186000,6824711880553000,0,"R",120,17179869389,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711880594000,3,14276000,6824711894870000,0,"R",120,17179869392,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711880611000,6,5024000,6824711885635000,0,"R",120,17179869393,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711885679000,6,8649000,6824711894328000,0,"R",120,17179869395,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711886877000,0,585000,6824711887462000,0,"R",120,17179869398,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711887580000,0,455000,6824711888035000,0,"R",120,17179869400,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711888143000,1,88000,6824711888231000,0,"R",120,17179869403,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711888316000,1,979000,6824711889295000,0,"R",120,17179869405,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711888362000,0,604000,6824711888966000,0,"R",120,17179869406,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711889144000,0,532000,6824711889676000,0,"R",120,17179869408,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711889570000,1,1823000,6824711891393000,0,"R",120,17179869410,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711889834000,2,34646000,6824711924480000,0,"R",120,17179869413,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711891429000,0,393000,6824711891822000,0,"R",120,17179869415,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711891673000,1,472000,6824711892145000,0,"R",120,17179869416,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711892000000,0,1451000,6824711893451000,0,"R",120,17179869418,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711892240000,1,12180000,6824711904420000,0,"R",120,17179869420,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711893852000,0,27555000,6824711921407000,0,"R",120,17179869427,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711894628000,6,2368000,6824711896996000,0,"R",120,17179869429,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711894947000,3,4289000,6824711899236000,0,"R",120,17179869431,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711897302000,6,48000,6824711897350000,0,"R",120,17179869433,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711897393000,6,3585000,6824711900978000,0,"R",120,17179869435,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711899493000,3,4694000,6824711904187000,0,"R",120,17179869437,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711901100000,6,50000,6824711901150000,0,"R",120,17179869439,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711901190000,6,826872000,6824712728062000,0,"R",120,17179869441,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711904399000,3,55334000,6824711959733000,0,"R",120,17179869443,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711904492000,1,14769000,6824711919261000,0,"R",120,17179869445,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711919406000,1,3219000,6824711922625000,0,"R",120,17179869447,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711922318000,0,65000,6824711922383000,0,"R",120,17179869450,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711922440000,0,585000,6824711923025000,0,"R",120,17179869452,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711923102000,1,584000,6824711923686000,0,"R",120,17179869455,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711923264000,0,1073000,6824711924337000,0,"R",120,17179869456,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711924095000,1,2591000,6824711926686000,0,"R",120,17179869458,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711924573000,2,34369000,6824711958942000,0,"R",120,17179869461,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711926753000,0,601000,6824711927354000,0,"R",120,17179869463,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711927027000,1,795000,6824711927822000,0,"R",120,17179869464,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711927540000,0,30747000,6824711958287000,0,"R",120,17179869466,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711927908000,1,30404000,6824711958312000,0,"R",120,17179869468,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711935149000,5,791709000,6824712726858000,0,"R",120,17179869470,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711958707000,1,827000,6824711959534000,0,"R",120,17179869475,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711959344000,2,862000,6824711960206000,0,"R",120,17179869479,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711960113000,1,3163000,6824711963276000,0,"R",120,17179869483,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711960292000,2,31867000,6824711992159000,0,"R",120,17179869485,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711960679000,0,1939000,6824711962618000,0,"R",120,17179869488,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711962795000,3,29662000,6824711992457000,0,"R",120,17179869491,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711963242000,0,720000,6824711963962000,0,"R",120,17179869493,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711963544000,1,27817000,6824711991361000,0,"R",120,17179869496,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711964055000,0,26981000,6824711991036000,0,"R",120,17179869498,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711991873000,1,90000,6824711991963000,0,"R",120,17179869502,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711992049000,1,1109000,6824711993158000,0,"R",120,17179869504,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711992203000,0,811000,6824711993014000,0,"R",120,17179869506,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711992698000,2,31632000,6824712024330000,0,"R",120,17179869508,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711993018000,3,29607000,6824712022625000,0,"R",120,17179869510,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711993246000,1,2846000,6824711996092000,0,"R",120,17179869512,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711996061000,0,723000,6824711996784000,0,"R",120,17179869513,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711996491000,1,795000,6824711997286000,0,"R",120,17179869515,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711996990000,0,72000,6824711997062000,0,"R",120,17179869517,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711997127000,0,25255000,6824712022382000,0,"R",120,17179869519,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711997375000,1,26567000,6824712023942000,0,"R",120,17179869521,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712022716000,3,37690000,6824712060406000,0,"R",120,17179869525,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712024030000,0,921000,6824712024951000,0,"R",120,17179869528,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712024581000,1,1190000,6824712025771000,0,"R",120,17179869530,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712024654000,2,1208000,6824712025862000,0,"R",120,17179869531,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712025482000,0,3497000,6824712028979000,0,"R",120,17179869533,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712025945000,2,34179000,6824712060124000,0,"R",120,17179869536,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712028934000,1,717000,6824712029651000,0,"R",120,17179869537,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712029372000,0,798000,6824712030170000,0,"R",120,17179869539,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712029855000,1,29454000,6824712059309000,0,"R",120,17179869541,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712030259000,0,70000,6824712030329000,0,"R",120,17179869543,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712030399000,0,28593000,6824712058992000,0,"R",120,17179869545,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712059828000,1,364000,6824712060192000,0,"R",120,17179869549,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712060340000,1,928000,6824712061268000,0,"R",120,17179869554,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712060637000,2,31702000,6824712092339000,0,"R",120,17179869556,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712060952000,3,31540000,6824712092492000,0,"R",120,17179869557,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712061338000,0,3134000,6824712064472000,0,"R",120,17179869561,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712064440000,1,710000,6824712065150000,0,"R",120,17179869562,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712064872000,0,780000,6824712065652000,0,"R",120,17179869564,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712065351000,1,10437000,6824712075788000,0,"R",120,17179869566,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712065741000,0,24857000,6824712090598000,0,"R",120,17179869568,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712076555000,1,15181000,6824712091736000,0,"R",120,17179869572,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712092143000,0,90000,6824712092233000,0,"R",120,17179869576,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712092146000,1,1144000,6824712093290000,0,"R",120,17179869577,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712092312000,0,820000,6824712093132000,0,"R",120,17179869579,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712092941000,2,4352000,6824712097293000,0,"R",120,17179869582,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712092979000,3,33505000,6824712126484000,0,"R",120,17179869583,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712093222000,0,3125000,6824712096347000,0,"R",120,17179869585,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712096318000,1,443000,6824712096761000,0,"R",120,17179869587,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712096863000,0,27799000,6824712124662000,0,"R",120,17179869590,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712096969000,1,28547000,6824712125516000,0,"R",120,17179869591,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712097387000,2,27295000,6824712124682000,0,"R",120,17179869593,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712124986000,2,1342000,6824712126328000,0,"R",120,17179869596,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712126048000,1,3632000,6824712129680000,0,"R",120,17179869602,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712126389000,0,970000,6824712127359000,0,"R",120,17179869605,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712127196000,3,32061000,6824712159257000,0,"R",120,17179869607,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712127443000,0,1769000,6824712129212000,0,"R",120,17179869609,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712129255000,2,29843000,6824712159098000,0,"R",120,17179869611,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712129511000,0,530000,6824712130041000,0,"R",120,17179869612,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712129857000,1,28493000,6824712158350000,0,"R",120,17179869614,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712130129000,0,64000,6824712130193000,0,"R",120,17179869616,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712130249000,0,496000,6824712130745000,0,"R",120,17179869618,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712132045000,7,62353000,6824712194398000,0,"R",120,17179869625,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712135451000,0,5153000,6824712140604000,0,"R",120,17179869630,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712140840000,0,16732000,6824712157572000,0,"R",120,17179869633,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712158802000,1,87000,6824712158889000,0,"R",120,17179869637,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712158976000,1,981000,6824712159957000,0,"R",120,17179869639,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712159015000,0,478000,6824712159493000,0,"R",120,17179869640,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712159619000,2,33324000,6824712192943000,0,"R",120,17179869644,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712159816000,3,33271000,6824712193087000,0,"R",120,17179869645,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712160044000,1,3767000,6824712163811000,0,"R",120,17179869647,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712163783000,0,718000,6824712164501000,0,"R",120,17179869651,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712164216000,1,792000,6824712165008000,0,"R",120,17179869653,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712164704000,0,26926000,6824712191630000,0,"R",120,17179869655,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712165096000,1,26545000,6824712191641000,0,"R",120,17179869657,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712191899000,1,160000,6824712192059000,0,"R",120,17179869660,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712192674000,1,1433000,6824712194107000,0,"R",120,17179869665,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712193196000,3,33652000,6824712226848000,0,"R",120,17179869668,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712193513000,0,1329000,6824712194842000,0,"R",120,17179869669,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712194470000,7,52792000,6824712247262000,0,"R",120,17179869672,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712194663000,1,2149000,6824712196812000,0,"R",120,17179869673,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712194931000,0,1217000,6824712196148000,0,"R",120,17179869675,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712196116000,2,30414000,6824712226530000,0,"R",120,17179869676,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712196533000,0,781000,6824712197314000,0,"R",120,17179869678,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712197012000,1,28707000,6824712225719000,0,"R",120,17179869680,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712197402000,0,28073000,6824712225475000,0,"R",120,17179869682,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712226240000,1,81000,6824712226321000,0,"R",120,17179869686,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712226408000,1,1183000,6824712227591000,0,"R",120,17179869688,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712226595000,0,894000,6824712227489000,0,"R",120,17179869690,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712227199000,2,32486000,6824712259685000,0,"R",120,17179869692,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712227394000,3,101387000,6824712328781000,0,"R",120,17179869693,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712227679000,1,3014000,6824712230693000,0,"R",120,17179869696,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712230650000,0,717000,6824712231367000,0,"R",120,17179869697,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712231087000,1,782000,6824712231869000,0,"R",120,17179869699,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712231567000,0,13149000,6824712244716000,0,"R",120,17179869701,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712231956000,1,12891000,6824712244847000,0,"R",120,17179869703,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712245040000,0,87000,6824712245127000,0,"R",120,17179869706,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712245040000,1,14256000,6824712259296000,0,"R",120,17179869707,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712245385000,0,12652000,6824712258037000,0,"R",120,17179869709,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712247465000,7,71000,6824712247536000,0,"R",120,17179869711,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712247598000,7,14402000,6824712262000000,0,"R",120,17179869713,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712259395000,0,83000,6824712259478000,0,"R",120,17179869717,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712259564000,0,904000,6824712260468000,0,"R",120,17179869719,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712259922000,1,1420000,6824712261342000,0,"R",120,17179869721,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712260461000,2,979000,6824712261440000,0,"R",120,17179869723,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712260991000,0,3489000,6824712264480000,0,"R",120,17179869725,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712261538000,2,31144000,6824712292682000,0,"R",120,17179869728,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712262773000,7,467225000,6824712729998000,0,"R",120,17179869730,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712264416000,1,745000,6824712265161000,0,"R",120,17179869731,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712264879000,0,791000,6824712265670000,0,"R",120,17179869733,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712265370000,1,26002000,6824712291372000,0,"R",120,17179869735,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712265766000,0,19023000,6824712284789000,0,"R",120,17179869737,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712285450000,0,2460000,6824712287910000,0,"R",120,17179869740,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712288785000,0,83000,6824712288868000,0,"R",120,17179869743,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712288947000,0,1078000,6824712290025000,0,"R",120,17179869745,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712291126000,0,55000,6824712291181000,0,"R",120,17179869748,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712291229000,0,733000,6824712291962000,0,"R",120,17179869750,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712292130000,1,1482000,6824712293612000,0,"R",120,17179869753,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712292278000,0,1237000,6824712293515000,0,"R",120,17179869754,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712293237000,2,4208000,6824712297445000,0,"R",120,17179869756,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712293695000,1,2925000,6824712296620000,0,"R",120,17179869759,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712296584000,0,315000,6824712296899000,0,"R",120,17179869760,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712297134000,0,29796000,6824712326930000,0,"R",120,17179869764,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712297146000,1,30662000,6824712327808000,0,"R",120,17179869765,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712297536000,2,29403000,6824712326939000,0,"R",120,17179869767,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712327104000,2,1506000,6824712328610000,0,"R",120,17179869770,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712328336000,1,4173000,6824712332509000,0,"R",120,17179869776,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712328559000,0,938000,6824712329497000,0,"R",120,17179869777,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712329355000,3,32279000,6824712361634000,0,"R",120,17179869780,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712329584000,0,2242000,6824712331826000,0,"R",120,17179869782,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712331793000,2,29260000,6824712361053000,0,"R",120,17179869783,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712332220000,0,790000,6824712333010000,0,"R",120,17179869785,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712332711000,1,27609000,6824712360320000,0,"R",120,17179869787,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712333095000,0,26074000,6824712359169000,0,"R",120,17179869789,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712360760000,1,80000,6824712360840000,0,"R",120,17179869793,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712361392000,1,52000,6824712361444000,0,"R",120,17179869798,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712361543000,2,32596000,6824712394139000,0,"R",120,17179869800,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712361736000,3,33366000,6824712395102000,0,"R",120,17179869802,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712362118000,0,2398000,6824712364516000,0,"R",120,17179869803,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712364472000,1,724000,6824712365196000,0,"R",120,17179869804,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712364910000,0,797000,6824712365707000,0,"R",120,17179869806,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712365405000,1,27749000,6824712393154000,0,"R",120,17179869808,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712365795000,0,27098000,6824712392893000,0,"R",120,17179869810,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712393831000,1,936000,6824712394767000,0,"R",120,17179869814,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712394204000,0,745000,6824712394949000,0,"R",120,17179869816,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712394700000,2,32976000,6824712427676000,0,"R",120,17179869817,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712395204000,3,33047000,6824712428251000,0,"R",120,17179869821,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712395292000,1,2827000,6824712398119000,0,"R",120,17179869822,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712398082000,0,723000,6824712398805000,0,"R",120,17179869823,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712398523000,1,782000,6824712399305000,0,"R",120,17179869825,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712399011000,0,27138000,6824712426149000,0,"R",120,17179869827,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712399393000,1,27547000,6824712426940000,0,"R",120,17179869829,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712427387000,1,62000,6824712427449000,0,"R",120,17179869833,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712427749000,0,1055000,6824712428804000,0,"R",120,17179869837,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712428005000,1,3964000,6824712431969000,0,"R",120,17179869838,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712428161000,2,33130000,6824712461291000,0,"R",120,17179869839,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712428354000,3,33090000,6824712461444000,0,"R",120,17179869841,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712431936000,0,704000,6824712432640000,0,"R",120,17179869843,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712432366000,1,792000,6824712433158000,0,"R",120,17179869845,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712432856000,0,26763000,6824712459619000,0,"R",120,17179869847,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712433246000,1,27279000,6824712460525000,0,"R",120,17179869849,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712460972000,1,1100000,6824712462072000,0,"R",120,17179869853,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712461820000,2,32964000,6824712494784000,0,"R",120,17179869857,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712462014000,3,33363000,6824712495377000,0,"R",120,17179869860,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712462312000,0,3049000,6824712465361000,0,"R",120,17179869863,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712465308000,1,737000,6824712466045000,0,"R",120,17179869864,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712465765000,0,787000,6824712466552000,0,"R",120,17179869866,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712466249000,1,27754000,6824712494003000,0,"R",120,17179869868,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712466726000,0,26386000,6824712493112000,0,"R",120,17179869870,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712494508000,1,79000,6824712494587000,0,"R",120,17179869874,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712494924000,0,989000,6824712495913000,0,"R",120,17179869878,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712495145000,1,3951000,6824712499096000,0,"R",120,17179869879,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712495270000,2,33176000,6824712528446000,0,"R",120,17179869880,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712495482000,3,33062000,6824712528544000,0,"R",120,17179869882,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712499070000,0,712000,6824712499782000,0,"R",120,17179869884,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712499504000,1,790000,6824712500294000,0,"R",120,17179869886,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712500088000,0,26796000,6824712526884000,0,"R",120,17179869888,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712500386000,1,27266000,6824712527652000,0,"R",120,17179869890,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712528089000,1,1245000,6824712529334000,0,"R",120,17179869895,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712528238000,0,994000,6824712529232000,0,"R",120,17179869897,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712528933000,2,52000,6824712528985000,0,"R",120,17179869900,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712529063000,2,32595000,6824712561658000,0,"R",120,17179869902,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712529164000,3,33240000,6824712562404000,0,"R",120,17179869903,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712529420000,1,3171000,6824712532591000,0,"R",120,17179869906,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712532573000,0,701000,6824712533274000,0,"R",120,17179869908,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712532986000,1,786000,6824712533772000,0,"R",120,17179869910,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712533472000,0,70000,6824712533542000,0,"R",120,17179869912,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712533609000,0,26476000,6824712560085000,0,"R",120,17179869914,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712533861000,1,27413000,6824712561274000,0,"R",120,17179869916,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712561438000,0,79000,6824712561517000,0,"R",120,17179869920,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712561896000,1,1355000,6824712563251000,0,"R",120,17179869924,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712561987000,2,1400000,6824712563387000,0,"R",120,17179869925,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712562891000,0,3455000,6824712566346000,0,"R",120,17179869928,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712562980000,3,66067000,6824712629047000,0,"R",120,17179869929,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712563471000,2,66000,6824712563537000,0,"R",120,17179869932,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712563598000,2,28176000,6824712591774000,0,"R",120,17179869934,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712566295000,1,912000,6824712567207000,0,"R",120,17179869935,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712566926000,0,798000,6824712567724000,0,"R",120,17179869937,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712567416000,1,25855000,6824712593271000,0,"R",120,17179869939,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712567814000,0,23951000,6824712591765000,0,"R",120,17179869941,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712592417000,2,1974000,6824712594391000,0,"R",120,17179869946,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712592918000,0,855000,6824712593773000,0,"R",120,17179869947,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712594019000,1,75000,6824712594094000,0,"R",120,17179869950,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712594086000,0,1123000,6824712595209000,0,"R",120,17179869951,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712594167000,1,1145000,6824712595312000,0,"R",120,17179869953,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712594934000,2,33189000,6824712628123000,0,"R",120,17179869955,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712595396000,1,3046000,6824712598442000,0,"R",120,17179869958,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712598402000,0,638000,6824712599040000,0,"R",120,17179869959,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712598837000,1,566000,6824712599403000,0,"R",120,17179869961,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712599222000,0,27826000,6824712627048000,0,"R",120,17179869963,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712599490000,1,27821000,6824712627311000,0,"R",120,17179869965,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712627846000,1,97000,6824712627943000,0,"R",120,17179869969,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712628262000,0,1140000,6824712629402000,0,"R",120,17179869974,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712628610000,2,29797000,6824712658407000,0,"R",120,17179869975,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712628645000,1,4458000,6824712633103000,0,"R",120,17179869976,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712629488000,0,2932000,6824712632420000,0,"R",120,17179869979,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712632386000,3,20618000,6824712653004000,0,"R",120,17179869980,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712632825000,0,777000,6824712633602000,0,"R",120,17179869982,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712633403000,1,24713000,6824712658116000,0,"R",120,17179869984,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712633691000,0,8761000,6824712642452000,0,"R",120,17179869986,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712645364000,0,605000,6824712645969000,0,"R",120,17179869992,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712646484000,0,171000,6824712646655000,0,"R",120,17179869997,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712647185000,0,104000,6824712647289000,0,"R",120,17179870003,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712647483000,0,945000,6824712648428000,0,"R",120,17179870006,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712648919000,0,62000,6824712648981000,0,"R",120,17179870011,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712649431000,0,72000,6824712649503000,0,"R",120,17179870016,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712649702000,0,58000,6824712649760000,0,"R",120,17179870020,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712650304000,0,91000,6824712650395000,0,"R",120,17179870027,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712650857000,0,1177000,6824712652034000,0,"R",120,17179870031,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712652915000,0,447000,6824712653362000,0,"R",120,17179870036,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712653063000,3,70763000,6824712723826000,0,"R",120,17179870038,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712653408000,0,4244000,6824712657652000,0,"R",120,17179870040,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712658233000,0,57000,6824712658290000,0,"R",120,17179870044,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712658343000,0,1697000,6824712660040000,0,"R",120,17179870046,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712658524000,2,2025000,6824712660549000,0,"R",120,17179870048,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712658563000,1,1537000,6824712660100000,0,"R",120,17179870049,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712660284000,1,748000,6824712661032000,0,"R",120,17179870053,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712660528000,0,434000,6824712660962000,0,"R",120,17179870054,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712660883000,2,33798000,6824712694681000,0,"R",120,17179870056,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712661114000,1,1692000,6824712662806000,0,"R",120,17179870059,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712662890000,0,402000,6824712663292000,0,"R",120,17179870061,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712663110000,1,497000,6824712663607000,0,"R",120,17179870062,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712663482000,0,57000,6824712663539000,0,"R",120,17179870064,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712663592000,0,2553000,6824712666145000,0,"R",120,17179870066,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712663697000,1,25560000,6824712689257000,0,"R",120,17179870068,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712666254000,0,23413000,6824712689667000,0,"R",120,17179870070,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712689539000,1,2472000,6824712692011000,0,"R",120,17179870073,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712689766000,0,1565000,6824712691331000,0,"R",120,17179870075,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712691944000,0,66000,6824712692010000,0,"R",120,17179870078,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712692062000,0,412000,6824712692474000,0,"R",120,17179870081,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712692447000,1,1171000,6824712693618000,0,"R",120,17179870082,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712692587000,0,1292000,6824712693879000,0,"R",120,17179870084,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712693661000,1,535000,6824712694196000,0,"R",120,17179870086,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712694054000,0,541000,6824712694595000,0,"R",120,17179870088,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712694518000,1,1868000,6824712696386000,0,"R",120,17179870090,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712694773000,2,2264000,6824712697037000,0,"R",120,17179870093,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712696470000,0,141000,6824712696611000,0,"R",120,17179870095,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712696689000,0,44000,6824712696733000,0,"R",120,17179870097,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712696829000,1,10308000,6824712707137000,0,"R",120,17179870099,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712696897000,0,6225000,6824712703122000,0,"R",120,17179870100,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712697128000,2,25635000,6824712722763000,0,"R",120,17179870102,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712703184000,0,133000,6824712703317000,0,"R",120,17179870104,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712703389000,0,49000,6824712703438000,0,"R",120,17179870107,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712704839000,0,628000,6824712705467000,0,"R",120,17179870116,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712706447000,0,873000,6824712707320000,0,"R",120,17179870125,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712707194000,1,15412000,6824712722606000,0,"R",120,17179870127,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712708400000,0,15285000,6824712723685000,0,"R",120,17179870137,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712722715000,1,79000,6824712722794000,0,"R",120,17179870139,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712722836000,2,5437000,6824712728273000,0,"R",120,17179870142,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712722858000,1,2789000,6824712725647000,0,"R",120,17179870143,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712723833000,0,828000,6824712724661000,0,"R",120,17179870146,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712723898000,3,34414000,6824712758312000,0,"R",120,17179870147,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712725583000,0,365000,6824712725948000,0,"R",120,17179870152,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712726077000,0,1250000,6824712727327000,0,"R",120,17179870155,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712726130000,1,1587000,6824712727717000,0,"R",120,17179870156,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712726449000,4,657913000,6824713384362000,0,"R",120,17179870158,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712726904000,5,48000,6824712726952000,0,"R",120,17179870160,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712726990000,5,678798000,6824713405788000,0,"R",120,17179870162,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712727505000,0,702000,6824712728207000,0,"R",120,17179870164,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712728067000,1,2263000,6824712730330000,0,"R",120,17179870167,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712728110000,6,110547000,6824712838657000,0,"R",120,17179870168,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712728361000,2,33537000,6824712761898000,0,"R",120,17179870171,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712730044000,7,136266000,6824712866310000,0,"R",120,17179870173,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712730357000,0,484000,6824712730841000,0,"R",120,17179870175,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712730644000,1,567000,6824712731211000,0,"R",120,17179870176,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712731023000,0,2119000,6824712733142000,0,"R",120,17179870178,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712731306000,1,27902000,6824712759208000,0,"R",120,17179870180,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712733332000,0,25059000,6824712758391000,0,"R",120,17179870182,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712758468000,3,38802000,6824712797270000,0,"R",120,17179870186,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712759061000,0,699000,6824712759760000,0,"R",120,17179870188,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712759697000,1,1610000,6824712761307000,0,"R",120,17179870190,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712759891000,0,227000,6824712760118000,0,"R",120,17179870192,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712760681000,0,231000,6824712760912000,0,"R",120,17179870195,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712761094000,0,708000,6824712761802000,0,"R",120,17179870197,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712761670000,1,2291000,6824712763961000,0,"R",120,17179870199,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712761990000,2,35024000,6824712797014000,0,"R",120,17179870202,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712763992000,0,457000,6824712764449000,0,"R",120,17179870204,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712764273000,1,539000,6824712764812000,0,"R",120,17179870205,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712764631000,0,30567000,6824712795198000,0,"R",120,17179870207,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712764907000,1,30302000,6824712795209000,0,"R",120,17179870209,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712795372000,1,877000,6824712796249000,0,"R",120,17179870212,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712796917000,0,862000,6824712797779000,0,"R",120,17179870216,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712796932000,1,4294000,6824712801226000,0,"R",120,17179870217,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712797629000,2,32555000,6824712830184000,0,"R",120,17179870221,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712797866000,0,2676000,6824712800542000,0,"R",120,17179870223,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712800521000,3,61041000,6824712861562000,0,"R",120,17179870224,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712800939000,0,790000,6824712801729000,0,"R",120,17179870226,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712801429000,1,28175000,6824712829604000,0,"R",120,17179870228,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712801817000,0,26133000,6824712827950000,0,"R",120,17179870230,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712829427000,0,87000,6824712829514000,0,"R",120,17179870233,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712829897000,0,1050000,6824712830947000,0,"R",120,17179870237,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712830375000,1,1386000,6824712831761000,0,"R",120,17179870239,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712830486000,2,1407000,6824712831893000,0,"R",120,17179870240,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712831478000,0,3444000,6824712834922000,0,"R",120,17179870242,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712831979000,2,9415000,6824712841394000,0,"R",120,17179870245,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712834889000,1,707000,6824712835596000,0,"R",120,17179870246,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712835320000,0,775000,6824712836095000,0,"R",120,17179870248,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712835797000,1,24848000,6824712860645000,0,"R",120,17179870250,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712836188000,0,23047000,6824712859235000,0,"R",120,17179870252,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712838850000,6,70000,6824712838920000,0,"R",120,17179870254,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712838969000,6,3751000,6824712842720000,0,"R",120,17179870256,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712841559000,2,3497000,6824712845056000,0,"R",120,17179870258,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712843587000,6,2780000,6824712846367000,0,"R",120,17179870261,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712847128000,6,206037000,6824713053165000,0,"R",120,17179870265,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712861259000,0,553000,6824712861812000,0,"R",120,17179870278,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712861354000,1,1038000,6824712862392000,0,"R",120,17179870279,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712861731000,3,1521000,6824712863252000,0,"R",120,17179870281,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712862035000,0,716000,6824712862751000,0,"R",120,17179870283,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712862883000,1,3367000,6824712866250000,0,"R",120,17179870286,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712863545000,3,13874000,6824712877419000,0,"R",120,17179870291,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712865994000,0,1047000,6824712867041000,0,"R",120,17179870296,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712866384000,7,6718000,6824712873102000,0,"R",120,17179870299,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712866837000,1,771000,6824712867608000,0,"R",120,17179870300,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712867326000,0,9974000,6824712877300000,0,"R",120,17179870302,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712867794000,1,62000,6824712867856000,0,"R",120,17179870305,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712868783000,1,1322000,6824712870105000,0,"R",120,17179870318,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712870444000,1,20085000,6824712890529000,0,"R",120,17179870328,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712873174000,7,5793000,6824712878967000,0,"R",120,17179870330,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712877456000,0,6419000,6824712883875000,0,"R",120,17179870338,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712877608000,3,13785000,6824712891393000,0,"R",120,17179870341,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712879041000,7,22599000,6824712901640000,0,"R",120,17179870344,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712883950000,0,6876000,6824712890826000,0,"R",120,17179870349,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712890590000,1,2884000,6824712893474000,0,"R",120,17179870351,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712890978000,0,595000,6824712891573000,0,"R",120,17179870355,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712891451000,3,4407000,6824712895858000,0,"R",120,17179870358,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712891613000,0,803000,6824712892416000,0,"R",120,17179870360,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712893321000,0,850000,6824712894171000,0,"R",120,17179870363,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712894040000,1,1068000,6824712895108000,0,"R",120,17179870365,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712894282000,0,714000,6824712894996000,0,"R",120,17179870367,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712895136000,0,301000,6824712895437000,0,"R",120,17179870370,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712895518000,1,2511000,6824712898029000,0,"R",120,17179870372,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712895913000,3,20866000,6824712916779000,0,"R",120,17179870374,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712897917000,0,362000,6824712898279000,0,"R",120,17179870379,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712898359000,1,40000,6824712898399000,0,"R",120,17179870382,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712898452000,1,28312000,6824712926764000,0,"R",120,17179870384,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712898460000,0,1923000,6824712900383000,0,"R",120,17179870385,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712900434000,0,6845000,6824712907279000,0,"R",120,17179870389,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712901712000,7,80781000,6824712982493000,0,"R",120,17179870391,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712907413000,0,51000,6824712907464000,0,"R",120,17179870397,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712907491000,0,6442000,6824712913933000,0,"R",120,17179870400,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712914017000,0,1135000,6824712915152000,0,"R",120,17179870436,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712915191000,0,2005000,6824712917196000,0,"R",120,17179870441,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712916868000,3,6871000,6824712923739000,0,"R",120,17179870444,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712917234000,0,3105000,6824712920339000,0,"R",120,17179870446,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712920749000,0,63000,6824712920812000,0,"R",120,17179870454,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712921312000,2,8350000,6824712929662000,0,"R",120,17179870469,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712921771000,0,337000,6824712922108000,0,"R",120,17179870473,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712923366000,0,2472000,6824712925838000,0,"R",120,17179870478,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712923868000,3,6431000,6824712930299000,0,"R",120,17179870481,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712926546000,0,967000,6824712927513000,0,"R",120,17179870485,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712927351000,1,1624000,6824712928975000,0,"R",120,17179870489,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712927602000,0,969000,6824712928571000,0,"R",120,17179870491,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712928663000,0,909000,6824712929572000,0,"R",120,17179870493,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712929270000,1,2298000,6824712931568000,0,"R",120,17179870495,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712929691000,2,2432000,6824712932123000,0,"R",120,17179870498,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712930375000,3,34073000,6824712964448000,0,"R",120,17179870501,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712931425000,0,319000,6824712931744000,0,"R",120,17179870502,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712931791000,1,1518000,6824712933309000,0,"R",120,17179870505,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712931846000,0,29956000,6824712961802000,0,"R",120,17179870506,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712932156000,2,1529000,6824712933685000,0,"R",120,17179870508,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712933364000,1,935000,6824712934299000,0,"R",120,17179870510,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712933933000,2,27866000,6824712961799000,0,"R",120,17179870512,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712934318000,1,7968000,6824712942286000,0,"R",120,17179870514,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712942956000,1,19657000,6824712962613000,0,"R",120,17179870518,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712962584000,2,967000,6824712963551000,0,"R",120,17179870526,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712964069000,2,11256000,6824712975325000,0,"R",120,17179870534,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712964382000,0,882000,6824712965264000,0,"R",120,17179870537,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712965093000,3,29801000,6824712994894000,0,"R",120,17179870540,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712965362000,0,9149000,6824712974511000,0,"R",120,17179870542,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712975026000,0,904000,6824712975930000,0,"R",120,17179870546,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712975649000,2,11143000,6824712986792000,0,"R",120,17179870548,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712976043000,0,5748000,6824712981791000,0,"R",120,17179870550,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712982567000,7,268581000,6824713251148000,0,"R",120,17179870561,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712984800000,0,3033000,6824712987833000,0,"R",120,17179870571,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712986874000,2,6897000,6824712993771000,0,"R",120,17179870580,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712988439000,0,4499000,6824712992938000,0,"R",120,17179870585,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712993090000,0,998000,6824712994088000,0,"R",120,17179870596,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712993860000,2,587000,6824712994447000,0,"R",120,17179870599,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712994488000,2,1596000,6824712996084000,0,"R",120,17179870604,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712994664000,0,752000,6824712995416000,0,"R",120,17179870605,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712995124000,3,1089000,6824712996213000,0,"R",120,17179870607,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712995804000,0,2854000,6824712998658000,0,"R",120,17179870609,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712996274000,3,31193000,6824713027467000,0,"R",120,17179870612,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712998591000,2,346000,6824712998937000,0,"R",120,17179870617,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712999037000,0,34000,6824712999071000,0,"R",120,17179870620,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712999133000,0,22793000,6824713021926000,0,"R",120,17179870622,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824712999139000,2,28073000,6824713027212000,0,"R",120,17179870623,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713021197000,1,5881000,6824713027078000,0,"R",120,17179870643,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713027299000,1,655000,6824713027954000,0,"R",120,17179870664,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713027646000,3,1029000,6824713028675000,0,"R",120,17179870666,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713027659000,2,901000,6824713028560000,0,"R",120,17179870667,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713028268000,1,2352000,6824713030620000,0,"R",120,17179870669,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713028709000,3,34349000,6824713063058000,0,"R",120,17179870672,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713030474000,2,705000,6824713031179000,0,"R",120,17179870675,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713030894000,1,696000,6824713031590000,0,"R",120,17179870677,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713031316000,2,29313000,6824713060629000,0,"R",120,17179870679,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713031633000,1,2153000,6824713033786000,0,"R",120,17179870681,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713033822000,1,6659000,6824713040481000,0,"R",120,17179870687,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713040527000,1,3210000,6824713043737000,0,"R",120,17179870693,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713043773000,1,3242000,6824713047015000,0,"R",120,17179870697,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713047063000,1,3191000,6824713050254000,0,"R",120,17179870702,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713050296000,1,4103000,6824713054399000,0,"R",120,17179870706,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713053812000,6,196550000,6824713250362000,0,"R",120,17179870709,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713054429000,1,6141000,6824713060570000,0,"R",120,17179870715,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713060647000,1,274000,6824713060921000,0,"R",120,17179870723,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713061024000,1,915000,6824713061939000,0,"R",120,17179870725,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713061060000,2,1313000,6824713062373000,0,"R",120,17179870726,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713062024000,1,1073000,6824713063097000,0,"R",120,17179870728,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713062699000,2,2701000,6824713065400000,0,"R",120,17179870730,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713063125000,1,518000,6824713063643000,0,"R",120,17179870733,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713064325000,1,588000,6824713064913000,0,"R",120,17179870737,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713064767000,3,15375000,6824713080142000,0,"R",120,17179870738,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713065150000,1,321000,6824713065471000,0,"R",120,17179870740,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713065497000,1,1148000,6824713066645000,0,"R",120,17179870743,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713065510000,2,1194000,6824713066704000,0,"R",120,17179870744,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713066709000,1,41000,6824713066750000,0,"R",120,17179870747,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713066757000,2,4703000,6824713071460000,0,"R",120,17179870749,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713066768000,1,4421000,6824713071189000,0,"R",120,17179870750,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713071298000,1,679000,6824713071977000,0,"R",120,17179870752,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713071872000,2,322000,6824713072194000,0,"R",120,17179870754,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713072061000,1,129000,6824713072190000,0,"R",120,17179870757,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713072210000,1,337000,6824713072547000,0,"R",120,17179870760,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713072555000,2,85000,6824713072640000,0,"R",120,17179870764,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713072661000,2,249000,6824713072910000,0,"R",120,17179870766,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713072967000,2,23000,6824713072990000,0,"R",120,17179870770,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713073089000,2,196000,6824713073285000,0,"R",120,17179870772,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713073288000,1,270000,6824713073558000,0,"R",120,17179870775,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713073402000,2,3701000,6824713077103000,0,"R",120,17179870776,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713073573000,1,3170000,6824713076743000,0,"R",120,17179870778,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713076891000,1,199000,6824713077090000,0,"R",120,17179870780,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713077106000,1,2331000,6824713079437000,0,"R",120,17179870783,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713077122000,2,2542000,6824713079664000,0,"R",120,17179870784,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713079518000,1,417000,6824713079935000,0,"R",120,17179870786,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713079957000,2,23000,6824713079980000,0,"R",120,17179870789,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713080000000,2,320000,6824713080320000,0,"R",120,17179870793,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713080166000,3,419000,6824713080585000,0,"R",120,17179870795,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713080388000,2,452000,6824713080840000,0,"R",120,17179870798,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713080611000,3,6419000,6824713087030000,0,"R",120,17179870801,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713080906000,2,345000,6824713081251000,0,"R",120,17179870804,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713081357000,2,6049000,6824713087406000,0,"R",120,17179870807,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713087092000,3,964000,6824713088056000,0,"R",120,17179870809,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713087690000,2,783000,6824713088473000,0,"R",120,17179870811,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713088078000,3,36000,6824713088114000,0,"R",120,17179870814,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713088125000,1,464000,6824713088589000,0,"R",120,17179870816,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713088518000,3,43000,6824713088561000,0,"R",120,17179870818,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713088595000,3,122000,6824713088717000,0,"R",120,17179870822,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713088600000,2,1021000,6824713089621000,0,"R",120,17179870823,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713088806000,3,14000,6824713088820000,0,"R",120,17179870826,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713088837000,3,135000,6824713088972000,0,"R",120,17179870828,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713089016000,3,47000,6824713089063000,0,"R",120,17179870830,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713089187000,3,4413000,6824713093600000,0,"R",120,17179870833,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713089748000,2,4425000,6824713094173000,0,"R",120,17179870836,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713093636000,3,1371000,6824713095007000,0,"R",120,17179870841,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713093973000,1,507000,6824713094480000,0,"R",120,17179870842,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713094540000,2,9000,6824713094549000,0,"R",120,17179870845,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713094579000,1,9000,6824713094588000,0,"R",120,17179870847,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713094662000,1,934000,6824713095596000,0,"R",120,17179870849,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713094675000,2,1004000,6824713095679000,0,"R",120,17179870850,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713095274000,3,5029000,6824713100303000,0,"R",120,17179870852,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713095696000,2,2152000,6824713097848000,0,"R",120,17179870855,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713097732000,1,701000,6824713098433000,0,"R",120,17179870858,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713098169000,2,724000,6824713098893000,0,"R",120,17179870860,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713098604000,1,39000,6824713098643000,0,"R",120,17179870862,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713098756000,1,488000,6824713099244000,0,"R",120,17179870864,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713098918000,2,480000,6824713099398000,0,"R",120,17179870866,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713099427000,1,51000,6824713099478000,0,"R",120,17179870869,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713100370000,3,9000,6824713100379000,0,"R",120,17179870872,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713100974000,2,632000,6824713101606000,0,"R",120,17179870881,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713101233000,1,787000,6824713102020000,0,"R",120,17179870882,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713101302000,3,605000,6824713101907000,0,"R",120,17179870884,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713101637000,2,471000,6824713102108000,0,"R",120,17179870886,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713102034000,3,8819000,6824713110853000,0,"R",120,17179870890,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713102285000,2,4714000,6824713106999000,0,"R",120,17179870892,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713107045000,2,1111000,6824713108156000,0,"R",120,17179870894,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713107809000,1,1784000,6824713109593000,0,"R",120,17179870896,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713108180000,2,1871000,6824713110051000,0,"R",120,17179870898,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713109748000,1,1604000,6824713111352000,0,"R",120,17179870900,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713110557000,2,728000,6824713111285000,0,"R",120,17179870902,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713110973000,3,1252000,6824713112225000,0,"R",120,17179870905,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713111320000,2,474000,6824713111794000,0,"R",120,17179870907,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713111929000,2,466000,6824713112395000,0,"R",120,17179870911,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713112344000,3,10051000,6824713122395000,0,"R",120,17179870915,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713112537000,2,766000,6824713113303000,0,"R",120,17179870917,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713113333000,2,3671000,6824713117004000,0,"R",120,17179870919,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713117046000,2,851000,6824713117897000,0,"R",120,17179870921,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713117584000,1,3602000,6824713121186000,0,"R",120,17179870923,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713117919000,2,3713000,6824713121632000,0,"R",120,17179870925,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713121340000,1,1525000,6824713122865000,0,"R",120,17179870927,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713122151000,2,341000,6824713122492000,0,"R",120,17179870929,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713122520000,3,1113000,6824713123633000,0,"R",120,17179870933,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713122523000,2,120000,6824713122643000,0,"R",120,17179870934,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713122718000,2,23000,6824713122741000,0,"R",120,17179870937,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713122757000,2,136000,6824713122893000,0,"R",120,17179870939,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713122927000,2,101000,6824713123028000,0,"R",120,17179870942,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713123146000,2,29000,6824713123175000,0,"R",120,17179870946,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713123365000,2,3548000,6824713126913000,0,"R",120,17179870948,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713123663000,3,3867000,6824713127530000,0,"R",120,17179870950,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713127421000,1,507000,6824713127928000,0,"R",120,17179870956,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713127574000,3,559000,6824713128133000,0,"R",120,17179870958,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713127949000,2,518000,6824713128467000,0,"R",120,17179870962,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713128159000,3,8000,6824713128167000,0,"R",120,17179870964,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713128180000,3,1804000,6824713129984000,0,"R",120,17179870966,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713128186000,1,2334000,6824713130520000,0,"R",120,17179870967,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713130048000,3,1593000,6824713131641000,0,"R",120,17179870971,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713130421000,2,758000,6824713131179000,0,"R",120,17179870973,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713131293000,2,593000,6824713131886000,0,"R",120,17179870979,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713131406000,1,828000,6824713132234000,0,"R",120,17179870980,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713131671000,3,95000,6824713131766000,0,"R",120,17179870982,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713131912000,2,1066000,6824713132978000,0,"R",120,17179870985,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713131949000,3,1543000,6824713133492000,0,"R",120,17179870986,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713133072000,1,496000,6824713133568000,0,"R",120,17179870989,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713133207000,2,70000,6824713133277000,0,"R",120,17179870991,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713133347000,2,160000,6824713133507000,0,"R",120,17179870994,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713133515000,2,65000,6824713133580000,0,"R",120,17179870997,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713133545000,3,9733000,6824713143278000,0,"R",120,17179870998,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713133706000,2,37000,6824713133743000,0,"R",120,17179871003,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713133883000,2,3063000,6824713136946000,0,"R",120,17179871005,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713136987000,2,3274000,6824713140261000,0,"R",120,17179871007,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713140298000,2,1112000,6824713141410000,0,"R",120,17179871009,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713141075000,1,1022000,6824713142097000,0,"R",120,17179871011,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713141428000,2,1111000,6824713142539000,0,"R",120,17179871013,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713142249000,1,2185000,6824713144434000,0,"R",120,17179871015,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713143057000,2,1528000,6824713144585000,0,"R",120,17179871017,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713143335000,3,606000,6824713143941000,0,"R",120,17179871019,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713144077000,3,438000,6824713144515000,0,"R",120,17179871022,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713144632000,3,139000,6824713144771000,0,"R",120,17179871028,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713144787000,2,2129000,6824713146916000,0,"R",120,17179871032,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713145328000,1,1971000,6824713147299000,0,"R",120,17179871034,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713146958000,2,950000,6824713147908000,0,"R",120,17179871036,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713147564000,1,6404000,6824713153968000,0,"R",120,17179871038,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713147928000,2,5718000,6824713153646000,0,"R",120,17179871040,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713153695000,2,724000,6824713154419000,0,"R",120,17179871042,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713154122000,1,591000,6824713154713000,0,"R",120,17179871044,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713154376000,3,873000,6824713155249000,0,"R",120,17179871046,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713154731000,1,1001000,6824713155732000,0,"R",120,17179871049,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713154983000,2,683000,6824713155666000,0,"R",120,17179871050,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713155387000,3,344000,6824713155731000,0,"R",120,17179871053,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713155744000,2,88000,6824713155832000,0,"R",120,17179871057,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713155750000,3,177000,6824713155927000,0,"R",120,17179871058,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713155937000,2,171000,6824713156108000,0,"R",120,17179871063,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713155943000,3,6823000,6824713162766000,0,"R",120,17179871064,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713156142000,2,27000,6824713156169000,0,"R",120,17179871066,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713156254000,2,364000,6824713156618000,0,"R",120,17179871069,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713156751000,2,4509000,6824713161260000,0,"R",120,17179871072,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713161041000,1,887000,6824713161928000,0,"R",120,17179871076,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713161719000,2,304000,6824713162023000,0,"R",120,17179871078,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713162068000,1,358000,6824713162426000,0,"R",120,17179871081,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713162470000,2,1183000,6824713163653000,0,"R",120,17179871083,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713162798000,3,917000,6824713163715000,0,"R",120,17179871085,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713163771000,3,581000,6824713164352000,0,"R",120,17179871088,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713164151000,1,689000,6824713164840000,0,"R",120,17179871089,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713164404000,2,820000,6824713165224000,0,"R",120,17179871091,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713164603000,3,1967000,6824713166570000,0,"R",120,17179871092,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713164960000,1,408000,6824713165368000,0,"R",120,17179871094,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713165255000,2,581000,6824713165836000,0,"R",120,17179871096,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713165554000,1,1573000,6824713167127000,0,"R",120,17179871098,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713167227000,1,42000,6824713167269000,0,"R",120,17179871106,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713167320000,1,35000,6824713167355000,0,"R",120,17179871108,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713167554000,2,634000,6824713168188000,0,"R",120,17179871113,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713167572000,1,42000,6824713167614000,0,"R",120,17179871114,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713167685000,1,45000,6824713167730000,0,"R",120,17179871116,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713168139000,1,2254000,6824713170393000,0,"R",120,17179871122,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713168306000,2,8737000,6824713177043000,0,"R",120,17179871124,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713170044000,3,912000,6824713170956000,0,"R",120,17179871126,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713170596000,1,7765000,6824713178361000,0,"R",120,17179871128,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713170987000,3,6024000,6824713177011000,0,"R",120,17179871130,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713177042000,3,653000,6824713177695000,0,"R",120,17179871132,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713177395000,2,498000,6824713177893000,0,"R",120,17179871134,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713177839000,3,5798000,6824713183637000,0,"R",120,17179871136,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713177928000,2,920000,6824713178848000,0,"R",120,17179871138,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713178565000,1,1277000,6824713179842000,0,"R",120,17179871140,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713179649000,2,622000,6824713180271000,0,"R",120,17179871142,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713180035000,1,535000,6824713180570000,0,"R",120,17179871145,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713180616000,1,116000,6824713180732000,0,"R",120,17179871148,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713180791000,1,34000,6824713180825000,0,"R",120,17179871152,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713180842000,1,170000,6824713181012000,0,"R",120,17179871154,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713181056000,1,406000,6824713181462000,0,"R",120,17179871156,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713181545000,1,414000,6824713181959000,0,"R",120,17179871159,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713182138000,1,1920000,6824713184058000,0,"R",120,17179871162,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713183695000,3,1423000,6824713185118000,0,"R",120,17179871164,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713184758000,1,3775000,6824713188533000,0,"R",120,17179871166,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713185140000,3,5295000,6824713190435000,0,"R",120,17179871168,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713188702000,1,1106000,6824713189808000,0,"R",120,17179871170,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713189589000,2,668000,6824713190257000,0,"R",120,17179871172,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713189979000,1,588000,6824713190567000,0,"R",120,17179871175,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713190488000,3,904000,6824713191392000,0,"R",120,17179871179,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713190608000,1,445000,6824713191053000,0,"R",120,17179871181,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713191095000,2,22000,6824713191117000,0,"R",120,17179871184,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713191163000,1,41000,6824713191204000,0,"R",120,17179871188,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713191285000,1,50000,6824713191335000,0,"R",120,17179871192,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713191418000,3,4124000,6824713195542000,0,"R",120,17179871195,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713191519000,1,2312000,6824713193831000,0,"R",120,17179871196,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713194488000,1,600000,6824713195088000,0,"R",120,17179871200,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713195206000,2,990000,6824713196196000,0,"R",120,17179871203,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713195229000,1,889000,6824713196118000,0,"R",120,17179871204,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713195814000,3,811000,6824713196625000,0,"R",120,17179871206,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713196215000,2,3119000,6824713199334000,0,"R",120,17179871209,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713196669000,3,1654000,6824713198323000,0,"R",120,17179871212,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713198160000,1,730000,6824713198890000,0,"R",120,17179871214,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713198632000,3,5040000,6824713203672000,0,"R",120,17179871216,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713199051000,1,29000,6824713199080000,0,"R",120,17179871218,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713199198000,1,5504000,6824713204702000,0,"R",120,17179871220,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713199363000,2,4705000,6824713204068000,0,"R",120,17179871222,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713203746000,3,1079000,6824713204825000,0,"R",120,17179871224,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713204504000,2,743000,6824713205247000,0,"R",120,17179871226,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713204853000,3,1654000,6824713206507000,0,"R",120,17179871229,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713204917000,1,1067000,6824713205984000,0,"R",120,17179871230,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713206054000,1,9000,6824713206063000,0,"R",120,17179871233,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713206213000,2,904000,6824713207117000,0,"R",120,17179871237,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713206550000,3,436000,6824713206986000,0,"R",120,17179871239,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713207100000,3,2871000,6824713209971000,0,"R",120,17179871242,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713207230000,2,623000,6824713207853000,0,"R",120,17179871245,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713208032000,2,2366000,6824713210398000,0,"R",120,17179871248,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713210026000,3,1318000,6824713211344000,0,"R",120,17179871250,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713211033000,2,6391000,6824713217424000,0,"R",120,17179871252,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713211370000,3,5656000,6824713217026000,0,"R",120,17179871254,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713217077000,3,770000,6824713217847000,0,"R",120,17179871256,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713217499000,2,6882000,6824713224381000,0,"R",120,17179871258,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713217866000,3,6087000,6824713223953000,0,"R",120,17179871260,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713224040000,3,879000,6824713224919000,0,"R",120,17179871262,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713224571000,1,589000,6824713225160000,0,"R",120,17179871265,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713224639000,2,1469000,6824713226108000,0,"R",120,17179871266,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713225193000,1,2096000,6824713227289000,0,"R",120,17179871269,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713225851000,3,755000,6824713226606000,0,"R",120,17179871270,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713226312000,2,35000,6824713226347000,0,"R",120,17179871273,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713226390000,2,562000,6824713226952000,0,"R",120,17179871276,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713226992000,3,43000,6824713227035000,0,"R",120,17179871282,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713227065000,2,78000,6824713227143000,0,"R",120,17179871284,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713227162000,3,446000,6824713227608000,0,"R",120,17179871287,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713227832000,3,1635000,6824713229467000,0,"R",120,17179871291,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713227855000,1,548000,6824713228403000,0,"R",120,17179871292,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713228188000,2,681000,6824713228869000,0,"R",120,17179871293,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713228538000,1,565000,6824713229103000,0,"R",120,17179871295,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713229143000,2,1167000,6824713230310000,0,"R",120,17179871298,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713229490000,3,1513000,6824713231003000,0,"R",120,17179871300,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713230355000,2,1542000,6824713231897000,0,"R",120,17179871302,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713230856000,1,642000,6824713231498000,0,"R",120,17179871303,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713231261000,3,5466000,6824713236727000,0,"R",120,17179871305,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713231636000,1,6415000,6824713238051000,0,"R",120,17179871307,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713231925000,2,4745000,6824713236670000,0,"R",120,17179871309,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713236740000,2,246000,6824713236986000,0,"R",120,17179871312,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713236994000,3,1550000,6824713238544000,0,"R",120,17179871314,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713237003000,2,3473000,6824713240476000,0,"R",120,17179871315,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713238261000,1,7678000,6824713245939000,0,"R",120,17179871317,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713239368000,3,631000,6824713239999000,0,"R",120,17179871319,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713240187000,3,594000,6824713240781000,0,"R",120,17179871322,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713240851000,3,284000,6824713241135000,0,"R",120,17179871326,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713241170000,3,27000,6824713241197000,0,"R",120,17179871329,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713241280000,3,763000,6824713242043000,0,"R",120,17179871332,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713242258000,3,5163000,6824713247421000,0,"R",120,17179871335,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713243338000,2,3652000,6824713246990000,0,"R",120,17179871337,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713246089000,1,9699000,6824713255788000,0,"R",120,17179871340,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713247041000,2,1235000,6824713248276000,0,"R",120,17179871342,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713247908000,3,4863000,6824713252771000,0,"R",120,17179871344,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713248301000,2,4882000,6824713253183000,0,"R",120,17179871346,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713250775000,6,72000,6824713250847000,0,"R",120,17179871348,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713250859000,0,61000,6824713250920000,0,"R",120,17179871351,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713251167000,0,342000,6824713251509000,0,"R",120,17179871354,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713251567000,0,7123000,6824713258690000,0,"R",120,17179871356,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713252050000,7,3110000,6824713255160000,0,"R",120,17179871357,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713253479000,3,642000,6824713254121000,0,"R",120,17179871365,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713253823000,2,1690000,6824713255513000,0,"R",120,17179871369,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713254215000,3,534000,6824713254749000,0,"R",120,17179871371,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713255006000,6,74037000,6824713329043000,0,"R",120,17179871374,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713255075000,3,5496000,6824713260571000,0,"R",120,17179871375,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713255222000,7,6211000,6824713261433000,0,"R",120,17179871378,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713258854000,0,1935000,6824713260789000,0,"R",120,17179871399,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713260138000,2,1298000,6824713261436000,0,"R",120,17179871404,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713260895000,0,931000,6824713261826000,0,"R",120,17179871408,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713261084000,3,994000,6824713262078000,0,"R",120,17179871409,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713261535000,7,2709000,6824713264244000,0,"R",120,17179871413,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713261690000,2,748000,6824713262438000,0,"R",120,17179871415,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713262238000,0,529000,6824713262767000,0,"R",120,17179871418,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713262397000,3,11856000,6824713274253000,0,"R",120,17179871419,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713262484000,2,2645000,6824713265129000,0,"R",120,17179871421,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713264299000,7,7113000,6824713271412000,0,"R",120,17179871427,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713264984000,0,719000,6824713265703000,0,"R",120,17179871431,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713265463000,2,364000,6824713265827000,0,"R",120,17179871434,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713265879000,2,818000,6824713266697000,0,"R",120,17179871437,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713265888000,0,23236000,6824713289124000,0,"R",120,17179871438,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713266852000,2,6898000,6824713273750000,0,"R",120,17179871442,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713271464000,7,1149000,6824713272613000,0,"R",120,17179871444,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713272663000,7,4324000,6824713276987000,0,"R",120,17179871449,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713274061000,2,6571000,6824713280632000,0,"R",120,17179871454,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713274413000,3,13234000,6824713287647000,0,"R",120,17179871457,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713277021000,7,53046000,6824713330067000,0,"R",120,17179871462,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713280854000,2,6307000,6824713287161000,0,"R",120,17179871472,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713287241000,2,805000,6824713288046000,0,"R",120,17179871474,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713287732000,3,6253000,6824713293985000,0,"R",120,17179871477,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713288065000,2,5544000,6824713293609000,0,"R",120,17179871480,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713293654000,2,1390000,6824713295044000,0,"R",120,17179871485,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713294028000,3,1525000,6824713295553000,0,"R",120,17179871488,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713294260000,0,501000,6824713294761000,0,"R",120,17179871492,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713295111000,0,16000,6824713295127000,0,"R",120,17179871496,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713295230000,2,1013000,6824713296243000,0,"R",120,17179871498,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713295240000,0,922000,6824713296162000,0,"R",120,17179871499,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713295879000,3,4297000,6824713300176000,0,"R",120,17179871501,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713296274000,2,1983000,6824713298257000,0,"R",120,17179871504,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713298120000,0,672000,6824713298792000,0,"R",120,17179871505,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713298517000,2,708000,6824713299225000,0,"R",120,17179871507,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713298945000,0,25615000,6824713324560000,0,"R",120,17179871509,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713299262000,2,1065000,6824713300327000,0,"R",120,17179871511,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713300224000,3,7418000,6824713307642000,0,"R",120,17179871513,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713300384000,2,6852000,6824713307236000,0,"R",120,17179871516,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713307305000,2,404000,6824713307709000,0,"R",120,17179871522,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713307714000,3,9638000,6824713317352000,0,"R",120,17179871526,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713307726000,2,5944000,6824713313670000,0,"R",120,17179871528,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713313701000,2,3234000,6824713316935000,0,"R",120,17179871530,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713316981000,2,773000,6824713317754000,0,"R",120,17179871532,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713317408000,3,6640000,6824713324048000,0,"R",120,17179871535,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713317769000,2,5877000,6824713323646000,0,"R",120,17179871538,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713323700000,2,893000,6824713324593000,0,"R",120,17179871542,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713324107000,3,3572000,6824713327679000,0,"R",120,17179871544,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713324610000,2,2330000,6824713326940000,0,"R",120,17179871547,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713324769000,0,2944000,6824713327713000,0,"R",120,17179871548,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713327297000,2,154000,6824713327451000,0,"R",120,17179871550,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713327482000,2,276000,6824713327758000,0,"R",120,17179871552,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713327722000,3,1218000,6824713328940000,0,"R",120,17179871555,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713327805000,0,570000,6824713328375000,0,"R",120,17179871557,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713327855000,1,1280000,6824713329135000,0,"R",120,17179871559,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713328360000,2,884000,6824713329244000,0,"R",120,17179871560,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713329288000,1,523000,6824713329811000,0,"R",120,17179871567,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713329337000,3,722000,6824713330059000,0,"R",120,17179871568,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713329488000,2,470000,6824713329958000,0,"R",120,17179871569,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713329623000,6,113000,6824713329736000,0,"R",120,17179871570,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713329691000,0,2040000,6824713331731000,0,"R",120,17179871572,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713329828000,1,2390000,6824713332218000,0,"R",120,17179871575,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713330007000,2,1145000,6824713331152000,0,"R",120,17179871578,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713330982000,7,71506000,6824713402488000,0,"R",120,17179871581,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713331579000,3,5762000,6824713337341000,0,"R",120,17179871589,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713331751000,2,33000,6824713331784000,0,"R",120,17179871592,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713331946000,0,667000,6824713332613000,0,"R",120,17179871596,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713332322000,1,30785000,6824713363107000,0,"R",120,17179871598,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713332435000,2,4516000,6824713336951000,0,"R",120,17179871599,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713332637000,0,5094000,6824713337731000,0,"R",120,17179871601,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713337023000,2,6609000,6824713343632000,0,"R",120,17179871605,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713337394000,3,14884000,6824713352278000,0,"R",120,17179871607,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713337898000,0,14895000,6824713352793000,0,"R",120,17179871609,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713343976000,2,7683000,6824713351659000,0,"R",120,17179871616,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713352497000,3,11953000,6824713364450000,0,"R",120,17179871638,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713352998000,0,8273000,6824713361271000,0,"R",120,17179871641,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713353740000,2,7167000,6824713360907000,0,"R",120,17179871644,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713361441000,2,95000,6824713361536000,0,"R",120,17179871655,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713361721000,0,80000,6824713361801000,0,"R",120,17179871661,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713361858000,0,46000,6824713361904000,0,"R",120,17179871663,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713361943000,0,43000,6824713361986000,0,"R",120,17179871665,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713362125000,0,232000,6824713362357000,0,"R",120,17179871668,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713362894000,0,738000,6824713363632000,0,"R",120,17179871671,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713363381000,1,919000,6824713364300000,0,"R",120,17179871676,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713363987000,0,2520000,6824713366507000,0,"R",120,17179871679,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713364515000,3,13500000,6824713378015000,0,"R",120,17179871683,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713366417000,1,380000,6824713366797000,0,"R",120,17179871684,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713366867000,0,5605000,6824713372472000,0,"R",120,17179871687,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713366940000,1,28138000,6824713395078000,0,"R",120,17179871688,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713367583000,2,5336000,6824713372919000,0,"R",120,17179871693,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713373008000,2,144000,6824713373152000,0,"R",120,17179871704,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713373603000,0,8922000,6824713382525000,0,"R",120,17179871710,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713377786000,2,2753000,6824713380539000,0,"R",120,17179871717,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713378126000,3,5664000,6824713383790000,0,"R",120,17179871719,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713381326000,2,1876000,6824713383202000,0,"R",120,17179871727,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713382812000,0,744000,6824713383556000,0,"R",120,17179871733,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713383850000,3,11312000,6824713395162000,0,"R",120,17179871743,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713383993000,0,6047000,6824713390040000,0,"R",120,17179871745,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713384386000,4,18375000,6824713402761000,0,"R",120,17179871747,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713387418000,2,3209000,6824713390627000,0,"R",120,17179871753,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713390360000,0,476000,6824713390836000,0,"R",120,17179871759,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713391067000,0,424000,6824713391491000,0,"R",120,17179871763,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713391567000,0,314000,6824713391881000,0,"R",120,17179871766,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713392131000,0,1225000,6824713393356000,0,"R",120,17179871770,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713393510000,0,41000,6824713393551000,0,"R",120,17179871777,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713393618000,0,173000,6824713393791000,0,"R",120,17179871780,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713394054000,0,41000,6824713394095000,0,"R",120,17179871786,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713394162000,0,179000,6824713394341000,0,"R",120,17179871788,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713394624000,0,46000,6824713394670000,0,"R",120,17179871792,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713394869000,0,625000,6824713395494000,0,"R",120,17179871794,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713395361000,1,1958000,6824713397319000,0,"R",120,17179871799,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713395484000,3,8157000,6824713403641000,0,"R",120,17179871800,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713397312000,0,423000,6824713397735000,0,"R",120,17179871804,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713397587000,1,483000,6824713398070000,0,"R",120,17179871806,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713397897000,0,2323000,6824713400220000,0,"R",120,17179871808,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713398144000,1,3426000,6824713401570000,0,"R",120,17179871810,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713400823000,0,363000,6824713401186000,0,"R",120,17179871821,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713401367000,0,329000,6824713401696000,0,"R",120,17179871824,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713402068000,0,1411000,6824713403479000,0,"R",120,17179871827,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713402539000,7,4230000,6824713406769000,0,"R",120,17179871829,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713402926000,4,350000,6824713403276000,0,"R",120,17179871831,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713402995000,6,4234000,6824713407229000,0,"R",120,17179871834,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713403422000,2,498000,6824713403920000,0,"R",120,17179871837,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713403682000,0,507000,6824713404189000,0,"R",120,17179871841,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713403737000,3,885000,6824713404622000,0,"R",120,17179871842,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713404450000,2,572000,6824713405022000,0,"R",120,17179871847,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713404641000,0,3779000,6824713408420000,0,"R",120,17179871851,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713404681000,3,582000,6824713405263000,0,"R",120,17179871852,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713404751000,1,4130000,6824713408881000,0,"R",120,17179871854,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713405518000,3,2372000,6824713407890000,0,"R",120,17179871859,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713405850000,5,1152000,6824713407002000,0,"R",120,17179871861,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713406779000,7,26544000,6824713433323000,0,"R",120,17179871863,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713407031000,5,7986000,6824713415017000,0,"R",120,17179871865,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713407325000,6,1876000,6824713409201000,0,"R",120,17179871867,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713408131000,3,8216000,6824713416347000,0,"R",120,17179871870,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713408655000,0,53000,6824713408708000,0,"R",120,17179871875,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713408752000,0,7418000,6824713416170000,0,"R",120,17179871877,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713408894000,2,1471000,6824713410365000,0,"R",120,17179871880,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713409261000,6,6003000,6824713415264000,0,"R",120,17179871882,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713410122000,1,6146000,6824713416268000,0,"R",120,17179871884,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713411774000,2,3953000,6824713415727000,0,"R",120,17179871886,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713415058000,5,871000,6824713415929000,0,"R",120,17179871888,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713415378000,6,2157000,6824713417535000,0,"R",120,17179871890,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713415951000,5,4014000,6824713419965000,0,"R",120,17179871894,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713416080000,2,579000,6824713416659000,0,"R",120,17179871895,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713416352000,0,4993000,6824713421345000,0,"R",120,17179871900,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713416403000,3,2160000,6824713418563000,0,"R",120,17179871901,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713416732000,1,521000,6824713417253000,0,"R",120,17179871904,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713416743000,2,74000,6824713416817000,0,"R",120,17179871905,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713417027000,2,1013000,6824713418040000,0,"R",120,17179871908,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713417653000,6,1707000,6824713419360000,0,"R",120,17179871911,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713418333000,2,395000,6824713418728000,0,"R",120,17179871914,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713418786000,3,2669000,6824713421455000,0,"R",120,17179871919,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713418804000,2,62000,6824713418866000,0,"R",120,17179871920,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713419039000,2,1615000,6824713420654000,0,"R",120,17179871923,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713419410000,6,798000,6824713420208000,0,"R",120,17179871926,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713419994000,5,3214000,6824713423208000,0,"R",120,17179871928,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713420298000,6,1655000,6824713421953000,0,"R",120,17179871930,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713420880000,2,66000,6824713420946000,0,"R",120,17179871933,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713421226000,2,3867000,6824713425093000,0,"R",120,17179871937,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713421438000,0,49000,6824713421487000,0,"R",120,17179871939,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713421530000,0,6608000,6824713428138000,0,"R",120,17179871942,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713421704000,3,2240000,6824713423944000,0,"R",120,17179871945,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713422005000,6,1245000,6824713423250000,0,"R",120,17179871947,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713423252000,5,4584000,6824713427836000,0,"R",120,17179871950,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713423331000,6,90000,6824713423421000,0,"R",120,17179871951,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713423452000,1,101000,6824713423553000,0,"R",120,17179871954,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713423511000,6,2065000,6824713425576000,0,"R",120,17179871955,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713423600000,1,800000,6824713424400000,0,"R",120,17179871957,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713424178000,3,631000,6824713424809000,0,"R",120,17179871960,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713425047000,3,3858000,6824713428905000,0,"R",120,17179871964,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713425287000,2,1587000,6824713426874000,0,"R",120,17179871968,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713425626000,6,2459000,6824713428085000,0,"R",120,17179871970,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713426977000,2,1675000,6824713428652000,0,"R",120,17179871972,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713427865000,5,2265000,6824713430130000,0,"R",120,17179871974,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713428184000,6,2870000,6824713431054000,0,"R",120,17179871977,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713428242000,0,898000,6824713429140000,0,"R",120,17179871978,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713429089000,2,544000,6824713429633000,0,"R",120,17179871983,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713429146000,3,734000,6824713429880000,0,"R",120,17179871985,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713429336000,0,735000,6824713430071000,0,"R",120,17179871987,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713429920000,2,86000,6824713430006000,0,"R",120,17179871991,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713430060000,1,492000,6824713430552000,0,"R",120,17179871993,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713430067000,2,113000,6824713430180000,0,"R",120,17179871994,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713430154000,5,3393000,6824713433547000,0,"R",120,17179871998,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713430226000,3,1706000,6824713431932000,0,"R",120,17179872000,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713430806000,1,695000,6824713431501000,0,"R",120,17179872004,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713431172000,6,1852000,6824713433024000,0,"R",120,17179872006,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713431861000,0,492000,6824713432353000,0,"R",120,17179872012,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713432023000,3,128000,6824713432151000,0,"R",120,17179872015,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713432059000,2,655000,6824713432714000,0,"R",120,17179872016,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713432353000,3,349000,6824713432702000,0,"R",120,17179872019,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713432549000,0,28791000,6824713461340000,0,"R",120,17179872021,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713432779000,3,31370000,6824713464149000,0,"R",120,17179872025,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713432880000,2,3801000,6824713436681000,0,"R",120,17179872026,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713433101000,6,1961000,6824713435062000,0,"R",120,17179872029,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713433594000,5,1241000,6824713434835000,0,"R",120,17179872032,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713434865000,5,2740000,6824713437605000,0,"R",120,17179872034,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713435163000,6,471000,6824713435634000,0,"R",120,17179872036,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713435683000,6,316000,6824713435999000,0,"R",120,17179872039,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713436036000,6,273000,6824713436309000,0,"R",120,17179872043,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713436338000,6,35000,6824713436373000,0,"R",120,17179872046,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713436416000,6,184000,6824713436600000,0,"R",120,17179872049,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713436653000,6,83000,6824713436736000,0,"R",120,17179872052,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713436770000,2,222000,6824713436992000,0,"R",120,17179872055,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713436952000,6,678000,6824713437630000,0,"R",120,17179872056,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713437040000,2,6321000,6824713443361000,0,"R",120,17179872058,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713437635000,5,3002000,6824713440637000,0,"R",120,17179872061,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713437712000,6,15000,6824713437727000,0,"R",120,17179872062,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713437741000,6,40000,6824713437781000,0,"R",120,17179872064,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713437809000,6,39000,6824713437848000,0,"R",120,17179872067,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713437873000,6,136000,6824713438009000,0,"R",120,17179872069,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713438038000,6,283000,6824713438321000,0,"R",120,17179872074,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713438341000,6,34000,6824713438375000,0,"R",120,17179872076,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713438404000,6,71000,6824713438475000,0,"R",120,17179872078,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713438518000,6,10000,6824713438528000,0,"R",120,17179872082,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713438571000,6,2294000,6824713440865000,0,"R",120,17179872084,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713440667000,5,2936000,6824713443603000,0,"R",120,17179872086,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713440949000,6,533000,6824713441482000,0,"R",120,17179872088,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713441530000,6,315000,6824713441845000,0,"R",120,17179872091,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713441878000,6,270000,6824713442148000,0,"R",120,17179872095,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713442164000,6,35000,6824713442199000,0,"R",120,17179872098,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713442225000,6,51000,6824713442276000,0,"R",120,17179872100,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713442320000,6,184000,6824713442504000,0,"R",120,17179872103,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713442549000,6,1704000,6824713444253000,0,"R",120,17179872106,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713443453000,2,362000,6824713443815000,0,"R",120,17179872108,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713443764000,5,254000,6824713444018000,0,"R",120,17179872110,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713443864000,2,6152000,6824713450016000,0,"R",120,17179872112,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713444047000,5,6341000,6824713450388000,0,"R",120,17179872114,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713444335000,6,323000,6824713444658000,0,"R",120,17179872116,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713444705000,6,416000,6824713445121000,0,"R",120,17179872119,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713445165000,6,50000,6824713445215000,0,"R",120,17179872123,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713445251000,6,106000,6824713445357000,0,"R",120,17179872126,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713445395000,6,2679000,6824713448074000,0,"R",120,17179872129,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713447869000,7,782000,6824713448651000,0,"R",120,17179872131,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713448159000,6,279000,6824713448438000,0,"R",120,17179872133,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713448485000,6,380000,6824713448865000,0,"R",120,17179872136,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713448899000,6,269000,6824713449168000,0,"R",120,17179872140,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713449195000,6,48000,6824713449243000,0,"R",120,17179872143,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713449287000,6,389000,6824713449676000,0,"R",120,17179872146,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713449727000,6,349000,6824713450076000,0,"R",120,17179872149,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713450111000,2,11329000,6824713461440000,0,"R",120,17179872152,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713450163000,6,2199000,6824713452362000,0,"R",120,17179872153,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713450401000,5,6481000,6824713456882000,0,"R",120,17179872155,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713452193000,7,989000,6824713453182000,0,"R",120,17179872157,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713452449000,6,485000,6824713452934000,0,"R",120,17179872159,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713452981000,6,601000,6824713453582000,0,"R",120,17179872162,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713453628000,6,571000,6824713454199000,0,"R",120,17179872166,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713454244000,6,182000,6824713454426000,0,"R",120,17179872170,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713454471000,6,1697000,6824713456168000,0,"R",120,17179872173,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713455964000,7,1116000,6824713457080000,0,"R",120,17179872175,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713456251000,6,535000,6824713456786000,0,"R",120,17179872177,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713456833000,6,411000,6824713457244000,0,"R",120,17179872182,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713456897000,5,644000,6824713457541000,0,"R",120,17179872184,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713457314000,6,585000,6824713457899000,0,"R",120,17179872187,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713457549000,5,2749000,6824713460298000,0,"R",120,17179872191,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713457945000,6,5819000,6824713463764000,0,"R",120,17179872197,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713460132000,7,539000,6824713460671000,0,"R",120,17179872201,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713460395000,5,1447000,6824713461842000,0,"R",120,17179872203,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713461361000,7,250000,6824713461611000,0,"R",120,17179872212,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713461449000,0,460000,6824713461909000,0,"R",120,17179872214,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713461813000,2,364000,6824713462177000,0,"R",120,17179872219,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713461891000,5,1341000,6824713463232000,0,"R",120,17179872221,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713461977000,0,38000,6824713462015000,0,"R",120,17179872223,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713462129000,1,262000,6824713462391000,0,"R",120,17179872225,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713462177000,0,142000,6824713462319000,0,"R",120,17179872227,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713462432000,2,1186000,6824713463618000,0,"R",120,17179872230,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713462466000,1,2550000,6824713465016000,0,"R",120,17179872231,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713463241000,5,334000,6824713463575000,0,"R",120,17179872233,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713463589000,5,243000,6824713463832000,0,"R",120,17179872235,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713463834000,6,2237000,6824713466071000,0,"R",120,17179872239,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713463837000,5,1034000,6824713464871000,0,"R",120,17179872240,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713464109000,0,488000,6824713464597000,0,"R",120,17179872241,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713464139000,2,5608000,6824713469747000,0,"R",120,17179872242,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713464431000,3,3478000,6824713467909000,0,"R",120,17179872244,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713464647000,7,582000,6824713465229000,0,"R",120,17179872247,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713464769000,0,2190000,6824713466959000,0,"R",120,17179872248,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713464956000,5,693000,6824713465649000,0,"R",120,17179872250,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713465107000,1,1435000,6824713466542000,0,"R",120,17179872252,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713465582000,7,689000,6824713466271000,0,"R",120,17179872257,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713465669000,5,418000,6824713466087000,0,"R",120,17179872259,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713466080000,4,812000,6824713466892000,0,"R",120,17179872261,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713466087000,6,4893000,6824713470980000,0,"R",120,17179872262,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713466095000,5,2929000,6824713469024000,0,"R",120,17179872264,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713467005000,4,1148000,6824713468153000,0,"R",120,17179872274,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713467020000,0,1748000,6824713468768000,0,"R",120,17179872275,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713468013000,3,1027000,6824713469040000,0,"R",120,17179872281,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713468683000,4,29000,6824713468712000,0,"R",120,17179872288,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713468783000,4,263000,6824713469046000,0,"R",120,17179872292,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713468839000,0,3202000,6824713472041000,0,"R",120,17179872293,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713469089000,4,153000,6824713469242000,0,"R",120,17179872297,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713469111000,3,1771000,6824713470882000,0,"R",120,17179872298,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713469256000,4,2174000,6824713471430000,0,"R",120,17179872300,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713469815000,2,281000,6824713470096000,0,"R",120,17179872302,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713469932000,5,770000,6824713470702000,0,"R",120,17179872305,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713470126000,1,2368000,6824713472494000,0,"R",120,17179872307,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713470745000,5,381000,6824713471126000,0,"R",120,17179872309,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713470944000,3,15328000,6824713486272000,0,"R",120,17179872311,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713471089000,6,2971000,6824713474060000,0,"R",120,17179872313,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713471215000,5,687000,6824713471902000,0,"R",120,17179872315,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713471676000,4,2529000,6824713474205000,0,"R",120,17179872317,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713471970000,5,263000,6824713472233000,0,"R",120,17179872319,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713472291000,0,508000,6824713472799000,0,"R",120,17179872323,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713472590000,1,47000,6824713472637000,0,"R",120,17179872325,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713472842000,1,2946000,6824713475788000,0,"R",120,17179872330,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713472860000,0,44000,6824713472904000,0,"R",120,17179872331,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713472979000,0,453000,6824713473432000,0,"R",120,17179872333,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713473117000,5,861000,6824713473978000,0,"R",120,17179872335,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713473673000,0,946000,6824713474619000,0,"R",120,17179872338,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713473866000,2,283000,6824713474149000,0,"R",120,17179872339,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713474198000,2,596000,6824713474794000,0,"R",120,17179872343,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713474304000,6,2488000,6824713476792000,0,"R",120,17179872345,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713474354000,4,1066000,6824713475420000,0,"R",120,17179872346,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713474837000,0,521000,6824713475358000,0,"R",120,17179872350,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713474875000,2,189000,6824713475064000,0,"R",120,17179872351,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713475431000,4,340000,6824713475771000,0,"R",120,17179872359,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713475568000,0,10190000,6824713485758000,0,"R",120,17179872362,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713475569000,2,10187000,6824713485756000,0,"R",120,17179872363,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713475869000,4,1395000,6824713477264000,0,"R",120,17179872366,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713475877000,1,621000,6824713476498000,0,"R",120,17179872367,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713476667000,5,361000,6824713477028000,0,"R",120,17179872371,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713476822000,6,7677000,6824713484499000,0,"R",120,17179872374,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713476852000,1,9339000,6824713486191000,0,"R",120,17179872375,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713477161000,7,61280000,6824713538441000,0,"R",120,17179872378,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713477304000,4,31231000,6824713508535000,0,"R",120,17179872380,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713484448000,5,365000,6824713484813000,0,"R",120,17179872382,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713484522000,6,6802000,6824713491324000,0,"R",120,17179872384,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713484849000,5,6226000,6824713491075000,0,"R",120,17179872386,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713485915000,2,6523000,6824713492438000,0,"R",120,17179872389,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713485915000,0,9244000,6824713495159000,0,"R",120,17179872390,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713486291000,1,9985000,6824713496276000,0,"R",120,17179872393,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713486366000,3,6074000,6824713492440000,0,"R",120,17179872394,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713491133000,5,6463000,6824713497596000,0,"R",120,17179872396,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713491378000,6,47434000,6824713538812000,0,"R",120,17179872398,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713492655000,3,6627000,6824713499282000,0,"R",120,17179872401,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713492656000,2,2845000,6824713495501000,0,"R",120,17179872402,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713495302000,0,61000,6824713495363000,0,"R",120,17179872404,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713495425000,0,586000,6824713496011000,0,"R",120,17179872406,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713496076000,2,458000,6824713496534000,0,"R",120,17179872409,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713496275000,0,505000,6824713496780000,0,"R",120,17179872410,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713496792000,1,472000,6824713497264000,0,"R",120,17179872414,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713496881000,0,83000,6824713496964000,0,"R",120,17179872415,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713496992000,2,10168000,6824713507160000,0,"R",120,17179872417,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713497029000,0,2730000,6824713499759000,0,"R",120,17179872418,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713497621000,5,6805000,6824713504426000,0,"R",120,17179872421,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713499302000,1,572000,6824713499874000,0,"R",120,17179872423,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713499610000,3,7250000,6824713506860000,0,"R",120,17179872424,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713500026000,0,6835000,6824713506861000,0,"R",120,17179872427,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713500028000,1,7524000,6824713507552000,0,"R",120,17179872428,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713504822000,5,26596000,6824713531418000,0,"R",120,17179872431,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713507151000,3,22498000,6824713529649000,0,"R",120,17179872434,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713507151000,0,1456000,6824713508607000,0,"R",120,17179872435,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713507259000,2,10658000,6824713517917000,0,"R",120,17179872437,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713507988000,1,16424000,6824713524412000,0,"R",120,17179872439,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713508663000,0,4135000,6824713512798000,0,"R",120,17179872442,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713508785000,4,35595000,6824713544380000,0,"R",120,17179872443,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713513035000,0,4264000,6824713517299000,0,"R",120,17179872445,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713518082000,0,5664000,6824713523746000,0,"R",120,17179872451,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713518220000,2,10550000,6824713528770000,0,"R",120,17179872453,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713524059000,0,4757000,6824713528816000,0,"R",120,17179872458,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713524499000,1,4727000,6824713529226000,0,"R",120,17179872460,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713529360000,1,961000,6824713530321000,0,"R",120,17179872466,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713530217000,3,33925000,6824713564142000,0,"R",120,17179872476,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713530327000,0,1013000,6824713531340000,0,"R",120,17179872479,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713530415000,2,1002000,6824713531417000,0,"R",120,17179872480,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713531384000,1,2683000,6824713534067000,0,"R",120,17179872483,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713531506000,2,8373000,6824713539879000,0,"R",120,17179872486,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713534099000,0,433000,6824713534532000,0,"R",120,17179872488,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713534377000,1,510000,6824713534887000,0,"R",120,17179872489,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713534720000,0,2286000,6824713537006000,0,"R",120,17179872491,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713534972000,1,29038000,6824713564010000,0,"R",120,17179872493,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713537139000,0,2739000,6824713539878000,0,"R",120,17179872497,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713538554000,7,5437000,6824713543991000,0,"R",120,17179872499,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713538867000,6,4782000,6824713543649000,0,"R",120,17179872501,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713540211000,2,1202000,6824713541413000,0,"R",120,17179872507,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713540496000,0,316000,6824713540812000,0,"R",120,17179872512,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713540888000,0,6183000,6824713547071000,0,"R",120,17179872514,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713541459000,2,6115000,6824713547574000,0,"R",120,17179872517,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713543732000,6,730000,6824713544462000,0,"R",120,17179872529,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713544125000,7,6499000,6824713550624000,0,"R",120,17179872531,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713544477000,4,6494000,6824713550971000,0,"R",120,17179872534,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713544507000,6,5784000,6824713550291000,0,"R",120,17179872535,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713547389000,0,13607000,6824713560996000,0,"R",120,17179872540,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713547676000,2,15043000,6824713562719000,0,"R",120,17179872545,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713550371000,6,24532000,6824713574903000,0,"R",120,17179872547,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713550712000,7,23645000,6824713574357000,0,"R",120,17179872549,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713551019000,4,14066000,6824713565085000,0,"R",120,17179872551,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713562329000,0,966000,6824713563295000,0,"R",120,17179872560,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713563788000,2,972000,6824713564760000,0,"R",120,17179872569,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713564584000,1,2497000,6824713567081000,0,"R",120,17179872573,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713564620000,0,1978000,6824713566598000,0,"R",120,17179872575,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713564850000,2,3091000,6824713567941000,0,"R",120,17179872577,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713565599000,4,22373000,6824713587972000,0,"R",120,17179872579,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713566715000,0,1121000,6824713567836000,0,"R",120,17179872583,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713567611000,1,1518000,6824713569129000,0,"R",120,17179872585,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713567817000,3,13943000,6824713581760000,0,"R",120,17179872586,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713567904000,0,700000,6824713568604000,0,"R",120,17179872588,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713568331000,2,4718000,6824713573049000,0,"R",120,17179872590,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713568822000,0,11756000,6824713580578000,0,"R",120,17179872592,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713569236000,1,12634000,6824713581870000,0,"R",120,17179872595,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713573162000,2,2555000,6824713575717000,0,"R",120,17179872597,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713574461000,7,12988000,6824713587449000,0,"R",120,17179872603,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713574951000,6,5495000,6824713580446000,0,"R",120,17179872605,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713575828000,2,22002000,6824713597830000,0,"R",120,17179872607,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713580478000,6,6544000,6824713587022000,0,"R",120,17179872611,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713581383000,0,892000,6824713582275000,0,"R",120,17179872614,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713581947000,3,16557000,6824713598504000,0,"R",120,17179872617,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713581961000,1,15601000,6824713597562000,0,"R",120,17179872618,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713582364000,0,14442000,6824713596806000,0,"R",120,17179872620,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713587068000,6,1013000,6824713588081000,0,"R",120,17179872629,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713587532000,7,6610000,6824713594142000,0,"R",120,17179872631,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713588023000,4,6549000,6824713594572000,0,"R",120,17179872633,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713588105000,6,5555000,6824713593660000,0,"R",120,17179872635,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713593702000,6,41271000,6824713634973000,0,"R",120,17179872641,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713594196000,7,40777000,6824713634973000,0,"R",120,17179872643,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713594603000,4,40370000,6824713634973000,0,"R",120,17179872645,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713597480000,0,864000,6824713598344000,0,"R",120,17179872648,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713598080000,1,765000,6824713598845000,0,"R",120,17179872651,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713598609000,3,32422000,6824713631031000,0,"R",120,17179872654,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713598635000,2,932000,6824713599567000,0,"R",120,17179872655,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713599401000,1,2173000,6824713601574000,0,"R",120,17179872657,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713599657000,2,23565000,6824713623222000,0,"R",120,17179872659,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713601561000,0,678000,6824713602239000,0,"R",120,17179872660,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713601969000,1,395000,6824713602364000,0,"R",120,17179872662,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713602443000,1,27933000,6824713630376000,0,"R",120,17179872665,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713602448000,0,26982000,6824713629430000,0,"R",120,17179872666,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713623454000,2,5577000,6824713629031000,0,"R",120,17179872674,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713626993000,5,7817000,6824713634810000,0,"R",120,17179872680,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713630764000,1,886000,6824713631650000,0,"R",120,17179872686,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713631383000,0,2291000,6824713633674000,0,"R",120,17179872690,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713631536000,3,3437000,6824713634973000,0,"R",120,17179872691,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713633450000,1,1179000,6824713634629000,0,"R",120,17179872700,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713633887000,0,1086000,6824713634973000,0,"R",120,17179872703,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713634760000,1,213000,6824713634973000,0,"R",120,17179872705,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824713634973000,5,0,6824713634973000,0,"R",120,17179872709,"[NULL]","swapper/5",0,"[NULL]","[NULL]"
+6824711826499000,6,20000,6824711826519000,2,"S",100,17179869184,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824711828824000,6,43000,6824711828867000,2,"S",100,17179869215,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824711828950000,6,14000,6824711828964000,2,"S",100,17179869220,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824711828989000,6,9000,6824711828998000,2,"S",100,17179869223,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824711829100000,6,34000,6824711829134000,2,"S",100,17179869226,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824711829172000,6,16000,6824711829188000,2,"S",100,17179869228,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824711829222000,6,33000,6824711829255000,2,"S",100,17179869231,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824711829295000,6,13000,6824711829308000,2,"S",100,17179869234,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824711829402000,6,12000,6824711829414000,2,"S",100,17179869237,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824711829437000,6,7000,6824711829444000,2,"S",100,17179869240,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712838657000,6,193000,6824712838850000,2,"S",100,17179870253,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712842720000,6,303000,6824712843023000,2,"S",100,17179870259,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712846367000,6,406000,6824712846773000,2,"S",100,17179870263,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712867684000,1,110000,6824712867794000,2,"S",100,17179870304,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712867856000,1,140000,6824712867996000,2,"S",100,17179870306,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712868056000,1,59000,6824712868115000,2,"S",100,17179870308,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712868226000,1,78000,6824712868304000,2,"S",100,17179870311,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712868352000,1,57000,6824712868409000,2,"S",100,17179870313,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712868454000,1,72000,6824712868526000,2,"S",100,17179870315,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712870105000,1,117000,6824712870222000,2,"S",100,17179870321,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712870335000,1,43000,6824712870378000,2,"S",100,17179870326,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712908806000,2,188000,6824712908994000,2,"S",100,17179870403,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712911162000,2,10000,6824712911172000,2,"S",100,17179870426,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712911219000,2,22000,6824712911241000,2,"S",100,17179870428,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712920339000,0,118000,6824712920457000,2,"S",100,17179870449,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712920812000,0,59000,6824712920871000,2,"S",100,17179870455,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712920927000,0,28000,6824712920955000,2,"S",100,17179870458,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712921082000,0,68000,6824712921150000,2,"S",100,17179870463,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712921200000,0,48000,6824712921248000,2,"S",100,17179870465,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712921296000,0,38000,6824712921334000,2,"S",100,17179870468,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712922108000,0,39000,6824712922147000,2,"S",100,17179870474,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712961978000,0,108000,6824712962086000,2,"S",100,17179870521,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712962325000,0,174000,6824712962499000,2,"S",100,17179870523,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712963048000,1,140000,6824712963188000,2,"S",100,17179870528,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712984235000,1,175000,6824712984410000,2,"S",100,17179870567,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712985020000,1,73000,6824712985093000,2,"S",100,17179870572,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712985693000,1,141000,6824712985834000,2,"S",100,17179870574,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712985885000,1,79000,6824712985964000,2,"S",100,17179870576,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824712988528000,1,87000,6824712988615000,2,"S",100,17179870586,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713071977000,1,50000,6824713072027000,2,"S",100,17179870755,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713072190000,1,20000,6824713072210000,2,"S",100,17179870758,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713072498000,2,31000,6824713072529000,2,"S",100,17179870761,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713072640000,2,21000,6824713072661000,2,"S",100,17179870765,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713072910000,2,25000,6824713072935000,2,"S",100,17179870767,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713079935000,1,31000,6824713079966000,2,"S",100,17179870788,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713079980000,2,20000,6824713080000000,2,"S",100,17179870791,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713080320000,2,27000,6824713080347000,2,"S",100,17179870796,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713080585000,3,26000,6824713080611000,2,"S",100,17179870800,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713080840000,2,23000,6824713080863000,2,"S",100,17179870802,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713088473000,2,53000,6824713088526000,2,"S",100,17179870817,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713088561000,3,34000,6824713088595000,2,"S",100,17179870820,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713088717000,3,48000,6824713088765000,2,"S",100,17179870824,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713088820000,3,17000,6824713088837000,2,"S",100,17179870827,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713088972000,3,44000,6824713089016000,2,"S",100,17179870829,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713089063000,3,35000,6824713089098000,2,"S",100,17179870831,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713100303000,3,67000,6824713100370000,2,"S",100,17179870871,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713100379000,3,72000,6824713100451000,2,"S",100,17179870873,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713101255000,3,47000,6824713101302000,2,"S",100,17179870883,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713101907000,3,54000,6824713101961000,2,"S",100,17179870887,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713110853000,3,66000,6824713110919000,2,"S",100,17179870903,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713111285000,2,35000,6824713111320000,2,"S",100,17179870906,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713111794000,2,71000,6824713111865000,2,"S",100,17179870909,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713112225000,3,47000,6824713112272000,2,"S",100,17179870912,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713122395000,3,74000,6824713122469000,2,"S",100,17179870930,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713122492000,2,31000,6824713122523000,2,"S",100,17179870932,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713122643000,2,45000,6824713122688000,2,"S",100,17179870935,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713122741000,2,16000,6824713122757000,2,"S",100,17179870938,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713122893000,2,34000,6824713122927000,2,"S",100,17179870941,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713123028000,2,42000,6824713123070000,2,"S",100,17179870943,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713132978000,2,164000,6824713133142000,2,"S",100,17179870988,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713133277000,2,50000,6824713133327000,2,"S",100,17179870992,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713133507000,2,8000,6824713133515000,2,"S",100,17179870996,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713155731000,3,19000,6824713155750000,2,"S",100,17179871055,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713155832000,2,47000,6824713155879000,2,"S",100,17179871059,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713155927000,3,16000,6824713155943000,2,"S",100,17179871062,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713156108000,2,34000,6824713156142000,2,"S",100,17179871065,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713156169000,2,40000,6824713156209000,2,"S",100,17179871067,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713166570000,3,92000,6824713166662000,2,"S",100,17179871100,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713167127000,1,100000,6824713167227000,2,"S",100,17179871105,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713167269000,1,51000,6824713167320000,2,"S",100,17179871107,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713167355000,1,100000,6824713167455000,2,"S",100,17179871109,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713167518000,1,54000,6824713167572000,2,"S",100,17179871112,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713167614000,1,71000,6824713167685000,2,"S",100,17179871115,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713167730000,1,100000,6824713167830000,2,"S",100,17179871117,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713179842000,1,126000,6824713179968000,2,"S",100,17179871143,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713180570000,1,46000,6824713180616000,2,"S",100,17179871147,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713180732000,1,31000,6824713180763000,2,"S",100,17179871149,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713180825000,1,17000,6824713180842000,2,"S",100,17179871153,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713181012000,1,44000,6824713181056000,2,"S",100,17179871155,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713181462000,1,39000,6824713181501000,2,"S",100,17179871157,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713189808000,1,118000,6824713189926000,2,"S",100,17179871173,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713190567000,1,41000,6824713190608000,2,"S",100,17179871180,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713191053000,1,39000,6824713191092000,2,"S",100,17179871182,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713191115000,1,33000,6824713191148000,2,"S",100,17179871185,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713191204000,1,40000,6824713191244000,2,"S",100,17179871189,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713205984000,1,70000,6824713206054000,2,"S",100,17179871232,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713206063000,1,59000,6824713206122000,2,"S",100,17179871234,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713206507000,3,43000,6824713206550000,2,"S",100,17179871238,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713206986000,3,67000,6824713207053000,2,"S",100,17179871240,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713207117000,2,57000,6824713207174000,2,"S",100,17179871243,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713226108000,2,128000,6824713226236000,2,"S",100,17179871271,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713226347000,2,23000,6824713226370000,2,"S",100,17179871274,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713226949000,3,43000,6824713226992000,2,"S",100,17179871279,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713227035000,3,61000,6824713227096000,2,"S",100,17179871283,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713239999000,3,127000,6824713240126000,2,"S",100,17179871320,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713240781000,3,38000,6824713240819000,2,"S",100,17179871324,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713241135000,3,35000,6824713241170000,2,"S",100,17179871327,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713241197000,3,40000,6824713241237000,2,"S",100,17179871330,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713252771000,3,197000,6824713252968000,2,"S",100,17179871358,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713253154000,3,188000,6824713253342000,2,"S",100,17179871360,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713253410000,3,69000,6824713253479000,2,"S",100,17179871364,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713254121000,3,94000,6824713254215000,2,"S",100,17179871370,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713254749000,3,113000,6824713254862000,2,"S",100,17179871372,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713256945000,2,173000,6824713257118000,2,"S",100,17179871384,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713257177000,2,41000,6824713257218000,2,"S",100,17179871386,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713331386000,2,66000,6824713331452000,2,"S",100,17179871584,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713372919000,2,89000,6824713373008000,2,"S",100,17179871702,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713404622000,3,59000,6824713404681000,2,"S",100,17179871850,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713405263000,3,117000,6824713405380000,2,"S",100,17179871856,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713407890000,3,127000,6824713408017000,2,"S",100,17179871868,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713408420000,0,106000,6824713408526000,2,"S",100,17179871872,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713408591000,2,198000,6824713408789000,2,"S",100,17179871874,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713415727000,2,177000,6824713415904000,2,"S",100,17179871891,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713416347000,3,56000,6824713416403000,2,"S",100,17179871899,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713416659000,2,84000,6824713416743000,2,"S",100,17179871902,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713416817000,2,91000,6824713416908000,2,"S",100,17179871906,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713418040000,2,115000,6824713418155000,2,"S",100,17179871912,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713418563000,3,106000,6824713418669000,2,"S",100,17179871916,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713418728000,2,76000,6824713418804000,2,"S",100,17179871918,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713418866000,2,86000,6824713418952000,2,"S",100,17179871921,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713420654000,2,115000,6824713420769000,2,"S",100,17179871931,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713420946000,2,147000,6824713421093000,2,"S",100,17179871934,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713421455000,3,119000,6824713421574000,2,"S",100,17179871940,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713423944000,3,121000,6824713424065000,2,"S",100,17179871958,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713424809000,3,127000,6824713424936000,2,"S",100,17179871962,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713425093000,2,105000,6824713425198000,2,"S",100,17179871965,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713428905000,3,123000,6824713429028000,2,"S",100,17179871980,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713429880000,3,203000,6824713430083000,2,"S",100,17179871990,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713430552000,1,120000,6824713430672000,2,"S",100,17179872001,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713431501000,1,118000,6824713431619000,2,"S",100,17179872007,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713431932000,3,91000,6824713432023000,2,"S",100,17179872014,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713432151000,3,92000,6824713432243000,2,"S",100,17179872017,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713432702000,3,77000,6824713432779000,2,"S",100,17179872023,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713433024000,6,46000,6824713433070000,2,"S",100,17179872027,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713435634000,6,36000,6824713435670000,2,"S",100,17179872037,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713435999000,6,24000,6824713436023000,2,"S",100,17179872041,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713436309000,6,29000,6824713436338000,2,"S",100,17179872045,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713436373000,6,29000,6824713436402000,2,"S",100,17179872047,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713437727000,6,14000,6824713437741000,2,"S",100,17179872063,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713437781000,6,19000,6824713437800000,2,"S",100,17179872065,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713437848000,6,25000,6824713437873000,2,"S",100,17179872068,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713438009000,6,19000,6824713438028000,2,"S",100,17179872071,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713438321000,6,20000,6824713438341000,2,"S",100,17179872075,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713438375000,6,29000,6824713438404000,2,"S",100,17179872077,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713438475000,6,29000,6824713438504000,2,"S",100,17179872079,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713441482000,6,36000,6824713441518000,2,"S",100,17179872089,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713441845000,6,22000,6824713441867000,2,"S",100,17179872093,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713442148000,6,16000,6824713442164000,2,"S",100,17179872097,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713442199000,6,26000,6824713442225000,2,"S",100,17179872099,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713442276000,6,29000,6824713442305000,2,"S",100,17179872101,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713444658000,6,36000,6824713444694000,2,"S",100,17179872117,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713445121000,6,35000,6824713445156000,2,"S",100,17179872121,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713445215000,6,27000,6824713445242000,2,"S",100,17179872124,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713448438000,6,36000,6824713448474000,2,"S",100,17179872134,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713448865000,6,23000,6824713448888000,2,"S",100,17179872138,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713449168000,6,27000,6824713449195000,2,"S",100,17179872142,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713449243000,6,29000,6824713449272000,2,"S",100,17179872144,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713452934000,6,35000,6824713452969000,2,"S",100,17179872160,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713453582000,6,35000,6824713453617000,2,"S",100,17179872164,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713454199000,6,30000,6824713454229000,2,"S",100,17179872168,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713456786000,6,36000,6824713456822000,2,"S",100,17179872180,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713457500000,7,44000,6824713457544000,2,"S",100,17179872188,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713457839000,7,32000,6824713457871000,2,"S",100,17179872193,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713460671000,7,35000,6824713460706000,2,"S",100,17179872204,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713461029000,7,22000,6824713461051000,2,"S",100,17179872207,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713461331000,7,30000,6824713461361000,2,"S",100,17179872210,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713461611000,7,30000,6824713461641000,2,"S",100,17179872215,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713465229000,7,21000,6824713465250000,2,"S",100,17179872253,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713465553000,7,29000,6824713465582000,2,"S",100,17179872256,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713466271000,7,37000,6824713466308000,2,"S",100,17179872265,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713466638000,7,28000,6824713466666000,2,"S",100,17179872269,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713467587000,7,70000,6824713467657000,2,"S",100,17179872277,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713468153000,4,109000,6824713468262000,2,"R+",100,17179872282,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713468612000,4,48000,6824713468660000,2,"S",100,17179872286,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713468712000,4,53000,6824713468765000,2,"S",100,17179872289,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824713475420000,4,11000,6824713475431000,2,"S",100,17179872357,2,"kworker/u17:1",1134,"[NULL]","[NULL]"
+6824711826519000,6,69000,6824711826588000,3,"S",120,17179869185,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824711828867000,6,19000,6824711828886000,3,"S",120,17179869217,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824711828964000,6,21000,6824711828985000,3,"S",120,17179869221,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824711829188000,6,23000,6824711829211000,3,"S",120,17179869229,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824711829308000,6,19000,6824711829327000,3,"S",120,17179869235,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824711829414000,6,7000,6824711829421000,3,"S",120,17179869238,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824711829896000,6,16000,6824711829912000,3,"S",120,17179869244,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824711846655000,6,11000,6824711846666000,3,"S",120,17179869287,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824712843023000,6,564000,6824712843587000,3,"S",120,17179870260,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824712846773000,6,355000,6824712847128000,3,"S",120,17179870264,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713351649000,6,56000,6824713351705000,3,"S",120,17179871625,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713351956000,6,11000,6824713351967000,3,"S",120,17179871630,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713352244000,6,24000,6824713352268000,3,"S",120,17179871635,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713359927000,6,41000,6824713359968000,3,"S",120,17179871648,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713433070000,6,31000,6824713433101000,3,"S",120,17179872028,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713435670000,6,13000,6824713435683000,3,"S",120,17179872038,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713436023000,6,13000,6824713436036000,3,"S",120,17179872042,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713436402000,6,14000,6824713436416000,3,"S",120,17179872048,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713437800000,6,9000,6824713437809000,3,"S",120,17179872066,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713438028000,6,10000,6824713438038000,3,"S",120,17179872072,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713438504000,6,14000,6824713438518000,3,"S",120,17179872080,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713441518000,6,12000,6824713441530000,3,"S",120,17179872090,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713441867000,6,11000,6824713441878000,3,"S",120,17179872094,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713442305000,6,15000,6824713442320000,3,"S",120,17179872102,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713444694000,6,11000,6824713444705000,3,"S",120,17179872118,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713445156000,6,9000,6824713445165000,3,"S",120,17179872122,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713445242000,6,9000,6824713445251000,3,"S",120,17179872125,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713448474000,6,11000,6824713448485000,3,"S",120,17179872135,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713448888000,6,11000,6824713448899000,3,"S",120,17179872139,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713449272000,6,15000,6824713449287000,3,"S",120,17179872145,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713452969000,6,12000,6824713452981000,3,"S",120,17179872161,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713453617000,6,11000,6824713453628000,3,"S",120,17179872165,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713454229000,6,15000,6824713454244000,3,"S",120,17179872169,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824713456822000,6,11000,6824713456833000,3,"S",120,17179872181,3,"kworker/6:1",14833,"[NULL]","[NULL]"
+6824711826574000,2,0,6824711826574000,4,"[NULL]",120,17179869186,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824711828893000,2,0,6824711828893000,4,"[NULL]",120,17179869219,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824711828993000,2,0,6824711828993000,4,"[NULL]",120,17179869224,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824711829227000,2,0,6824711829227000,4,"[NULL]",120,17179869232,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824711829450000,2,0,6824711829450000,4,"[NULL]",120,17179869242,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712845056000,2,0,6824712845056000,4,"[NULL]",120,17179870262,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712849147000,2,0,6824712849147000,4,"[NULL]",120,17179870266,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712868223000,2,0,6824712868223000,4,"[NULL]",120,17179870310,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712868660000,2,0,6824712868660000,4,"[NULL]",120,17179870317,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712870331000,2,0,6824712870331000,4,"[NULL]",120,17179870325,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712909100000,2,0,6824712909100000,4,"[NULL]",120,17179870406,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712909817000,2,0,6824712909817000,4,"[NULL]",120,17179870416,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712910101000,2,0,6824712910101000,4,"[NULL]",120,17179870417,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712910177000,2,0,6824712910177000,4,"[NULL]",120,17179870418,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712910498000,2,0,6824712910498000,4,"[NULL]",120,17179870424,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712911480000,2,0,6824712911480000,4,"[NULL]",120,17179870432,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712920555000,0,0,6824712920555000,4,"[NULL]",120,17179870451,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712920963000,0,0,6824712920963000,4,"[NULL]",120,17179870461,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712921026000,0,0,6824712921026000,4,"[NULL]",120,17179870462,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712921375000,0,0,6824712921375000,4,"[NULL]",120,17179870471,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712922178000,0,0,6824712922178000,4,"[NULL]",120,17179870476,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712963693000,1,0,6824712963693000,4,"[NULL]",120,17179870532,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712964318000,1,0,6824712964318000,4,"[NULL]",120,17179870536,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712984575000,1,0,6824712984575000,4,"[NULL]",120,17179870570,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712986150000,1,0,6824712986150000,4,"[NULL]",120,17179870578,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712987385000,1,0,6824712987385000,4,"[NULL]",120,17179870582,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824712988684000,1,0,6824712988684000,4,"[NULL]",120,17179870588,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713072194000,2,0,6824713072194000,4,"[NULL]",120,17179870759,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713072547000,1,0,6824713072547000,4,"[NULL]",120,17179870763,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713072957000,1,0,6824713072957000,4,"[NULL]",120,17179870769,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713079994000,1,0,6824713079994000,4,"[NULL]",120,17179870792,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713080536000,1,0,6824713080536000,4,"[NULL]",120,17179870799,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713081062000,1,0,6824713081062000,4,"[NULL]",120,17179870805,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713088589000,1,0,6824713088589000,4,"[NULL]",120,17179870821,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713089216000,1,0,6824713089216000,4,"[NULL]",120,17179870834,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713100548000,3,0,6824713100548000,4,"[NULL]",120,17179870875,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713100655000,3,0,6824713100655000,4,"[NULL]",120,17179870878,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713100682000,3,0,6824713100682000,4,"[NULL]",120,17179870880,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713102020000,1,0,6824713102020000,4,"[NULL]",120,17179870889,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713111352000,1,0,6824713111352000,4,"[NULL]",120,17179870908,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713112309000,1,0,6824713112309000,4,"[NULL]",120,17179870914,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713122865000,1,0,6824713122865000,4,"[NULL]",120,17179870940,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713123128000,1,0,6824713123128000,4,"[NULL]",120,17179870945,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713133568000,1,0,6824713133568000,4,"[NULL]",120,17179870999,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713133683000,1,0,6824713133683000,4,"[NULL]",120,17179871002,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713144434000,1,0,6824713144434000,4,"[NULL]",120,17179871023,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713144585000,2,0,6824713144585000,4,"[NULL]",120,17179871026,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713144771000,3,0,6824713144771000,4,"[NULL]",120,17179871031,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713155732000,1,0,6824713155732000,4,"[NULL]",120,17179871056,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713155909000,1,0,6824713155909000,4,"[NULL]",120,17179871061,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713156561000,1,0,6824713156561000,4,"[NULL]",120,17179871070,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713166720000,3,0,6824713166720000,4,"[NULL]",120,17179871103,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713167465000,3,0,6824713167465000,4,"[NULL]",120,17179871111,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713168116000,3,0,6824713168116000,4,"[NULL]",120,17179871121,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713180271000,2,0,6824713180271000,4,"[NULL]",120,17179871146,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713180783000,2,0,6824713180783000,4,"[NULL]",120,17179871151,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713181884000,2,0,6824713181884000,4,"[NULL]",120,17179871160,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713190257000,2,0,6824713190257000,4,"[NULL]",120,17179871176,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713191117000,2,0,6824713191117000,4,"[NULL]",120,17179871186,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713191270000,2,0,6824713191270000,4,"[NULL]",120,17179871191,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713206179000,1,0,6824713206179000,4,"[NULL]",120,17179871236,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713207410000,1,0,6824713207410000,4,"[NULL]",120,17179871246,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713226606000,3,0,6824713226606000,4,"[NULL]",120,17179871277,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713227143000,2,0,6824713227143000,4,"[NULL]",120,17179871286,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713240476000,2,0,6824713240476000,4,"[NULL]",120,17179871323,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713241138000,2,0,6824713241138000,4,"[NULL]",120,17179871328,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713241658000,2,0,6824713241658000,4,"[NULL]",120,17179871333,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713253183000,2,0,6824713253183000,4,"[NULL]",120,17179871361,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713255513000,2,0,6824713255513000,4,"[NULL]",120,17179871379,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713257399000,2,0,6824713257399000,4,"[NULL]",120,17179871391,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713257519000,2,0,6824713257519000,4,"[NULL]",120,17179871392,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713257817000,2,0,6824713257817000,4,"[NULL]",120,17179871395,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713258143000,2,0,6824713258143000,4,"[NULL]",120,17179871397,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713331468000,2,0,6824713331468000,4,"[NULL]",120,17179871587,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713331539000,2,0,6824713331539000,4,"[NULL]",120,17179871588,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713331866000,2,0,6824713331866000,4,"[NULL]",120,17179871595,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713352509000,2,0,6824713352509000,4,"[NULL]",120,17179871639,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713353216000,2,0,6824713353216000,4,"[NULL]",120,17179871642,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713353520000,2,0,6824713353520000,4,"[NULL]",120,17179871643,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713362488000,2,0,6824713362488000,4,"[NULL]",120,17179871670,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713363168000,2,0,6824713363168000,4,"[NULL]",120,17179871673,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713364258000,2,0,6824713364258000,4,"[NULL]",120,17179871680,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713373152000,2,0,6824713373152000,4,"[NULL]",120,17179871706,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713375110000,2,0,6824713375110000,4,"[NULL]",120,17179871714,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713375472000,2,0,6824713375472000,4,"[NULL]",120,17179871715,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713383202000,2,0,6824713383202000,4,"[NULL]",120,17179871734,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713383781000,2,0,6824713383781000,4,"[NULL]",120,17179871740,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713383954000,2,0,6824713383954000,4,"[NULL]",120,17179871744,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713384391000,2,0,6824713384391000,4,"[NULL]",120,17179871748,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713384645000,2,0,6824713384645000,4,"[NULL]",120,17179871749,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713390627000,2,0,6824713390627000,4,"[NULL]",120,17179871760,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713391262000,2,0,6824713391262000,4,"[NULL]",120,17179871764,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713392093000,2,0,6824713392093000,4,"[NULL]",120,17179871769,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713392521000,2,0,6824713392521000,4,"[NULL]",120,17179871773,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713393575000,2,0,6824713393575000,4,"[NULL]",120,17179871779,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713393969000,2,0,6824713393969000,4,"[NULL]",120,17179871783,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713394969000,2,0,6824713394969000,4,"[NULL]",120,17179871795,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713395239000,2,0,6824713395239000,4,"[NULL]",120,17179871798,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713395498000,2,0,6824713395498000,4,"[NULL]",120,17179871802,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713400451000,0,0,6824713400451000,4,"[NULL]",120,17179871816,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713400655000,0,0,6824713400655000,4,"[NULL]",120,17179871820,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713401570000,1,0,6824713401570000,4,"[NULL]",120,17179871825,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713403944000,1,0,6824713403944000,4,"[NULL]",120,17179871844,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713405022000,2,0,6824713405022000,4,"[NULL]",120,17179871855,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713405472000,2,0,6824713405472000,4,"[NULL]",120,17179871858,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713408168000,2,0,6824713408168000,4,"[NULL]",120,17179871871,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713408881000,1,0,6824713408881000,4,"[NULL]",120,17179871879,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713416268000,1,0,6824713416268000,4,"[NULL]",120,17179871897,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713417253000,1,0,6824713417253000,4,"[NULL]",120,17179871909,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713418495000,1,0,6824713418495000,4,"[NULL]",120,17179871915,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713419057000,1,0,6824713419057000,4,"[NULL]",120,17179871924,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713421105000,1,0,6824713421105000,4,"[NULL]",120,17179871936,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713421658000,1,0,6824713421658000,4,"[NULL]",120,17179871944,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713424400000,1,0,6824713424400000,4,"[NULL]",120,17179871961,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713425271000,1,0,6824713425271000,4,"[NULL]",120,17179871967,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713429304000,1,0,6824713429304000,4,"[NULL]",120,17179871986,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713430180000,2,0,6824713430180000,4,"[NULL]",120,17179871999,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713430761000,2,0,6824713430761000,4,"[NULL]",120,17179872003,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713431720000,1,0,6824713431720000,4,"[NULL]",120,17179872010,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713432581000,1,0,6824713432581000,4,"[NULL]",120,17179872022,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713433323000,7,0,6824713433323000,4,"[NULL]",120,17179872030,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713435899000,7,0,6824713435899000,4,"[NULL]",120,17179872040,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713436260000,7,0,6824713436260000,4,"[NULL]",120,17179872044,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713436582000,7,0,6824713436582000,4,"[NULL]",120,17179872050,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713437982000,7,0,6824713437982000,4,"[NULL]",120,17179872070,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713438038000,7,0,6824713438038000,4,"[NULL]",120,17179872073,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713438515000,7,0,6824713438515000,4,"[NULL]",120,17179872081,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713441741000,7,0,6824713441741000,4,"[NULL]",120,17179872092,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713442102000,7,0,6824713442102000,4,"[NULL]",120,17179872096,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713442486000,7,0,6824713442486000,4,"[NULL]",120,17179872104,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713444885000,7,0,6824713444885000,4,"[NULL]",120,17179872120,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713445338000,7,0,6824713445338000,4,"[NULL]",120,17179872127,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713448651000,7,0,6824713448651000,4,"[NULL]",120,17179872137,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713449119000,7,0,6824713449119000,4,"[NULL]",120,17179872141,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713449487000,7,0,6824713449487000,4,"[NULL]",120,17179872147,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713453182000,7,0,6824713453182000,4,"[NULL]",120,17179872163,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713453842000,7,0,6824713453842000,4,"[NULL]",120,17179872167,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713454408000,7,0,6824713454408000,4,"[NULL]",120,17179872171,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713457080000,7,0,6824713457080000,4,"[NULL]",120,17179872185,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713457556000,7,0,6824713457556000,4,"[NULL]",120,17179872192,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713457883000,7,0,6824713457883000,4,"[NULL]",120,17179872195,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713460714000,7,0,6824713460714000,4,"[NULL]",120,17179872206,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713461059000,7,0,6824713461059000,4,"[NULL]",120,17179872209,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713461654000,7,0,6824713461654000,4,"[NULL]",120,17179872217,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713465259000,7,0,6824713465259000,4,"[NULL]",120,17179872255,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713466316000,7,0,6824713466316000,4,"[NULL]",120,17179872267,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713466677000,7,0,6824713466677000,4,"[NULL]",120,17179872271,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713467707000,7,0,6824713467707000,4,"[NULL]",120,17179872279,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713469024000,5,0,6824713469024000,4,"[NULL]",120,17179872294,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713472233000,5,0,6824713472233000,4,"[NULL]",120,17179872322,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713472793000,5,0,6824713472793000,4,"[NULL]",120,17179872328,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713473978000,5,0,6824713473978000,4,"[NULL]",120,17179872340,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713475028000,5,0,6824713475028000,4,"[NULL]",120,17179872352,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713475389000,5,0,6824713475389000,4,"[NULL]",120,17179872356,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713475430000,5,0,6824713475430000,4,"[NULL]",120,17179872358,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713475512000,5,0,6824713475512000,4,"[NULL]",120,17179872361,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713477028000,5,0,6824713477028000,4,"[NULL]",120,17179872376,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713531418000,5,0,6824713531418000,4,"[NULL]",120,17179872485,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713540436000,5,0,6824713540436000,4,"[NULL]",120,17179872510,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713541739000,5,0,6824713541739000,4,"[NULL]",120,17179872521,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824713542910000,5,0,6824713542910000,4,"[NULL]",120,17179872527,"[NULL]","UsbFfs-worker",20308,"[NULL]","[NULL]"
+6824711826692000,6,16000,6824711826708000,5,"S",120,17179869189,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824711833442000,6,8000,6824711833450000,5,"S",120,17179869250,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824711840931000,6,24000,6824711840955000,5,"S",120,17179869260,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824711846639000,6,16000,6824711846655000,5,"S",120,17179869286,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824711854118000,6,7000,6824711854125000,5,"S",120,17179869300,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824711860985000,6,67000,6824711861052000,5,"S",120,17179869326,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712863547000,2,40000,6824712863587000,5,"S",120,17179870292,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712870137000,2,41000,6824712870178000,5,"S",120,17179870322,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712876836000,2,146000,6824712876982000,5,"S",120,17179870331,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712877570000,2,32000,6824712877602000,5,"S",120,17179870339,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712883875000,0,37000,6824712883912000,5,"S",120,17179870347,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712890898000,0,80000,6824712890978000,5,"S",120,17179870354,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712917196000,0,38000,6824712917234000,5,"S",120,17179870445,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712923300000,0,66000,6824712923366000,5,"S",120,17179870477,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712923847000,3,21000,6824712923868000,5,"S",120,17179870480,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712930299000,3,39000,6824712930338000,5,"S",120,17179870499,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712979438000,1,54000,6824712979492000,5,"S",120,17179870554,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712983357000,1,58000,6824712983415000,5,"S",120,17179870564,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712989997000,1,90000,6824712990087000,5,"S",120,17179870589,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712990255000,1,24000,6824712990279000,5,"S",120,17179870592,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824712996659000,1,76000,6824712996735000,5,"S",120,17179870613,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713023717000,0,29000,6824713023746000,5,"S",120,17179870646,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713029982000,0,33000,6824713030015000,5,"S",120,17179870673,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713036648000,0,56000,6824713036704000,5,"S",120,17179870688,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713036758000,0,10000,6824713036768000,5,"S",120,17179870690,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713043737000,1,36000,6824713043773000,5,"S",120,17179870696,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713050254000,1,42000,6824713050296000,5,"S",120,17179870704,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713255199000,7,23000,6824713255222000,5,"S",120,17179871377,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713261433000,7,52000,6824713261485000,5,"S",120,17179871410,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713264244000,7,55000,6824713264299000,5,"S",120,17179871426,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713271412000,7,52000,6824713271464000,5,"S",120,17179871443,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713272613000,7,50000,6824713272663000,5,"S",120,17179871448,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713276987000,7,34000,6824713277021000,5,"S",120,17179871461,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713466087000,5,8000,6824713466095000,5,"S",120,17179872263,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713469919000,5,7000,6824713469926000,5,"S",120,17179872303,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713476792000,6,30000,6824713476822000,5,"S",120,17179872373,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713484499000,6,23000,6824713484522000,5,"S",120,17179872383,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713538812000,6,55000,6824713538867000,5,"S",120,17179872500,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713543649000,6,83000,6824713543732000,5,"S",120,17179872528,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713544462000,6,45000,6824713544507000,5,"S",120,17179872533,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713550291000,6,80000,6824713550371000,5,"S",120,17179872546,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713574903000,6,48000,6824713574951000,5,"S",120,17179872604,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713580446000,6,32000,6824713580478000,5,"S",120,17179872610,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713587022000,6,46000,6824713587068000,5,"S",120,17179872628,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713588081000,6,24000,6824713588105000,5,"S",120,17179872634,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824713593660000,6,42000,6824713593702000,5,"S",120,17179872640,6,"rcu_sched",8,"[NULL]","[NULL]"
+6824711826588000,6,32000,6824711826620000,6,"S",120,17179869187,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824711833423000,6,19000,6824711833442000,6,"S",120,17179869248,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824711840892000,6,39000,6824711840931000,6,"S",120,17179869259,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824711846617000,6,22000,6824711846639000,6,"S",120,17179869285,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824711854105000,6,13000,6824711854118000,6,"S",120,17179869299,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824711860907000,6,78000,6824711860985000,6,"S",120,17179869325,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824711867770000,0,70000,6824711867840000,6,"S",120,17179869338,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824711873383000,0,136000,6824711873519000,6,"S",120,17179869344,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824711880240000,0,57000,6824711880297000,6,"S",120,17179869386,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824711886679000,0,139000,6824711886818000,6,"S",120,17179869396,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824711893451000,0,109000,6824711893560000,6,"S",120,17179869421,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712135109000,0,37000,6824712135146000,6,"S",120,17179869628,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712140604000,0,103000,6824712140707000,6,"S",120,17179869631,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712853606000,2,62000,6824712853668000,6,"S",120,17179870268,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712860291000,2,57000,6824712860348000,6,"S",120,17179870274,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712863372000,2,95000,6824712863467000,6,"S",120,17179870289,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712863587000,2,24000,6824712863611000,6,"S",120,17179870293,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712870081000,2,56000,6824712870137000,6,"S",120,17179870320,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712876982000,2,88000,6824712877070000,6,"S",120,17179870332,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712877156000,2,40000,6824712877196000,6,"S",120,17179870334,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712883912000,0,38000,6824712883950000,6,"S",120,17179870348,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712890826000,0,72000,6824712890898000,6,"S",120,17179870352,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712891573000,0,40000,6824712891613000,6,"S",120,17179870359,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712896660000,0,76000,6824712896736000,6,"S",120,17179870375,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712900383000,0,51000,6824712900434000,6,"S",120,17179870388,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712907336000,0,77000,6824712907413000,6,"S",120,17179870395,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712907464000,0,27000,6824712907491000,6,"S",120,17179870398,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712913933000,0,84000,6824712914017000,6,"S",120,17179870434,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712915152000,0,39000,6824712915191000,6,"S",120,17179870440,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712920666000,0,83000,6824712920749000,6,"S",120,17179870452,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712921756000,0,15000,6824712921771000,6,"S",120,17179870472,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712926846000,1,16000,6824712926862000,6,"S",120,17179870487,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712933309000,1,55000,6824712933364000,6,"S",120,17179870509,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712934299000,1,19000,6824712934318000,6,"S",120,17179870513,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712942588000,1,197000,6824712942785000,6,"S",120,17179870516,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712981529000,1,40000,6824712981569000,6,"S",120,17179870557,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712986792000,2,82000,6824712986874000,6,"S",120,17179870579,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712993771000,2,89000,6824712993860000,6,"S",120,17179870597,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824712994447000,2,41000,6824712994488000,6,"S",120,17179870603,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713000007000,1,107000,6824713000114000,6,"S",120,17179870624,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713010841000,1,35000,6824713010876000,6,"S",120,17179870631,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713016633000,1,67000,6824713016700000,6,"S",120,17179870635,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713016802000,1,12000,6824713016814000,6,"S",120,17179870638,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713023775000,0,30000,6824713023805000,6,"S",120,17179870648,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713026928000,0,45000,6824713026973000,6,"S",120,17179870656,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713027236000,0,14000,6824713027250000,6,"S",120,17179870661,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713033323000,0,89000,6824713033412000,6,"S",120,17179870682,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713033498000,0,13000,6824713033511000,6,"S",120,17179870684,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713040481000,1,46000,6824713040527000,6,"S",120,17179870692,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713047015000,1,48000,6824713047063000,6,"S",120,17179870700,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713054399000,1,30000,6824713054429000,6,"S",120,17179870714,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713060593000,1,54000,6824713060647000,6,"S",120,17179870721,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713066645000,1,64000,6824713066709000,6,"S",120,17179870745,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713066750000,1,18000,6824713066768000,6,"S",120,17179870748,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713073263000,1,25000,6824713073288000,6,"S",120,17179870773,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713073558000,1,15000,6824713073573000,6,"S",120,17179870777,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713080142000,3,24000,6824713080166000,6,"S",120,17179870794,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713087030000,3,62000,6824713087092000,6,"S",120,17179870808,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713088056000,3,22000,6824713088078000,6,"S",120,17179870813,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713093600000,3,36000,6824713093636000,6,"S",120,17179870840,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713100618000,1,54000,6824713100672000,6,"S",120,17179870876,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713101606000,2,31000,6824713101637000,6,"S",120,17179870885,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713106999000,2,46000,6824713107045000,6,"S",120,17179870893,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713108156000,2,24000,6824713108180000,6,"S",120,17179870897,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713113303000,2,30000,6824713113333000,6,"S",120,17179870918,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713117004000,2,42000,6824713117046000,6,"S",120,17179870920,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713117897000,2,22000,6824713117919000,6,"S",120,17179870924,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713123633000,3,30000,6824713123663000,6,"S",120,17179870949,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713129984000,3,64000,6824713130048000,6,"S",120,17179870970,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713131886000,2,26000,6824713131912000,6,"S",120,17179870984,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713136946000,2,41000,6824713136987000,6,"S",120,17179871006,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713140261000,2,37000,6824713140298000,6,"S",120,17179871008,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713141410000,2,18000,6824713141428000,6,"S",120,17179871012,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713146916000,2,42000,6824713146958000,6,"S",120,17179871035,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713147908000,2,20000,6824713147928000,6,"S",120,17179871039,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713153646000,2,49000,6824713153695000,6,"S",120,17179871041,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713154713000,1,18000,6824713154731000,6,"S",120,17179871048,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713163715000,3,56000,6824713163771000,6,"S",120,17179871087,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713169981000,3,63000,6824713170044000,6,"S",120,17179871125,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713170956000,3,31000,6824713170987000,6,"S",120,17179871129,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713177011000,3,31000,6824713177042000,6,"S",120,17179871131,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713183637000,3,58000,6824713183695000,6,"S",120,17179871163,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713185118000,3,22000,6824713185140000,6,"S",120,17179871167,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713190435000,3,53000,6824713190488000,6,"S",120,17179871177,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713191392000,3,26000,6824713191418000,6,"S",120,17179871194,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713196625000,3,44000,6824713196669000,6,"S",120,17179871210,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713203672000,3,74000,6824713203746000,6,"S",120,17179871223,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713204825000,3,28000,6824713204853000,6,"S",120,17179871228,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713209971000,3,55000,6824713210026000,6,"S",120,17179871249,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713211344000,3,26000,6824713211370000,6,"S",120,17179871253,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713217026000,3,51000,6824713217077000,6,"S",120,17179871255,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713217847000,3,19000,6824713217866000,6,"S",120,17179871259,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713223953000,3,87000,6824713224040000,6,"S",120,17179871261,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713225160000,1,33000,6824713225193000,6,"S",120,17179871268,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713230310000,2,45000,6824713230355000,6,"S",120,17179871301,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713236670000,2,70000,6824713236740000,6,"S",120,17179871310,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713236986000,2,17000,6824713237003000,6,"S",120,17179871313,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713243295000,2,43000,6824713243338000,6,"S",120,17179871336,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713246990000,2,51000,6824713247041000,6,"S",120,17179871341,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713248276000,2,25000,6824713248301000,6,"S",120,17179871345,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713260035000,2,103000,6824713260138000,6,"S",120,17179871402,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713266697000,2,86000,6824713266783000,6,"R+",120,17179871439,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713266816000,2,36000,6824713266852000,6,"S",120,17179871441,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713273750000,2,109000,6824713273859000,6,"R+",120,17179871450,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713274035000,2,26000,6824713274061000,6,"S",120,17179871453,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713280752000,2,55000,6824713280807000,6,"R+",120,17179871469,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713280834000,2,20000,6824713280854000,6,"S",120,17179871471,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713287161000,2,80000,6824713287241000,6,"S",120,17179871473,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713288046000,2,19000,6824713288065000,6,"S",120,17179871479,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713293609000,2,45000,6824713293654000,6,"S",120,17179871484,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713300348000,2,36000,6824713300384000,6,"S",120,17179871515,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713307236000,2,69000,6824713307305000,6,"S",120,17179871521,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713307709000,2,17000,6824713307726000,6,"S",120,17179871525,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713313670000,2,31000,6824713313701000,6,"S",120,17179871529,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713316935000,2,46000,6824713316981000,6,"S",120,17179871531,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713317754000,2,15000,6824713317769000,6,"S",120,17179871537,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713323646000,2,54000,6824713323700000,6,"S",120,17179871541,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713324593000,2,17000,6824713324610000,6,"S",120,17179871546,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713329978000,2,29000,6824713330007000,6,"S",120,17179871577,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713336951000,2,72000,6824713337023000,6,"S",120,17179871604,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713343779000,2,140000,6824713343919000,6,"R+",120,17179871613,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713343948000,2,28000,6824713343976000,6,"S",120,17179871615,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713351659000,2,259000,6824713351918000,6,"R+",120,17179871626,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713360907000,2,128000,6824713361035000,6,"R+",120,17179871650,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713361390000,2,51000,6824713361441000,6,"S",120,17179871654,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713367055000,2,85000,6824713367140000,6,"R+",120,17179871690,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713367549000,2,34000,6824713367583000,6,"S",120,17179871692,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713374404000,2,168000,6824713374572000,6,"R+",120,17179871711,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713375066000,2,44000,6824713375110000,6,"S",120,17179871713,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713380672000,2,103000,6824713380775000,6,"R+",120,17179871721,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713381165000,2,41000,6824713381206000,6,"R+",120,17179871723,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713381281000,2,45000,6824713381326000,6,"S",120,17179871725,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713386941000,2,96000,6824713387037000,6,"R+",120,17179871750,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713387377000,2,41000,6824713387418000,6,"S",120,17179871752,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713393438000,2,137000,6824713393575000,6,"S",120,17179871775,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713403641000,3,96000,6824713403737000,6,"S",120,17179871840,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713404689000,1,62000,6824713404751000,6,"S",120,17179871853,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713410030000,1,92000,6824713410122000,6,"S",120,17179871883,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713416675000,1,57000,6824713416732000,6,"S",120,17179871903,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713423358000,1,94000,6824713423452000,6,"S",120,17179871952,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713423553000,1,47000,6824713423600000,6,"S",120,17179871956,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713430006000,2,61000,6824713430067000,6,"S",120,17179871992,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713436681000,2,89000,6824713436770000,6,"S",120,17179872053,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713436992000,2,48000,6824713437040000,6,"S",120,17179872057,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713443361000,2,92000,6824713443453000,6,"S",120,17179872107,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713443815000,2,49000,6824713443864000,6,"S",120,17179872111,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713450016000,2,95000,6824713450111000,6,"S",120,17179872150,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713450388000,5,13000,6824713450401000,6,"S",120,17179872154,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713456882000,5,15000,6824713456897000,6,"S",120,17179872183,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713457541000,5,8000,6824713457549000,6,"S",120,17179872189,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713463232000,5,9000,6824713463241000,6,"S",120,17179872232,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713463575000,5,14000,6824713463589000,6,"S",120,17179872234,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713463832000,5,5000,6824713463837000,6,"S",120,17179872238,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713469926000,5,6000,6824713469932000,6,"S",120,17179872304,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713470702000,5,43000,6824713470745000,6,"S",120,17179872308,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713476618000,5,8000,6824713476626000,6,"S",120,17179872369,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713484404000,5,44000,6824713484448000,6,"S",120,17179872381,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713491075000,5,58000,6824713491133000,6,"S",120,17179872395,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713497596000,5,25000,6824713497621000,6,"S",120,17179872420,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713504740000,5,82000,6824713504822000,6,"S",120,17179872430,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713512798000,0,237000,6824713513035000,6,"S",120,17179872444,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713517299000,0,410000,6824713517709000,6,"S",120,17179872446,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713523746000,0,88000,6824713523834000,6,"S",120,17179872454,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713523988000,0,28000,6824713524016000,6,"S",120,17179872456,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713530206000,0,40000,6824713530246000,6,"S",120,17179872475,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713537006000,0,74000,6824713537080000,6,"S",120,17179872495,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713540295000,0,37000,6824713540332000,6,"S",120,17179872508,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713547051000,5,95000,6824713547146000,6,"S",120,17179872536,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713547374000,5,21000,6824713547395000,6,"S",120,17179872539,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713553310000,5,86000,6824713553396000,6,"S",120,17179872552,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713562834000,5,14000,6824713562848000,6,"S",120,17179872564,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713566624000,5,23000,6824713566647000,6,"S",120,17179872581,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713573294000,5,49000,6824713573343000,6,"S",120,17179872598,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713580010000,5,60000,6824713580070000,6,"S",120,17179872608,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713586606000,5,29000,6824713586635000,6,"S",120,17179872623,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713586772000,5,8000,6824713586780000,6,"S",120,17179872626,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713593260000,5,24000,6824713593284000,6,"S",120,17179872636,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713621423000,5,19000,6824713621442000,6,"S",120,17179872671,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713626613000,5,45000,6824713626658000,6,"S",120,17179872675,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713626705000,5,6000,6824713626711000,6,"S",120,17179872678,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824713634810000,5,70000,6824713634880000,6,"S",120,17179872706,4,"rcu_preempt",7,"[NULL]","[NULL]"
+6824711826620000,6,72000,6824711826692000,7,"S",120,17179869188,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824711840955000,6,143000,6824711841098000,7,"S",120,17179869261,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824711861102000,6,168000,6824711861270000,7,"S",120,17179869328,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713406769000,7,10000,6824713406779000,7,"S",120,17179871862,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713423421000,6,90000,6824713423511000,7,"S",120,17179871953,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713436736000,6,216000,6824713436952000,7,"S",120,17179872054,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713443603000,5,161000,6824713443764000,7,"S",120,17179872109,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713450076000,6,87000,6824713450163000,7,"S",120,17179872151,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713457244000,6,70000,6824713457314000,7,"S",120,17179872186,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713463764000,6,70000,6824713463834000,7,"S",120,17179872237,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713470980000,6,109000,6824713471089000,7,"S",120,17179872312,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713491324000,6,54000,6824713491378000,7,"S",120,17179872397,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713517938000,0,144000,6824713518082000,7,"S",120,17179872449,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713539878000,0,278000,6824713540156000,7,"R+",120,17179872503,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713540450000,0,46000,6824713540496000,7,"S",120,17179872511,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713553396000,5,69000,6824713553465000,7,"S",120,17179872553,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713562801000,5,33000,6824713562834000,7,"S",120,17179872563,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713573343000,5,37000,6824713573380000,7,"S",120,17179872599,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713586635000,5,43000,6824713586678000,7,"S",120,17179872624,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713593284000,5,18000,6824713593302000,7,"S",120,17179872637,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713621388000,5,35000,6824713621423000,7,"S",120,17179872670,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713626658000,5,26000,6824713626684000,7,"S",120,17179872676,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824713634880000,5,39000,6824713634919000,7,"S",120,17179872707,5,"rcuop/4",44,"[NULL]","[NULL]"
+6824711843165000,2,225000,6824711843390000,8,"R",120,17179869272,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824711843629000,2,152000,6824711843781000,8,"S",120,17179869275,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824711861270000,6,32000,6824711861302000,8,"S",120,17179869329,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824711886818000,0,59000,6824711886877000,8,"S",120,17179869397,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713251509000,0,58000,6824713251567000,8,"S",120,17179871355,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713266783000,2,33000,6824713266816000,8,"S",120,17179871440,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713273859000,2,152000,6824713274011000,8,"S",120,17179871451,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713329958000,2,20000,6824713329978000,8,"S",120,17179871576,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713343919000,2,29000,6824713343948000,8,"S",120,17179871614,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713351918000,2,591000,6824713352509000,8,"S",120,17179871629,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713361035000,2,355000,6824713361390000,8,"S",120,17179871651,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713367140000,2,409000,6824713367549000,8,"S",120,17179871691,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713374572000,2,494000,6824713375066000,8,"S",120,17179871712,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713380775000,2,390000,6824713381165000,8,"S",120,17179871722,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713387037000,2,340000,6824713387377000,8,"S",120,17179871751,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713403920000,2,530000,6824713404450000,8,"S",120,17179871843,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713410365000,2,1409000,6824713411774000,8,"S",120,17179871885,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713474149000,2,49000,6824713474198000,8,"S",120,17179872342,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713492438000,2,218000,6824713492656000,8,"S",120,17179872399,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824713517990000,2,147000,6824713518137000,8,"S",120,17179872450,7,"rcuop/6",60,"[NULL]","[NULL]"
+6824711826730000,0,80000,6824711826810000,9,"S",120,17179869191,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824711841864000,0,161000,6824711842025000,9,"S",120,17179869269,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824711873710000,0,46000,6824711873756000,9,"S",120,17179869347,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824711893598000,0,52000,6824711893650000,9,"S",120,17179869423,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824712135028000,0,81000,6824712135109000,9,"S",120,17179869627,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824712140707000,0,133000,6824712140840000,9,"S",120,17179869632,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824712981441000,1,88000,6824712981529000,9,"S",120,17179870556,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824712993843000,1,145000,6824712993988000,9,"S",120,17179870598,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713000114000,1,92000,6824713000206000,9,"S",120,17179870625,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713010789000,1,52000,6824713010841000,9,"S",120,17179870630,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713016700000,1,66000,6824713016766000,9,"S",120,17179870636,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713027171000,1,67000,6824713027238000,9,"S",120,17179870659,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713033412000,0,86000,6824713033498000,9,"S",120,17179870683,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713047056000,0,43000,6824713047099000,9,"S",120,17179870701,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713053944000,0,46000,6824713053990000,9,"S",120,17179870710,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713066704000,2,53000,6824713066757000,9,"S",120,17179870746,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713073285000,2,117000,6824713073402000,9,"S",120,17179870774,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713087406000,2,284000,6824713087690000,9,"S",120,17179870810,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713100672000,1,561000,6824713101233000,9,"S",120,17179870879,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713107427000,1,382000,6824713107809000,9,"S",120,17179870895,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713117371000,1,213000,6824713117584000,9,"S",120,17179870922,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713130876000,1,61000,6824713130937000,9,"R",120,17179870975,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713131051000,1,355000,6824713131406000,9,"S",120,17179870977,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713140652000,1,423000,6824713141075000,9,"S",120,17179871010,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713147299000,1,265000,6824713147564000,9,"S",120,17179871037,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713154200000,3,176000,6824713154376000,9,"S",120,17179871045,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713170393000,1,203000,6824713170596000,9,"S",120,17179871127,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713184058000,1,700000,6824713184758000,9,"S",120,17179871165,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713190480000,2,615000,6824713191095000,9,"S",120,17179871178,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713204068000,2,436000,6824713204504000,9,"S",120,17179871225,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713210398000,2,635000,6824713211033000,9,"S",120,17179871251,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713217424000,2,75000,6824713217499000,9,"S",120,17179871257,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713224381000,2,258000,6824713224639000,9,"S",120,17179871264,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713236727000,3,267000,6824713236994000,9,"S",120,17179871311,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713247421000,3,487000,6824713247908000,9,"S",120,17179871343,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713260571000,3,513000,6824713261084000,9,"S",120,17179871405,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713274253000,3,160000,6824713274413000,9,"S",120,17179871455,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713287647000,3,85000,6824713287732000,9,"S",120,17179871475,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713293985000,3,43000,6824713294028000,9,"S",120,17179871486,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713300176000,3,48000,6824713300224000,9,"S",120,17179871512,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713307642000,3,72000,6824713307714000,9,"S",120,17179871523,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713317352000,3,56000,6824713317408000,9,"S",120,17179871533,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713324048000,3,59000,6824713324107000,9,"S",120,17179871543,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713337341000,3,53000,6824713337394000,9,"S",120,17179871606,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713352278000,3,219000,6824713352497000,9,"S",120,17179871637,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713466959000,0,61000,6824713467020000,9,"S",120,17179872273,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713485758000,0,157000,6824713485915000,9,"S",120,17179872388,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713506861000,0,290000,6824713507151000,9,"S",120,17179872433,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713508607000,0,56000,6824713508663000,9,"S",120,17179872441,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713523834000,0,154000,6824713523988000,9,"R+",120,17179872455,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713524016000,0,43000,6824713524059000,9,"S",120,17179872457,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713537080000,0,59000,6824713537139000,9,"S",120,17179872496,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713567836000,0,68000,6824713567904000,9,"S",120,17179872587,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824713581225000,0,158000,6824713581383000,9,"S",120,17179872613,8,"rcuop/0",10,"[NULL]","[NULL]"
+6824711827034000,2,51000,6824711827085000,10,"S",120,17179869200,15,"rcuop/7",68,"[NULL]","[NULL]"
+6824711843781000,2,441000,6824711844222000,10,"S",120,17179869276,15,"rcuop/7",68,"[NULL]","[NULL]"
+6824711826853000,3,54000,6824711826907000,11,"S",120,17179869195,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824711843498000,2,131000,6824711843629000,11,"S",120,17179869274,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824712993988000,1,34000,6824712994022000,11,"S",120,17179870600,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713000206000,1,61000,6824713000267000,11,"S",120,17179870626,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713016766000,1,36000,6824713016802000,11,"S",120,17179870637,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713027238000,1,61000,6824713027299000,11,"S",120,17179870662,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713033786000,1,36000,6824713033822000,11,"S",120,17179870686,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713274317000,1,223000,6824713274540000,11,"S",120,17179871456,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713287694000,1,49000,6824713287743000,11,"S",120,17179871476,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713294016000,1,29000,6824713294045000,11,"S",120,17179871487,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713307686000,1,32000,6824713307718000,11,"S",120,17179871524,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713317382000,1,116000,6824713317498000,11,"S",120,17179871534,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713324560000,0,209000,6824713324769000,11,"S",120,17179871545,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713337731000,0,167000,6824713337898000,11,"S",120,17179871608,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713352793000,0,205000,6824713352998000,11,"S",120,17179871640,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713486191000,1,100000,6824713486291000,11,"S",120,17179872391,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713507552000,1,436000,6824713507988000,11,"S",120,17179872438,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713524412000,1,87000,6824713524499000,11,"S",120,17179872459,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824713581870000,1,91000,6824713581961000,11,"S",120,17179872616,11,"rcuop/1",20,"[NULL]","[NULL]"
+6824711826788000,2,81000,6824711826869000,12,"S",120,17179869192,10,"rcuop/5",52,"[NULL]","[NULL]"
+6824711841865000,2,1300000,6824711843165000,12,"S",120,17179869270,10,"rcuop/5",52,"[NULL]","[NULL]"
+6824711861384000,2,457000,6824711861841000,12,"S",120,17179869331,10,"rcuop/5",52,"[NULL]","[NULL]"
+6824713518137000,2,83000,6824713518220000,12,"S",120,17179872452,10,"rcuop/5",52,"[NULL]","[NULL]"
+6824713547574000,2,56000,6824713547630000,12,"S",120,17179872542,10,"rcuop/5",52,"[NULL]","[NULL]"
+6824713553465000,5,36000,6824713553501000,12,"S",120,17179872554,10,"rcuop/5",52,"[NULL]","[NULL]"
+6824713573380000,5,23000,6824713573403000,12,"S",120,17179872600,10,"rcuop/5",52,"[NULL]","[NULL]"
+6824713586678000,5,94000,6824713586772000,12,"S",120,17179872625,10,"rcuop/5",52,"[NULL]","[NULL]"
+6824713593302000,5,19000,6824713593321000,12,"S",120,17179872638,10,"rcuop/5",52,"[NULL]","[NULL]"
+6824713626684000,5,21000,6824713626705000,12,"S",120,17179872677,10,"rcuop/5",52,"[NULL]","[NULL]"
+6824713634919000,5,54000,6824713634973000,12,"S",120,17179872708,10,"rcuop/5",52,"[NULL]","[NULL]"
+6824711826820000,3,33000,6824711826853000,13,"S",120,17179869194,9,"rcuos/0",11,"[NULL]","[NULL]"
+6824712979311000,1,127000,6824712979438000,13,"S",120,17179870553,9,"rcuos/0",11,"[NULL]","[NULL]"
+6824712990087000,1,92000,6824712990179000,13,"S",120,17179870590,9,"rcuos/0",11,"[NULL]","[NULL]"
+6824712996735000,1,52000,6824712996787000,13,"S",120,17179870614,9,"rcuos/0",11,"[NULL]","[NULL]"
+6824713023655000,0,62000,6824713023717000,13,"S",120,17179870645,9,"rcuos/0",11,"[NULL]","[NULL]"
+6824713036704000,0,54000,6824713036758000,13,"S",120,17179870689,9,"rcuos/0",11,"[NULL]","[NULL]"
+6824713050287000,0,36000,6824713050323000,13,"S",120,17179870705,9,"rcuos/0",11,"[NULL]","[NULL]"
+6824713262716000,1,92000,6824713262808000,13,"S",120,17179871422,9,"rcuos/0",11,"[NULL]","[NULL]"
+6824713271489000,1,125000,6824713271614000,13,"S",120,17179871445,9,"rcuos/0",11,"[NULL]","[NULL]"
+6824713277040000,1,41000,6824713277081000,13,"S",120,17179871463,9,"rcuos/0",11,"[NULL]","[NULL]"
+6824713469747000,2,68000,6824713469815000,13,"S",120,17179872301,9,"rcuos/0",11,"[NULL]","[NULL]"
+6824713485756000,2,159000,6824713485915000,13,"S",120,17179872387,9,"rcuos/0",11,"[NULL]","[NULL]"
+6824711826997000,1,21000,6824711827018000,14,"S",120,17179869198,12,"rcuos/1",21,"[NULL]","[NULL]"
+6824712990179000,1,76000,6824712990255000,14,"S",120,17179870591,12,"rcuos/1",21,"[NULL]","[NULL]"
+6824712996787000,1,28000,6824712996815000,14,"S",120,17179870615,12,"rcuos/1",21,"[NULL]","[NULL]"
+6824713271614000,1,43000,6824713271657000,14,"S",120,17179871446,12,"rcuos/1",21,"[NULL]","[NULL]"
+6824713277081000,1,23000,6824713277104000,14,"S",120,17179871464,12,"rcuos/1",21,"[NULL]","[NULL]"
+6824713486272000,3,94000,6824713486366000,14,"S",120,17179872392,12,"rcuos/1",21,"[NULL]","[NULL]"
+6824711826869000,2,165000,6824711827034000,15,"S",120,17179869196,13,"adbd",20305,"[NULL]","[NULL]"
+6824711828575000,3,250000,6824711828825000,15,"S",120,17179869214,13,"adbd",20305,"[NULL]","[NULL]"
+6824712853668000,2,3944000,6824712857612000,15,"S",120,17179870269,13,"adbd",20305,"[NULL]","[NULL]"
+6824712865159000,2,3064000,6824712868223000,15,"R+",120,17179870295,13,"adbd",20305,"[NULL]","[NULL]"
+6824712907844000,2,962000,6824712908806000,15,"R+",120,17179870402,13,"adbd",20305,"[NULL]","[NULL]"
+6824712909408000,2,164000,6824712909572000,15,"R+",120,17179870411,13,"adbd",20305,"[NULL]","[NULL]"
+6824712909614000,2,53000,6824712909667000,15,"R+",120,17179870413,13,"adbd",20305,"[NULL]","[NULL]"
+6824712909729000,2,88000,6824712909817000,15,"S",120,17179870415,13,"adbd",20305,"[NULL]","[NULL]"
+6824712911172000,2,47000,6824712911219000,15,"R",120,17179870427,13,"adbd",20305,"[NULL]","[NULL]"
+6824712911241000,2,85000,6824712911326000,15,"S",120,17179870429,13,"adbd",20305,"[NULL]","[NULL]"
+6824712919470000,2,1271000,6824712920741000,15,"S",120,17179870448,13,"adbd",20305,"[NULL]","[NULL]"
+6824712981791000,0,2438000,6824712984229000,15,"S",120,17179870559,13,"adbd",20305,"[NULL]","[NULL]"
+6824712987027000,1,358000,6824712987385000,15,"S",120,17179870581,13,"adbd",20305,"[NULL]","[NULL]"
+6824712987833000,0,421000,6824712988254000,15,"S",120,17179870583,13,"adbd",20305,"[NULL]","[NULL]"
+6824713071460000,2,412000,6824713071872000,15,"S",120,17179870753,13,"adbd",20305,"[NULL]","[NULL]"
+6824713072990000,2,99000,6824713073089000,15,"S",120,17179870771,13,"adbd",20305,"[NULL]","[NULL]"
+6824713079664000,2,293000,6824713079957000,15,"S",120,17179870787,13,"adbd",20305,"[NULL]","[NULL]"
+6824713081251000,2,106000,6824713081357000,15,"S",120,17179870806,13,"adbd",20305,"[NULL]","[NULL]"
+6824713088114000,3,404000,6824713088518000,15,"S",120,17179870815,13,"adbd",20305,"[NULL]","[NULL]"
+6824713089621000,2,127000,6824713089748000,15,"S",120,17179870835,13,"adbd",20305,"[NULL]","[NULL]"
+6824713099398000,2,1576000,6824713100974000,15,"S",120,17179870868,13,"adbd",20305,"[NULL]","[NULL]"
+6824713102108000,2,177000,6824713102285000,15,"S",120,17179870891,13,"adbd",20305,"[NULL]","[NULL]"
+6824713110051000,2,506000,6824713110557000,15,"S",120,17179870901,13,"adbd",20305,"[NULL]","[NULL]"
+6824713112395000,2,142000,6824713112537000,15,"S",120,17179870916,13,"adbd",20305,"[NULL]","[NULL]"
+6824713121632000,2,519000,6824713122151000,15,"S",120,17179870928,13,"adbd",20305,"[NULL]","[NULL]"
+6824713123175000,2,190000,6824713123365000,15,"S",120,17179870947,13,"adbd",20305,"[NULL]","[NULL]"
+6824713132234000,1,838000,6824713133072000,15,"S",120,17179870987,13,"adbd",20305,"[NULL]","[NULL]"
+6824713133743000,2,140000,6824713133883000,15,"S",120,17179871004,13,"adbd",20305,"[NULL]","[NULL]"
+6824713142539000,2,518000,6824713143057000,15,"S",120,17179871016,13,"adbd",20305,"[NULL]","[NULL]"
+6824713145177000,1,151000,6824713145328000,15,"S",120,17179871033,13,"adbd",20305,"[NULL]","[NULL]"
+6824713154419000,2,564000,6824713154983000,15,"S",120,17179871047,13,"adbd",20305,"[NULL]","[NULL]"
+6824713156618000,2,133000,6824713156751000,15,"S",120,17179871071,13,"adbd",20305,"[NULL]","[NULL]"
+6824713165836000,2,847000,6824713166683000,15,"R+",120,17179871099,13,"adbd",20305,"[NULL]","[NULL]"
+6824713166910000,2,644000,6824713167554000,15,"S",120,17179871104,13,"adbd",20305,"[NULL]","[NULL]"
+6824713168188000,2,118000,6824713168306000,15,"S",120,17179871123,13,"adbd",20305,"[NULL]","[NULL]"
+6824713178848000,2,801000,6824713179649000,15,"S",120,17179871141,13,"adbd",20305,"[NULL]","[NULL]"
+6824713181959000,1,179000,6824713182138000,15,"S",120,17179871161,13,"adbd",20305,"[NULL]","[NULL]"
+6824713189029000,2,560000,6824713189589000,15,"S",120,17179871171,13,"adbd",20305,"[NULL]","[NULL]"
+6824713191335000,1,184000,6824713191519000,15,"S",120,17179871193,13,"adbd",20305,"[NULL]","[NULL]"
+6824713205247000,2,966000,6824713206213000,15,"S",120,17179871231,13,"adbd",20305,"[NULL]","[NULL]"
+6824713207853000,2,179000,6824713208032000,15,"S",120,17179871247,13,"adbd",20305,"[NULL]","[NULL]"
+6824713224919000,3,932000,6824713225851000,15,"S",120,17179871267,13,"adbd",20305,"[NULL]","[NULL]"
+6824713227608000,3,224000,6824713227832000,15,"S",120,17179871289,13,"adbd",20305,"[NULL]","[NULL]"
+6824713238544000,3,824000,6824713239368000,15,"S",120,17179871318,13,"adbd",20305,"[NULL]","[NULL]"
+6824713242043000,3,215000,6824713242258000,15,"S",120,17179871334,13,"adbd",20305,"[NULL]","[NULL]"
+6824713251148000,7,902000,6824713252050000,15,"S",120,17179871353,13,"adbd",20305,"[NULL]","[NULL]"
+6824713257690000,2,127000,6824713257817000,15,"S",120,17179871394,13,"adbd",20305,"[NULL]","[NULL]"
+6824713258012000,2,131000,6824713258143000,15,"S",120,17179871396,13,"adbd",20305,"[NULL]","[NULL]"
+6824713258690000,0,164000,6824713258854000,15,"S",120,17179871398,13,"adbd",20305,"[NULL]","[NULL]"
+6824713330067000,7,915000,6824713330982000,15,"S",120,17179871580,13,"adbd",20305,"[NULL]","[NULL]"
+6824713349895000,6,389000,6824713350284000,15,"S",120,17179871621,13,"adbd",20305,"[NULL]","[NULL]"
+6824713358741000,6,311000,6824713359052000,15,"S",120,17179871646,13,"adbd",20305,"[NULL]","[NULL]"
+6824713370075000,6,299000,6824713370374000,15,"S",120,17179871697,13,"adbd",20305,"[NULL]","[NULL]"
+6824713381406000,6,288000,6824713381694000,15,"S",120,17179871729,13,"adbd",20305,"[NULL]","[NULL]"
+6824713388490000,6,145000,6824713388635000,15,"S",120,17179871755,13,"adbd",20305,"[NULL]","[NULL]"
+6824713399516000,6,162000,6824713399678000,15,"S",120,17179871812,13,"adbd",20305,"[NULL]","[NULL]"
+6824713401696000,0,372000,6824713402068000,15,"S",120,17179871826,13,"adbd",20305,"[NULL]","[NULL]"
+6824713402761000,4,165000,6824713402926000,15,"S",120,17179871830,13,"adbd",20305,"[NULL]","[NULL]"
+6824713405788000,5,62000,6824713405850000,15,"S",120,17179871860,13,"adbd",20305,"[NULL]","[NULL]"
+6824713407229000,6,96000,6824713407325000,15,"S",120,17179871866,13,"adbd",20305,"[NULL]","[NULL]"
+6824713409201000,6,60000,6824713409261000,15,"S",120,17179871881,13,"adbd",20305,"[NULL]","[NULL]"
+6824713415264000,6,114000,6824713415378000,15,"S",120,17179871889,13,"adbd",20305,"[NULL]","[NULL]"
+6824713417535000,6,118000,6824713417653000,15,"S",120,17179871910,13,"adbd",20305,"[NULL]","[NULL]"
+6824713419360000,6,50000,6824713419410000,15,"S",120,17179871925,13,"adbd",20305,"[NULL]","[NULL]"
+6824713420208000,6,90000,6824713420298000,15,"S",120,17179871929,13,"adbd",20305,"[NULL]","[NULL]"
+6824713421953000,6,52000,6824713422005000,15,"S",120,17179871946,13,"adbd",20305,"[NULL]","[NULL]"
+6824713423250000,6,81000,6824713423331000,15,"S",120,17179871949,13,"adbd",20305,"[NULL]","[NULL]"
+6824713425576000,6,50000,6824713425626000,15,"S",120,17179871969,13,"adbd",20305,"[NULL]","[NULL]"
+6824713428085000,6,99000,6824713428184000,15,"S",120,17179871975,13,"adbd",20305,"[NULL]","[NULL]"
+6824713431054000,6,118000,6824713431172000,15,"S",120,17179872005,13,"adbd",20305,"[NULL]","[NULL]"
+6824713433547000,5,47000,6824713433594000,15,"S",120,17179872031,13,"adbd",20305,"[NULL]","[NULL]"
+6824713435062000,6,101000,6824713435163000,15,"S",120,17179872035,13,"adbd",20305,"[NULL]","[NULL]"
+6824713436600000,6,53000,6824713436653000,15,"S",120,17179872051,13,"adbd",20305,"[NULL]","[NULL]"
+6824713437630000,6,82000,6824713437712000,15,"S",120,17179872060,13,"adbd",20305,"[NULL]","[NULL]"
+6824713438528000,6,43000,6824713438571000,15,"S",120,17179872083,13,"adbd",20305,"[NULL]","[NULL]"
+6824713440865000,6,84000,6824713440949000,15,"S",120,17179872087,13,"adbd",20305,"[NULL]","[NULL]"
+6824713442504000,6,45000,6824713442549000,15,"S",120,17179872105,13,"adbd",20305,"[NULL]","[NULL]"
+6824713444253000,6,82000,6824713444335000,15,"S",120,17179872115,13,"adbd",20305,"[NULL]","[NULL]"
+6824713445357000,6,38000,6824713445395000,15,"S",120,17179872128,13,"adbd",20305,"[NULL]","[NULL]"
+6824713448074000,6,85000,6824713448159000,15,"S",120,17179872132,13,"adbd",20305,"[NULL]","[NULL]"
+6824713449676000,6,51000,6824713449727000,15,"S",120,17179872148,13,"adbd",20305,"[NULL]","[NULL]"
+6824713452362000,6,87000,6824713452449000,15,"S",120,17179872158,13,"adbd",20305,"[NULL]","[NULL]"
+6824713454426000,6,45000,6824713454471000,15,"S",120,17179872172,13,"adbd",20305,"[NULL]","[NULL]"
+6824713456168000,6,83000,6824713456251000,15,"S",120,17179872176,13,"adbd",20305,"[NULL]","[NULL]"
+6824713457899000,6,46000,6824713457945000,15,"S",120,17179872196,13,"adbd",20305,"[NULL]","[NULL]"
+6824713460298000,5,97000,6824713460395000,15,"S",120,17179872202,13,"adbd",20305,"[NULL]","[NULL]"
+6824713461842000,5,49000,6824713461891000,15,"S",120,17179872220,13,"adbd",20305,"[NULL]","[NULL]"
+6824713464871000,5,85000,6824713464956000,15,"S",120,17179872249,13,"adbd",20305,"[NULL]","[NULL]"
+6824713466892000,4,113000,6824713467005000,15,"S",120,17179872272,13,"adbd",20305,"[NULL]","[NULL]"
+6824713469046000,4,43000,6824713469089000,15,"S",120,17179872296,13,"adbd",20305,"[NULL]","[NULL]"
+6824713471430000,4,246000,6824713471676000,15,"S",120,17179872316,13,"adbd",20305,"[NULL]","[NULL]"
+6824713474205000,4,149000,6824713474354000,15,"S",120,17179872344,13,"adbd",20305,"[NULL]","[NULL]"
+6824713475771000,4,98000,6824713475869000,15,"S",120,17179872364,13,"adbd",20305,"[NULL]","[NULL]"
+6824713477264000,4,40000,6824713477304000,15,"S",120,17179872379,13,"adbd",20305,"[NULL]","[NULL]"
+6824713539042000,5,1123000,6824713540165000,15,"S",120,17179872502,13,"adbd",20305,"[NULL]","[NULL]"
+6824713542368000,5,84000,6824713542452000,15,"S",120,17179872523,13,"adbd",20305,"[NULL]","[NULL]"
+6824711827060000,6,8000,6824711827068000,16,"S",120,17179869201,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711827100000,6,4000,6824711827104000,16,"S",120,17179869204,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711827113000,6,31000,6824711827144000,16,"S",120,17179869206,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711844180000,6,95000,6824711844275000,16,"D",120,17179869277,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711844847000,6,13000,6824711844860000,16,"S",120,17179869283,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711846666000,6,149000,6824711846815000,16,"S",120,17179869288,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711873308000,6,68000,6824711873376000,16,"D",120,17179869342,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711874041000,6,477000,6824711874518000,16,"D",120,17179869349,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711875190000,6,207000,6824711875397000,16,"D",120,17179869353,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711876064000,6,202000,6824711876266000,16,"D",120,17179869357,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711876376000,6,96000,6824711876472000,16,"D",120,17179869359,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711877176000,6,125000,6824711877301000,16,"D",120,17179869363,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711877979000,6,198000,6824711878177000,16,"D",120,17179869367,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711878649000,6,182000,6824711878831000,16,"D",120,17179869371,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711879277000,6,161000,6824711879438000,16,"D",120,17179869375,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711879550000,6,82000,6824711879632000,16,"D",120,17179869377,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711879801000,6,192000,6824711879993000,16,"D",120,17179869380,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711880224000,6,143000,6824711880367000,16,"D",120,17179869384,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711880553000,6,58000,6824711880611000,16,"S",120,17179869391,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711894328000,6,300000,6824711894628000,16,"D",120,17179869428,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711896996000,6,306000,6824711897302000,16,"D",120,17179869432,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711900978000,6,122000,6824711901100000,16,"S",120,17179869438,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711959299000,0,1274000,6824711960573000,16,"R+",120,17179869478,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711960627000,0,52000,6824711960679000,16,"D",120,17179869487,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711962583000,3,212000,6824711962795000,16,"D",120,17179869489,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711963469000,1,75000,6824711963544000,16,"S",120,17179869495,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712023719000,0,311000,6824712024030000,16,"S",120,17179869526,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712060258000,0,735000,6824712060993000,16,"R+",120,17179869553,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712061058000,0,280000,6824712061338000,16,"S",120,17179869559,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712076393000,1,162000,6824712076555000,16,"S",120,17179869571,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712126240000,0,149000,6824712126389000,16,"S",120,17179869603,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712130745000,0,331000,6824712131076000,16,"R+",120,17179869619,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712131278000,0,65000,6824712131343000,16,"R+",120,17179869621,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712160201000,0,878000,6824712161079000,16,"S",120,17179869648,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712192248000,0,299000,6824712192547000,16,"S",120,17179869663,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712528168000,0,70000,6824712528238000,16,"S",120,17179869896,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712561706000,0,1079000,6824712562785000,16,"S",120,17179869923,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712628128000,0,134000,6824712628262000,16,"S",120,17179869973,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712642452000,0,1867000,6824712644319000,16,"R+",120,17179869987,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712645257000,0,107000,6824712645364000,16,"S",120,17179869991,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712652142000,0,349000,6824712652491000,16,"S",120,17179870033,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712652870000,0,45000,6824712652915000,16,"S",120,17179870035,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712660137000,0,391000,6824712660528000,16,"S",120,17179870052,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712689667000,0,99000,6824712689766000,16,"S",120,17179870074,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712703122000,0,62000,6824712703184000,16,"D",120,17179870103,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712703438000,0,613000,6824712704051000,16,"D",120,17179870108,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712704180000,0,129000,6824712704309000,16,"D",120,17179870110,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712704423000,0,123000,6824712704546000,16,"D",120,17179870112,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712704653000,0,136000,6824712704789000,16,"D",120,17179870114,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712705467000,0,160000,6824712705627000,16,"D",120,17179870117,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712705748000,0,124000,6824712705872000,16,"D",120,17179870119,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712706008000,0,152000,6824712706160000,16,"D",120,17179870121,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712706274000,0,125000,6824712706399000,16,"D",120,17179870123,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712707320000,0,162000,6824712707482000,16,"D",120,17179870128,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712707587000,0,128000,6824712707715000,16,"D",120,17179870130,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712707830000,0,124000,6824712707954000,16,"D",120,17179870132,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712708064000,0,140000,6824712708204000,16,"D",120,17179870134,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712708318000,0,82000,6824712708400000,16,"S",120,17179870136,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712758349000,3,119000,6824712758468000,16,"S",120,17179870184,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712760172000,0,509000,6824712760681000,16,"S",120,17179870194,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712829763000,0,134000,6824712829897000,16,"S",120,17179870236,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712860337000,0,922000,6824712861259000,16,"S",120,17179870275,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712877300000,0,156000,6824712877456000,16,"S",120,17179870336,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712926764000,1,82000,6824712926846000,16,"S",120,17179870486,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712962499000,0,997000,6824712963496000,16,"S",120,17179870525,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824712976783000,1,140000,6824712976923000,16,"S",120,17179870551,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713027078000,1,93000,6824713027171000,16,"S",120,17179870658,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713063643000,1,682000,6824713064325000,16,"S",120,17179870736,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713076743000,1,148000,6824713076891000,16,"D",120,17179870779,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713077090000,1,16000,6824713077106000,16,"S",120,17179870781,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713126913000,2,467000,6824713127380000,16,"R+",120,17179870954,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713127578000,2,33000,6824713127611000,16,"S",120,17179870959,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713163653000,2,751000,6824713164404000,16,"S",120,17179871086,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713177043000,2,352000,6824713177395000,16,"D",120,17179871133,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713177893000,2,35000,6824713177928000,16,"S",120,17179871137,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713226952000,2,113000,6824713227065000,16,"S",120,17179871280,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713263357000,1,1008000,6824713264365000,16,"S",120,17179871425,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713276643000,1,103000,6824713276746000,16,"S",120,17179871459,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713326940000,2,357000,6824713327297000,16,"D",120,17179871549,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713327451000,2,31000,6824713327482000,16,"S",120,17179871551,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713363482000,2,776000,6824713364258000,16,"S",120,17179871677,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713377045000,2,741000,6824713377786000,16,"S",120,17179871716,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713426874000,2,103000,6824713426977000,16,"S",120,17179871971,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713463618000,2,521000,6824713464139000,16,"S",120,17179872236,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713476626000,5,41000,6824713476667000,16,"S",120,17179872370,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713528991000,0,531000,6824713529522000,16,"R+",120,17179872464,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713530246000,0,81000,6824713530327000,16,"S",120,17179872477,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713563641000,0,888000,6824713564529000,16,"S",120,17179872567,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713580578000,0,647000,6824713581225000,16,"D",120,17179872612,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713582275000,0,89000,6824713582364000,16,"S",120,17179872619,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824713631086000,0,116000,6824713631202000,16,"S",120,17179872688,14,"kworker/u16:7",19422,"[NULL]","[NULL]"
+6824711827138000,7,5000,6824711827143000,17,"S",120,17179869207,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712131989000,7,56000,6824712132045000,17,"S",120,17179869623,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712194398000,7,72000,6824712194470000,17,"S",120,17179869671,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712247262000,7,203000,6824712247465000,17,"S",120,17179869710,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712262000000,7,773000,6824712262773000,17,"S",120,17179869729,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712296993000,1,153000,6824712297146000,17,"S",120,17179869763,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712361094000,0,1024000,6824712362118000,17,"S",120,17179869797,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712427607000,0,142000,6824712427749000,17,"S",120,17179869835,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712461170000,0,668000,6824712461838000,17,"R+",120,17179869854,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712462031000,0,281000,6824712462312000,17,"S",120,17179869861,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712494775000,0,149000,6824712494924000,17,"S",120,17179869876,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712527065000,0,125000,6824712527190000,17,"S",120,17179869892,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712644410000,0,777000,6824712645187000,17,"D",120,17179869989,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712645969000,0,204000,6824712646173000,17,"D",120,17179869993,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712646296000,0,140000,6824712646436000,17,"D",120,17179869995,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712646701000,0,144000,6824712646845000,17,"D",120,17179869999,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712646969000,0,167000,6824712647136000,17,"D",120,17179870001,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712647289000,0,146000,6824712647435000,17,"D",120,17179870004,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712648428000,0,169000,6824712648597000,17,"D",120,17179870007,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712648716000,0,149000,6824712648865000,17,"D",120,17179870009,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712648981000,0,150000,6824712649131000,17,"D",120,17179870012,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712649244000,0,139000,6824712649383000,17,"D",120,17179870014,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712649503000,0,130000,6824712649633000,17,"R+",120,17179870017,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712649661000,0,41000,6824712649702000,17,"D",120,17179870019,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712649760000,0,262000,6824712650022000,17,"R+",120,17179870021,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712650101000,0,134000,6824712650235000,17,"R+",120,17179870024,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712650262000,0,42000,6824712650304000,17,"D",120,17179870026,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712650395000,0,177000,6824712650572000,17,"R+",120,17179870028,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712650635000,0,222000,6824712650857000,17,"D",120,17179870030,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712652034000,0,108000,6824712652142000,17,"R+",120,17179870032,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824712652491000,0,379000,6824712652870000,17,"S",120,17179870034,16,"kworker/u16:2",19725,"[NULL]","[NULL]"
+6824711827287000,3,999000,6824711828286000,18,"x",120,17179869211,17,"sh",20447,"[NULL]","[NULL]"
+6824711828286000,3,281000,6824711828567000,19,"x",120,17179869212,13,"shell",20448,"[NULL]","[NULL]"
+6824711828567000,3,8000,6824711828575000,20,"S",120,17179869213,18,"rcuos/2",29,"[NULL]","[NULL]"
+6824711846909000,3,64000,6824711846973000,20,"S",120,17179869292,18,"rcuos/2",29,"[NULL]","[NULL]"
+6824712863315000,3,230000,6824712863545000,20,"S",120,17179870288,18,"rcuos/2",29,"[NULL]","[NULL]"
+6824712877419000,3,189000,6824712877608000,20,"S",120,17179870337,18,"rcuos/2",29,"[NULL]","[NULL]"
+6824712891393000,3,58000,6824712891451000,20,"S",120,17179870357,18,"rcuos/2",29,"[NULL]","[NULL]"
+6824712916779000,3,89000,6824712916868000,20,"S",120,17179870443,18,"rcuos/2",29,"[NULL]","[NULL]"
+6824712923739000,3,108000,6824712923847000,20,"S",120,17179870479,18,"rcuos/2",29,"[NULL]","[NULL]"
+6824712930338000,3,37000,6824712930375000,20,"S",120,17179870500,18,"rcuos/2",29,"[NULL]","[NULL]"
+6824713473109000,5,8000,6824713473117000,20,"S",120,17179872334,18,"rcuos/2",29,"[NULL]","[NULL]"
+6824713484813000,5,36000,6824713484849000,20,"S",120,17179872385,18,"rcuos/2",29,"[NULL]","[NULL]"
+6824711833286000,5,153000,6824711833439000,21,"R+",120,17179869247,19,"kswapd0",150,"[NULL]","[NULL]"
+6824711833513000,5,994000,6824711834507000,21,"S",120,17179869252,19,"kswapd0",150,"[NULL]","[NULL]"
+6824711935090000,5,59000,6824711935149000,21,"S",120,17179869469,19,"kswapd0",150,"[NULL]","[NULL]"
+6824711833250000,5,36000,6824711833286000,22,"S",49,17179869246,20,"sugov:4",606,"[NULL]","[NULL]"
+6824711860779000,6,128000,6824711860907000,22,"S",49,17179869324,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713253403000,6,156000,6824713253559000,22,"S",49,17179871363,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713329043000,6,147000,6824713329190000,22,"S",49,17179871563,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713333331000,6,103000,6824713333434000,22,"S",49,17179871602,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713343236000,6,17000,6824713343253000,22,"S",49,17179871610,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713344097000,6,32000,6824713344129000,22,"S",49,17179871618,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713351519000,6,22000,6824713351541000,22,"S",49,17179871623,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713363280000,6,49000,6824713363329000,22,"S",49,17179871674,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713370024000,6,36000,6824713370060000,22,"S",49,17179871695,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713381295000,6,45000,6824713381340000,22,"S",49,17179871726,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713383240000,6,170000,6824713383410000,22,"D",49,17179871735,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713384362000,4,24000,6824713384386000,22,"S",49,17179871746,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713402952000,6,43000,6824713402995000,22,"S",49,17179871833,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713467338000,7,249000,6824713467587000,22,"D",49,17179872276,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713468262000,4,82000,6824713468344000,22,"S",49,17179872283,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713468380000,4,232000,6824713468612000,22,"D",49,17179872285,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713469242000,4,14000,6824713469256000,22,"S",49,17179872299,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713504426000,5,314000,6824713504740000,22,"D",49,17179872429,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713508535000,4,250000,6824713508785000,22,"S",49,17179872440,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713562621000,5,180000,6824713562801000,22,"S",49,17179872561,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713583320000,5,148000,6824713583468000,22,"S",49,17179872621,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713603274000,5,115000,6824713603389000,22,"S",49,17179872667,20,"sugov:4",606,"[NULL]","[NULL]"
+6824713621250000,5,138000,6824713621388000,22,"S",49,17179872669,20,"sugov:4",606,"[NULL]","[NULL]"
+6824711833439000,5,74000,6824711833513000,23,"S",120,17179869249,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824711846773000,5,35000,6824711846808000,23,"S",120,17179869289,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824711873519000,0,76000,6824711873595000,23,"S",120,17179869345,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824711893560000,0,38000,6824711893598000,23,"S",120,17179869422,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824712853478000,2,128000,6824712853606000,23,"S",120,17179870267,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824712863467000,2,80000,6824712863547000,23,"S",120,17179870290,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824712877070000,2,86000,6824712877156000,23,"S",120,17179870333,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824712890890000,2,188000,6824712891078000,23,"S",120,17179870353,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824712896729000,2,38000,6824712896767000,23,"S",120,17179870376,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824712899889000,2,124000,6824712900013000,23,"S",120,17179870386,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824712907400000,2,66000,6824712907466000,23,"S",120,17179870396,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824712913992000,2,65000,6824712914057000,23,"S",120,17179870435,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824712914727000,2,46000,6824712914773000,23,"S",120,17179870438,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824712920741000,2,90000,6824712920831000,23,"S",120,17179870453,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824712933685000,2,248000,6824712933933000,23,"S",120,17179870511,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824712942785000,1,171000,6824712942956000,23,"S",120,17179870517,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824713274011000,2,24000,6824713274035000,23,"S",120,17179871452,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824713280807000,2,27000,6824713280834000,23,"S",120,17179871470,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824713470882000,3,62000,6824713470944000,23,"S",120,17179872310,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824713492440000,3,215000,6824713492655000,23,"S",120,17179872400,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824713517709000,0,229000,6824713517938000,23,"S",120,17179872447,21,"rcuop/2",28,"[NULL]","[NULL]"
+6824711834230000,2,26000,6824711834256000,24,"S",120,17179869253,22,"rcuop/3",36,"[NULL]","[NULL]"
+6824711847022000,2,328000,6824711847350000,24,"S",120,17179869294,22,"rcuop/3",36,"[NULL]","[NULL]"
+6824713517917000,2,73000,6824713517990000,24,"S",120,17179872448,22,"rcuop/3",36,"[NULL]","[NULL]"
+6824711840142000,2,74000,6824711840216000,25,"S",120,17179869257,24,"ksoftirqd/2",25,"[NULL]","[NULL]"
+6824712124682000,2,304000,6824712124986000,25,"S",120,17179869595,24,"ksoftirqd/2",25,"[NULL]","[NULL]"
+6824712326939000,2,165000,6824712327104000,25,"S",120,17179869769,24,"ksoftirqd/2",25,"[NULL]","[NULL]"
+6824712563537000,2,61000,6824712563598000,25,"S",120,17179869933,24,"ksoftirqd/2",25,"[NULL]","[NULL]"
+6824712841394000,2,165000,6824712841559000,25,"S",120,17179870257,24,"ksoftirqd/2",25,"[NULL]","[NULL]"
+6824712961799000,2,620000,6824712962419000,25,"S",120,17179870519,24,"ksoftirqd/2",25,"[NULL]","[NULL]"
+6824713403325000,2,97000,6824713403422000,25,"S",120,17179871836,24,"ksoftirqd/2",25,"[NULL]","[NULL]"
+6824713507160000,2,99000,6824713507259000,25,"S",120,17179872436,24,"ksoftirqd/2",25,"[NULL]","[NULL]"
+6824713528770000,2,179000,6824713528949000,25,"S",120,17179872461,24,"ksoftirqd/2",25,"[NULL]","[NULL]"
+6824711840034000,2,108000,6824711840142000,26,"S",49,17179869256,23,"sugov:0",605,"[NULL]","[NULL]"
+6824711843390000,2,108000,6824711843498000,26,"S",49,17179869273,23,"sugov:0",605,"[NULL]","[NULL]"
+6824711865947000,0,139000,6824711866086000,26,"S",49,17179869333,23,"sugov:0",605,"[NULL]","[NULL]"
+6824712883536000,2,224000,6824712883760000,26,"S",49,17179870345,23,"sugov:0",605,"[NULL]","[NULL]"
+6824712903346000,2,197000,6824712903543000,26,"S",49,17179870392,23,"sugov:0",605,"[NULL]","[NULL]"
+6824712920931000,2,327000,6824712921258000,26,"S",49,17179870459,23,"sugov:0",605,"[NULL]","[NULL]"
+6824712942286000,1,302000,6824712942588000,26,"S",49,17179870515,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713003341000,1,209000,6824713003550000,26,"S",49,17179870628,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713020699000,1,225000,6824713020924000,26,"S",49,17179870641,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713043361000,0,195000,6824713043556000,26,"S",49,17179870694,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713046588000,0,37000,6824713046625000,26,"S",49,17179870698,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713063315000,0,161000,6824713063476000,26,"S",49,17179870734,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713096641000,0,233000,6824713096874000,26,"S",49,17179870856,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713098643000,1,113000,6824713098756000,26,"S",49,17179870863,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713129965000,0,223000,6824713130188000,26,"S",49,17179870969,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713130937000,1,114000,6824713131051000,26,"S",49,17179870976,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713166683000,2,227000,6824713166910000,26,"S",49,17179871102,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713167882000,1,132000,6824713168014000,26,"S",49,17179871119,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713196629000,0,168000,6824713196797000,26,"S",49,17179871211,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713199080000,1,118000,6824713199198000,26,"S",49,17179871219,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713250920000,0,247000,6824713251167000,26,"S",49,17179871352,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713255788000,1,140000,6824713255928000,26,"S",49,17179871380,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713256661000,1,87000,6824713256748000,26,"S",49,17179871382,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713280018000,1,235000,6824713280253000,26,"S",49,17179871466,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713280632000,2,120000,6824713280752000,26,"S",49,17179871468,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713303330000,1,176000,6824713303506000,26,"S",49,17179871517,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713306621000,1,71000,6824713306692000,26,"S",49,17179871519,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713323323000,1,140000,6824713323463000,26,"S",49,17179871539,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713343632000,2,147000,6824713343779000,26,"S",49,17179871612,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713372709000,0,188000,6824713372897000,26,"S",49,17179871700,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713380539000,2,133000,6824713380672000,26,"S",49,17179871720,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713381206000,2,75000,6824713381281000,26,"S",49,17179871724,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713404321000,0,140000,6824713404461000,26,"S",49,17179871846,23,"sugov:0",605,"[NULL]","[NULL]"
+6824713631775000,2,255000,6824713632030000,26,"S",49,17179872694,23,"sugov:0",605,"[NULL]","[NULL]"
+6824711841071000,5,11000,6824711841082000,27,"S",120,17179869262,25,"rcuos/4",45,"[NULL]","[NULL]"
+6824711861052000,6,50000,6824711861102000,27,"S",120,17179869327,25,"rcuos/4",45,"[NULL]","[NULL]"
+6824713466071000,6,16000,6824713466087000,27,"S",120,17179872260,25,"rcuos/4",45,"[NULL]","[NULL]"
+6824713477142000,7,19000,6824713477161000,27,"S",120,17179872377,25,"rcuos/4",45,"[NULL]","[NULL]"
+6824713538441000,7,113000,6824713538554000,27,"S",120,17179872498,25,"rcuos/4",45,"[NULL]","[NULL]"
+6824713543991000,7,134000,6824713544125000,27,"S",120,17179872530,25,"rcuos/4",45,"[NULL]","[NULL]"
+6824713550624000,7,88000,6824713550712000,27,"S",120,17179872548,25,"rcuos/4",45,"[NULL]","[NULL]"
+6824713574357000,7,104000,6824713574461000,27,"S",120,17179872602,25,"rcuos/4",45,"[NULL]","[NULL]"
+6824713587449000,7,83000,6824713587532000,27,"S",120,17179872630,25,"rcuos/4",45,"[NULL]","[NULL]"
+6824713594142000,7,54000,6824713594196000,27,"S",120,17179872642,25,"rcuos/4",45,"[NULL]","[NULL]"
+6824711841104000,7,11000,6824711841115000,28,"S",120,17179869265,26,"rcuos/6",61,"[NULL]","[NULL]"
+6824713255160000,7,39000,6824713255199000,28,"S",120,17179871376,26,"rcuos/6",61,"[NULL]","[NULL]"
+6824713261485000,7,50000,6824713261535000,28,"S",120,17179871412,26,"rcuos/6",61,"[NULL]","[NULL]"
+6824711841115000,7,12000,6824711841127000,29,"S",120,17179869266,27,"rcuos/7",69,"[NULL]","[NULL]"
+6824711841127000,7,10000,6824711841137000,30,"S",120,17179869267,28,"kworker/7:2",14813,"[NULL]","[NULL]"
+6824713457544000,7,12000,6824713457556000,30,"S",120,17179872190,28,"kworker/7:2",14813,"[NULL]","[NULL]"
+6824713457871000,7,12000,6824713457883000,30,"S",120,17179872194,28,"kworker/7:2",14813,"[NULL]","[NULL]"
+6824713460706000,7,8000,6824713460714000,30,"S",120,17179872205,28,"kworker/7:2",14813,"[NULL]","[NULL]"
+6824713461051000,7,8000,6824713461059000,30,"S",120,17179872208,28,"kworker/7:2",14813,"[NULL]","[NULL]"
+6824713461641000,7,13000,6824713461654000,30,"S",120,17179872216,28,"kworker/7:2",14813,"[NULL]","[NULL]"
+6824713465250000,7,9000,6824713465259000,30,"S",120,17179872254,28,"kworker/7:2",14813,"[NULL]","[NULL]"
+6824713466308000,7,8000,6824713466316000,30,"S",120,17179872266,28,"kworker/7:2",14813,"[NULL]","[NULL]"
+6824713466666000,7,11000,6824713466677000,30,"S",120,17179872270,28,"kworker/7:2",14813,"[NULL]","[NULL]"
+6824713467657000,7,50000,6824713467707000,30,"S",120,17179872278,28,"kworker/7:2",14813,"[NULL]","[NULL]"
+6824711844222000,2,48000,6824711844270000,31,"S",120,17179869278,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824712260333000,2,128000,6824712260461000,31,"S",120,17179869722,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824712860206000,2,85000,6824712860291000,31,"S",120,17179870273,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824712908994000,2,81000,6824712909075000,31,"S",120,17179870404,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824712909328000,2,49000,6824712909377000,31,"R+",120,17179870408,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824712909398000,2,10000,6824712909408000,31,"S",120,17179870410,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824712910268000,2,37000,6824712910305000,31,"R",120,17179870419,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824712910340000,2,34000,6824712910374000,31,"R",120,17179870421,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824712910420000,2,78000,6824712910498000,31,"S",120,17179870423,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824712911438000,2,42000,6824712911480000,31,"S",120,17179870431,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824712962419000,2,165000,6824712962584000,31,"S",120,17179870524,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713072529000,2,26000,6824713072555000,31,"S",120,17179870762,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713072935000,2,32000,6824713072967000,31,"S",120,17179870768,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713080347000,2,41000,6824713080388000,31,"S",120,17179870797,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713080863000,2,43000,6824713080906000,31,"S",120,17179870803,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713088526000,2,74000,6824713088600000,31,"S",120,17179870819,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713111865000,2,64000,6824713111929000,31,"S",120,17179870910,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713122688000,2,30000,6824713122718000,31,"S",120,17179870936,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713123070000,2,76000,6824713123146000,31,"S",120,17179870944,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713133142000,2,65000,6824713133207000,31,"S",120,17179870990,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713133327000,2,20000,6824713133347000,31,"S",120,17179870993,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713133620000,2,86000,6824713133706000,31,"S",120,17179871001,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713144730000,2,57000,6824713144787000,31,"S",120,17179871030,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713155879000,2,58000,6824713155937000,31,"S",120,17179871060,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713156209000,2,45000,6824713156254000,31,"S",120,17179871068,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713207174000,2,56000,6824713207230000,31,"S",120,17179871244,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713226236000,2,76000,6824713226312000,31,"S",120,17179871272,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713226370000,2,20000,6824713226390000,31,"S",120,17179871275,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713257118000,2,59000,6824713257177000,31,"R+",120,17179871385,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713257241000,2,60000,6824713257301000,31,"R+",120,17179871388,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713257327000,2,72000,6824713257399000,31,"S",120,17179871390,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713257646000,2,44000,6824713257690000,31,"S",120,17179871393,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713331324000,2,62000,6824713331386000,31,"S",120,17179871583,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713331456000,2,12000,6824713331468000,31,"S",120,17179871586,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713331823000,2,43000,6824713331866000,31,"S",120,17179871594,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713408789000,2,105000,6824713408894000,31,"S",120,17179871878,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713415904000,2,176000,6824713416080000,31,"S",120,17179871892,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713416908000,2,119000,6824713417027000,31,"S",120,17179871907,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713418155000,2,178000,6824713418333000,31,"S",120,17179871913,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713418952000,2,87000,6824713419039000,31,"S",120,17179871922,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713420769000,2,111000,6824713420880000,31,"S",120,17179871932,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713421093000,2,133000,6824713421226000,31,"S",120,17179871935,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713425198000,2,89000,6824713425287000,31,"S",120,17179871966,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824713475281000,2,288000,6824713475569000,31,"S",120,17179872354,29,"kworker/2:0",18823,"[NULL]","[NULL]"
+6824711844547000,3,172000,6824711844719000,32,"S",120,17179869281,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711874600000,3,138000,6824711874738000,32,"S",120,17179869351,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711875658000,3,86000,6824711875744000,32,"S",120,17179869355,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711876473000,3,71000,6824711876544000,32,"S",120,17179869361,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711877327000,3,143000,6824711877470000,32,"S",120,17179869365,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711878186000,3,193000,6824711878379000,32,"S",120,17179869369,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711878848000,3,140000,6824711878988000,32,"S",120,17179869373,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711879654000,3,182000,6824711879836000,32,"S",120,17179869379,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711880234000,3,64000,6824711880298000,32,"S",120,17179869385,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711880392000,3,202000,6824711880594000,32,"S",120,17179869390,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711894870000,3,77000,6824711894947000,32,"S",120,17179869430,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711899236000,3,257000,6824711899493000,32,"S",120,17179869436,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711904187000,3,212000,6824711904399000,32,"S",120,17179869442,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711960573000,0,54000,6824711960627000,32,"S",120,17179869486,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711963017000,0,225000,6824711963242000,32,"S",120,17179869492,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712645187000,0,70000,6824712645257000,32,"S",120,17179869990,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712646173000,0,123000,6824712646296000,32,"S",120,17179869994,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712646436000,0,48000,6824712646484000,32,"S",120,17179869996,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712646845000,0,124000,6824712646969000,32,"S",120,17179870000,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712647136000,0,49000,6824712647185000,32,"S",120,17179870002,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712647435000,0,48000,6824712647483000,32,"S",120,17179870005,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712648597000,0,119000,6824712648716000,32,"S",120,17179870008,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712648865000,0,54000,6824712648919000,32,"S",120,17179870010,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712649131000,0,113000,6824712649244000,32,"S",120,17179870013,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712649383000,0,48000,6824712649431000,32,"S",120,17179870015,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712649633000,0,28000,6824712649661000,32,"S",120,17179870018,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712650067000,0,34000,6824712650101000,32,"S",120,17179870023,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712650235000,0,27000,6824712650262000,32,"S",120,17179870025,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712650572000,0,63000,6824712650635000,32,"S",120,17179870029,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712666145000,0,109000,6824712666254000,32,"S",120,17179870069,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712704051000,0,129000,6824712704180000,32,"S",120,17179870109,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712704309000,0,114000,6824712704423000,32,"S",120,17179870111,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712704546000,0,107000,6824712704653000,32,"S",120,17179870113,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712704789000,0,50000,6824712704839000,32,"S",120,17179870115,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712705627000,0,121000,6824712705748000,32,"S",120,17179870118,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712705872000,0,136000,6824712706008000,32,"S",120,17179870120,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712706160000,0,114000,6824712706274000,32,"S",120,17179870122,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712706399000,0,48000,6824712706447000,32,"S",120,17179870124,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712707482000,0,105000,6824712707587000,32,"S",120,17179870129,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712707715000,0,115000,6824712707830000,32,"S",120,17179870131,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712707954000,0,110000,6824712708064000,32,"S",120,17179870133,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712708204000,0,114000,6824712708318000,32,"S",120,17179870135,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824712733142000,0,190000,6824712733332000,32,"S",120,17179870181,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824713077103000,2,19000,6824713077122000,32,"S",120,17179870782,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824713127530000,3,44000,6824713127574000,32,"S",120,17179870957,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824713177695000,3,144000,6824713177839000,32,"S",120,17179871135,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824713327679000,3,43000,6824713327722000,32,"S",120,17179871553,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824713378015000,3,111000,6824713378126000,32,"S",120,17179871718,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824713383790000,3,60000,6824713383850000,32,"S",120,17179871741,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824713467909000,3,104000,6824713468013000,32,"S",120,17179872280,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824713469040000,3,71000,6824713469111000,32,"S",120,17179872295,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824713506860000,3,291000,6824713507151000,32,"S",120,17179872432,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824713530124000,3,93000,6824713530217000,32,"S",120,17179872474,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824713581760000,3,187000,6824713581947000,32,"S",120,17179872615,30,"smem_native_rpm",87,"[NULL]","[NULL]"
+6824711846973000,3,63000,6824711847036000,33,"S",120,17179869293,31,"rcuos/3",37,"[NULL]","[NULL]"
+6824711850532000,3,50000,6824711850582000,34,"S",120,17179869297,32,"ksoftirqd/3",33,"[NULL]","[NULL]"
+6824712758312000,3,37000,6824712758349000,34,"S",120,17179870183,32,"ksoftirqd/3",33,"[NULL]","[NULL]"
+6824711854169000,0,120000,6824711854289000,35,"S",120,17179869302,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824711873595000,0,115000,6824711873710000,35,"S",120,17179869346,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824711887462000,0,118000,6824711887580000,35,"S",120,17179869399,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824711893650000,0,78000,6824711893728000,35,"D",120,17179869424,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824711893793000,0,59000,6824711893852000,35,"S",120,17179869426,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824711921407000,0,185000,6824711921592000,35,"S",120,17179869448,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824711958612000,0,107000,6824711958719000,35,"S",120,17179869474,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824711991036000,0,265000,6824711991301000,35,"S",120,17179869499,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712022382000,0,182000,6824712022564000,35,"S",120,17179869522,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712058992000,0,265000,6824712059257000,35,"S",120,17179869546,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712090598000,0,224000,6824712090822000,35,"S",120,17179869573,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712125136000,0,150000,6824712125286000,35,"S",120,17179869597,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712157572000,0,451000,6824712158023000,35,"S",120,17179869634,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712161079000,0,86000,6824712161165000,35,"S",120,17179869649,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712192109000,0,139000,6824712192248000,35,"S",120,17179869662,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712225475000,0,204000,6824712225679000,35,"S",120,17179869683,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712258037000,0,225000,6824712258262000,35,"S",120,17179869714,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712287910000,0,209000,6824712288119000,35,"R+",120,17179869741,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712290025000,0,115000,6824712290140000,35,"S",120,17179869746,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712327409000,0,171000,6824712327580000,35,"S",120,17179869771,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712359169000,0,225000,6824712359394000,35,"S",120,17179869790,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712361009000,0,85000,6824712361094000,35,"S",120,17179869795,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712392893000,0,266000,6824712393159000,35,"S",120,17179869811,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712426149000,0,223000,6824712426372000,35,"S",120,17179869830,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712459619000,0,225000,6824712459844000,35,"S",120,17179869850,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712461898000,0,133000,6824712462031000,35,"S",120,17179869859,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712493112000,0,746000,6824712493858000,35,"S",120,17179869871,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712526884000,0,181000,6824712527065000,35,"S",120,17179869891,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712560085000,0,224000,6824712560309000,35,"S",120,17179869917,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712562785000,0,106000,6824712562891000,35,"S",120,17179869927,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712591834000,0,141000,6824712591975000,35,"S",120,17179869944,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712627048000,0,215000,6824712627263000,35,"S",120,17179869966,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712657652000,0,93000,6824712657745000,35,"S",120,17179870041,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712660040000,0,97000,6824712660137000,35,"S",120,17179870050,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712691331000,0,95000,6824712691426000,35,"S",120,17179870076,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712703338000,0,51000,6824712703389000,35,"D",120,17179870106,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712907279000,0,57000,6824712907336000,35,"S",120,17179870394,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712920457000,0,98000,6824712920555000,35,"S",120,17179870450,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712920871000,0,56000,6824712920927000,35,"R+",120,17179870457,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712920955000,0,8000,6824712920963000,35,"S",120,17179870460,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712921150000,0,50000,6824712921200000,35,"R+",120,17179870464,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712921248000,0,48000,6824712921296000,35,"R+",120,17179870466,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712921334000,0,41000,6824712921375000,35,"S",120,17179870470,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712922147000,0,31000,6824712922178000,35,"S",120,17179870475,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712925838000,0,33000,6824712925871000,35,"R+",120,17179870482,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712926516000,0,30000,6824712926546000,35,"S",120,17179870484,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712961802000,0,176000,6824712961978000,35,"S",120,17179870520,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712964184000,0,198000,6824712964382000,35,"S",120,17179870535,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824712992938000,0,152000,6824712993090000,35,"S",120,17179870594,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713026023000,0,91000,6824713026114000,35,"S",120,17179870654,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713059527000,0,91000,6824713059618000,35,"S",120,17179870716,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713060353000,0,48000,6824713060401000,35,"S",120,17179870718,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713092987000,0,74000,6824713093061000,35,"S",120,17179870837,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713126463000,0,72000,6824713126535000,35,"S",120,17179870951,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713160021000,0,109000,6824713160130000,35,"S",120,17179871073,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713193444000,0,76000,6824713193520000,35,"S",120,17179871197,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713226912000,0,65000,6824713226977000,35,"S",120,17179871278,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713260789000,0,106000,6824713260895000,35,"S",120,17179871406,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713290165000,0,67000,6824713290232000,35,"S",120,17179871482,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713294190000,0,70000,6824713294260000,35,"S",120,17179871490,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713327713000,0,92000,6824713327805000,35,"S",120,17179871554,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713361389000,0,127000,6824713361516000,35,"R+",120,17179871653,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713361560000,0,61000,6824713361621000,35,"R+",120,17179871658,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713361654000,0,67000,6824713361721000,35,"S",120,17179871660,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713362056000,0,69000,6824713362125000,35,"S",120,17179871667,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713372971000,0,177000,6824713373148000,35,"R+",120,17179871703,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713373212000,0,142000,6824713373354000,35,"R+",120,17179871707,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713373433000,0,170000,6824713373603000,35,"S",120,17179871709,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713382639000,0,173000,6824713382812000,35,"S",120,17179871732,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713383658000,0,115000,6824713383773000,35,"R+",120,17179871738,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713383826000,0,167000,6824713383993000,35,"S",120,17179871742,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713390182000,0,178000,6824713390360000,35,"S",120,17179871758,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713390923000,0,144000,6824713391067000,35,"S",120,17179871762,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713391968000,0,163000,6824713392131000,35,"S",120,17179871768,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713393446000,0,64000,6824713393510000,35,"S",120,17179871776,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713393863000,0,110000,6824713393973000,35,"R+",120,17179871782,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713394008000,0,46000,6824713394054000,35,"S",120,17179871785,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713394400000,0,224000,6824713394624000,35,"S",120,17179871790,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713400331000,0,120000,6824713400451000,35,"S",120,17179871815,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713400564000,0,40000,6824713400604000,35,"R+",120,17179871817,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713400638000,0,17000,6824713400655000,35,"S",120,17179871819,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713401264000,0,103000,6824713401367000,35,"S",120,17179871823,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713403583000,0,99000,6824713403682000,35,"S",120,17179871839,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713404516000,0,125000,6824713404641000,35,"S",120,17179871849,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713408526000,0,129000,6824713408655000,35,"S",120,17179871873,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713416271000,0,81000,6824713416352000,35,"S",120,17179871898,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713428138000,0,104000,6824713428242000,35,"S",120,17179871976,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713461340000,0,109000,6824713461449000,35,"S",120,17179872211,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713472172000,0,119000,6824713472291000,35,"S",120,17179872321,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713473538000,0,135000,6824713473673000,35,"S",120,17179872337,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713474727000,0,110000,6824713474837000,35,"S",120,17179872348,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713475454000,0,114000,6824713475568000,35,"S",120,17179872360,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713495159000,0,143000,6824713495302000,35,"S",120,17179872403,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713528816000,0,175000,6824713528991000,35,"S",120,17179872462,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713529657000,0,56000,6824713529713000,35,"R+",120,17179872469,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713529768000,0,119000,6824713529887000,35,"R+",120,17179872471,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713530101000,0,105000,6824713530206000,35,"S",120,17179872473,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713540332000,0,118000,6824713540450000,35,"S",120,17179872509,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713562094000,0,235000,6824713562329000,35,"S",120,17179872559,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713564529000,0,91000,6824713564620000,35,"S",120,17179872572,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713566598000,0,117000,6824713566715000,35,"S",120,17179872580,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713597240000,0,240000,6824713597480000,35,"S",120,17179872647,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824713629430000,0,258000,6824713629688000,35,"S",120,17179872682,33,"kworker/0:5",20371,"[NULL]","[NULL]"
+6824711854448000,1,404000,6824711854852000,36,"S",111,17179869304,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824711887766000,1,377000,6824711888143000,36,"S",111,17179869401,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824711921592000,0,726000,6824711922318000,36,"S",111,17179869449,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824711958719000,0,580000,6824711959299000,36,"S",111,17179869476,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824711991301000,0,902000,6824711992203000,36,"S",111,17179869500,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712022564000,0,1155000,6824712023719000,36,"S",111,17179869523,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712059257000,0,1001000,6824712060258000,36,"S",111,17179869547,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712090822000,0,1321000,6824712092143000,36,"S",111,17179869574,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712125286000,0,705000,6824712125991000,36,"R+",111,17179869598,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712126041000,0,199000,6824712126240000,36,"S",111,17179869601,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712158023000,0,992000,6824712159015000,36,"S",111,17179869635,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712192547000,0,966000,6824712193513000,36,"S",111,17179869664,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712225679000,0,916000,6824712226595000,36,"S",111,17179869684,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712258262000,0,1133000,6824712259395000,36,"S",111,17179869715,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712290140000,0,986000,6824712291126000,36,"S",111,17179869747,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712327580000,0,701000,6824712328281000,36,"R+",111,17179869772,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712328333000,0,226000,6824712328559000,36,"S",111,17179869775,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712359394000,0,1615000,6824712361009000,36,"S",111,17179869791,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712393159000,0,1045000,6824712394204000,36,"S",111,17179869813,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712426372000,0,1235000,6824712427607000,36,"S",111,17179869831,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712459844000,0,1326000,6824712461170000,36,"S",111,17179869851,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712493858000,0,917000,6824712494775000,36,"S",111,17179869872,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712527190000,0,978000,6824712528168000,36,"S",111,17179869893,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712560309000,0,1129000,6824712561438000,36,"S",111,17179869918,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712591975000,0,943000,6824712592918000,36,"S",111,17179869945,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712627263000,0,865000,6824712628128000,36,"S",111,17179869967,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712657745000,0,488000,6824712658233000,36,"S",111,17179870042,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712691426000,0,518000,6824712691944000,36,"S",111,17179870077,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712724975000,0,544000,6824712725519000,36,"S",111,17179870150,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712758487000,0,574000,6824712759061000,36,"S",111,17179870187,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712795849000,0,1068000,6824712796917000,36,"S",111,17179870214,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712828253000,0,1174000,6824712829427000,36,"S",111,17179870232,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712859372000,0,965000,6824712860337000,36,"S",111,17179870272,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712892521000,0,800000,6824712893321000,36,"S",111,17179870362,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712925871000,0,645000,6824712926516000,36,"S",111,17179870483,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712962086000,0,239000,6824712962325000,36,"R+",111,17179870522,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712963496000,0,688000,6824712964184000,36,"S",111,17179870530,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824712993039000,1,804000,6824712993843000,36,"S",111,17179870595,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713026114000,0,814000,6824713026928000,36,"S",111,17179870655,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713059618000,0,735000,6824713060353000,36,"S",111,17179870717,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713093393000,1,580000,6824713093973000,36,"S",111,17179870839,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713126839000,1,582000,6824713127421000,36,"S",111,17179870953,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713160463000,1,578000,6824713161041000,36,"S",111,17179871075,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713193831000,1,657000,6824713194488000,36,"S",111,17179871199,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713227289000,1,566000,6824713227855000,36,"S",111,17179871288,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713260847000,1,692000,6824713261539000,36,"S",111,17179871407,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713294227000,1,650000,6824713294877000,36,"S",111,17179871491,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713327758000,2,602000,6824713328360000,36,"S",111,17179871556,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713361536000,2,952000,6824713362488000,36,"S",111,17179871657,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713394483000,2,486000,6824713394969000,36,"S",111,17179871791,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713428652000,2,437000,6824713429089000,36,"S",111,17179871979,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713461440000,2,373000,6824713461813000,36,"S",111,17179872213,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713495501000,2,575000,6824713496076000,36,"S",111,17179872407,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713528949000,2,1466000,6824713530415000,36,"S",111,17179872463,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713562719000,2,997000,6824713563716000,36,"S",111,17179872562,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713597830000,2,805000,6824713598635000,36,"S",111,17179872650,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713629688000,0,932000,6824713630620000,36,"R+",111,17179872683,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824713631202000,0,181000,6824713631383000,36,"S",111,17179872689,34,"SDM_EventThread",685,"[NULL]","[NULL]"
+6824711854751000,0,327000,6824711855078000,38,"S",120,17179869305,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824711888035000,0,327000,6824711888362000,38,"S",120,17179869402,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824711922625000,1,477000,6824711923102000,38,"S",120,17179869453,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824711959534000,1,579000,6824711960113000,38,"S",120,17179869480,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824711992457000,3,561000,6824711993018000,38,"S",120,17179869507,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712023942000,1,639000,6824712024581000,38,"S",120,17179869527,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712060406000,3,546000,6824712060952000,38,"S",120,17179869555,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712092339000,2,602000,6824712092941000,38,"S",120,17179869580,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712126484000,3,712000,6824712127196000,38,"S",120,17179869606,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712159257000,3,559000,6824712159816000,38,"S",120,17179869642,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712194107000,1,556000,6824712194663000,38,"S",120,17179869670,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712226848000,3,546000,6824712227394000,38,"S",120,17179869691,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712259296000,1,626000,6824712259922000,38,"S",120,17179869716,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712291372000,1,758000,6824712292130000,38,"S",120,17179869751,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712328781000,3,574000,6824712329355000,38,"S",120,17179869779,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712360840000,1,552000,6824712361392000,38,"S",120,17179869794,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712394767000,1,525000,6824712395292000,38,"S",120,17179869818,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712427449000,1,556000,6824712428005000,38,"S",120,17179869834,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712461444000,3,570000,6824712462014000,38,"S",120,17179869856,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712494587000,1,558000,6824712495145000,38,"S",120,17179869875,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712528544000,3,620000,6824712529164000,38,"S",120,17179869899,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712561274000,1,622000,6824712561896000,38,"S",120,17179869919,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712593271000,1,748000,6824712594019000,38,"S",120,17179869948,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712628086000,1,559000,6824712628645000,38,"S",120,17179869971,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712658116000,1,447000,6824712658563000,38,"S",120,17179870043,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712692011000,1,436000,6824712692447000,38,"S",120,17179870080,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712725647000,1,483000,6824712726130000,38,"S",120,17179870153,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712759208000,1,489000,6824712759697000,38,"S",120,17179870189,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712797014000,2,615000,6824712797629000,38,"S",120,17179870218,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712829604000,1,771000,6824712830375000,38,"S",120,17179870235,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712860645000,1,709000,6824712861354000,38,"S",120,17179870277,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712893474000,1,566000,6824712894040000,38,"S",120,17179870364,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712926862000,1,489000,6824712927351000,38,"S",120,17179870488,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712964515000,3,578000,6824712965093000,38,"S",120,17179870539,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824712994088000,0,576000,6824712994664000,38,"S",120,17179870602,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713027212000,2,447000,6824713027659000,38,"S",120,17179870660,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713060629000,2,431000,6824713061060000,38,"S",120,17179870722,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713094173000,2,367000,6824713094540000,38,"S",120,17179870843,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713094549000,2,126000,6824713094675000,38,"S",120,17179870846,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713127611000,2,338000,6824713127949000,38,"S",120,17179870960,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713161260000,2,459000,6824713161719000,38,"S",120,17179871077,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713194795000,2,411000,6824713195206000,38,"S",120,17179871201,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713227745000,2,443000,6824713228188000,38,"S",120,17179871290,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713261826000,0,412000,6824713262238000,38,"S",120,17179871416,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713294761000,0,350000,6824713295111000,38,"S",120,17179871493,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713295127000,0,113000,6824713295240000,38,"S",120,17179871497,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713328940000,3,397000,6824713329337000,38,"S",120,17179871562,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713362357000,0,537000,6824713362894000,38,"S",120,17179871669,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713395162000,3,322000,6824713395484000,38,"S",120,17179871797,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713428982000,1,322000,6824713429304000,38,"S",120,17179871981,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713461708000,1,421000,6824713462129000,38,"S",120,17179872218,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713496276000,1,516000,6824713496792000,38,"S",120,17179872411,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713530826000,1,558000,6824713531384000,38,"S",120,17179872481,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713564010000,1,574000,6824713564584000,38,"S",120,17179872570,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713598845000,1,556000,6824713599401000,38,"S",120,17179872656,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824713631031000,3,505000,6824713631536000,38,"S",120,17179872687,35,"HwBinder:640_1",721,"[NULL]","[NULL]"
+6824711855178000,1,179000,6824711855357000,40,"S",97,17179869308,35,"DispSync",676,"[NULL]","[NULL]"
+6824711855961000,2,72000,6824711856033000,40,"S",97,17179869313,35,"DispSync",676,"[NULL]","[NULL]"
+6824711858291000,0,79000,6824711858370000,40,"S",97,17179869320,35,"DispSync",676,"[NULL]","[NULL]"
+6824711888231000,1,85000,6824711888316000,40,"S",97,17179869404,35,"DispSync",676,"[NULL]","[NULL]"
+6824711888966000,0,178000,6824711889144000,40,"S",97,17179869407,35,"DispSync",676,"[NULL]","[NULL]"
+6824711889748000,2,86000,6824711889834000,40,"S",97,17179869412,35,"DispSync",676,"[NULL]","[NULL]"
+6824711892145000,1,95000,6824711892240000,40,"S",97,17179869419,35,"DispSync",676,"[NULL]","[NULL]"
+6824711923025000,0,239000,6824711923264000,40,"S",97,17179869454,35,"DispSync",676,"[NULL]","[NULL]"
+6824711924480000,2,93000,6824711924573000,40,"S",97,17179869460,35,"DispSync",676,"[NULL]","[NULL]"
+6824711927822000,1,86000,6824711927908000,40,"S",97,17179869467,35,"DispSync",676,"[NULL]","[NULL]"
+6824711958287000,0,325000,6824711958612000,40,"S",97,17179869471,35,"DispSync",676,"[NULL]","[NULL]"
+6824711959733000,3,66000,6824711959799000,40,"S",97,17179869481,35,"DispSync",676,"[NULL]","[NULL]"
+6824711960206000,2,86000,6824711960292000,40,"S",97,17179869484,35,"DispSync",676,"[NULL]","[NULL]"
+6824711963962000,0,93000,6824711964055000,40,"S",97,17179869497,35,"DispSync",676,"[NULL]","[NULL]"
+6824711991361000,1,512000,6824711991873000,40,"S",97,17179869501,35,"DispSync",676,"[NULL]","[NULL]"
+6824711993158000,1,88000,6824711993246000,40,"S",97,17179869511,35,"DispSync",676,"[NULL]","[NULL]"
+6824711997286000,1,89000,6824711997375000,40,"S",97,17179869520,35,"DispSync",676,"[NULL]","[NULL]"
+6824712024330000,2,324000,6824712024654000,40,"S",97,17179869529,35,"DispSync",676,"[NULL]","[NULL]"
+6824712025862000,2,83000,6824712025945000,40,"S",97,17179869535,35,"DispSync",676,"[NULL]","[NULL]"
+6824712030170000,0,89000,6824712030259000,40,"S",97,17179869542,35,"DispSync",676,"[NULL]","[NULL]"
+6824712059309000,1,519000,6824712059828000,40,"S",97,17179869548,35,"DispSync",676,"[NULL]","[NULL]"
+6824712060993000,0,65000,6824712061058000,40,"S",97,17179869558,35,"DispSync",676,"[NULL]","[NULL]"
+6824712065652000,0,89000,6824712065741000,40,"S",97,17179869567,35,"DispSync",676,"[NULL]","[NULL]"
+6824712091736000,1,410000,6824712092146000,40,"S",97,17179869575,35,"DispSync",676,"[NULL]","[NULL]"
+6824712093132000,0,90000,6824712093222000,40,"S",97,17179869584,35,"DispSync",676,"[NULL]","[NULL]"
+6824712097293000,2,94000,6824712097387000,40,"S",97,17179869592,35,"DispSync",676,"[NULL]","[NULL]"
+6824712124662000,0,474000,6824712125136000,40,"S",97,17179869594,35,"DispSync",676,"[NULL]","[NULL]"
+6824712125991000,0,50000,6824712126041000,40,"S",97,17179869600,35,"DispSync",676,"[NULL]","[NULL]"
+6824712127359000,0,84000,6824712127443000,40,"S",97,17179869608,35,"DispSync",676,"[NULL]","[NULL]"
+6824712130041000,0,88000,6824712130129000,40,"S",97,17179869615,35,"DispSync",676,"[NULL]","[NULL]"
+6824712158350000,1,452000,6824712158802000,40,"S",97,17179869636,35,"DispSync",676,"[NULL]","[NULL]"
+6824712159957000,1,87000,6824712160044000,40,"S",97,17179869646,35,"DispSync",676,"[NULL]","[NULL]"
+6824712165008000,1,88000,6824712165096000,40,"S",97,17179869656,35,"DispSync",676,"[NULL]","[NULL]"
+6824712191630000,0,479000,6824712192109000,40,"S",97,17179869658,35,"DispSync",676,"[NULL]","[NULL]"
+6824712193087000,3,109000,6824712193196000,40,"S",97,17179869667,35,"DispSync",676,"[NULL]","[NULL]"
+6824712194842000,0,89000,6824712194931000,40,"S",97,17179869674,35,"DispSync",676,"[NULL]","[NULL]"
+6824712197314000,0,88000,6824712197402000,40,"S",97,17179869681,35,"DispSync",676,"[NULL]","[NULL]"
+6824712225719000,1,521000,6824712226240000,40,"S",97,17179869685,35,"DispSync",676,"[NULL]","[NULL]"
+6824712227591000,1,88000,6824712227679000,40,"S",97,17179869695,35,"DispSync",676,"[NULL]","[NULL]"
+6824712231869000,1,87000,6824712231956000,40,"S",97,17179869702,35,"DispSync",676,"[NULL]","[NULL]"
+6824712259685000,2,648000,6824712260333000,40,"S",97,17179869720,35,"DispSync",676,"[NULL]","[NULL]"
+6824712261440000,2,98000,6824712261538000,40,"S",97,17179869727,35,"DispSync",676,"[NULL]","[NULL]"
+6824712265670000,0,96000,6824712265766000,40,"S",97,17179869736,35,"DispSync",676,"[NULL]","[NULL]"
+6824712291962000,0,316000,6824712292278000,40,"S",97,17179869752,35,"DispSync",676,"[NULL]","[NULL]"
+6824712293612000,1,83000,6824712293695000,40,"S",97,17179869758,35,"DispSync",676,"[NULL]","[NULL]"
+6824712297445000,2,91000,6824712297536000,40,"S",97,17179869766,35,"DispSync",676,"[NULL]","[NULL]"
+6824712326930000,0,479000,6824712327409000,40,"S",97,17179869768,35,"DispSync",676,"[NULL]","[NULL]"
+6824712328281000,0,52000,6824712328333000,40,"S",97,17179869774,35,"DispSync",676,"[NULL]","[NULL]"
+6824712329497000,0,87000,6824712329584000,40,"S",97,17179869781,35,"DispSync",676,"[NULL]","[NULL]"
+6824712333010000,0,85000,6824712333095000,40,"S",97,17179869788,35,"DispSync",676,"[NULL]","[NULL]"
+6824712360320000,1,440000,6824712360760000,40,"S",97,17179869792,35,"DispSync",676,"[NULL]","[NULL]"
+6824712361634000,3,102000,6824712361736000,40,"S",97,17179869801,35,"DispSync",676,"[NULL]","[NULL]"
+6824712365707000,0,88000,6824712365795000,40,"S",97,17179869809,35,"DispSync",676,"[NULL]","[NULL]"
+6824712393154000,1,677000,6824712393831000,40,"S",97,17179869812,35,"DispSync",676,"[NULL]","[NULL]"
+6824712395102000,3,102000,6824712395204000,40,"S",97,17179869820,35,"DispSync",676,"[NULL]","[NULL]"
+6824712399305000,1,88000,6824712399393000,40,"S",97,17179869828,35,"DispSync",676,"[NULL]","[NULL]"
+6824712426940000,1,447000,6824712427387000,40,"S",97,17179869832,35,"DispSync",676,"[NULL]","[NULL]"
+6824712428251000,3,103000,6824712428354000,40,"S",97,17179869840,35,"DispSync",676,"[NULL]","[NULL]"
+6824712433158000,1,88000,6824712433246000,40,"S",97,17179869848,35,"DispSync",676,"[NULL]","[NULL]"
+6824712460525000,1,447000,6824712460972000,40,"S",97,17179869852,35,"DispSync",676,"[NULL]","[NULL]"
+6824712461838000,0,60000,6824712461898000,40,"S",97,17179869858,35,"DispSync",676,"[NULL]","[NULL]"
+6824712466552000,0,174000,6824712466726000,40,"S",97,17179869869,35,"DispSync",676,"[NULL]","[NULL]"
+6824712494003000,1,505000,6824712494508000,40,"S",97,17179869873,35,"DispSync",676,"[NULL]","[NULL]"
+6824712495377000,3,105000,6824712495482000,40,"S",97,17179869881,35,"DispSync",676,"[NULL]","[NULL]"
+6824712500294000,1,92000,6824712500386000,40,"S",97,17179869889,35,"DispSync",676,"[NULL]","[NULL]"
+6824712527652000,1,437000,6824712528089000,40,"S",97,17179869894,35,"DispSync",676,"[NULL]","[NULL]"
+6824712529334000,1,86000,6824712529420000,40,"S",97,17179869905,35,"DispSync",676,"[NULL]","[NULL]"
+6824712533772000,1,89000,6824712533861000,40,"S",97,17179869915,35,"DispSync",676,"[NULL]","[NULL]"
+6824712561658000,2,329000,6824712561987000,40,"S",97,17179869922,35,"DispSync",676,"[NULL]","[NULL]"
+6824712563387000,2,84000,6824712563471000,40,"S",97,17179869931,35,"DispSync",676,"[NULL]","[NULL]"
+6824712567724000,0,90000,6824712567814000,40,"S",97,17179869940,35,"DispSync",676,"[NULL]","[NULL]"
+6824712593773000,0,313000,6824712594086000,40,"S",97,17179869949,35,"DispSync",676,"[NULL]","[NULL]"
+6824712595312000,1,84000,6824712595396000,40,"S",97,17179869957,35,"DispSync",676,"[NULL]","[NULL]"
+6824712599403000,1,87000,6824712599490000,40,"S",97,17179869964,35,"DispSync",676,"[NULL]","[NULL]"
+6824712627311000,1,535000,6824712627846000,40,"S",97,17179869968,35,"DispSync",676,"[NULL]","[NULL]"
+6824712629402000,0,86000,6824712629488000,40,"S",97,17179869978,35,"DispSync",676,"[NULL]","[NULL]"
+6824712633602000,0,89000,6824712633691000,40,"S",97,17179869985,35,"DispSync",676,"[NULL]","[NULL]"
+6824712658407000,2,117000,6824712658524000,40,"S",97,17179870047,35,"DispSync",676,"[NULL]","[NULL]"
+6824712660100000,1,184000,6824712660284000,40,"S",97,17179870051,35,"DispSync",676,"[NULL]","[NULL]"
+6824712661032000,1,82000,6824712661114000,40,"S",97,17179870058,35,"DispSync",676,"[NULL]","[NULL]"
+6824712663607000,1,90000,6824712663697000,40,"S",97,17179870067,35,"DispSync",676,"[NULL]","[NULL]"
+6824712692474000,0,113000,6824712692587000,40,"S",97,17179870083,35,"DispSync",676,"[NULL]","[NULL]"
+6824712693879000,0,175000,6824712694054000,40,"S",97,17179870087,35,"DispSync",676,"[NULL]","[NULL]"
+6824712694681000,2,92000,6824712694773000,40,"S",97,17179870092,35,"DispSync",676,"[NULL]","[NULL]"
+6824712697037000,2,91000,6824712697128000,40,"S",97,17179870101,35,"DispSync",676,"[NULL]","[NULL]"
+6824712725948000,0,129000,6824712726077000,40,"S",97,17179870154,35,"DispSync",676,"[NULL]","[NULL]"
+6824712727327000,0,178000,6824712727505000,40,"S",97,17179870163,35,"DispSync",676,"[NULL]","[NULL]"
+6824712728273000,2,88000,6824712728361000,40,"S",97,17179870170,35,"DispSync",676,"[NULL]","[NULL]"
+6824712731211000,1,95000,6824712731306000,40,"S",97,17179870179,35,"DispSync",676,"[NULL]","[NULL]"
+6824712759760000,0,131000,6824712759891000,40,"S",97,17179870191,35,"DispSync",676,"[NULL]","[NULL]"
+6824712760912000,0,182000,6824712761094000,40,"S",97,17179870196,35,"DispSync",676,"[NULL]","[NULL]"
+6824712761898000,2,92000,6824712761990000,40,"S",97,17179870201,35,"DispSync",676,"[NULL]","[NULL]"
+6824712764812000,1,95000,6824712764907000,40,"S",97,17179870208,35,"DispSync",676,"[NULL]","[NULL]"
+6824712795198000,0,480000,6824712795678000,40,"S",97,17179870210,35,"DispSync",676,"[NULL]","[NULL]"
+6824712797270000,3,69000,6824712797339000,40,"S",97,17179870219,35,"DispSync",676,"[NULL]","[NULL]"
+6824712797779000,0,87000,6824712797866000,40,"S",97,17179870222,35,"DispSync",676,"[NULL]","[NULL]"
+6824712801729000,0,88000,6824712801817000,40,"S",97,17179870229,35,"DispSync",676,"[NULL]","[NULL]"
+6824712830184000,2,302000,6824712830486000,40,"S",97,17179870238,35,"DispSync",676,"[NULL]","[NULL]"
+6824712831893000,2,86000,6824712831979000,40,"S",97,17179870244,35,"DispSync",676,"[NULL]","[NULL]"
+6824712836095000,0,93000,6824712836188000,40,"S",97,17179870251,35,"DispSync",676,"[NULL]","[NULL]"
+6824712861562000,3,169000,6824712861731000,40,"S",97,17179870280,35,"DispSync",676,"[NULL]","[NULL]"
+6824712861812000,0,223000,6824712862035000,40,"S",97,17179870282,35,"DispSync",676,"[NULL]","[NULL]"
+6824712863252000,3,63000,6824712863315000,40,"S",97,17179870287,35,"DispSync",676,"[NULL]","[NULL]"
+6824712867608000,1,76000,6824712867684000,40,"S",97,17179870303,35,"DispSync",676,"[NULL]","[NULL]"
+6824712894171000,0,111000,6824712894282000,40,"S",97,17179870366,35,"DispSync",676,"[NULL]","[NULL]"
+6824712894996000,0,140000,6824712895136000,40,"S",97,17179870368,35,"DispSync",676,"[NULL]","[NULL]"
+6824712895858000,3,55000,6824712895913000,40,"S",97,17179870373,35,"DispSync",676,"[NULL]","[NULL]"
+6824712898399000,1,53000,6824712898452000,40,"S",97,17179870383,35,"DispSync",676,"[NULL]","[NULL]"
+6824712927513000,0,89000,6824712927602000,40,"S",97,17179870490,35,"DispSync",676,"[NULL]","[NULL]"
+6824712928571000,0,92000,6824712928663000,40,"S",97,17179870492,35,"DispSync",676,"[NULL]","[NULL]"
+6824712929662000,2,29000,6824712929691000,40,"S",97,17179870497,35,"DispSync",676,"[NULL]","[NULL]"
+6824712932123000,2,33000,6824712932156000,40,"S",97,17179870507,35,"DispSync",676,"[NULL]","[NULL]"
+6824712962613000,1,435000,6824712963048000,40,"S",97,17179870527,35,"DispSync",676,"[NULL]","[NULL]"
+6824712964448000,3,67000,6824712964515000,40,"S",97,17179870538,35,"DispSync",676,"[NULL]","[NULL]"
+6824712965264000,0,98000,6824712965362000,40,"S",97,17179870541,35,"DispSync",676,"[NULL]","[NULL]"
+6824712975930000,0,113000,6824712976043000,40,"S",97,17179870549,35,"DispSync",676,"[NULL]","[NULL]"
+6824712994894000,3,230000,6824712995124000,40,"S",97,17179870606,35,"DispSync",676,"[NULL]","[NULL]"
+6824712996213000,3,61000,6824712996274000,40,"S",97,17179870611,35,"DispSync",676,"[NULL]","[NULL]"
+6824712999071000,0,62000,6824712999133000,40,"S",97,17179870621,35,"DispSync",676,"[NULL]","[NULL]"
+6824713027467000,3,179000,6824713027646000,40,"S",97,17179870665,35,"DispSync",676,"[NULL]","[NULL]"
+6824713028675000,3,34000,6824713028709000,40,"S",97,17179870671,35,"DispSync",676,"[NULL]","[NULL]"
+6824713031590000,1,43000,6824713031633000,40,"S",97,17179870680,35,"DispSync",676,"[NULL]","[NULL]"
+6824713060921000,1,103000,6824713061024000,40,"S",97,17179870724,35,"DispSync",676,"[NULL]","[NULL]"
+6824713061939000,1,85000,6824713062024000,40,"S",97,17179870727,35,"DispSync",676,"[NULL]","[NULL]"
+6824713063097000,1,28000,6824713063125000,40,"S",97,17179870732,35,"DispSync",676,"[NULL]","[NULL]"
+6824713065471000,1,26000,6824713065497000,40,"S",97,17179870742,35,"DispSync",676,"[NULL]","[NULL]"
+6824713094480000,1,99000,6824713094579000,40,"S",97,17179870844,35,"DispSync",676,"[NULL]","[NULL]"
+6824713094588000,1,74000,6824713094662000,40,"S",97,17179870848,35,"DispSync",676,"[NULL]","[NULL]"
+6824713095679000,2,17000,6824713095696000,40,"S",97,17179870854,35,"DispSync",676,"[NULL]","[NULL]"
+6824713098893000,2,25000,6824713098918000,40,"S",97,17179870865,35,"DispSync",676,"[NULL]","[NULL]"
+6824713127380000,2,198000,6824713127578000,40,"S",97,17179870955,35,"DispSync",676,"[NULL]","[NULL]"
+6824713128133000,3,26000,6824713128159000,40,"S",97,17179870963,35,"DispSync",676,"[NULL]","[NULL]"
+6824713128167000,3,13000,6824713128180000,40,"S",97,17179870965,35,"DispSync",676,"[NULL]","[NULL]"
+6824713131641000,3,30000,6824713131671000,40,"S",97,17179870981,35,"DispSync",676,"[NULL]","[NULL]"
+6824713161928000,1,140000,6824713162068000,40,"S",97,17179871079,35,"DispSync",676,"[NULL]","[NULL]"
+6824713162766000,3,32000,6824713162798000,40,"S",97,17179871084,35,"DispSync",676,"[NULL]","[NULL]"
+6824713165224000,2,31000,6824713165255000,40,"S",97,17179871095,35,"DispSync",676,"[NULL]","[NULL]"
+6824713195088000,1,141000,6824713195229000,40,"S",97,17179871202,35,"DispSync",676,"[NULL]","[NULL]"
+6824713196196000,2,19000,6824713196215000,40,"S",97,17179871208,35,"DispSync",676,"[NULL]","[NULL]"
+6824713199334000,2,29000,6824713199363000,40,"S",97,17179871221,35,"DispSync",676,"[NULL]","[NULL]"
+6824713228403000,1,135000,6824713228538000,40,"S",97,17179871294,35,"DispSync",676,"[NULL]","[NULL]"
+6824713229467000,3,23000,6824713229490000,40,"S",97,17179871299,35,"DispSync",676,"[NULL]","[NULL]"
+6824713231897000,2,28000,6824713231925000,40,"S",97,17179871308,35,"DispSync",676,"[NULL]","[NULL]"
+6824713261436000,2,254000,6824713261690000,40,"S",97,17179871411,35,"DispSync",676,"[NULL]","[NULL]"
+6824713262438000,2,46000,6824713262484000,40,"S",97,17179871420,35,"DispSync",676,"[NULL]","[NULL]"
+6824713265827000,2,52000,6824713265879000,40,"S",97,17179871436,35,"DispSync",676,"[NULL]","[NULL]"
+6824713295044000,2,186000,6824713295230000,40,"S",97,17179871495,35,"DispSync",676,"[NULL]","[NULL]"
+6824713296243000,2,31000,6824713296274000,40,"S",97,17179871503,35,"DispSync",676,"[NULL]","[NULL]"
+6824713299225000,2,37000,6824713299262000,40,"S",97,17179871510,35,"DispSync",676,"[NULL]","[NULL]"
+6824713329135000,1,153000,6824713329288000,40,"S",97,17179871564,35,"DispSync",676,"[NULL]","[NULL]"
+6824713329811000,1,17000,6824713329828000,40,"S",97,17179871574,35,"DispSync",676,"[NULL]","[NULL]"
+6824713332613000,0,24000,6824713332637000,40,"S",97,17179871600,35,"DispSync",676,"[NULL]","[NULL]"
+6824713363107000,1,274000,6824713363381000,40,"S",97,17179871672,35,"DispSync",676,"[NULL]","[NULL]"
+6824713364450000,3,65000,6824713364515000,40,"S",97,17179871682,35,"DispSync",676,"[NULL]","[NULL]"
+6824713367022000,2,33000,6824713367055000,40,"S",97,17179871689,35,"DispSync",676,"[NULL]","[NULL]"
+6824713394670000,0,199000,6824713394869000,40,"S",97,17179871793,35,"DispSync",676,"[NULL]","[NULL]"
+6824713395494000,0,49000,6824713395543000,40,"S",97,17179871801,35,"DispSync",676,"[NULL]","[NULL]"
+6824713398070000,1,74000,6824713398144000,40,"S",97,17179871809,35,"DispSync",676,"[NULL]","[NULL]"
+6824713429140000,0,196000,6824713429336000,40,"S",97,17179871984,35,"DispSync",676,"[NULL]","[NULL]"
+6824713429867000,1,193000,6824713430060000,40,"S",97,17179871989,35,"DispSync",676,"[NULL]","[NULL]"
+6824713432714000,2,166000,6824713432880000,40,"S",97,17179872024,35,"DispSync",676,"[NULL]","[NULL]"
+6824713461909000,0,68000,6824713461977000,40,"S",97,17179872222,35,"DispSync",676,"[NULL]","[NULL]"
+6824713462015000,0,162000,6824713462177000,40,"S",97,17179872224,35,"DispSync",676,"[NULL]","[NULL]"
+6824713462391000,1,75000,6824713462466000,40,"S",97,17179872229,35,"DispSync",676,"[NULL]","[NULL]"
+6824713465016000,1,91000,6824713465107000,40,"S",97,17179872251,35,"DispSync",676,"[NULL]","[NULL]"
+6824713496011000,0,264000,6824713496275000,40,"S",97,17179872408,35,"DispSync",676,"[NULL]","[NULL]"
+6824713496780000,0,101000,6824713496881000,40,"S",97,17179872413,35,"DispSync",676,"[NULL]","[NULL]"
+6824713496964000,0,65000,6824713497029000,40,"S",97,17179872416,35,"DispSync",676,"[NULL]","[NULL]"
+6824713499874000,1,154000,6824713500028000,40,"S",97,17179872426,35,"DispSync",676,"[NULL]","[NULL]"
+6824713529649000,3,475000,6824713530124000,40,"S",97,17179872468,35,"DispSync",676,"[NULL]","[NULL]"
+6824713531417000,2,89000,6824713531506000,40,"S",97,17179872484,35,"DispSync",676,"[NULL]","[NULL]"
+6824713534887000,1,85000,6824713534972000,40,"S",97,17179872492,35,"DispSync",676,"[NULL]","[NULL]"
+6824713563295000,0,346000,6824713563641000,40,"S",97,17179872566,35,"DispSync",676,"[NULL]","[NULL]"
+6824713564760000,2,90000,6824713564850000,40,"S",97,17179872576,35,"DispSync",676,"[NULL]","[NULL]"
+6824713569129000,1,107000,6824713569236000,40,"S",97,17179872594,35,"DispSync",676,"[NULL]","[NULL]"
+6824713596806000,0,434000,6824713597240000,40,"S",97,17179872646,35,"DispSync",676,"[NULL]","[NULL]"
+6824713598504000,3,105000,6824713598609000,40,"S",97,17179872653,35,"DispSync",676,"[NULL]","[NULL]"
+6824713599567000,2,90000,6824713599657000,40,"S",97,17179872658,35,"DispSync",676,"[NULL]","[NULL]"
+6824713602364000,1,79000,6824713602443000,40,"S",97,17179872664,35,"DispSync",676,"[NULL]","[NULL]"
+6824713630376000,1,388000,6824713630764000,40,"S",97,17179872684,35,"DispSync",676,"[NULL]","[NULL]"
+6824713631650000,1,63000,6824713631713000,40,"S",97,17179872692,35,"DispSync",676,"[NULL]","[NULL]"
+6824711855549000,0,272000,6824711855821000,41,"S",97,17179869310,35,"app",678,"[NULL]","[NULL]"
+6824711858020000,1,151000,6824711858171000,41,"S",97,17179869318,35,"app",678,"[NULL]","[NULL]"
+6824711889295000,1,275000,6824711889570000,41,"S",97,17179869409,35,"app",678,"[NULL]","[NULL]"
+6824711891822000,0,178000,6824711892000000,41,"S",97,17179869417,35,"app",678,"[NULL]","[NULL]"
+6824711923686000,1,409000,6824711924095000,41,"S",97,17179869457,35,"app",678,"[NULL]","[NULL]"
+6824711927354000,0,186000,6824711927540000,41,"S",97,17179869465,35,"app",678,"[NULL]","[NULL]"
+6824711958942000,2,402000,6824711959344000,41,"S",97,17179869477,35,"app",678,"[NULL]","[NULL]"
+6824711963276000,1,193000,6824711963469000,41,"S",97,17179869494,35,"app",678,"[NULL]","[NULL]"
+6824711992159000,2,539000,6824711992698000,41,"S",97,17179869505,35,"app",678,"[NULL]","[NULL]"
+6824711996784000,0,206000,6824711996990000,41,"S",97,17179869516,35,"app",678,"[NULL]","[NULL]"
+6824712024951000,0,531000,6824712025482000,41,"S",97,17179869532,35,"app",678,"[NULL]","[NULL]"
+6824712029651000,1,204000,6824712029855000,41,"S",97,17179869540,35,"app",678,"[NULL]","[NULL]"
+6824712060124000,2,513000,6824712060637000,41,"S",97,17179869550,35,"app",678,"[NULL]","[NULL]"
+6824712065150000,1,201000,6824712065351000,41,"S",97,17179869565,35,"app",678,"[NULL]","[NULL]"
+6824712092492000,3,487000,6824712092979000,41,"S",97,17179869581,35,"app",678,"[NULL]","[NULL]"
+6824712096761000,1,208000,6824712096969000,41,"S",97,17179869589,35,"app",678,"[NULL]","[NULL]"
+6824712125516000,1,532000,6824712126048000,41,"S",97,17179869599,35,"app",678,"[NULL]","[NULL]"
+6824712129680000,1,177000,6824712129857000,41,"S",97,17179869613,35,"app",678,"[NULL]","[NULL]"
+6824712159098000,2,521000,6824712159619000,41,"S",97,17179869641,35,"app",678,"[NULL]","[NULL]"
+6824712164501000,0,203000,6824712164704000,41,"S",97,17179869654,35,"app",678,"[NULL]","[NULL]"
+6824712192059000,1,615000,6824712192674000,41,"S",97,17179869661,35,"app",678,"[NULL]","[NULL]"
+6824712196812000,1,200000,6824712197012000,41,"S",97,17179869679,35,"app",678,"[NULL]","[NULL]"
+6824712226530000,2,669000,6824712227199000,41,"S",97,17179869689,35,"app",678,"[NULL]","[NULL]"
+6824712231367000,0,200000,6824712231567000,41,"S",97,17179869700,35,"app",678,"[NULL]","[NULL]"
+6824712260468000,0,523000,6824712260991000,41,"S",97,17179869724,35,"app",678,"[NULL]","[NULL]"
+6824712265161000,1,209000,6824712265370000,41,"S",97,17179869734,35,"app",678,"[NULL]","[NULL]"
+6824712292682000,2,555000,6824712293237000,41,"S",97,17179869755,35,"app",678,"[NULL]","[NULL]"
+6824712296899000,0,235000,6824712297134000,41,"S",97,17179869762,35,"app",678,"[NULL]","[NULL]"
+6824712327808000,1,528000,6824712328336000,41,"S",97,17179869773,35,"app",678,"[NULL]","[NULL]"
+6824712332509000,1,202000,6824712332711000,41,"S",97,17179869786,35,"app",678,"[NULL]","[NULL]"
+6824712361053000,2,490000,6824712361543000,41,"S",97,17179869796,35,"app",678,"[NULL]","[NULL]"
+6824712365196000,1,209000,6824712365405000,41,"S",97,17179869807,35,"app",678,"[NULL]","[NULL]"
+6824712394139000,2,561000,6824712394700000,41,"S",97,17179869815,35,"app",678,"[NULL]","[NULL]"
+6824712398805000,0,206000,6824712399011000,41,"S",97,17179869826,35,"app",678,"[NULL]","[NULL]"
+6824712427676000,2,485000,6824712428161000,41,"S",97,17179869836,35,"app",678,"[NULL]","[NULL]"
+6824712432640000,0,216000,6824712432856000,41,"S",97,17179869846,35,"app",678,"[NULL]","[NULL]"
+6824712461291000,2,529000,6824712461820000,41,"S",97,17179869855,35,"app",678,"[NULL]","[NULL]"
+6824712466045000,1,204000,6824712466249000,41,"S",97,17179869867,35,"app",678,"[NULL]","[NULL]"
+6824712494784000,2,486000,6824712495270000,41,"S",97,17179869877,35,"app",678,"[NULL]","[NULL]"
+6824712499782000,0,306000,6824712500088000,41,"S",97,17179869887,35,"app",678,"[NULL]","[NULL]"
+6824712528446000,2,487000,6824712528933000,41,"S",97,17179869898,35,"app",678,"[NULL]","[NULL]"
+6824712528985000,2,78000,6824712529063000,41,"S",97,17179869901,35,"app",678,"[NULL]","[NULL]"
+6824712533274000,0,198000,6824712533472000,41,"S",97,17179869911,35,"app",678,"[NULL]","[NULL]"
+6824712562404000,3,576000,6824712562980000,41,"S",97,17179869926,35,"app",678,"[NULL]","[NULL]"
+6824712567207000,1,209000,6824712567416000,41,"S",97,17179869938,35,"app",678,"[NULL]","[NULL]"
+6824712594391000,2,543000,6824712594934000,41,"S",97,17179869954,35,"app",678,"[NULL]","[NULL]"
+6824712599040000,0,182000,6824712599222000,41,"S",97,17179869962,35,"app",678,"[NULL]","[NULL]"
+6824712628123000,2,487000,6824712628610000,41,"S",97,17179869972,35,"app",678,"[NULL]","[NULL]"
+6824712633103000,1,300000,6824712633403000,41,"S",97,17179869983,35,"app",678,"[NULL]","[NULL]"
+6824712660549000,2,334000,6824712660883000,41,"S",97,17179870055,35,"app",678,"[NULL]","[NULL]"
+6824712663292000,0,190000,6824712663482000,41,"S",97,17179870063,35,"app",678,"[NULL]","[NULL]"
+6824712694196000,1,322000,6824712694518000,41,"S",97,17179870089,35,"app",678,"[NULL]","[NULL]"
+6824712696611000,0,78000,6824712696689000,41,"S",97,17179870096,35,"app",678,"[NULL]","[NULL]"
+6824712696733000,0,164000,6824712696897000,41,"S",97,17179870098,35,"app",678,"[NULL]","[NULL]"
+6824712727717000,1,350000,6824712728067000,41,"S",97,17179870165,35,"app",678,"[NULL]","[NULL]"
+6824712730841000,0,182000,6824712731023000,41,"S",97,17179870177,35,"app",678,"[NULL]","[NULL]"
+6824712761307000,1,363000,6824712761670000,41,"S",97,17179870198,35,"app",678,"[NULL]","[NULL]"
+6824712764449000,0,182000,6824712764631000,41,"S",97,17179870206,35,"app",678,"[NULL]","[NULL]"
+6824712796249000,1,683000,6824712796932000,41,"S",97,17179870215,35,"app",678,"[NULL]","[NULL]"
+6824712801226000,1,203000,6824712801429000,41,"S",97,17179870227,35,"app",678,"[NULL]","[NULL]"
+6824712830947000,0,531000,6824712831478000,41,"S",97,17179870241,35,"app",678,"[NULL]","[NULL]"
+6824712835596000,1,201000,6824712835797000,41,"S",97,17179870249,35,"app",678,"[NULL]","[NULL]"
+6824712862392000,1,491000,6824712862883000,41,"S",97,17179870284,35,"app",678,"[NULL]","[NULL]"
+6824712867041000,0,285000,6824712867326000,41,"S",97,17179870301,35,"app",678,"[NULL]","[NULL]"
+6824712895108000,1,410000,6824712895518000,41,"S",97,17179870369,35,"app",678,"[NULL]","[NULL]"
+6824712898279000,0,181000,6824712898460000,41,"S",97,17179870381,35,"app",678,"[NULL]","[NULL]"
+6824712928975000,1,295000,6824712929270000,41,"S",97,17179870494,35,"app",678,"[NULL]","[NULL]"
+6824712931744000,0,102000,6824712931846000,41,"S",97,17179870504,35,"app",678,"[NULL]","[NULL]"
+6824712963551000,2,518000,6824712964069000,41,"S",97,17179870531,35,"app",678,"[NULL]","[NULL]"
+6824712975325000,2,324000,6824712975649000,41,"S",97,17179870547,35,"app",678,"[NULL]","[NULL]"
+6824712995416000,0,388000,6824712995804000,41,"S",97,17179870608,35,"app",678,"[NULL]","[NULL]"
+6824712998937000,2,202000,6824712999139000,41,"S",97,17179870619,35,"app",678,"[NULL]","[NULL]"
+6824713027954000,1,314000,6824713028268000,41,"S",97,17179870668,35,"app",678,"[NULL]","[NULL]"
+6824713031179000,2,137000,6824713031316000,41,"S",97,17179870678,35,"app",678,"[NULL]","[NULL]"
+6824713062373000,2,326000,6824713062699000,41,"S",97,17179870729,35,"app",678,"[NULL]","[NULL]"
+6824713065400000,2,110000,6824713065510000,41,"S",97,17179870741,35,"app",678,"[NULL]","[NULL]"
+6824713095007000,3,267000,6824713095274000,41,"S",97,17179870851,35,"app",678,"[NULL]","[NULL]"
+6824713098433000,1,171000,6824713098604000,41,"S",97,17179870861,35,"app",678,"[NULL]","[NULL]"
+6824713127928000,1,258000,6824713128186000,41,"S",97,17179870961,35,"app",678,"[NULL]","[NULL]"
+6824713131179000,2,114000,6824713131293000,41,"S",97,17179870978,35,"app",678,"[NULL]","[NULL]"
+6824713162023000,2,447000,6824713162470000,41,"S",97,17179871080,35,"app",678,"[NULL]","[NULL]"
+6824713164840000,1,120000,6824713164960000,41,"S",97,17179871093,35,"app",678,"[NULL]","[NULL]"
+6824713195542000,3,272000,6824713195814000,41,"S",97,17179871205,35,"app",678,"[NULL]","[NULL]"
+6824713198890000,1,161000,6824713199051000,41,"S",97,17179871217,35,"app",678,"[NULL]","[NULL]"
+6824713228869000,2,274000,6824713229143000,41,"S",97,17179871296,35,"app",678,"[NULL]","[NULL]"
+6824713231498000,1,138000,6824713231636000,41,"S",97,17179871306,35,"app",678,"[NULL]","[NULL]"
+6824713262078000,3,319000,6824713262397000,41,"S",97,17179871417,35,"app",678,"[NULL]","[NULL]"
+6824713265703000,0,185000,6824713265888000,41,"S",97,17179871435,35,"app",678,"[NULL]","[NULL]"
+6824713295553000,3,326000,6824713295879000,41,"S",97,17179871500,35,"app",678,"[NULL]","[NULL]"
+6824713298792000,0,153000,6824713298945000,41,"S",97,17179871508,35,"app",678,"[NULL]","[NULL]"
+6824713329244000,2,244000,6824713329488000,41,"S",97,17179871566,35,"app",678,"[NULL]","[NULL]"
+6824713332218000,1,104000,6824713332322000,41,"S",97,17179871597,35,"app",678,"[NULL]","[NULL]"
+6824713363632000,0,355000,6824713363987000,41,"S",97,17179871678,35,"app",678,"[NULL]","[NULL]"
+6824713366797000,1,143000,6824713366940000,41,"S",97,17179871686,35,"app",678,"[NULL]","[NULL]"
+6824713395078000,1,283000,6824713395361000,41,"S",97,17179871796,35,"app",678,"[NULL]","[NULL]"
+6824713397735000,0,162000,6824713397897000,41,"S",97,17179871807,35,"app",678,"[NULL]","[NULL]"
+6824713429633000,2,287000,6824713429920000,41,"S",97,17179871988,35,"app",678,"[NULL]","[NULL]"
+6824713431854000,2,46000,6824713431900000,41,"S",97,17179872011,35,"app",678,"[NULL]","[NULL]"
+6824713432353000,0,196000,6824713432549000,41,"S",97,17179872020,35,"app",678,"[NULL]","[NULL]"
+6824713462177000,2,255000,6824713462432000,41,"S",97,17179872226,35,"app",678,"[NULL]","[NULL]"
+6824713464597000,0,172000,6824713464769000,41,"S",97,17179872245,35,"app",678,"[NULL]","[NULL]"
+6824713496534000,2,458000,6824713496992000,41,"S",97,17179872412,35,"app",678,"[NULL]","[NULL]"
+6824713499759000,0,267000,6824713500026000,41,"S",97,17179872425,35,"app",678,"[NULL]","[NULL]"
+6824713530321000,1,505000,6824713530826000,41,"S",97,17179872478,35,"app",678,"[NULL]","[NULL]"
+6824713534532000,0,188000,6824713534720000,41,"S",97,17179872490,35,"app",678,"[NULL]","[NULL]"
+6824713564142000,3,453000,6824713564595000,41,"S",97,17179872571,35,"app",678,"[NULL]","[NULL]"
+6824713568604000,0,218000,6824713568822000,41,"S",97,17179872591,35,"app",678,"[NULL]","[NULL]"
+6824713597562000,1,518000,6824713598080000,41,"S",97,17179872649,35,"app",678,"[NULL]","[NULL]"
+6824713602239000,0,209000,6824713602448000,41,"S",97,17179872663,35,"app",678,"[NULL]","[NULL]"
+6824713630620000,0,466000,6824713631086000,41,"S",97,17179872685,35,"app",678,"[NULL]","[NULL]"
+6824713634629000,1,131000,6824713634760000,41,"S",97,17179872704,35,"app",678,"[NULL]","[NULL]"
+6824711855902000,1,1771000,6824711857673000,42,"S",120,17179869312,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824711889676000,0,1753000,6824711891429000,42,"S",120,17179869411,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824711924337000,0,2416000,6824711926753000,42,"S",120,17179869459,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824711959799000,3,2784000,6824711962583000,42,"S",120,17179869482,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824711993014000,0,3047000,6824711996061000,42,"S",120,17179869509,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712025771000,1,3163000,6824712028934000,42,"S",120,17179869534,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712061268000,1,3172000,6824712064440000,42,"S",120,17179869560,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712093290000,1,3028000,6824712096318000,42,"S",120,17179869586,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712126328000,2,2927000,6824712129255000,42,"S",120,17179869604,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712159493000,0,708000,6824712160201000,42,"R",120,17179869643,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712161165000,0,2618000,6824712163783000,42,"S",120,17179869650,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712192943000,2,3173000,6824712196116000,42,"S",120,17179869666,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712227489000,0,3161000,6824712230650000,42,"S",120,17179869694,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712261342000,1,3074000,6824712264416000,42,"S",120,17179869726,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712293515000,0,3069000,6824712296584000,42,"S",120,17179869757,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712328610000,2,3183000,6824712331793000,42,"S",120,17179869778,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712361444000,1,3028000,6824712364472000,42,"S",120,17179869799,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712394949000,0,3133000,6824712398082000,42,"S",120,17179869819,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712428804000,0,3132000,6824712431936000,42,"S",120,17179869842,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712462072000,1,3236000,6824712465308000,42,"S",120,17179869862,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712495913000,0,3157000,6824712499070000,42,"S",120,17179869883,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712529232000,0,835000,6824712530067000,42,"R",120,17179869904,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712563251000,1,3044000,6824712566295000,42,"S",120,17179869930,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712595209000,0,3193000,6824712598402000,42,"S",120,17179869956,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712629047000,3,3339000,6824712632386000,42,"S",120,17179869977,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712660962000,0,1928000,6824712662890000,42,"S",120,17179870057,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712694595000,0,1875000,6824712696470000,42,"S",120,17179870091,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712728207000,0,2150000,6824712730357000,42,"S",120,17179870169,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712761802000,0,2190000,6824712763992000,42,"S",120,17179870200,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712797339000,3,3182000,6824712800521000,42,"S",120,17179870220,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712831761000,1,3128000,6824712834889000,42,"S",120,17179870243,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712862751000,0,3243000,6824712865994000,42,"S",120,17179870285,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712895437000,0,1223000,6824712896660000,42,"R",120,17179870371,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712896736000,0,1181000,6824712897917000,42,"S",120,17179870377,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712929572000,0,1853000,6824712931425000,42,"S",120,17179870496,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712963915000,1,403000,6824712964318000,42,"R",120,17179870533,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712971397000,1,2878000,6824712974275000,42,"S",120,17179870543,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824712996084000,2,2507000,6824712998591000,42,"S",120,17179870610,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713028560000,2,1914000,6824713030474000,42,"S",120,17179870670,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713063058000,3,1709000,6824713064767000,42,"S",120,17179870731,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713095596000,1,2136000,6824713097732000,42,"S",120,17179870853,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713128467000,2,1954000,6824713130421000,42,"S",120,17179870968,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713162426000,1,1725000,6824713164151000,42,"S",120,17179871082,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713196118000,1,2042000,6824713198160000,42,"S",120,17179871207,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713229103000,1,1753000,6824713230856000,42,"S",120,17179871297,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713262767000,0,2217000,6824713264984000,42,"S",120,17179871423,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713296162000,0,1958000,6824713298120000,42,"S",120,17179871502,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713330059000,3,1520000,6824713331579000,42,"S",120,17179871579,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713364300000,1,2117000,6824713366417000,42,"S",120,17179871681,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713395543000,0,1769000,6824713397312000,42,"S",120,17179871803,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713430071000,0,1790000,6824713431861000,42,"S",120,17179871995,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713462319000,0,1790000,6824713464109000,42,"S",120,17179872228,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713497264000,1,2038000,6824713499302000,42,"S",120,17179872419,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713531340000,0,2759000,6824713534099000,42,"S",120,17179872482,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713564595000,3,3222000,6824713567817000,42,"S",120,17179872574,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713598344000,0,3217000,6824713601561000,42,"S",120,17179872652,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824713631713000,1,1737000,6824713633450000,42,"S",120,17179872693,36,"ndroid.systemui",1664,"[NULL]","[NULL]"
+6824711857615000,0,250000,6824711857865000,43,"S",120,17179869315,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824711891393000,1,280000,6824711891673000,43,"S",120,17179869414,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824711926686000,1,341000,6824711927027000,43,"S",120,17179869462,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824711962618000,0,399000,6824711963017000,43,"S",120,17179869490,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824711996092000,1,399000,6824711996491000,43,"S",120,17179869514,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712028979000,0,393000,6824712029372000,43,"S",120,17179869538,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712064472000,0,400000,6824712064872000,43,"S",120,17179869563,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712096347000,0,516000,6824712096863000,43,"S",120,17179869588,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712129212000,0,299000,6824712129511000,43,"S",120,17179869610,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712163811000,1,405000,6824712164216000,43,"S",120,17179869652,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712196148000,0,385000,6824712196533000,43,"S",120,17179869677,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712230693000,1,394000,6824712231087000,43,"S",120,17179869698,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712264480000,0,399000,6824712264879000,43,"S",120,17179869732,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712296620000,1,373000,6824712296993000,43,"S",120,17179869761,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712331826000,0,394000,6824712332220000,43,"S",120,17179869784,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712364516000,0,394000,6824712364910000,43,"S",120,17179869805,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712398119000,1,404000,6824712398523000,43,"S",120,17179869824,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712431969000,1,397000,6824712432366000,43,"S",120,17179869844,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712465361000,0,404000,6824712465765000,43,"S",120,17179869865,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712499096000,1,408000,6824712499504000,43,"S",120,17179869885,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712532591000,1,395000,6824712532986000,43,"S",120,17179869909,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712566346000,0,580000,6824712566926000,43,"S",120,17179869936,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712598442000,1,395000,6824712598837000,43,"S",120,17179869960,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712632420000,0,405000,6824712632825000,43,"S",120,17179869981,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712662806000,1,304000,6824712663110000,43,"S",120,17179870060,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712696386000,1,443000,6824712696829000,43,"S",120,17179870094,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712730330000,1,314000,6824712730644000,43,"S",120,17179870174,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712763961000,1,312000,6824712764273000,43,"S",120,17179870203,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712800542000,0,397000,6824712800939000,43,"S",120,17179870225,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712834922000,0,398000,6824712835320000,43,"S",120,17179870247,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712866250000,1,587000,6824712866837000,43,"S",120,17179870297,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712898029000,1,330000,6824712898359000,43,"S",120,17179870380,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712931568000,1,223000,6824712931791000,43,"S",120,17179870503,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712974511000,0,515000,6824712975026000,43,"S",120,17179870545,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824712998658000,0,379000,6824712999037000,43,"S",120,17179870618,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713030620000,1,274000,6824713030894000,43,"S",120,17179870676,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713064913000,1,237000,6824713065150000,43,"S",120,17179870739,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713097848000,2,321000,6824713098169000,43,"S",120,17179870859,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713130520000,1,356000,6824713130876000,43,"S",120,17179870974,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713164352000,3,251000,6824713164603000,43,"S",120,17179871090,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713198323000,3,309000,6824713198632000,43,"S",120,17179871215,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713231003000,3,258000,6824713231261000,43,"S",120,17179871304,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713265129000,2,305000,6824713265434000,43,"S",120,17179871432,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713298257000,2,260000,6824713298517000,43,"S",120,17179871506,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713331731000,0,215000,6824713331946000,43,"S",120,17179871591,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713366507000,0,360000,6824713366867000,43,"S",120,17179871685,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713397319000,1,268000,6824713397587000,43,"S",120,17179871805,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713431590000,2,264000,6824713431854000,43,"R+",120,17179872008,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713431900000,2,159000,6824713432059000,43,"S",120,17179872013,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713464149000,3,282000,6824713464431000,43,"S",120,17179872243,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713499282000,3,328000,6824713499610000,43,"S",120,17179872422,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713534067000,1,310000,6824713534377000,43,"S",120,17179872487,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713567941000,2,390000,6824713568331000,43,"S",120,17179872589,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713601574000,1,395000,6824713601969000,43,"S",120,17179872661,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824713633674000,0,213000,6824713633887000,43,"S",120,17179872701,35,"Binder:640_2",675,"[NULL]","[NULL]"
+6824711860063000,0,48000,6824711860111000,44,"S",120,17179869322,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824711866086000,0,46000,6824711866132000,44,"S",120,17179869334,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824711867021000,0,47000,6824711867068000,44,"S",120,17179869336,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824711872463000,0,52000,6824711872515000,44,"S",120,17179869340,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824711880085000,0,155000,6824711880240000,44,"S",120,17179869383,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824711922383000,0,57000,6824711922440000,44,"S",120,17179869451,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824711997062000,0,65000,6824711997127000,44,"S",120,17179869518,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712030329000,0,70000,6824712030399000,44,"S",120,17179869544,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712092233000,0,79000,6824712092312000,44,"S",120,17179869578,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712130193000,0,56000,6824712130249000,44,"S",120,17179869617,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712245127000,0,258000,6824712245385000,44,"S",120,17179869708,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712259478000,0,86000,6824712259564000,44,"S",120,17179869718,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712285365000,0,85000,6824712285450000,44,"S",120,17179869739,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712288868000,0,79000,6824712288947000,44,"S",120,17179869744,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712291181000,0,48000,6824712291229000,44,"S",120,17179869749,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712533542000,0,67000,6824712533609000,44,"S",120,17179869913,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712561517000,0,189000,6824712561706000,44,"S",120,17179869921,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712591765000,0,69000,6824712591834000,44,"S",120,17179869942,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712658290000,0,53000,6824712658343000,44,"S",120,17179870045,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712663539000,0,53000,6824712663592000,44,"S",120,17179870065,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712692010000,0,52000,6824712692062000,44,"S",120,17179870079,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712703317000,0,21000,6824712703338000,44,"S",120,17179870105,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824712829514000,0,249000,6824712829763000,44,"S",120,17179870234,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824713495363000,0,62000,6824713495425000,44,"S",120,17179872405,37,"ksoftirqd/0",3,"[NULL]","[NULL]"
+6824711885635000,6,44000,6824711885679000,45,"S",120,17179869394,38,"ksoftirqd/6",57,"[NULL]","[NULL]"
+6824711897350000,6,43000,6824711897393000,45,"S",120,17179869434,38,"ksoftirqd/6",57,"[NULL]","[NULL]"
+6824711901150000,6,40000,6824711901190000,45,"S",120,17179869440,38,"ksoftirqd/6",57,"[NULL]","[NULL]"
+6824712838920000,6,49000,6824712838969000,45,"S",120,17179870255,38,"ksoftirqd/6",57,"[NULL]","[NULL]"
+6824711893728000,0,65000,6824711893793000,46,"S",120,17179869425,39,"kworker/0:1",19511,"[NULL]","[NULL]"
+6824712723685000,0,148000,6824712723833000,46,"D",120,17179870144,39,"kworker/0:1",19511,"[NULL]","[NULL]"
+6824712724739000,0,236000,6824712724975000,46,"R+",120,17179870149,39,"kworker/0:1",19511,"[NULL]","[NULL]"
+6824712725519000,0,64000,6824712725583000,46,"S",120,17179870151,39,"kworker/0:1",19511,"[NULL]","[NULL]"
+6824712758391000,0,96000,6824712758487000,46,"S",120,17179870185,39,"kworker/0:1",19511,"[NULL]","[NULL]"
+6824712760118000,0,54000,6824712760172000,46,"S",120,17179870193,39,"kworker/0:1",19511,"[NULL]","[NULL]"
+6824712795678000,0,171000,6824712795849000,46,"S",120,17179870213,39,"kworker/0:1",19511,"[NULL]","[NULL]"
+6824712827950000,0,303000,6824712828253000,46,"S",120,17179870231,39,"kworker/0:1",19511,"[NULL]","[NULL]"
+6824712859235000,0,137000,6824712859372000,46,"S",120,17179870271,39,"kworker/0:1",19511,"[NULL]","[NULL]"
+6824712892416000,0,105000,6824712892521000,46,"S",120,17179870361,39,"kworker/0:1",19511,"[NULL]","[NULL]"
+6824711904420000,1,72000,6824711904492000,47,"S",120,17179869444,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824711919261000,1,145000,6824711919406000,47,"S",120,17179869446,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824711958312000,1,275000,6824711958587000,47,"S",120,17179869472,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824711991963000,1,86000,6824711992049000,47,"S",120,17179869503,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824712060192000,1,37000,6824712060229000,47,"S",120,17179869551,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824712076168000,1,225000,6824712076393000,47,"S",120,17179869570,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824712158889000,1,87000,6824712158976000,47,"S",120,17179869638,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824712191641000,1,258000,6824712191899000,47,"S",120,17179869659,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824712226321000,1,87000,6824712226408000,47,"S",120,17179869687,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824712594094000,1,73000,6824712594167000,47,"S",120,17179869952,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824712627943000,1,143000,6824712628086000,47,"S",120,17179869970,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824712689257000,1,201000,6824712689458000,47,"S",120,17179870071,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824712693618000,1,43000,6824712693661000,47,"S",120,17179870085,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824712707137000,1,57000,6824712707194000,47,"S",120,17179870126,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824712722794000,1,64000,6824712722858000,47,"S",120,17179870141,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824712795209000,1,163000,6824712795372000,47,"S",120,17179870211,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824713060570000,1,23000,6824713060593000,47,"S",120,17179870720,40,"ksoftirqd/1",17,"[NULL]","[NULL]"
+6824711958587000,1,120000,6824711958707000,48,"S",120,17179869473,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824712060229000,1,111000,6824712060340000,48,"S",120,17179869552,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824712689458000,1,81000,6824712689539000,48,"D",120,17179870072,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824712890529000,1,61000,6824712890590000,48,"S",120,17179870350,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824712963188000,1,505000,6824712963693000,48,"S",120,17179870529,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824712984410000,1,138000,6824712984548000,48,"S",120,17179870568,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824712985834000,1,51000,6824712985885000,48,"R+",120,17179870575,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824712985964000,1,186000,6824712986150000,48,"S",120,17179870577,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824712988615000,1,69000,6824712988684000,48,"S",120,17179870587,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713072027000,1,34000,6824713072061000,48,"S",120,17179870756,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713079966000,1,28000,6824713079994000,48,"S",120,17179870790,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713167455000,1,63000,6824713167518000,48,"S",120,17179871110,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713167830000,1,52000,6824713167882000,48,"R",120,17179871118,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713168014000,1,125000,6824713168139000,48,"S",120,17179871120,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713179968000,1,67000,6824713180035000,48,"S",120,17179871144,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713180763000,1,28000,6824713180791000,48,"S",120,17179871150,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713181501000,1,44000,6824713181545000,48,"S",120,17179871158,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713189926000,1,53000,6824713189979000,48,"S",120,17179871174,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713191092000,1,23000,6824713191115000,48,"R+",120,17179871183,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713191148000,1,15000,6824713191163000,48,"S",120,17179871187,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713191244000,1,41000,6824713191285000,48,"S",120,17179871190,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713206122000,1,57000,6824713206179000,48,"S",120,17179871235,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713260031000,1,69000,6824713260100000,48,"S",120,17179871401,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713430672000,1,134000,6824713430806000,48,"S",120,17179872002,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713431619000,1,101000,6824713431720000,48,"S",120,17179872009,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713472737000,1,105000,6824713472842000,48,"S",120,17179872327,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824713476698000,1,154000,6824713476852000,48,"S",120,17179872372,41,"kworker/1:1",18800,"[NULL]","[NULL]"
+6824712022625000,3,91000,6824712022716000,49,"S",120,17179869524,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713088765000,3,41000,6824713088806000,49,"S",120,17179870825,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713089098000,3,89000,6824713089187000,49,"S",120,17179870832,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713100451000,3,97000,6824713100548000,49,"S",120,17179870874,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713100638000,3,17000,6824713100655000,49,"S",120,17179870877,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713101961000,3,73000,6824713102034000,49,"S",120,17179870888,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713110919000,3,54000,6824713110973000,49,"S",120,17179870904,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713112272000,3,72000,6824713112344000,49,"S",120,17179870913,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713122469000,3,51000,6824713122520000,49,"S",120,17179870931,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713144017000,3,60000,6824713144077000,49,"S",120,17179871021,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713144551000,3,44000,6824713144595000,49,"S",120,17179871025,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713155332000,3,55000,6824713155387000,49,"S",120,17179871052,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713166662000,3,58000,6824713166720000,49,"S",120,17179871101,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713207053000,3,47000,6824713207100000,49,"S",120,17179871241,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713227096000,3,66000,6824713227162000,49,"S",120,17179871285,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713240126000,3,61000,6824713240187000,49,"S",120,17179871321,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713240819000,3,32000,6824713240851000,49,"S",120,17179871325,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713241237000,3,43000,6824713241280000,49,"S",120,17179871331,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713252968000,3,186000,6824713253154000,49,"S",120,17179871359,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713253342000,3,68000,6824713253410000,49,"S",120,17179871362,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713254862000,3,213000,6824713255075000,49,"S",120,17179871373,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713405380000,3,138000,6824713405518000,49,"S",120,17179871857,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713408017000,3,114000,6824713408131000,49,"S",120,17179871869,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713418669000,3,117000,6824713418786000,49,"S",120,17179871917,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713421574000,3,130000,6824713421704000,49,"S",120,17179871943,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713424065000,3,113000,6824713424178000,49,"S",120,17179871959,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713424936000,3,111000,6824713425047000,49,"S",120,17179871963,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713429028000,3,118000,6824713429146000,49,"S",120,17179871982,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713430083000,3,143000,6824713430226000,49,"S",120,17179871996,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824713432243000,3,110000,6824713432353000,49,"S",120,17179872018,42,"kworker/3:1",17791,"[NULL]","[NULL]"
+6824712075788000,1,0,6824712075788000,50,"[NULL]",120,17179869569,"[NULL]","Executor-7",14762,"[NULL]","[NULL]"
+6824713099478000,1,0,6824713099478000,50,"[NULL]",120,17179870870,"[NULL]","Executor-7",14762,"[NULL]","[NULL]"
+6824712131076000,0,202000,6824712131278000,51,"D",120,17179869620,43,"rild",1339,"[NULL]","[NULL]"
+6824712131343000,0,671000,6824712132014000,51,"S",120,17179869622,43,"rild",1339,"[NULL]","[NULL]"
+6824712132014000,0,442000,6824712132456000,53,"S",120,17179869624,43,"rild",1260,"[NULL]","[NULL]"
+6824712132456000,0,0,6824712132456000,54,"[NULL]",120,17179869626,"[NULL]","suspend@1.0-ser",796,"[NULL]","[NULL]"
+6824712135146000,0,0,6824712135146000,54,"[NULL]",120,17179869629,"[NULL]","suspend@1.0-ser",796,"[NULL]","[NULL]"
+6824712244716000,0,324000,6824712245040000,55,"S",120,17179869704,44,"ogle.android.as",15167,"[NULL]","[NULL]"
+6824713246025000,1,64000,6824713246089000,55,"S",120,17179871339,44,"ogle.android.as",15167,"[NULL]","[NULL]"
+6824712244847000,1,193000,6824712245040000,56,"S",120,17179869705,44,"ogle.android.as",15166,"[NULL]","[NULL]"
+6824713245939000,1,86000,6824713246025000,56,"S",120,17179871338,44,"ogle.android.as",15166,"[NULL]","[NULL]"
+6824712247536000,7,62000,6824712247598000,58,"S",120,17179869712,45,"ksoftirqd/7",65,"[NULL]","[NULL]"
+6824712284789000,0,0,6824712284789000,59,"[NULL]",100,17179869738,"[NULL]","thermal-engine",2490,"[NULL]","[NULL]"
+6824712288119000,0,0,6824712288119000,59,"[NULL]",100,17179869742,"[NULL]","thermal-engine",2490,"[NULL]","[NULL]"
+6824713289124000,0,0,6824713289124000,59,"[NULL]",100,17179871481,"[NULL]","thermal-engine",2490,"[NULL]","[NULL]"
+6824713290232000,0,0,6824713290232000,59,"[NULL]",100,17179871483,"[NULL]","thermal-engine",2490,"[NULL]","[NULL]"
+6824712530067000,0,0,6824712530067000,60,"[NULL]",120,17179869907,"[NULL]","Executor-7",14763,"[NULL]","[NULL]"
+6824713547071000,0,0,6824713547071000,60,"[NULL]",120,17179872537,"[NULL]","Executor-7",14763,"[NULL]","[NULL]"
+6824712591774000,2,643000,6824712592417000,61,"S",120,17179869943,46,"hwservicemanage",602,"[NULL]","[NULL]"
+6824713629031000,2,2744000,6824713631775000,61,"R+",120,17179872681,46,"hwservicemanage",602,"[NULL]","[NULL]"
+6824713632030000,2,108000,6824713632138000,61,"S",120,17179872695,46,"hwservicemanage",602,"[NULL]","[NULL]"
+6824713632575000,2,334000,6824713632909000,61,"S",120,17179872697,46,"hwservicemanage",602,"[NULL]","[NULL]"
+6824712644319000,0,91000,6824712644410000,62,"S",100,17179869988,47,"kworker/0:1H",558,"[NULL]","[NULL]"
+6824712646655000,0,46000,6824712646701000,62,"S",100,17179869998,47,"kworker/0:1H",558,"[NULL]","[NULL]"
+6824712650022000,0,45000,6824712650067000,62,"S",100,17179870022,47,"kworker/0:1H",558,"[NULL]","[NULL]"
+6824712653362000,0,46000,6824712653408000,62,"S",100,17179870039,47,"kworker/0:1H",558,"[NULL]","[NULL]"
+6824712653004000,3,59000,6824712653063000,63,"S",100,17179870037,48,"kworker/3:1H",578,"[NULL]","[NULL]"
+6824712722606000,1,109000,6824712722715000,64,"S",0,17179870138,49,"watchdog/1",15,"[NULL]","[NULL]"
+6824712722763000,2,73000,6824712722836000,65,"S",0,17179870140,50,"watchdog/2",23,"[NULL]","[NULL]"
+6824712723826000,3,72000,6824712723898000,66,"S",0,17179870145,51,"watchdog/3",31,"[NULL]","[NULL]"
+6824712724661000,0,78000,6824712724739000,67,"S",120,17179870148,52,"kworker/0:3",19397,"[NULL]","[NULL]"
+6824712726382000,4,67000,6824712726449000,68,"S",0,17179870157,53,"watchdog/4",39,"[NULL]","[NULL]"
+6824712726858000,5,46000,6824712726904000,69,"S",0,17179870159,54,"watchdog/5",47,"[NULL]","[NULL]"
+6824712726952000,5,38000,6824712726990000,70,"S",120,17179870161,55,"ksoftirqd/5",49,"[NULL]","[NULL]"
+6824712728062000,6,48000,6824712728110000,71,"S",0,17179870166,56,"watchdog/6",55,"[NULL]","[NULL]"
+6824712729998000,7,46000,6824712730044000,72,"S",0,17179870172,57,"watchdog/7",63,"[NULL]","[NULL]"
+6824712857612000,2,2594000,6824712860206000,73,"R+",120,17179870270,58,"sh",20457,"[NULL]","[NULL]"
+6824712860348000,2,3024000,6824712863372000,73,"R+",120,17179870276,58,"sh",20457,"[NULL]","[NULL]"
+6824712863611000,2,1548000,6824712865159000,73,"R+",120,17179870294,58,"sh",20457,"[NULL]","[NULL]"
+6824712869884000,2,197000,6824712870081000,73,"R+",120,17179870319,58,"sh",20457,"[NULL]","[NULL]"
+6824712870178000,2,153000,6824712870331000,73,"R+",120,17179870323,58,"sh",20457,"[NULL]","[NULL]"
+6824712878043000,2,5493000,6824712883536000,73,"R+",120,17179870342,58,"sh",20457,"[NULL]","[NULL]"
+6824712883760000,2,7130000,6824712890890000,73,"R",120,17179870346,58,"sh",20457,"[NULL]","[NULL]"
+6824712891078000,2,5651000,6824712896729000,73,"R",120,17179870356,58,"sh",20457,"[NULL]","[NULL]"
+6824712896767000,2,3122000,6824712899889000,73,"R",120,17179870378,58,"sh",20457,"[NULL]","[NULL]"
+6824712900013000,2,3333000,6824712903346000,73,"R",120,17179870387,58,"sh",20457,"[NULL]","[NULL]"
+6824712903543000,2,3857000,6824712907400000,73,"R",120,17179870393,58,"sh",20457,"[NULL]","[NULL]"
+6824712907466000,2,180000,6824712907646000,73,"R+",120,17179870399,58,"sh",20457,"[NULL]","[NULL]"
+6824712916623000,2,1909000,6824712918532000,73,"x",120,17179870442,58,"sh",20457,"[NULL]","[NULL]"
+6824712866310000,7,74000,6824712866384000,74,"S",120,17179870298,59,"hwrng",215,"[NULL]","[NULL]"
+6824712873102000,7,72000,6824712873174000,74,"S",120,17179870329,59,"hwrng",215,"[NULL]","[NULL]"
+6824712878967000,7,74000,6824712879041000,74,"S",120,17179870343,59,"hwrng",215,"[NULL]","[NULL]"
+6824712901640000,7,72000,6824712901712000,74,"S",120,17179870390,59,"hwrng",215,"[NULL]","[NULL]"
+6824712982493000,7,74000,6824712982567000,74,"S",120,17179870560,59,"hwrng",215,"[NULL]","[NULL]"
+6824712982696000,1,31000,6824712982727000,74,"S",120,17179870562,59,"hwrng",215,"[NULL]","[NULL]"
+6824712984548000,1,27000,6824712984575000,74,"S",120,17179870569,59,"hwrng",215,"[NULL]","[NULL]"
+6824713010971000,1,26000,6824713010997000,74,"S",120,17179870633,59,"hwrng",215,"[NULL]","[NULL]"
+6824713024218000,0,23000,6824713024241000,74,"S",120,17179870650,59,"hwrng",215,"[NULL]","[NULL]"
+6824713024797000,0,9000,6824713024806000,74,"S",120,17179870652,59,"hwrng",215,"[NULL]","[NULL]"
+6824713054055000,0,22000,6824713054077000,74,"S",120,17179870712,59,"hwrng",215,"[NULL]","[NULL]"
+6824713264595000,1,23000,6824713264618000,74,"S",120,17179871429,59,"hwrng",215,"[NULL]","[NULL]"
+6824713265434000,2,29000,6824713265463000,74,"S",120,17179871433,59,"hwrng",215,"[NULL]","[NULL]"
+6824713300327000,2,21000,6824713300348000,74,"S",120,17179871514,59,"hwrng",215,"[NULL]","[NULL]"
+6824713539879000,2,332000,6824713540211000,74,"S",120,17179872504,59,"hwrng",215,"[NULL]","[NULL]"
+6824713541413000,2,46000,6824713541459000,74,"S",120,17179872516,59,"hwrng",215,"[NULL]","[NULL]"
+6824713547630000,2,46000,6824713547676000,74,"S",120,17179872544,59,"hwrng",215,"[NULL]","[NULL]"
+6824713563716000,2,72000,6824713563788000,74,"S",120,17179872568,59,"hwrng",215,"[NULL]","[NULL]"
+6824713573049000,2,113000,6824713573162000,74,"S",120,17179872596,59,"hwrng",215,"[NULL]","[NULL]"
+6824713575717000,2,111000,6824713575828000,74,"S",120,17179872606,59,"hwrng",215,"[NULL]","[NULL]"
+6824713623222000,2,232000,6824713623454000,74,"S",120,17179872673,59,"hwrng",215,"[NULL]","[NULL]"
+6824712867996000,1,60000,6824712868056000,75,"R+",120,17179870307,60,"kworker/1:0",19220,"[NULL]","[NULL]"
+6824712868115000,1,111000,6824712868226000,75,"R+",120,17179870309,60,"kworker/1:0",19220,"[NULL]","[NULL]"
+6824712868304000,1,48000,6824712868352000,75,"R+",120,17179870312,60,"kworker/1:0",19220,"[NULL]","[NULL]"
+6824712868409000,1,45000,6824712868454000,75,"R+",120,17179870314,60,"kworker/1:0",19220,"[NULL]","[NULL]"
+6824712868526000,1,257000,6824712868783000,75,"S",120,17179870316,60,"kworker/1:0",19220,"[NULL]","[NULL]"
+6824712870222000,1,113000,6824712870335000,75,"R+",120,17179870324,60,"kworker/1:0",19220,"[NULL]","[NULL]"
+6824712870378000,1,66000,6824712870444000,75,"S",120,17179870327,60,"kworker/1:0",19220,"[NULL]","[NULL]"
+6824712877196000,2,374000,6824712877570000,76,"R",120,17179870335,13,"shell",20458,"[NULL]","[NULL]"
+6824712877602000,2,441000,6824712878043000,76,"S",120,17179870340,13,"shell",20458,"[NULL]","[NULL]"
+6824712907646000,2,198000,6824712907844000,76,"S",120,17179870401,13,"shell",20458,"[NULL]","[NULL]"
+6824712911326000,2,112000,6824712911438000,76,"S",120,17179870430,13,"shell",20458,"[NULL]","[NULL]"
+6824712918532000,2,938000,6824712919470000,76,"x",120,17179870447,13,"shell",20458,"[NULL]","[NULL]"
+6824712909075000,2,25000,6824712909100000,77,"S",100,17179870405,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824712909278000,2,50000,6824712909328000,77,"S",100,17179870407,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824712909377000,2,21000,6824712909398000,77,"S",100,17179870409,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824712909572000,2,42000,6824712909614000,77,"S",100,17179870412,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824712909667000,2,62000,6824712909729000,77,"S",100,17179870414,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824712910305000,2,35000,6824712910340000,77,"S",100,17179870420,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824712910374000,2,46000,6824712910420000,77,"S",100,17179870422,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824712911070000,2,92000,6824712911162000,77,"S",100,17179870425,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713133492000,3,53000,6824713133545000,77,"S",100,17179870995,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713133580000,2,40000,6824713133620000,77,"S",100,17179871000,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713143278000,3,57000,6824713143335000,77,"S",100,17179871018,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713143941000,3,76000,6824713144017000,77,"S",100,17179871020,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713144515000,3,36000,6824713144551000,77,"S",100,17179871024,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713144595000,3,37000,6824713144632000,77,"S",100,17179871027,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713144672000,2,58000,6824713144730000,77,"S",100,17179871029,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713155249000,3,83000,6824713155332000,77,"S",100,17179871051,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713155666000,2,78000,6824713155744000,77,"S",100,17179871054,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713257218000,2,23000,6824713257241000,77,"S",100,17179871387,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713257301000,2,26000,6824713257327000,77,"S",100,17179871389,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713331152000,2,172000,6824713331324000,77,"S",100,17179871582,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713331452000,2,4000,6824713331456000,77,"S",100,17179871585,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713331718000,2,33000,6824713331751000,77,"S",100,17179871590,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713331784000,2,39000,6824713331823000,77,"S",100,17179871593,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713351541000,6,108000,6824713351649000,77,"S",100,17179871624,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713351917000,6,39000,6824713351956000,77,"S",100,17179871628,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713352088000,6,38000,6824713352126000,77,"S",100,17179871632,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713352184000,6,60000,6824713352244000,77,"S",100,17179871634,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713361271000,0,118000,6824713361389000,77,"S",100,17179871652,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713361516000,0,44000,6824713361560000,77,"S",100,17179871656,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713361621000,0,33000,6824713361654000,77,"S",100,17179871659,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713361801000,0,57000,6824713361858000,77,"S",100,17179871662,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713361904000,0,39000,6824713361943000,77,"S",100,17179871664,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713361986000,0,70000,6824713362056000,77,"S",100,17179871666,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713372472000,0,237000,6824713372709000,77,"R+",100,17179871699,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713372897000,0,74000,6824713372971000,77,"S",100,17179871701,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713373148000,0,64000,6824713373212000,77,"S",100,17179871705,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713373354000,0,79000,6824713373433000,77,"S",100,17179871708,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713382525000,0,114000,6824713382639000,77,"S",100,17179871731,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713383556000,0,102000,6824713383658000,77,"S",100,17179871737,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713383773000,0,53000,6824713383826000,77,"S",100,17179871739,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713390040000,0,142000,6824713390182000,77,"S",100,17179871757,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713390836000,0,87000,6824713390923000,77,"S",100,17179871761,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713391491000,0,76000,6824713391567000,77,"S",100,17179871765,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713391881000,0,87000,6824713391968000,77,"S",100,17179871767,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713393356000,0,90000,6824713393446000,77,"S",100,17179871774,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713393551000,0,67000,6824713393618000,77,"S",100,17179871778,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713393791000,0,72000,6824713393863000,77,"S",100,17179871781,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713393973000,0,35000,6824713394008000,77,"S",100,17179871784,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713394095000,0,67000,6824713394162000,77,"S",100,17179871787,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713394341000,0,59000,6824713394400000,77,"S",100,17179871789,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713400220000,0,111000,6824713400331000,77,"S",100,17179871814,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713400604000,0,34000,6824713400638000,77,"S",100,17179871818,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713401186000,0,78000,6824713401264000,77,"S",100,17179871822,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713403479000,0,104000,6824713403583000,77,"S",100,17179871838,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713404189000,0,132000,6824713404321000,77,"R+",100,17179871845,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713404461000,0,55000,6824713404516000,77,"S",100,17179871848,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713408708000,0,44000,6824713408752000,77,"S",100,17179871876,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713416170000,0,101000,6824713416271000,77,"S",100,17179871896,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713421345000,0,93000,6824713421438000,77,"S",100,17179871938,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713421487000,0,43000,6824713421530000,77,"S",100,17179871941,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713468768000,0,71000,6824713468839000,77,"S",100,17179872291,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713472041000,0,131000,6824713472172000,77,"S",100,17179872320,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713472494000,1,96000,6824713472590000,77,"S",100,17179872324,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713472637000,1,100000,6824713472737000,77,"S",100,17179872326,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713472799000,0,61000,6824713472860000,77,"S",100,17179872329,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713472904000,0,75000,6824713472979000,77,"S",100,17179872332,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713473432000,0,106000,6824713473538000,77,"S",100,17179872336,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713474619000,0,108000,6824713474727000,77,"S",100,17179872347,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713474794000,2,81000,6824713474875000,77,"S",100,17179872349,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713475064000,2,217000,6824713475281000,77,"S",100,17179872353,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713475358000,0,96000,6824713475454000,77,"S",100,17179872355,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713475788000,1,89000,6824713475877000,77,"S",100,17179872365,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713476498000,1,200000,6824713476698000,77,"S",100,17179872368,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713529226000,1,134000,6824713529360000,77,"S",100,17179872465,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713529522000,0,135000,6824713529657000,77,"S",100,17179872467,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713529713000,0,55000,6824713529768000,77,"S",100,17179872470,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713529887000,0,214000,6824713530101000,77,"S",100,17179872472,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713540156000,0,139000,6824713540295000,77,"S",100,17179872505,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713540812000,0,76000,6824713540888000,77,"S",100,17179872513,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713541392000,5,115000,6824713541507000,77,"S",100,17179872515,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713541575000,5,59000,6824713541634000,77,"S",100,17179872519,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713542339000,5,29000,6824713542368000,77,"S",100,17179872522,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824713542781000,5,61000,6824713542842000,77,"S",100,17179872525,61,"kworker/u17:2",14944,"[NULL]","[NULL]"
+6824712913561000,2,431000,6824712913992000,78,"R+",120,17179870433,62,"sh",20459,"[NULL]","[NULL]"
+6824712914057000,2,670000,6824712914727000,78,"R+",120,17179870437,62,"sh",20459,"[NULL]","[NULL]"
+6824712914773000,2,1850000,6824712916623000,78,"R+",120,17179870439,62,"sh",20459,"[NULL]","[NULL]"
+6824712920831000,2,100000,6824712920931000,78,"R+",120,17179870456,62,"sh",20459,"[NULL]","[NULL]"
+6824712921258000,2,54000,6824712921312000,78,"x",120,17179870467,62,"sh",20459,"[NULL]","[NULL]"
+6824712974275000,1,2508000,6824712976783000,79,"R+",120,17179870544,63,"sh",20460,"[NULL]","[NULL]"
+6824712976923000,1,2388000,6824712979311000,79,"R+",120,17179870552,63,"sh",20460,"[NULL]","[NULL]"
+6824712979492000,1,1949000,6824712981441000,79,"R+",120,17179870555,63,"sh",20460,"[NULL]","[NULL]"
+6824712981569000,1,1127000,6824712982696000,79,"R+",120,17179870558,63,"sh",20460,"[NULL]","[NULL]"
+6824712982727000,1,630000,6824712983357000,79,"R",120,17179870563,63,"sh",20460,"[NULL]","[NULL]"
+6824712983415000,1,820000,6824712984235000,79,"R+",120,17179870565,63,"sh",20460,"[NULL]","[NULL]"
+6824712985093000,1,600000,6824712985693000,79,"R+",120,17179870573,63,"sh",20460,"[NULL]","[NULL]"
+6824712990279000,1,2760000,6824712993039000,79,"R+",120,17179870593,63,"sh",20460,"[NULL]","[NULL]"
+6824712994022000,1,2637000,6824712996659000,79,"R",120,17179870601,63,"sh",20460,"[NULL]","[NULL]"
+6824712996815000,1,3192000,6824713000007000,79,"R+",120,17179870616,63,"sh",20460,"[NULL]","[NULL]"
+6824713000267000,1,3074000,6824713003341000,79,"R",120,17179870627,63,"sh",20460,"[NULL]","[NULL]"
+6824713003550000,1,7239000,6824713010789000,79,"R",120,17179870629,63,"sh",20460,"[NULL]","[NULL]"
+6824713010876000,1,95000,6824713010971000,79,"R+",120,17179870632,63,"sh",20460,"[NULL]","[NULL]"
+6824713010997000,1,5636000,6824713016633000,79,"R",120,17179870634,63,"sh",20460,"[NULL]","[NULL]"
+6824713016814000,1,1724000,6824713018538000,79,"S",120,17179870639,63,"sh",20460,"[NULL]","[NULL]"
+6824713470096000,2,3770000,6824713473866000,79,"x",120,17179872306,63,"sh",20460,"[NULL]","[NULL]"
+6824712984229000,0,571000,6824712984800000,80,"S",120,17179870566,13,"shell",20461,"[NULL]","[NULL]"
+6824712988254000,0,185000,6824712988439000,80,"S",120,17179870584,13,"shell",20461,"[NULL]","[NULL]"
+6824713071189000,1,109000,6824713071298000,80,"S",120,17179870751,13,"shell",20461,"[NULL]","[NULL]"
+6824713079437000,1,81000,6824713079518000,80,"S",120,17179870785,13,"shell",20461,"[NULL]","[NULL]"
+6824713087986000,1,139000,6824713088125000,80,"S",120,17179870812,13,"shell",20461,"[NULL]","[NULL]"
+6824713099244000,1,183000,6824713099427000,80,"S",120,17179870867,13,"shell",20461,"[NULL]","[NULL]"
+6824713109593000,1,155000,6824713109748000,80,"S",120,17179870899,13,"shell",20461,"[NULL]","[NULL]"
+6824713121186000,1,154000,6824713121340000,80,"S",120,17179870926,13,"shell",20461,"[NULL]","[NULL]"
+6824713131766000,3,183000,6824713131949000,80,"S",120,17179870983,13,"shell",20461,"[NULL]","[NULL]"
+6824713142097000,1,152000,6824713142249000,80,"S",120,17179871014,13,"shell",20461,"[NULL]","[NULL]"
+6824713153968000,1,154000,6824713154122000,80,"S",120,17179871043,13,"shell",20461,"[NULL]","[NULL]"
+6824713165368000,1,186000,6824713165554000,80,"S",120,17179871097,13,"shell",20461,"[NULL]","[NULL]"
+6824713178361000,1,204000,6824713178565000,80,"S",120,17179871139,13,"shell",20461,"[NULL]","[NULL]"
+6824713188533000,1,169000,6824713188702000,80,"S",120,17179871169,13,"shell",20461,"[NULL]","[NULL]"
+6824713204702000,1,215000,6824713204917000,80,"S",120,17179871227,13,"shell",20461,"[NULL]","[NULL]"
+6824713224315000,1,256000,6824713224571000,80,"S",120,17179871263,13,"shell",20461,"[NULL]","[NULL]"
+6824713238051000,1,210000,6824713238261000,80,"S",120,17179871316,13,"shell",20461,"[NULL]","[NULL]"
+6824713250362000,6,413000,6824713250775000,80,"S",120,17179871347,13,"shell",20461,"[NULL]","[NULL]"
+6824713253782000,6,16000,6824713253798000,80,"S",120,17179871367,13,"shell",20461,"[NULL]","[NULL]"
+6824713329190000,6,433000,6824713329623000,80,"S",120,17179871565,13,"shell",20461,"[NULL]","[NULL]"
+6824713344050000,6,47000,6824713344097000,80,"R+",120,17179871617,13,"shell",20461,"[NULL]","[NULL]"
+6824713344129000,6,10000,6824713344139000,80,"S",120,17179871619,13,"shell",20461,"[NULL]","[NULL]"
+6824713358681000,6,60000,6824713358741000,80,"S",120,17179871645,13,"shell",20461,"[NULL]","[NULL]"
+6824713369959000,6,65000,6824713370024000,80,"R+",120,17179871694,13,"shell",20461,"[NULL]","[NULL]"
+6824713370060000,6,15000,6824713370075000,80,"S",120,17179871696,13,"shell",20461,"[NULL]","[NULL]"
+6824713381340000,6,66000,6824713381406000,80,"S",120,17179871728,13,"shell",20461,"[NULL]","[NULL]"
+6824713388461000,6,29000,6824713388490000,80,"S",120,17179871754,13,"shell",20461,"[NULL]","[NULL]"
+6824713392418000,6,21000,6824713392439000,80,"S",120,17179871771,13,"shell",20461,"[NULL]","[NULL]"
+6824713399486000,6,30000,6824713399516000,80,"S",120,17179871811,13,"shell",20461,"[NULL]","[NULL]"
+6824713402488000,7,51000,6824713402539000,80,"S",120,17179871828,13,"shell",20461,"[NULL]","[NULL]"
+6824713407002000,5,29000,6824713407031000,80,"S",120,17179871864,13,"shell",20461,"[NULL]","[NULL]"
+6824713415017000,5,41000,6824713415058000,80,"S",120,17179871887,13,"shell",20461,"[NULL]","[NULL]"
+6824713415929000,5,22000,6824713415951000,80,"S",120,17179871893,13,"shell",20461,"[NULL]","[NULL]"
+6824713419965000,5,29000,6824713419994000,80,"S",120,17179871927,13,"shell",20461,"[NULL]","[NULL]"
+6824713423208000,5,44000,6824713423252000,80,"S",120,17179871948,13,"shell",20461,"[NULL]","[NULL]"
+6824713427836000,5,29000,6824713427865000,80,"S",120,17179871973,13,"shell",20461,"[NULL]","[NULL]"
+6824713430130000,5,24000,6824713430154000,80,"S",120,17179871997,13,"shell",20461,"[NULL]","[NULL]"
+6824713434835000,5,30000,6824713434865000,80,"S",120,17179872033,13,"shell",20461,"[NULL]","[NULL]"
+6824713437605000,5,30000,6824713437635000,80,"S",120,17179872059,13,"shell",20461,"[NULL]","[NULL]"
+6824713440637000,5,30000,6824713440667000,80,"S",120,17179872085,13,"shell",20461,"[NULL]","[NULL]"
+6824713444018000,5,29000,6824713444047000,80,"S",120,17179872113,13,"shell",20461,"[NULL]","[NULL]"
+6824713447845000,7,24000,6824713447869000,80,"S",120,17179872130,13,"shell",20461,"[NULL]","[NULL]"
+6824713452167000,7,26000,6824713452193000,80,"S",120,17179872156,13,"shell",20461,"[NULL]","[NULL]"
+6824713455943000,7,21000,6824713455964000,80,"S",120,17179872174,13,"shell",20461,"[NULL]","[NULL]"
+6824713460102000,7,30000,6824713460132000,80,"S",120,17179872200,13,"shell",20461,"[NULL]","[NULL]"
+6824713464620000,7,27000,6824713464647000,80,"S",120,17179872246,13,"shell",20461,"[NULL]","[NULL]"
+6824713465649000,5,20000,6824713465669000,80,"S",120,17179872258,13,"shell",20461,"[NULL]","[NULL]"
+6824713471126000,5,89000,6824713471215000,80,"S",120,17179872314,13,"shell",20461,"[NULL]","[NULL]"
+6824713471902000,5,68000,6824713471970000,80,"S",120,17179872318,13,"shell",20461,"[NULL]","[NULL]"
+6824713474060000,6,244000,6824713474304000,80,"x",120,17179872341,13,"shell",20461,"[NULL]","[NULL]"
+6824713018538000,1,2161000,6824713020699000,81,"R+",120,17179870640,64,"sh",20462,"[NULL]","[NULL]"
+6824713020924000,1,273000,6824713021197000,81,"S",120,17179870642,64,"sh",20462,"[NULL]","[NULL]"
+6824713255928000,1,733000,6824713256661000,81,"R+",120,17179871381,64,"sh",20462,"[NULL]","[NULL]"
+6824713256748000,1,2388000,6824713259136000,81,"S",120,17179871383,64,"sh",20462,"[NULL]","[NULL]"
+6824713466542000,1,3584000,6824713470126000,81,"x",120,17179872268,64,"sh",20462,"[NULL]","[NULL]"
+6824713021926000,0,1729000,6824713023655000,82,"R+",120,17179870644,65,"ps",20463,"[NULL]","[NULL]"
+6824713023746000,0,29000,6824713023775000,82,"R+",120,17179870647,65,"ps",20463,"[NULL]","[NULL]"
+6824713023805000,0,413000,6824713024218000,82,"R+",120,17179870649,65,"ps",20463,"[NULL]","[NULL]"
+6824713024241000,0,556000,6824713024797000,82,"R+",120,17179870651,65,"ps",20463,"[NULL]","[NULL]"
+6824713024806000,0,1217000,6824713026023000,82,"R+",120,17179870653,65,"ps",20463,"[NULL]","[NULL]"
+6824713026973000,0,263000,6824713027236000,82,"R+",120,17179870657,65,"ps",20463,"[NULL]","[NULL]"
+6824713027250000,0,2732000,6824713029982000,82,"R",120,17179870663,65,"ps",20463,"[NULL]","[NULL]"
+6824713030015000,0,3308000,6824713033323000,82,"R+",120,17179870674,65,"ps",20463,"[NULL]","[NULL]"
+6824713033511000,0,3137000,6824713036648000,82,"R",120,17179870685,65,"ps",20463,"[NULL]","[NULL]"
+6824713036768000,0,6593000,6824713043361000,82,"R",120,17179870691,65,"ps",20463,"[NULL]","[NULL]"
+6824713043556000,0,3032000,6824713046588000,82,"R",120,17179870695,65,"ps",20463,"[NULL]","[NULL]"
+6824713046625000,0,431000,6824713047056000,82,"R",120,17179870699,65,"ps",20463,"[NULL]","[NULL]"
+6824713047099000,0,3188000,6824713050287000,82,"R",120,17179870703,65,"ps",20463,"[NULL]","[NULL]"
+6824713050323000,0,3621000,6824713053944000,82,"R",120,17179870707,65,"ps",20463,"[NULL]","[NULL]"
+6824713053990000,0,65000,6824713054055000,82,"R+",120,17179870711,65,"ps",20463,"[NULL]","[NULL]"
+6824713054077000,0,5450000,6824713059527000,82,"R",120,17179870713,65,"ps",20463,"[NULL]","[NULL]"
+6824713060401000,0,2914000,6824713063315000,82,"R+",120,17179870719,65,"ps",20463,"[NULL]","[NULL]"
+6824713063476000,0,29511000,6824713092987000,82,"R+",120,17179870735,65,"ps",20463,"[NULL]","[NULL]"
+6824713093061000,0,3580000,6824713096641000,82,"R+",120,17179870838,65,"ps",20463,"[NULL]","[NULL]"
+6824713096874000,0,29589000,6824713126463000,82,"R+",120,17179870857,65,"ps",20463,"[NULL]","[NULL]"
+6824713126535000,0,3430000,6824713129965000,82,"R+",120,17179870952,65,"ps",20463,"[NULL]","[NULL]"
+6824713130188000,0,29833000,6824713160021000,82,"R",120,17179870972,65,"ps",20463,"[NULL]","[NULL]"
+6824713160130000,0,33314000,6824713193444000,82,"R+",120,17179871074,65,"ps",20463,"[NULL]","[NULL]"
+6824713193520000,0,3109000,6824713196629000,82,"R+",120,17179871198,65,"ps",20463,"[NULL]","[NULL]"
+6824713196797000,0,30115000,6824713226912000,82,"R+",120,17179871213,65,"ps",20463,"[NULL]","[NULL]"
+6824713226977000,0,23808000,6824713250785000,82,"R",120,17179871281,65,"ps",20463,"[NULL]","[NULL]"
+6824713250847000,6,2556000,6824713253403000,82,"R",120,17179871350,65,"ps",20463,"[NULL]","[NULL]"
+6824713253559000,6,223000,6824713253782000,82,"R+",120,17179871366,65,"ps",20463,"[NULL]","[NULL]"
+6824713253798000,6,1208000,6824713255006000,82,"x",120,17179871368,65,"ps",20463,"[NULL]","[NULL]"
+6824713053165000,6,647000,6824713053812000,83,"S",120,17179870708,66,"m.android.phone",1702,"[NULL]","[NULL]"
+6824713250785000,0,74000,6824713250859000,84,"S",0,17179871349,67,"migration/0",13,"[NULL]","[NULL]"
+6824713329642000,0,49000,6824713329691000,84,"S",0,17179871571,67,"migration/0",13,"[NULL]","[NULL]"
+6824713259136000,1,895000,6824713260031000,85,"R+",120,17179871400,68,"ps",20464,"[NULL]","[NULL]"
+6824713260100000,1,747000,6824713260847000,85,"R+",120,17179871403,68,"ps",20464,"[NULL]","[NULL]"
+6824713261539000,1,1177000,6824713262716000,85,"R+",120,17179871414,68,"ps",20464,"[NULL]","[NULL]"
+6824713262808000,1,549000,6824713263357000,85,"R+",120,17179871424,68,"ps",20464,"[NULL]","[NULL]"
+6824713264365000,1,230000,6824713264595000,85,"R+",120,17179871428,68,"ps",20464,"[NULL]","[NULL]"
+6824713264618000,1,6871000,6824713271489000,85,"R+",120,17179871430,68,"ps",20464,"[NULL]","[NULL]"
+6824713271657000,1,2660000,6824713274317000,85,"R+",120,17179871447,68,"ps",20464,"[NULL]","[NULL]"
+6824713274540000,1,2103000,6824713276643000,85,"R+",120,17179871458,68,"ps",20464,"[NULL]","[NULL]"
+6824713276746000,1,294000,6824713277040000,85,"R+",120,17179871460,68,"ps",20464,"[NULL]","[NULL]"
+6824713277104000,1,2914000,6824713280018000,85,"R+",120,17179871465,68,"ps",20464,"[NULL]","[NULL]"
+6824713280253000,1,7441000,6824713287694000,85,"R",120,17179871467,68,"ps",20464,"[NULL]","[NULL]"
+6824713287743000,1,6273000,6824713294016000,85,"R+",120,17179871478,68,"ps",20464,"[NULL]","[NULL]"
+6824713294045000,1,182000,6824713294227000,85,"R",120,17179871489,68,"ps",20464,"[NULL]","[NULL]"
+6824713294877000,1,8453000,6824713303330000,85,"R+",120,17179871494,68,"ps",20464,"[NULL]","[NULL]"
+6824713303506000,1,3115000,6824713306621000,85,"R+",120,17179871518,68,"ps",20464,"[NULL]","[NULL]"
+6824713306692000,1,994000,6824713307686000,85,"R+",120,17179871520,68,"ps",20464,"[NULL]","[NULL]"
+6824713307718000,1,9664000,6824713317382000,85,"R+",120,17179871527,68,"ps",20464,"[NULL]","[NULL]"
+6824713317498000,1,5825000,6824713323323000,85,"R+",120,17179871536,68,"ps",20464,"[NULL]","[NULL]"
+6824713323463000,1,4344000,6824713327807000,85,"R+",120,17179871540,68,"ps",20464,"[NULL]","[NULL]"
+6824713328375000,0,1267000,6824713329642000,85,"R",120,17179871561,68,"ps",20464,"[NULL]","[NULL]"
+6824713329736000,6,3595000,6824713333331000,85,"R+",120,17179871573,68,"ps",20464,"[NULL]","[NULL]"
+6824713333434000,6,9802000,6824713343236000,85,"R+",120,17179871603,68,"ps",20464,"[NULL]","[NULL]"
+6824713343253000,6,797000,6824713344050000,85,"R+",120,17179871611,68,"ps",20464,"[NULL]","[NULL]"
+6824713344139000,6,5756000,6824713349895000,85,"R+",120,17179871620,68,"ps",20464,"[NULL]","[NULL]"
+6824713350284000,6,1235000,6824713351519000,85,"R+",120,17179871622,68,"ps",20464,"[NULL]","[NULL]"
+6824713351705000,6,212000,6824713351917000,85,"R+",120,17179871627,68,"ps",20464,"[NULL]","[NULL]"
+6824713351967000,6,121000,6824713352088000,85,"R",120,17179871631,68,"ps",20464,"[NULL]","[NULL]"
+6824713352126000,6,58000,6824713352184000,85,"R+",120,17179871633,68,"ps",20464,"[NULL]","[NULL]"
+6824713352268000,6,6413000,6824713358681000,85,"R+",120,17179871636,68,"ps",20464,"[NULL]","[NULL]"
+6824713359052000,6,875000,6824713359927000,85,"R+",120,17179871647,68,"ps",20464,"[NULL]","[NULL]"
+6824713359968000,6,3312000,6824713363280000,85,"R",120,17179871649,68,"ps",20464,"[NULL]","[NULL]"
+6824713363329000,6,6630000,6824713369959000,85,"R+",120,17179871675,68,"ps",20464,"[NULL]","[NULL]"
+6824713370374000,6,10921000,6824713381295000,85,"R+",120,17179871698,68,"ps",20464,"[NULL]","[NULL]"
+6824713381694000,6,1546000,6824713383240000,85,"R+",120,17179871730,68,"ps",20464,"[NULL]","[NULL]"
+6824713383410000,6,5051000,6824713388461000,85,"R+",120,17179871736,68,"ps",20464,"[NULL]","[NULL]"
+6824713388635000,6,3783000,6824713392418000,85,"R+",120,17179871756,68,"ps",20464,"[NULL]","[NULL]"
+6824713392439000,6,7047000,6824713399486000,85,"R+",120,17179871772,68,"ps",20464,"[NULL]","[NULL]"
+6824713399678000,6,3250000,6824713402928000,85,"R+",120,17179871813,68,"ps",20464,"[NULL]","[NULL]"
+6824713403276000,4,53289000,6824713456565000,85,"R",120,17179871835,68,"ps",20464,"[NULL]","[NULL]"
+6824713456581000,4,3324000,6824713459905000,85,"R",120,17179872179,68,"ps",20464,"[NULL]","[NULL]"
+6824713459919000,4,6161000,6824713466080000,85,"x",120,17179872199,68,"ps",20464,"[NULL]","[NULL]"
+6824713327807000,1,48000,6824713327855000,86,"S",0,17179871558,69,"migration/1",16,"[NULL]","[NULL]"
+6824713402928000,6,24000,6824713402952000,87,"S",0,17179871832,70,"migration/6",56,"[NULL]","[NULL]"
+6824713456565000,4,16000,6824713456581000,88,"S",120,17179872178,71,"kworker/4:1",19875,"[NULL]","[NULL]"
+6824713459905000,4,14000,6824713459919000,88,"S",120,17179872198,71,"kworker/4:1",19875,"[NULL]","[NULL]"
+6824713468344000,4,36000,6824713468380000,88,"R",120,17179872284,71,"kworker/4:1",19875,"[NULL]","[NULL]"
+6824713468660000,4,23000,6824713468683000,88,"S",120,17179872287,71,"kworker/4:1",19875,"[NULL]","[NULL]"
+6824713468765000,4,18000,6824713468783000,88,"S",120,17179872290,71,"kworker/4:1",19875,"[NULL]","[NULL]"
+6824713535935000,5,3107000,6824713539042000,89,"R+",120,17179872494,72,"sh",20465,"[NULL]","[NULL]"
+6824713540165000,5,271000,6824713540436000,89,"R+",120,17179872506,72,"sh",20465,"[NULL]","[NULL]"
+6824713542452000,5,329000,6824713542781000,89,"R+",120,17179872524,72,"sh",20465,"[NULL]","[NULL]"
+6824713547620000,5,5690000,6824713553310000,89,"R",120,17179872543,72,"sh",20465,"[NULL]","[NULL]"
+6824713553501000,5,6486000,6824713559987000,89,"R",120,17179872555,72,"sh",20465,"[NULL]","[NULL]"
+6824713560044000,5,2577000,6824713562621000,89,"R+",120,17179872557,72,"sh",20465,"[NULL]","[NULL]"
+6824713562848000,5,3776000,6824713566624000,89,"R",120,17179872565,72,"sh",20465,"[NULL]","[NULL]"
+6824713566647000,5,2458000,6824713569105000,89,"S",120,17179872582,72,"sh",20465,"[NULL]","[NULL]"
+6824713541507000,5,68000,6824713541575000,90,"R+",120,17179872518,73,"kworker/5:2",19092,"[NULL]","[NULL]"
+6824713541634000,5,105000,6824713541739000,90,"S",120,17179872520,73,"kworker/5:2",19092,"[NULL]","[NULL]"
+6824713542842000,5,68000,6824713542910000,90,"S",120,17179872526,73,"kworker/5:2",19092,"[NULL]","[NULL]"
+6824713559987000,5,57000,6824713560044000,90,"S",120,17179872556,73,"kworker/5:2",19092,"[NULL]","[NULL]"
+6824713544380000,4,97000,6824713544477000,91,"S",120,17179872532,74,"rcuos/5",53,"[NULL]","[NULL]"
+6824713550971000,4,48000,6824713551019000,91,"S",120,17179872550,74,"rcuos/5",53,"[NULL]","[NULL]"
+6824713587972000,4,51000,6824713588023000,91,"S",120,17179872632,74,"rcuos/5",53,"[NULL]","[NULL]"
+6824713594572000,4,31000,6824713594603000,91,"S",120,17179872644,74,"rcuos/5",53,"[NULL]","[NULL]"
+6824713547146000,5,228000,6824713547374000,92,"R",120,17179872538,13,"shell",20466,"[NULL]","[NULL]"
+6824713547395000,5,225000,6824713547620000,92,"S",120,17179872541,13,"shell",20466,"[NULL]","[NULL]"
+6824713560996000,0,1098000,6824713562094000,93,"D",100,17179872558,75,"FileWatcherThre",908,"[NULL]","[NULL]"
+6824713565085000,4,514000,6824713565599000,93,"D",100,17179872578,75,"FileWatcherThre",908,"[NULL]","[NULL]"
+6824713567081000,1,530000,6824713567611000,93,"S",100,17179872584,75,"FileWatcherThre",908,"[NULL]","[NULL]"
+6824713569105000,5,4189000,6824713573294000,95,"R+",120,17179872593,76,"atrace",20467,"[NULL]","[NULL]"
+6824713573403000,5,6607000,6824713580010000,95,"R+",120,17179872601,76,"atrace",20467,"[NULL]","[NULL]"
+6824713580070000,5,3250000,6824713583320000,95,"R+",120,17179872609,76,"atrace",20467,"[NULL]","[NULL]"
+6824713583468000,5,3138000,6824713586606000,95,"R",120,17179872622,76,"atrace",20467,"[NULL]","[NULL]"
+6824713586780000,5,6480000,6824713593260000,95,"R",120,17179872627,76,"atrace",20467,"[NULL]","[NULL]"
+6824713593321000,5,9953000,6824713603274000,95,"R",120,17179872639,76,"atrace",20467,"[NULL]","[NULL]"
+6824713603389000,5,17861000,6824713621250000,95,"R+",120,17179872668,76,"atrace",20467,"[NULL]","[NULL]"
+6824713621442000,5,5171000,6824713626613000,95,"R",120,17179872672,76,"atrace",20467,"[NULL]","[NULL]"
+6824713626711000,5,282000,6824713626993000,95,"S",120,17179872679,76,"atrace",20467,"[NULL]","[NULL]"
+6824713632138000,2,437000,6824713632575000,95,"R+",120,17179872696,76,"atrace",20467,"[NULL]","[NULL]"
+6824713632909000,2,263000,6824713633172000,95,"R+",120,17179872698,76,"atrace",20467,"[NULL]","[NULL]"
+6824713633172000,2,0,6824713633172000,96,"[NULL]",120,17179872699,"[NULL]","atrace@1.0-serv",635,"[NULL]","[NULL]"
+6824713633681000,2,1292000,6824713634973000,96,"R",120,17179872702,"[NULL]","atrace@1.0-serv",635,"[NULL]","[NULL]"
diff --git a/test/trace_processor/systrace_html.sql b/test/trace_processor/systrace_html.sql
new file mode 100644
index 0000000..0bab8f3
--- /dev/null
+++ b/test/trace_processor/systrace_html.sql
@@ -0,0 +1 @@
+select * from sched join thread using(utid)
\ No newline at end of file
diff --git a/test/trace_processor/track_event_same_tids.py b/test/trace_processor/track_event_same_tids.py
new file mode 100644
index 0000000..c838d6d
--- /dev/null
+++ b/test/trace_processor/track_event_same_tids.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# 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.
+
+from os import sys, path
+sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
+import synth_common
+
+trace = synth_common.create_trace()
+
+# Chrome renderer processes don't know their "true" tids on some platforms.
+# Instead, they each write tids that start at 1 - which means, the same tids are
+# used in multiple different processes at the same time. This trace replicates
+# such a situation.
+
+trace.add_thread_track_descriptor(
+ ps=1, ts=0, uuid=1, pid=5, tid=1, thread_name="t1", inc_state_cleared=True)
+trace.add_thread_track_descriptor(
+ ps=1, ts=0, uuid=2, pid=10, tid=1, thread_name="t2")
+
+trace.add_track_event(
+ ps=1, ts=1000, track_uuid=1, cat="cat", name="name1", type=3)
+trace.add_track_event(
+ ps=1, ts=2000, track_uuid=2, cat="cat", name="name2", type=3)
+
+print(trace.trace.SerializeToString())
diff --git a/test/trace_processor/track_event_same_tids_slices.out b/test/trace_processor/track_event_same_tids_slices.out
new file mode 100644
index 0000000..f66b8ce
--- /dev/null
+++ b/test/trace_processor/track_event_same_tids_slices.out
@@ -0,0 +1,3 @@
+"ts","dur","category","name"
+1000,0,"cat","name1"
+2000,0,"cat","name2"
diff --git a/test/trace_processor/track_event_same_tids_threads.out b/test/trace_processor/track_event_same_tids_threads.out
new file mode 100644
index 0000000..b4ce83a
--- /dev/null
+++ b/test/trace_processor/track_event_same_tids_threads.out
@@ -0,0 +1,5 @@
+"tid","pid","pname","tname"
+1,5,"[NULL]","t1"
+1,10,"[NULL]","t2"
+5,5,"[NULL]","[NULL]"
+10,10,"[NULL]","[NULL]"
diff --git a/test/trace_processor/track_event_slices.sql b/test/trace_processor/track_event_slices.sql
new file mode 100644
index 0000000..b69c990
--- /dev/null
+++ b/test/trace_processor/track_event_slices.sql
@@ -0,0 +1 @@
+select ts, dur, category, name from slice order by ts asc;
\ No newline at end of file
diff --git a/tools/add_test_trace.sh b/tools/add_test_trace.sh
index 1c47fca..976955a 100755
--- a/tools/add_test_trace.sh
+++ b/tools/add_test_trace.sh
@@ -57,12 +57,12 @@
echo "Updating tools/install-build-deps"
echo ""
-OLD_SHA=$(cat tools/install-build-deps | grep '/test-data-.*.zip' -A1 | tail -n1 | cut -c5-44)
+OLD_SHA=$(cat tools/install-build-deps | grep '/test-data-.*.zip' -A1 | tail -n1 | cut -c10-49)
# Cannot easily use sed -i, it has different syntax on Linux vs Mac.
cat tools/install-build-deps \
- | sed -e 's|/test-data-.*.zip|/'$NEW_TEST_DATA'|g' \
- | sed -e 's|'$OLD_SHA'|'$NEW_SHA'|g' \
+ | sed -e "s|/test-data-.*.zip|/$NEW_TEST_DATA|g" \
+ | sed -e "s|$OLD_SHA|$NEW_SHA|g" \
> tools/install-build-deps.tmp
mv -f tools/install-build-deps.tmp tools/install-build-deps
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index 5610db4..2d1203b 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -154,6 +154,7 @@
('required', {'libperfetto_android_internal', 'trigger_perfetto'}),
],
'libperfetto_android_internal': [('static_libs', {'libhealthhalutils'}),],
+ 'trace_processor_shell': [('static_executable', True),],
}
@@ -170,7 +171,10 @@
def enable_protoc_lib(module):
- module.shared_libs.add('libprotoc')
+ if module.type == 'cc_binary_host':
+ module.static_libs.add('libprotoc')
+ else:
+ module.shared_libs.add('libprotoc')
def enable_libunwindstack(module):
@@ -197,7 +201,10 @@
def enable_zlib(module):
- module.shared_libs.add('libz')
+ if module.type == 'cc_binary_host':
+ module.static_libs.add('libz')
+ else:
+ module.shared_libs.add('libz')
# Android equivalents for third-party libraries that the upstream project
@@ -312,6 +319,7 @@
self.android = Target('android')
self.host = Target('host')
self.lto = None
+ self.static_executable = False
self.data = set()
# The genrule_XXX below are properties that must to be propagated back
# on the module(s) that depend on the genrule.
@@ -340,6 +348,7 @@
self._output_field(output, 'include_dirs')
self._output_field(output, 'header_libs')
self._output_field(output, 'required')
+ self._output_field(output, 'static_executable')
self._output_field(output, 'tool_files')
self._output_field(output, 'data')
@@ -617,6 +626,8 @@
curr = getattr(module, key)
if add_val and isinstance(add_val, set) and isinstance(curr, set):
curr.update(add_val)
+ elif isinstance(add_val, bool) and isinstance(curr, bool):
+ setattr(module, key, add_val)
else:
raise Error('Unimplemented type of additional_args: %r' % key)
diff --git a/tools/gen_bazel b/tools/gen_bazel
index af4584b..38dcee9 100755
--- a/tools/gen_bazel
+++ b/tools/gen_bazel
@@ -215,7 +215,7 @@
assert (target.type == 'proto_library')
def get_sources_label(target_name):
- return re.sub('_(lite|zero)$', '',
+ return re.sub('_(lite|zero|cpp)$', '',
get_bazel_label_name(target_name)) + '_protos'
sources_label_name = get_sources_label(target.name)
diff --git a/tools/install-build-deps b/tools/install-build-deps
index 99db737..26a2e1a 100755
--- a/tools/install-build-deps
+++ b/tools/install-build-deps
@@ -145,8 +145,8 @@
# Example traces for regression tests.
(
'buildtools/test_data.zip',
- 'https://storage.googleapis.com/perfetto/test-data-20191008-115945.zip',
- '4738c53cec52dc2bf98d7c3a1b6f0bccfaaf26f8',
+ 'https://storage.googleapis.com/perfetto/test-data-20191025-102200.zip',
+ '25a61211f82cd73c6ce5b67da9d73f046de7b3f9',
'all',
),
diff --git a/tools/trace_processor b/tools/trace_processor
index 2af5b8f..e85568e 100755
--- a/tools/trace_processor
+++ b/tools/trace_processor
@@ -31,8 +31,8 @@
import urllib
TRACE_PROCESSOR_SHELL_SHAS = {
- 'linux': '8e7ce3affdaa1d1f66a0bd58368782784bf6c9a6',
- 'mac': '78709d06d30260119f31963143073dde24f03da0',
+ 'linux': 'dc506737a39264232609261f235caecf7e1cb4e6',
+ 'mac': '54c84c12d15a89e2b83a2be6e25d1d799f4ed93b',
}
TRACE_PROCESSOR_SHELL_PATH = tempfile.gettempdir()
TRACE_PROCESSOR_SHELL_BASE_URL = ('https://storage.googleapis.com/perfetto/')
diff --git a/tools/trace_to_text/main.cc b/tools/trace_to_text/main.cc
index 66651f8..223fc64 100644
--- a/tools/trace_to_text/main.cc
+++ b/tools/trace_to_text/main.cc
@@ -38,17 +38,18 @@
namespace {
int Usage(const char* argv0) {
- printf(
- "Usage: %s systrace|json|ctrace|text|profile [--pid PID] "
- "[--timestamps TIMESTAMP1,TIMESTAMP2,...] "
- "[--truncate start|end] "
- "[trace.pb] "
- "[trace.txt]\n"
- "\nProfile mode only:\n"
- "\t--timestamps TIMESTAMP1,TIMESTAMP2,... generate profiles "
- "only for these timestamps\n"
- "\t--pid PID generate profiles only for this process id\n",
- argv0);
+ fprintf(stderr,
+ "Usage: %s systrace|json|ctrace|text|profile [--pid PID] "
+ "[--timestamps TIMESTAMP1,TIMESTAMP2,...] "
+ "[--truncate start|end] "
+ "[--full-sort] "
+ "[trace.pb] "
+ "[trace.txt]\n"
+ "\nProfile mode only:\n"
+ "\t--timestamps TIMESTAMP1,TIMESTAMP2,... generate profiles "
+ "only for these timestamps\n"
+ "\t--pid PID generate profiles only for this process id\n",
+ argv0);
return 1;
}
@@ -67,6 +68,7 @@
Keep truncate_keep = Keep::kAll;
uint64_t pid = 0;
std::vector<uint64_t> timestamps;
+ bool full_sort = false;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
printf("%s\n", PERFETTO_GET_GIT_REVISION());
@@ -93,6 +95,8 @@
for (const std::string& ts : ts_strings) {
timestamps.emplace_back(StringToUint64OrDie(ts.c_str()));
}
+ } else if (strcmp(argv[i], "--full-sort") == 0) {
+ full_sort = true;
} else {
positional_args.push_back(argv[i]);
}
@@ -141,15 +145,15 @@
if (format == "json")
return TraceToJson(input_stream, output_stream, /*compress=*/false,
- truncate_keep);
+ truncate_keep, full_sort);
if (format == "systrace")
return TraceToSystrace(input_stream, output_stream, /*compress=*/false,
- truncate_keep);
+ truncate_keep, full_sort);
if (format == "ctrace")
return TraceToSystrace(input_stream, output_stream, /*compress=*/true,
- truncate_keep);
+ truncate_keep, full_sort);
if (truncate_keep != Keep::kAll) {
PERFETTO_ELOG(
@@ -157,6 +161,12 @@
return 1;
}
+ if (full_sort) {
+ PERFETTO_ELOG(
+ "--full-sort is unsupported for text|profile|symbolize format.");
+ return 1;
+ }
+
if (format == "text")
return TraceToText(input_stream, output_stream);
diff --git a/tools/trace_to_text/symbolize_profile.cc b/tools/trace_to_text/symbolize_profile.cc
index cb8f1e2..1d2812d 100644
--- a/tools/trace_to_text/symbolize_profile.cc
+++ b/tools/trace_to_text/symbolize_profile.cc
@@ -76,7 +76,7 @@
[output](const perfetto::protos::TracePacket& packet) {
WriteTracePacket(packet.SerializeAsString(), output);
});
- return true;
+ return 0;
}
} // namespace trace_to_text
diff --git a/tools/trace_to_text/trace_to_json.cc b/tools/trace_to_text/trace_to_json.cc
index b45fff8..7f4ba66 100644
--- a/tools/trace_to_text/trace_to_json.cc
+++ b/tools/trace_to_text/trace_to_json.cc
@@ -79,11 +79,13 @@
int TraceToJson(std::istream* input,
std::ostream* output,
bool compress,
- Keep truncate_keep) {
+ Keep truncate_keep,
+ bool full_sort) {
std::unique_ptr<TraceWriter> trace_writer(
compress ? new DeflateTraceWriter(output) : new TraceWriter(output));
trace_processor::Config config;
+ config.force_full_sort = full_sort;
std::unique_ptr<trace_processor::TraceProcessor> tp =
trace_processor::TraceProcessor::CreateInstance(config);
diff --git a/tools/trace_to_text/trace_to_json.h b/tools/trace_to_text/trace_to_json.h
index 03237fd..dc0aa18 100644
--- a/tools/trace_to_text/trace_to_json.h
+++ b/tools/trace_to_text/trace_to_json.h
@@ -27,7 +27,8 @@
int TraceToJson(std::istream* input,
std::ostream* output,
bool compress,
- Keep truncate_keep);
+ Keep truncate_keep,
+ bool full_sort);
} // namespace trace_to_text
} // namespace perfetto
diff --git a/tools/trace_to_text/trace_to_systrace.cc b/tools/trace_to_text/trace_to_systrace.cc
index 0c6aee2..8e8b310 100644
--- a/tools/trace_to_text/trace_to_systrace.cc
+++ b/tools/trace_to_text/trace_to_systrace.cc
@@ -165,11 +165,13 @@
int TraceToSystrace(std::istream* input,
std::ostream* output,
bool compress,
- Keep truncate_keep) {
+ Keep truncate_keep,
+ bool full_sort) {
std::unique_ptr<TraceWriter> trace_writer(
compress ? new DeflateTraceWriter(output) : new TraceWriter(output));
trace_processor::Config config;
+ config.force_full_sort = full_sort;
std::unique_ptr<trace_processor::TraceProcessor> tp =
trace_processor::TraceProcessor::CreateInstance(config);
diff --git a/tools/trace_to_text/trace_to_systrace.h b/tools/trace_to_text/trace_to_systrace.h
index edd62c7..4e540f6 100644
--- a/tools/trace_to_text/trace_to_systrace.h
+++ b/tools/trace_to_text/trace_to_systrace.h
@@ -34,7 +34,8 @@
int TraceToSystrace(std::istream* input,
std::ostream* output,
bool compress,
- Keep truncate_keep);
+ Keep truncate_keep,
+ bool full_sort);
int ExtractSystrace(trace_processor::TraceProcessor*,
TraceWriter*,
diff --git a/tools/traceconv b/tools/traceconv
index 53cd5c4..17a5f01 100755
--- a/tools/traceconv
+++ b/tools/traceconv
@@ -33,8 +33,8 @@
# Keep this in sync with the SHAs in catapult file
# systrace/systrace/tracing_agents/atrace_from_file_agent.py.
TRACE_TO_TEXT_SHAS = {
- 'linux': 'c579caa592b21f45102e8bd8cc984ebf25ebb401',
- 'mac': 'f3ad823b0b8d27ca66d3421131790dfa4e58708d',
+ 'linux': '1fba664cb045b119fef96e5827872affcf58e896',
+ 'mac': 'ffc682f302d37ede89938bd3b92d8b7b9701d682',
}
TRACE_TO_TEXT_PATH = tempfile.gettempdir()
TRACE_TO_TEXT_BASE_URL = ('https://storage.googleapis.com/perfetto/')
diff --git a/ui/src/assets/record.scss b/ui/src/assets/record.scss
index b1aea32..2de7ccd 100644
--- a/ui/src/assets/record.scss
+++ b/ui/src/assets/record.scss
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+:root {
+ --record-text-color: #333;
+}
+
// The whole record page.
.record-page {
position: relative;
@@ -397,7 +401,7 @@
font-size: 14px;
font-weight: 200;
min-height: 50px;
- color: #666;
+ color: var(--record-text-color);
line-height: 20px;
}
@@ -473,21 +477,24 @@
// 1) The full-width one (default), e.g. the one used in the main recording
// page for the duration of the trace. This one has both an icon and a
// label on the top.
- // 2) The smaller ones (.thin) used in the probes. This one has no icon and
- // the label is just next to the slider.
+ // 2) The smaller ones (.thin) used in the probes. This one has no icon.
.slider {
@include transition(0.3s);
display: grid;
grid-template-columns: 40px 1fr 130px 0;
- grid-template-rows: 30px 1fr;
- grid-template-areas: "hdr hdr hdr hdr" "icon slider label unit";
+ grid-template-rows: 30px min-content 1fr;
+ grid-template-areas: "hdr hdr hdr hdr" "descr descr descr descr"
+ "icon slider label unit";
margin-top: var(--record-section-padding);
&.thin {
- grid-template-columns: 1fr 3fr 100px 0;
- grid-template-rows: 45px;
- grid-template-areas: "hdr slider label unit";
- margin-top: initial;
+ grid-template-columns: 1fr 1fr 100px 0;
+ grid-template-areas: "hdr hdr hdr hdr" "descr descr descr descr"
+ "slider slider label unit";
+ }
+
+ &.greyed-out {
+ opacity: 0.5;
}
>* {
@@ -504,10 +511,18 @@
&.thin >header {
opacity: 1;
- color: #666;
+ color: var(--record-text-color);
font-size: 14px;
}
+ &.thin >header.descr {
+ grid-area: descr;
+ font-size: 12px;
+ color: #666;
+ height: 20px;
+ line-height: 20px;
+ }
+
&:hover > header {
opacity: 1;
transition-duration: 0.15s;
@@ -527,6 +542,8 @@
scroll-snap-type: mandatory;
background-color : transparent;
outline: none;
+ margin-left: -10px;
+ margin-top: -5px;
&::-webkit-slider-runnable-track {
margin: 10px;
@@ -601,18 +618,20 @@
&.thin .spinner {
font-size: 14px;
+ margin-top: -5px;
}
.unit {
grid-area: unit;
font-size: 12px;
- color: #666;
+ color: var(--record-text-color);
position: relative;
line-height: 37px;
overflow: hidden;
width: 35px;
left: -45px;
text-align: right;
+ margin-top: -5px;
}
}
@@ -637,7 +656,7 @@
@include transition();
min-height: 25px;
font-size: 12px;
- color: #666;
+ color: var(--record-text-color);
cursor: pointer;
padding: 5px 0;
}
diff --git a/ui/src/common/protos.ts b/ui/src/common/protos.ts
index 2e7ed36..71eb0cd 100644
--- a/ui/src/common/protos.ts
+++ b/ui/src/common/protos.ts
@@ -25,8 +25,11 @@
import BufferConfig = protos.perfetto.protos.TraceConfig.BufferConfig;
import ChromeConfig = protos.perfetto.protos.ChromeConfig;
import ConsumerPort = protos.perfetto.protos.ConsumerPort;
+import ContinuousDumpConfig =
+ protos.perfetto.protos.HeapprofdConfig.ContinuousDumpConfig;
import DataSourceConfig = protos.perfetto.protos.DataSourceConfig;
import FtraceConfig = protos.perfetto.protos.FtraceConfig;
+import HeapprofdConfig = protos.perfetto.protos.HeapprofdConfig;
import IAndroidPowerConfig = protos.perfetto.protos.IAndroidPowerConfig;
import IBufferConfig = protos.perfetto.protos.TraceConfig.IBufferConfig;
import IProcessStatsConfig = protos.perfetto.protos.IProcessStatsConfig;
@@ -202,8 +205,10 @@
BufferConfig,
ChromeConfig,
ConsumerPort,
+ ContinuousDumpConfig,
DataSourceConfig,
FtraceConfig,
+ HeapprofdConfig,
IAndroidPowerConfig,
IBufferConfig,
IProcessStatsConfig,
diff --git a/ui/src/common/state.ts b/ui/src/common/state.ts
index 5f31d28..b35898d 100644
--- a/ui/src/common/state.ts
+++ b/ui/src/common/state.ts
@@ -284,6 +284,13 @@
vmstatPeriodMs: number;
vmstatCounters: string[];
+ heapProfiling: boolean;
+ hpSamplingIntervalBytes: number;
+ hpProcesses: string;
+ hpContinuousDumpsPhase: number;
+ hpContinuousDumpsInterval: number;
+ hpSharedMemoryBuffer: number;
+
procStats: boolean;
procStatsPeriodMs: number;
@@ -336,6 +343,13 @@
vmstatPeriodMs: 1000,
vmstatCounters: [],
+ heapProfiling: false,
+ hpSamplingIntervalBytes: 4096,
+ hpProcesses: '',
+ hpContinuousDumpsPhase: 0,
+ hpContinuousDumpsInterval: 0,
+ hpSharedMemoryBuffer: 8 * 1048576,
+
memLmk: false,
procStats: false,
procStatsPeriodMs: 1000,
diff --git a/ui/src/controller/record_controller.ts b/ui/src/controller/record_controller.ts
index a518984..a6eea12 100644
--- a/ui/src/controller/record_controller.ts
+++ b/ui/src/controller/record_controller.ts
@@ -25,8 +25,10 @@
BufferConfig,
ChromeConfig,
ConsumerPort,
+ ContinuousDumpConfig,
DataSourceConfig,
FtraceConfig,
+ HeapprofdConfig,
ProcessStatsConfig,
SysStatsConfig,
TraceConfig,
@@ -222,6 +224,34 @@
trackInitialOomScore = true;
}
+ let heapprofd: HeapprofdConfig|undefined = undefined;
+ if (uiCfg.heapProfiling) {
+ // TODO(tneda): Check or inform user if buffer size are too small.
+ if (heapprofd === undefined) heapprofd = new HeapprofdConfig();
+ heapprofd.samplingIntervalBytes = uiCfg.hpSamplingIntervalBytes;
+ if (uiCfg.hpSharedMemoryBuffer >= 8192 &&
+ uiCfg.hpSharedMemoryBuffer % 4096 === 0) {
+ heapprofd.shmemSizeBytes = uiCfg.hpSharedMemoryBuffer;
+ }
+ if (uiCfg.hpProcesses !== '') {
+ uiCfg.hpProcesses.split('\n').forEach(value => {
+ if (isNaN(+value)) {
+ heapprofd!.processCmdline.push(value);
+ } else {
+ heapprofd!.pid.push(+value);
+ }
+ });
+ }
+ if (uiCfg.hpContinuousDumpsInterval > 0) {
+ heapprofd.continuousDumpConfig = new ContinuousDumpConfig();
+ heapprofd.continuousDumpConfig.dumpIntervalMs =
+ uiCfg.hpContinuousDumpsInterval;
+ heapprofd.continuousDumpConfig.dumpPhaseMs =
+ uiCfg.hpContinuousDumpsPhase > 0 ? uiCfg.hpContinuousDumpsPhase :
+ undefined;
+ }
+ }
+
if (uiCfg.procStats || procThreadAssociationPolling || trackInitialOomScore) {
const ds = new TraceConfig.DataSource();
ds.config = new DataSourceConfig();
@@ -342,6 +372,15 @@
protoCfg.dataSources.push(ds);
}
+ if (heapprofd !== undefined) {
+ const ds = new TraceConfig.DataSource();
+ ds.config = new DataSourceConfig();
+ ds.config.targetBuffer = 0;
+ ds.config.name = 'android.heapprofd';
+ ds.config.heapprofdConfig = heapprofd;
+ protoCfg.dataSources.push(ds);
+ }
+
if (uiCfg.ftrace || uiCfg.atraceApps.length > 0 || ftraceEvents.size > 0 ||
atraceCats.size > 0 || atraceApps.size > 0) {
const ds = new TraceConfig.DataSource();
@@ -395,7 +434,12 @@
// definition somehow but for now we just hard code keys which have this
// problem in the config.
function is64BitNumber(key: string): boolean {
- return key === 'maxFileSizeBytes';
+ return [
+ 'maxFileSizeBytes',
+ 'samplingIntervalBytes',
+ 'shmemSizeBytes',
+ 'pid'
+ ].includes(key);
}
function* message(msg: {}, indent: number): IterableIterator<string> {
for (const [key, value] of Object.entries(msg)) {
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index 5cf35ab..d91232f 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -535,7 +535,7 @@
summaryTrackId,
name,
id: pUuid,
- collapsed: true,
+ collapsed: !(upid !== null && heapUpids.has(upid)),
}));
if (upid !== null) {
diff --git a/ui/src/frontend/post_message_handler.ts b/ui/src/frontend/post_message_handler.ts
index 89124ea..2f5c02f 100644
--- a/ui/src/frontend/post_message_handler.ts
+++ b/ui/src/frontend/post_message_handler.ts
@@ -28,7 +28,7 @@
// ready, so the message handler always replies to a 'PING' message with 'PONG',
// which indicates it is ready to receive a trace.
export function postMessageHandler(messageEvent: MessageEvent) {
- if (!VALID_ORIGINS.includes(messageEvent.origin)) {
+ if (!isOriginAllowed(messageEvent.origin)) {
throw new Error('Invalid origin for postMessage: ' + messageEvent.origin);
}
@@ -69,3 +69,12 @@
globals.dispatch(Actions.openTraceFromBuffer({buffer}));
}
+
+// Returns whether messages from the origin should be accepted.
+function isOriginAllowed(origin: string): boolean {
+ if (VALID_ORIGINS.includes(origin)) return true;
+
+ if (new URL(origin).hostname.endsWith('corp.google.com')) return true;
+
+ return false;
+}
diff --git a/ui/src/frontend/record_page.ts b/ui/src/frontend/record_page.ts
index c59d978..5d87f7a 100644
--- a/ui/src/frontend/record_page.ts
+++ b/ui/src/frontend/record_page.ts
@@ -269,6 +269,101 @@
} as ProbeAttrs));
}
+function HeapSettings(cssClass: string) {
+ const valuesForMS = [
+ 0,
+ 1000,
+ 10 * 1000,
+ 30 * 1000,
+ 60 * 1000,
+ 5 * 60 * 1000,
+ 10 * 60 * 1000,
+ 30 * 60 * 1000,
+ 60 * 60 * 1000
+ ];
+ const valuesForShMemBuff = [
+ 0,
+ 512,
+ 1024,
+ 2 * 1024,
+ 4 * 1024,
+ 8 * 1024,
+ 16 * 1024,
+ 32 * 1024,
+ 64 * 1024,
+ 128 * 1024,
+ 256 * 1024,
+ 512 * 1024,
+ 1024 * 1024,
+ 64 * 1024 * 1024,
+ 128 * 1024 * 1024,
+ 256 * 1024 * 1024,
+ 512 * 1024 * 1024
+ ];
+
+ return m(
+ `.record-section${cssClass}`,
+ m(Textarea, {
+ title: 'Names or pids of the processes to track',
+ placeholder: 'One per line, e.g.:\n' +
+ 'system_server\n' +
+ '1503',
+ set: (cfg, val) => cfg.hpProcesses = val,
+ get: (cfg) => cfg.hpProcesses
+ } as TextareaAttrs),
+ m(Slider, {
+ title: 'Sampling interval',
+ cssClass: '.thin',
+ values: [
+ 0, 1, 2, 4, 8, 16, 32, 64,
+ 128, 256, 512, 1024, 2048, 4096, 8192, 16384,
+ 32768, 65536, 131072, 262144, 524288, 1048576
+ ],
+ unit: 'B',
+ min: 0,
+ set: (cfg, val) => cfg.hpSamplingIntervalBytes = val,
+ get: (cfg) => cfg.hpSamplingIntervalBytes
+ } as SliderAttrs),
+ m(Slider, {
+ title: 'Continuous dumps interval ',
+ description: 'Time between following dumps (0 = disabled)',
+ cssClass: '.thin',
+ values: valuesForMS,
+ unit: 'ms',
+ min: 0,
+ set: (cfg, val) => {
+ cfg.hpContinuousDumpsInterval = val;
+ },
+ get: (cfg) => cfg.hpContinuousDumpsInterval
+ } as SliderAttrs),
+ m(Slider, {
+ title: 'Continuous dumps phase',
+ description: 'Time before first dump',
+ cssClass: `.thin${
+ globals.state.recordConfig.hpContinuousDumpsInterval === 0 ?
+ '.greyed-out' :
+ ''}`,
+ values: valuesForMS,
+ unit: 'ms',
+ min: 0,
+ disabled: globals.state.recordConfig.hpContinuousDumpsInterval === 0,
+ set: (cfg, val) => cfg.hpContinuousDumpsPhase = val,
+ get: (cfg) => cfg.hpContinuousDumpsPhase
+ } as SliderAttrs),
+ m(Slider, {
+ title: `Shared memory buffer`,
+ cssClass: '.thin',
+ values: valuesForShMemBuff.filter(
+ value => value === 0 || value >= 8192 && value % 4096 === 0),
+ unit: 'B',
+ min: 0,
+ set: (cfg, val) => cfg.hpSharedMemoryBuffer = val,
+ get: (cfg) => cfg.hpSharedMemoryBuffer
+ } as SliderAttrs)
+ // TODO(tneda): Add advanced options.
+ );
+}
+
function MemorySettings(cssClass: string) {
const meminfoOpts = new Map<string, string>();
for (const x in MeminfoCounters) {
@@ -288,6 +383,17 @@
`.record-section${cssClass}`,
m(Probe,
{
+ title: 'Heap profiling',
+ // TODO(tneda): Image should be one with flamegraphs.
+ img: 'rec_meminfo.png',
+ descr: `Track native heap allocations & deallocations of an Android
+ process. (Available on Android 10+)`,
+ setEnabled: (cfg, val) => cfg.heapProfiling = val,
+ isEnabled: (cfg) => cfg.heapProfiling
+ } as ProbeAttrs,
+ HeapSettings(cssClass)),
+ m(Probe,
+ {
title: 'Kernel meminfo',
img: 'rec_meminfo.png',
descr: 'Polling of /proc/meminfo',
diff --git a/ui/src/frontend/record_widgets.ts b/ui/src/frontend/record_widgets.ts
index eb571d1..3d683f7 100644
--- a/ui/src/frontend/record_widgets.ts
+++ b/ui/src/frontend/record_widgets.ts
@@ -76,6 +76,9 @@
values: number[];
get: Getter<number>;
set: Setter<number>;
+ min?: number;
+ description?: string;
+ disabled?: boolean;
}
export class Slider implements m.ClassComponent<SliderAttrs> {
@@ -103,6 +106,9 @@
const id = attrs.title.replace(/[^a-z0-9]/gmi, '_').toLowerCase();
const maxIdx = attrs.values.length - 1;
const val = attrs.get(globals.state.recordConfig);
+ const min = attrs.min;
+ const description = attrs.description;
+ const disabled = attrs.disabled;
// Find the index of the closest value in the slider.
let idx = 0;
@@ -127,10 +133,13 @@
return m(
'.slider' + (attrs.cssClass || ''),
m('header', attrs.title),
+ description ? m('header.descr', attrs.description) : '',
attrs.icon !== undefined ? m('i.material-icons', attrs.icon) : [],
- m(`input[id="${id}"][type=range][min=0][max=${maxIdx}][value=${idx}]`,
+ m(`input[id="${id}"][type=range][min=0][max=${maxIdx}][value=${idx}]
+ ${disabled ? '[disabled]' : ''}`,
{oninput: m.withAttr('value', v => this.onSliderChange(attrs, v))}),
- m(`input.spinner[min=1][for=${id}]`, spinnerCfg),
+ m(`input.spinner[min=${min !== undefined ? min : 1}][for=${id}]`,
+ spinnerCfg),
m('.unit', attrs.unit));
}
}
@@ -206,6 +215,7 @@
cssClass?: string;
get: Getter<string>;
set: Setter<string>;
+ title?: string;
}
export class Textarea implements m.ClassComponent<TextareaAttrs> {
@@ -217,12 +227,15 @@
}
view({attrs}: m.CVnode<TextareaAttrs>) {
- return m(`textarea.extra-input${attrs.cssClass || ''}`, {
- onchange: (e: Event) =>
- this.onChange(attrs, e.target as HTMLTextAreaElement),
- placeholder: attrs.placeholder,
- value: attrs.get(globals.state.recordConfig)
- });
+ return m(
+ '.textarea-holder',
+ m('header', attrs.title),
+ m(`textarea.extra-input${attrs.cssClass || ''}`, {
+ onchange: (e: Event) =>
+ this.onChange(attrs, e.target as HTMLTextAreaElement),
+ placeholder: attrs.placeholder,
+ value: attrs.get(globals.state.recordConfig)
+ }));
}
}
diff --git a/ui/src/tracks/async_slices/controller.ts b/ui/src/tracks/async_slices/controller.ts
index 709223e..c5e5e88 100644
--- a/ui/src/tracks/async_slices/controller.ts
+++ b/ui/src/tracks/async_slices/controller.ts
@@ -39,7 +39,7 @@
await this.query(
`create view ${this.tableName('small')} as ` +
`select ts,dur,depth,name,slice_id from slice ` +
- `and track_id = ${this.config.trackId} ` +
+ `where track_id = ${this.config.trackId} ` +
`and dur < ${minNs} ` +
`order by ts;`);
@@ -64,14 +64,14 @@
await this.query(
`create view ${this.tableName('small')} as ` +
`select ts,dur,depth,name, slice_id from slice ` +
- `and track_id = ${this.config.trackId} ` +
+ `where track_id = ${this.config.trackId} ` +
`and dur < ${minNs} ` +
`order by ts `);
await this.query(
`create view ${this.tableName('big')} as ` +
`select ts,dur,depth,name, slice_id from slice ` +
- `and track_id = ${this.config.trackId} ` +
+ `where track_id = ${this.config.trackId} ` +
`and ts >= ${startNs} - dur ` +
`and ts <= ${endNs} ` +
`and dur >= ${minNs} ` +