Merge "perfetto-ui: Remove engine worker proxy hacks"
diff --git a/Android.bp b/Android.bp
index 0915ccf..9365d34 100644
--- a/Android.bp
+++ b/Android.bp
@@ -18,15 +18,17 @@
cc_library_shared {
name: "libtraced_shared",
srcs: [
- ":perfetto_protos_perfetto_common_common_gen",
- ":perfetto_protos_perfetto_config_config_gen",
- ":perfetto_protos_perfetto_config_config_zero_gen",
+ ":perfetto_protos_perfetto_common_lite_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_lite_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_ipc_ipc_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_minimal_lite_gen",
":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
":perfetto_protos_perfetto_trace_trusted_lite_gen",
":perfetto_protos_perfetto_trace_zero_gen",
":perfetto_src_ipc_wire_protocol_gen",
@@ -79,6 +81,7 @@
"src/traced/probes/probes_data_source.cc",
"src/traced/probes/probes_producer.cc",
"src/traced/probes/ps/process_stats_data_source.cc",
+ "src/traced/probes/sys_stats/sys_stats_data_source.cc",
"src/traced/service/service.cc",
"src/tracing/core/chrome_config.cc",
"src/tracing/core/commit_data_request.cc",
@@ -93,6 +96,7 @@
"src/tracing/core/shared_memory_abi.cc",
"src/tracing/core/shared_memory_arbiter_impl.cc",
"src/tracing/core/sliced_protobuf_input_stream.cc",
+ "src/tracing/core/sys_stats_config.cc",
"src/tracing/core/test_config.cc",
"src/tracing/core/trace_buffer.cc",
"src/tracing/core/trace_config.cc",
@@ -110,15 +114,17 @@
"perfetto_src_tracing_ipc",
],
generated_headers: [
- "perfetto_protos_perfetto_common_common_gen_headers",
- "perfetto_protos_perfetto_config_config_gen_headers",
- "perfetto_protos_perfetto_config_config_zero_gen_headers",
+ "perfetto_protos_perfetto_common_lite_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_lite_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
"perfetto_protos_perfetto_trace_zero_gen_headers",
"perfetto_src_ipc_wire_protocol_gen_headers",
@@ -136,15 +142,17 @@
cc_binary {
name: "perfetto",
srcs: [
- ":perfetto_protos_perfetto_common_common_gen",
- ":perfetto_protos_perfetto_config_config_gen",
- ":perfetto_protos_perfetto_config_config_zero_gen",
+ ":perfetto_protos_perfetto_common_lite_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_lite_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_ipc_ipc_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_minimal_lite_gen",
":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
":perfetto_protos_perfetto_trace_trusted_lite_gen",
":perfetto_protos_perfetto_trace_zero_gen",
":perfetto_src_ipc_wire_protocol_gen",
@@ -191,6 +199,7 @@
"src/tracing/core/shared_memory_abi.cc",
"src/tracing/core/shared_memory_arbiter_impl.cc",
"src/tracing/core/sliced_protobuf_input_stream.cc",
+ "src/tracing/core/sys_stats_config.cc",
"src/tracing/core/test_config.cc",
"src/tracing/core/trace_buffer.cc",
"src/tracing/core/trace_config.cc",
@@ -214,15 +223,17 @@
"libgtest_prod",
],
generated_headers: [
- "perfetto_protos_perfetto_common_common_gen_headers",
- "perfetto_protos_perfetto_config_config_gen_headers",
- "perfetto_protos_perfetto_config_config_zero_gen_headers",
+ "perfetto_protos_perfetto_common_lite_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_lite_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
"perfetto_protos_perfetto_trace_zero_gen_headers",
"perfetto_src_ipc_wire_protocol_gen_headers",
@@ -267,9 +278,10 @@
cc_test {
name: "perfetto_integrationtests",
srcs: [
- ":perfetto_protos_perfetto_common_common_gen",
- ":perfetto_protos_perfetto_config_config_gen",
- ":perfetto_protos_perfetto_config_config_zero_gen",
+ ":perfetto_protos_perfetto_common_lite_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_lite_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_ipc_ipc_gen",
":perfetto_protos_perfetto_trace_chrome_lite_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
@@ -281,6 +293,8 @@
":perfetto_protos_perfetto_trace_minimal_lite_gen",
":perfetto_protos_perfetto_trace_ps_lite_gen",
":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_lite_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
":perfetto_protos_perfetto_trace_trusted_lite_gen",
":perfetto_protos_perfetto_trace_zero_gen",
":perfetto_src_ipc_wire_protocol_gen",
@@ -339,6 +353,7 @@
"src/traced/probes/probes_data_source.cc",
"src/traced/probes/probes_producer.cc",
"src/traced/probes/ps/process_stats_data_source.cc",
+ "src/traced/probes/sys_stats/sys_stats_data_source.cc",
"src/tracing/core/chrome_config.cc",
"src/tracing/core/commit_data_request.cc",
"src/tracing/core/data_source_config.cc",
@@ -352,6 +367,7 @@
"src/tracing/core/shared_memory_abi.cc",
"src/tracing/core/shared_memory_arbiter_impl.cc",
"src/tracing/core/sliced_protobuf_input_stream.cc",
+ "src/tracing/core/sys_stats_config.cc",
"src/tracing/core/test_config.cc",
"src/tracing/core/trace_buffer.cc",
"src/tracing/core/trace_config.cc",
@@ -375,9 +391,10 @@
"perfetto_src_tracing_ipc",
],
generated_headers: [
- "perfetto_protos_perfetto_common_common_gen_headers",
- "perfetto_protos_perfetto_config_config_gen_headers",
- "perfetto_protos_perfetto_config_config_zero_gen_headers",
+ "perfetto_protos_perfetto_common_lite_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_lite_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
"perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
@@ -389,6 +406,8 @@
"perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_ps_lite_gen_headers",
"perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
"perfetto_protos_perfetto_trace_zero_gen_headers",
"perfetto_src_ipc_wire_protocol_gen_headers",
@@ -408,11 +427,12 @@
},
}
-// GN target: //protos/perfetto/common:common_gen
+// GN target: //protos/perfetto/common:lite_gen
genrule {
- name: "perfetto_protos_perfetto_common_common_gen",
+ name: "perfetto_protos_perfetto_common_lite_gen",
srcs: [
"protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
],
tools: [
"aprotoc",
@@ -420,14 +440,16 @@
cmd: "mkdir -p $(genDir)/external/perfetto/protos && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/protos --proto_path=external/perfetto/protos $(in)",
out: [
"external/perfetto/protos/perfetto/common/commit_data_request.pb.cc",
+ "external/perfetto/protos/perfetto/common/sys_stats_counters.pb.cc",
],
}
-// GN target: //protos/perfetto/common:common_gen
+// GN target: //protos/perfetto/common:lite_gen
genrule {
- name: "perfetto_protos_perfetto_common_common_gen_headers",
+ name: "perfetto_protos_perfetto_common_lite_gen_headers",
srcs: [
"protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
],
tools: [
"aprotoc",
@@ -435,15 +457,55 @@
cmd: "mkdir -p $(genDir)/external/perfetto/protos && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/protos --proto_path=external/perfetto/protos $(in)",
out: [
"external/perfetto/protos/perfetto/common/commit_data_request.pb.h",
+ "external/perfetto/protos/perfetto/common/sys_stats_counters.pb.h",
],
export_include_dirs: [
"protos",
],
}
-// GN target: //protos/perfetto/config:config_gen
+// GN target: //protos/perfetto/common:zero_gen
genrule {
- name: "perfetto_protos_perfetto_config_config_gen",
+ name: "perfetto_protos_perfetto_common_zero_gen",
+ srcs: [
+ "protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_protoc_plugin___gn_standalone_toolchain_gcc_like_host_",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/protos && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/protos --proto_path=external/perfetto/protos --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_protoc_plugin___gn_standalone_toolchain_gcc_like_host_) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/protos $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/common/commit_data_request.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/sys_stats_counters.pbzero.cc",
+ ],
+}
+
+// GN target: //protos/perfetto/common:zero_gen
+genrule {
+ name: "perfetto_protos_perfetto_common_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_protoc_plugin___gn_standalone_toolchain_gcc_like_host_",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/protos && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/protos --proto_path=external/perfetto/protos --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_protoc_plugin___gn_standalone_toolchain_gcc_like_host_) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/protos $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/common/commit_data_request.pbzero.h",
+ "external/perfetto/protos/perfetto/common/sys_stats_counters.pbzero.h",
+ ],
+ export_include_dirs: [
+ "protos",
+ ],
+}
+
+// GN target: //protos/perfetto/config:lite_gen
+genrule {
+ name: "perfetto_protos_perfetto_config_lite_gen",
srcs: [
"protos/perfetto/config/chrome/chrome_config.proto",
"protos/perfetto/config/data_source_config.proto",
@@ -451,6 +513,7 @@
"protos/perfetto/config/ftrace/ftrace_config.proto",
"protos/perfetto/config/inode_file/inode_file_config.proto",
"protos/perfetto/config/process_stats/process_stats_config.proto",
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
"protos/perfetto/config/test_config.proto",
"protos/perfetto/config/trace_config.proto",
],
@@ -465,14 +528,15 @@
"external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pb.cc",
"external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pb.cc",
"external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pb.cc",
+ "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pb.cc",
"external/perfetto/protos/perfetto/config/test_config.pb.cc",
"external/perfetto/protos/perfetto/config/trace_config.pb.cc",
],
}
-// GN target: //protos/perfetto/config:config_gen
+// GN target: //protos/perfetto/config:lite_gen
genrule {
- name: "perfetto_protos_perfetto_config_config_gen_headers",
+ name: "perfetto_protos_perfetto_config_lite_gen_headers",
srcs: [
"protos/perfetto/config/chrome/chrome_config.proto",
"protos/perfetto/config/data_source_config.proto",
@@ -480,6 +544,7 @@
"protos/perfetto/config/ftrace/ftrace_config.proto",
"protos/perfetto/config/inode_file/inode_file_config.proto",
"protos/perfetto/config/process_stats/process_stats_config.proto",
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
"protos/perfetto/config/test_config.proto",
"protos/perfetto/config/trace_config.proto",
],
@@ -494,6 +559,7 @@
"external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pb.h",
"external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pb.h",
"external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pb.h",
+ "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pb.h",
"external/perfetto/protos/perfetto/config/test_config.pb.h",
"external/perfetto/protos/perfetto/config/trace_config.pb.h",
],
@@ -502,9 +568,9 @@
],
}
-// GN target: //protos/perfetto/config:config_zero_gen
+// GN target: //protos/perfetto/config:zero_gen
genrule {
- name: "perfetto_protos_perfetto_config_config_zero_gen",
+ name: "perfetto_protos_perfetto_config_zero_gen",
srcs: [
"protos/perfetto/config/chrome/chrome_config.proto",
"protos/perfetto/config/data_source_config.proto",
@@ -512,6 +578,7 @@
"protos/perfetto/config/ftrace/ftrace_config.proto",
"protos/perfetto/config/inode_file/inode_file_config.proto",
"protos/perfetto/config/process_stats/process_stats_config.proto",
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
"protos/perfetto/config/test_config.proto",
"protos/perfetto/config/trace_config.proto",
],
@@ -527,14 +594,15 @@
"external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pbzero.cc",
"external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pbzero.cc",
"external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pbzero.cc",
+ "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.cc",
"external/perfetto/protos/perfetto/config/test_config.pbzero.cc",
"external/perfetto/protos/perfetto/config/trace_config.pbzero.cc",
],
}
-// GN target: //protos/perfetto/config:config_zero_gen
+// GN target: //protos/perfetto/config:zero_gen
genrule {
- name: "perfetto_protos_perfetto_config_config_zero_gen_headers",
+ name: "perfetto_protos_perfetto_config_zero_gen_headers",
srcs: [
"protos/perfetto/config/chrome/chrome_config.proto",
"protos/perfetto/config/data_source_config.proto",
@@ -542,6 +610,7 @@
"protos/perfetto/config/ftrace/ftrace_config.proto",
"protos/perfetto/config/inode_file/inode_file_config.proto",
"protos/perfetto/config/process_stats/process_stats_config.proto",
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
"protos/perfetto/config/test_config.proto",
"protos/perfetto/config/trace_config.proto",
],
@@ -557,6 +626,7 @@
"external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pbzero.h",
"external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pbzero.h",
"external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pbzero.h",
+ "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.h",
"external/perfetto/protos/perfetto/config/test_config.pbzero.h",
"external/perfetto/protos/perfetto/config/trace_config.pbzero.h",
],
@@ -3062,6 +3132,74 @@
],
}
+// GN target: //protos/perfetto/trace/sys_stats:lite_gen
+genrule {
+ name: "perfetto_protos_perfetto_trace_sys_stats_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/protos && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/protos --proto_path=external/perfetto/protos $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pb.cc",
+ ],
+}
+
+// GN target: //protos/perfetto/trace/sys_stats:lite_gen
+genrule {
+ name: "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/protos && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/protos --proto_path=external/perfetto/protos $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pb.h",
+ ],
+ export_include_dirs: [
+ "protos",
+ ],
+}
+
+// GN target: //protos/perfetto/trace/sys_stats:zero_gen
+genrule {
+ name: "perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_protoc_plugin___gn_standalone_toolchain_gcc_like_host_",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/protos && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/protos --proto_path=external/perfetto/protos --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_protoc_plugin___gn_standalone_toolchain_gcc_like_host_) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/protos $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pbzero.cc",
+ ],
+}
+
+// GN target: //protos/perfetto/trace/sys_stats:zero_gen
+genrule {
+ name: "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_protoc_plugin___gn_standalone_toolchain_gcc_like_host_",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/protos && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/protos --proto_path=external/perfetto/protos --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_protoc_plugin___gn_standalone_toolchain_gcc_like_host_) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/protos $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pbzero.h",
+ ],
+ export_include_dirs: [
+ "protos",
+ ],
+}
+
// GN target: //protos/perfetto/trace:trusted_lite_gen
genrule {
name: "perfetto_protos_perfetto_trace_trusted_lite_gen",
@@ -3463,15 +3601,17 @@
cc_library_static {
name: "perfetto_src_tracing_ipc",
srcs: [
- ":perfetto_protos_perfetto_common_common_gen",
- ":perfetto_protos_perfetto_config_config_gen",
- ":perfetto_protos_perfetto_config_config_zero_gen",
+ ":perfetto_protos_perfetto_common_lite_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_lite_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_ipc_ipc_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_minimal_lite_gen",
":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
":perfetto_protos_perfetto_trace_trusted_lite_gen",
":perfetto_protos_perfetto_trace_zero_gen",
":perfetto_src_ipc_wire_protocol_gen",
@@ -3513,6 +3653,7 @@
"src/tracing/core/shared_memory_abi.cc",
"src/tracing/core/shared_memory_arbiter_impl.cc",
"src/tracing/core/sliced_protobuf_input_stream.cc",
+ "src/tracing/core/sys_stats_config.cc",
"src/tracing/core/test_config.cc",
"src/tracing/core/trace_buffer.cc",
"src/tracing/core/trace_config.cc",
@@ -3539,29 +3680,33 @@
"include",
],
generated_headers: [
- "perfetto_protos_perfetto_common_common_gen_headers",
- "perfetto_protos_perfetto_config_config_gen_headers",
- "perfetto_protos_perfetto_config_config_zero_gen_headers",
+ "perfetto_protos_perfetto_common_lite_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_lite_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
"perfetto_protos_perfetto_trace_zero_gen_headers",
"perfetto_src_ipc_wire_protocol_gen_headers",
],
export_generated_headers: [
- "perfetto_protos_perfetto_common_common_gen_headers",
- "perfetto_protos_perfetto_config_config_gen_headers",
- "perfetto_protos_perfetto_config_config_zero_gen_headers",
+ "perfetto_protos_perfetto_common_lite_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_lite_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
"perfetto_protos_perfetto_trace_zero_gen_headers",
"perfetto_src_ipc_wire_protocol_gen_headers",
@@ -3579,13 +3724,15 @@
cc_library_static {
name: "perfetto_trace_protos",
srcs: [
- ":perfetto_protos_perfetto_config_config_gen",
+ ":perfetto_protos_perfetto_common_lite_gen",
+ ":perfetto_protos_perfetto_config_lite_gen",
":perfetto_protos_perfetto_trace_chrome_lite_gen",
":perfetto_protos_perfetto_trace_filesystem_lite_gen",
":perfetto_protos_perfetto_trace_ftrace_lite_gen",
":perfetto_protos_perfetto_trace_lite_gen",
":perfetto_protos_perfetto_trace_minimal_lite_gen",
":perfetto_protos_perfetto_trace_ps_lite_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_lite_gen",
],
shared_libs: [
"liblog",
@@ -3596,22 +3743,26 @@
"include",
],
generated_headers: [
- "perfetto_protos_perfetto_config_config_gen_headers",
+ "perfetto_protos_perfetto_common_lite_gen_headers",
+ "perfetto_protos_perfetto_config_lite_gen_headers",
"perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
"perfetto_protos_perfetto_trace_lite_gen_headers",
"perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_ps_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
],
export_generated_headers: [
- "perfetto_protos_perfetto_config_config_gen_headers",
+ "perfetto_protos_perfetto_common_lite_gen_headers",
+ "perfetto_protos_perfetto_config_lite_gen_headers",
"perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
"perfetto_protos_perfetto_trace_lite_gen_headers",
"perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_ps_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
],
defaults: [
"perfetto_defaults",
@@ -3626,9 +3777,10 @@
cc_test {
name: "perfetto_unittests",
srcs: [
- ":perfetto_protos_perfetto_common_common_gen",
- ":perfetto_protos_perfetto_config_config_gen",
- ":perfetto_protos_perfetto_config_config_zero_gen",
+ ":perfetto_protos_perfetto_common_lite_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_lite_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_ipc_ipc_gen",
":perfetto_protos_perfetto_trace_chrome_lite_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
@@ -3640,6 +3792,8 @@
":perfetto_protos_perfetto_trace_minimal_lite_gen",
":perfetto_protos_perfetto_trace_ps_lite_gen",
":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_lite_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
":perfetto_protos_perfetto_trace_trusted_lite_gen",
":perfetto_protos_perfetto_trace_zero_gen",
":perfetto_src_ipc_test_messages_gen",
@@ -3759,6 +3913,8 @@
"src/traced/probes/probes_producer.cc",
"src/traced/probes/ps/process_stats_data_source.cc",
"src/traced/probes/ps/process_stats_data_source_unittest.cc",
+ "src/traced/probes/sys_stats/sys_stats_data_source.cc",
+ "src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc",
"src/tracing/core/chrome_config.cc",
"src/tracing/core/commit_data_request.cc",
"src/tracing/core/data_source_config.cc",
@@ -3780,6 +3936,7 @@
"src/tracing/core/shared_memory_arbiter_impl_unittest.cc",
"src/tracing/core/sliced_protobuf_input_stream.cc",
"src/tracing/core/sliced_protobuf_input_stream_unittest.cc",
+ "src/tracing/core/sys_stats_config.cc",
"src/tracing/core/test_config.cc",
"src/tracing/core/trace_buffer.cc",
"src/tracing/core/trace_buffer_unittest.cc",
@@ -3820,9 +3977,10 @@
"perfetto_src_tracing_ipc",
],
generated_headers: [
- "perfetto_protos_perfetto_common_common_gen_headers",
- "perfetto_protos_perfetto_config_config_gen_headers",
- "perfetto_protos_perfetto_config_config_zero_gen_headers",
+ "perfetto_protos_perfetto_common_lite_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_lite_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
"perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
@@ -3834,6 +3992,8 @@
"perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_ps_lite_gen_headers",
"perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
"perfetto_protos_perfetto_trace_zero_gen_headers",
"perfetto_src_ipc_test_messages_gen_headers",
@@ -3862,13 +4022,33 @@
cc_binary_host {
name: "trace_to_text",
srcs: [
- ":perfetto_protos_perfetto_config_config_gen",
+ ":perfetto_protos_perfetto_common_lite_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_lite_gen",
":perfetto_protos_perfetto_trace_chrome_lite_gen",
":perfetto_protos_perfetto_trace_filesystem_lite_gen",
":perfetto_protos_perfetto_trace_ftrace_lite_gen",
":perfetto_protos_perfetto_trace_lite_gen",
":perfetto_protos_perfetto_trace_minimal_lite_gen",
":perfetto_protos_perfetto_trace_ps_lite_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_lite_gen",
+ "src/base/file_utils.cc",
+ "src/base/metatrace.cc",
+ "src/base/page_allocator.cc",
+ "src/base/string_splitter.cc",
+ "src/base/string_utils.cc",
+ "src/base/temp_file.cc",
+ "src/base/thread_checker.cc",
+ "src/base/time.cc",
+ "src/base/unix_task_runner.cc",
+ "src/base/virtual_destructors.cc",
+ "src/base/watchdog_posix.cc",
+ "src/protozero/message.cc",
+ "src/protozero/message_handle.cc",
+ "src/protozero/proto_decoder.cc",
+ "src/protozero/proto_field_descriptor.cc",
+ "src/protozero/scattered_stream_null_delegate.cc",
+ "src/protozero/scattered_stream_writer.cc",
"tools/trace_to_text/ftrace_event_formatter.cc",
"tools/trace_to_text/ftrace_inode_handler.cc",
"tools/trace_to_text/main.cc",
@@ -3878,14 +4058,20 @@
"libprotobuf-cpp-full",
"libprotobuf-cpp-lite",
],
+ static_libs: [
+ "libgtest_prod",
+ ],
generated_headers: [
- "perfetto_protos_perfetto_config_config_gen_headers",
+ "perfetto_protos_perfetto_common_lite_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_lite_gen_headers",
"perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
"perfetto_protos_perfetto_trace_lite_gen_headers",
"perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_ps_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
],
defaults: [
"perfetto_defaults",
diff --git a/include/perfetto/base/time.h b/include/perfetto/base/time.h
index d1895c1..760d494 100644
--- a/include/perfetto/base/time.h
+++ b/include/perfetto/base/time.h
@@ -53,6 +53,11 @@
TimeNanos GetWallTimeNs();
TimeNanos GetThreadCPUTimeNs();
+// TODO: Clock that counts time during suspend is not implemented on Windows.
+inline TimeNanos GetBootTimeNs() {
+ return GetWallTimeNs();
+}
+
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
inline TimeNanos GetWallTimeNs() {
@@ -66,6 +71,11 @@
return TimeNanos(mach_absolute_time() * monotonic_timebase_factor);
}
+// TODO: Clock that counts time during suspend is not implemented on Mac.
+inline TimeNanos GetBootTimeNs() {
+ return GetWallTimeNs();
+}
+
inline TimeNanos GetThreadCPUTimeNs() {
mach_port_t this_thread = mach_thread_self();
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
@@ -95,6 +105,11 @@
return TimeNanos(0);
}
+// TODO: Clock that counts time during suspend is not implemented on WASM.
+inline TimeNanos GetBootTimeNs() {
+ return GetWallTimeNs();
+}
+
#else
constexpr clockid_t kWallTimeClockSource = CLOCK_MONOTONIC;
@@ -105,6 +120,18 @@
return FromPosixTimespec(ts);
}
+// Return ns from boot. Conversely to GetWallTimeNs, this clock counts also time
+// during suspend (when supported).
+inline TimeNanos GetBootTimeNs() {
+ // Determine if CLOCK_BOOTTIME is available on the first call.
+ static const clockid_t kBootTimeClockSource = [] {
+ struct timespec ts = {};
+ int res = clock_gettime(CLOCK_BOOTTIME, &ts);
+ return res == 0 ? CLOCK_BOOTTIME : kWallTimeClockSource;
+ }();
+ return GetTimeInternalNs(kBootTimeClockSource);
+}
+
inline TimeNanos GetWallTimeNs() {
return GetTimeInternalNs(kWallTimeClockSource);
}
diff --git a/include/perfetto/traced/BUILD.gn b/include/perfetto/traced/BUILD.gn
index fefc5fa..f7dc66f 100644
--- a/include/perfetto/traced/BUILD.gn
+++ b/include/perfetto/traced/BUILD.gn
@@ -18,3 +18,16 @@
"traced.h",
]
}
+
+source_set("sys_stats_counters") {
+ deps = [
+ "../../../gn:default_deps",
+ ]
+ public_deps = [
+ "../../../protos/perfetto/common:zero",
+ "../base",
+ ]
+ sources = [
+ "sys_stats_counters.h",
+ ]
+}
diff --git a/include/perfetto/traced/sys_stats_counters.h b/include/perfetto/traced/sys_stats_counters.h
new file mode 100644
index 0000000..5bb0974
--- /dev/null
+++ b/include/perfetto/traced/sys_stats_counters.h
@@ -0,0 +1,233 @@
+/*
+ * 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 INCLUDE_PERFETTO_TRACED_SYS_STATS_COUNTERS_H_
+#define INCLUDE_PERFETTO_TRACED_SYS_STATS_COUNTERS_H_
+
+#include "perfetto/base/utils.h"
+#include "perfetto/common/sys_stats_counters.pbzero.h"
+
+#include <vector>
+
+namespace perfetto {
+
+struct KeyAndId {
+ const char* str;
+ int id;
+};
+
+constexpr KeyAndId kMeminfoKeys[] = {
+ {"MemTotal", protos::pbzero::MeminfoCounters::MEMINFO_MEM_TOTAL},
+ {"MemFree", protos::pbzero::MeminfoCounters::MEMINFO_MEM_FREE},
+ {"MemAvailable", protos::pbzero::MeminfoCounters::MEMINFO_MEM_AVAILABLE},
+ {"Buffers", protos::pbzero::MeminfoCounters::MEMINFO_BUFFERS},
+ {"Cached", protos::pbzero::MeminfoCounters::MEMINFO_CACHED},
+ {"SwapCached", protos::pbzero::MeminfoCounters::MEMINFO_SWAP_CACHED},
+ {"Active", protos::pbzero::MeminfoCounters::MEMINFO_ACTIVE},
+ {"Inactive", protos::pbzero::MeminfoCounters::MEMINFO_INACTIVE},
+ {"Active(anon)", protos::pbzero::MeminfoCounters::MEMINFO_ACTIVE_ANON},
+ {"Inactive(anon)", protos::pbzero::MeminfoCounters::MEMINFO_INACTIVE_ANON},
+ {"Active(file)", protos::pbzero::MeminfoCounters::MEMINFO_ACTIVE_FILE},
+ {"Inactive(file)", protos::pbzero::MeminfoCounters::MEMINFO_INACTIVE_FILE},
+ {"Unevictable", protos::pbzero::MeminfoCounters::MEMINFO_UNEVICTABLE},
+ {"Mlocked", protos::pbzero::MeminfoCounters::MEMINFO_MLOCKED},
+ {"SwapTotal", protos::pbzero::MeminfoCounters::MEMINFO_SWAP_TOTAL},
+ {"SwapFree", protos::pbzero::MeminfoCounters::MEMINFO_SWAP_FREE},
+ {"Dirty", protos::pbzero::MeminfoCounters::MEMINFO_DIRTY},
+ {"Writeback", protos::pbzero::MeminfoCounters::MEMINFO_WRITEBACK},
+ {"AnonPages", protos::pbzero::MeminfoCounters::MEMINFO_ANON_PAGES},
+ {"Mapped", protos::pbzero::MeminfoCounters::MEMINFO_MAPPED},
+ {"Shmem", protos::pbzero::MeminfoCounters::MEMINFO_SHMEM},
+ {"Slab", protos::pbzero::MeminfoCounters::MEMINFO_SLAB},
+ {"SReclaimable", protos::pbzero::MeminfoCounters::MEMINFO_SLAB_RECLAIMABLE},
+ {"SUnreclaim", protos::pbzero::MeminfoCounters::MEMINFO_SLAB_UNRECLAIMABLE},
+ {"KernelStack", protos::pbzero::MeminfoCounters::MEMINFO_KERNEL_STACK},
+ {"PageTables", protos::pbzero::MeminfoCounters::MEMINFO_PAGE_TABLES},
+ {"CommitLimit", protos::pbzero::MeminfoCounters::MEMINFO_COMMIT_LIMIT},
+ {"Committed_AS", protos::pbzero::MeminfoCounters::MEMINFO_COMMITED_AS},
+ {"VmallocTotal", protos::pbzero::MeminfoCounters::MEMINFO_VMALLOC_TOTAL},
+ {"VmallocUsed", protos::pbzero::MeminfoCounters::MEMINFO_VMALLOC_USED},
+ {"VmallocChunk", protos::pbzero::MeminfoCounters::MEMINFO_VMALLOC_CHUNK},
+ {"CmaTotal", protos::pbzero::MeminfoCounters::MEMINFO_CMA_TOTAL},
+ {"CmaFree", protos::pbzero::MeminfoCounters::MEMINFO_CMA_FREE},
+};
+
+const KeyAndId kVmstatKeys[] = {
+ {"nr_free_pages", protos::pbzero::VmstatCounters::VMSTAT_NR_FREE_PAGES},
+ {"nr_alloc_batch", protos::pbzero::VmstatCounters::VMSTAT_NR_ALLOC_BATCH},
+ {"nr_inactive_anon",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_INACTIVE_ANON},
+ {"nr_active_anon", protos::pbzero::VmstatCounters::VMSTAT_NR_ACTIVE_ANON},
+ {"nr_inactive_file",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_INACTIVE_FILE},
+ {"nr_active_file", protos::pbzero::VmstatCounters::VMSTAT_NR_ACTIVE_FILE},
+ {"nr_unevictable", protos::pbzero::VmstatCounters::VMSTAT_NR_UNEVICTABLE},
+ {"nr_mlock", protos::pbzero::VmstatCounters::VMSTAT_NR_MLOCK},
+ {"nr_anon_pages", protos::pbzero::VmstatCounters::VMSTAT_NR_ANON_PAGES},
+ {"nr_mapped", protos::pbzero::VmstatCounters::VMSTAT_NR_MAPPED},
+ {"nr_file_pages", protos::pbzero::VmstatCounters::VMSTAT_NR_FILE_PAGES},
+ {"nr_dirty", protos::pbzero::VmstatCounters::VMSTAT_NR_DIRTY},
+ {"nr_writeback", protos::pbzero::VmstatCounters::VMSTAT_NR_WRITEBACK},
+ {"nr_slab_reclaimable",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_SLAB_RECLAIMABLE},
+ {"nr_slab_unreclaimable",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_SLAB_UNRECLAIMABLE},
+ {"nr_page_table_pages",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_PAGE_TABLE_PAGES},
+ {"nr_kernel_stack", protos::pbzero::VmstatCounters::VMSTAT_NR_KERNEL_STACK},
+ {"nr_overhead", protos::pbzero::VmstatCounters::VMSTAT_NR_OVERHEAD},
+ {"nr_unstable", protos::pbzero::VmstatCounters::VMSTAT_NR_UNSTABLE},
+ {"nr_bounce", protos::pbzero::VmstatCounters::VMSTAT_NR_BOUNCE},
+ {"nr_vmscan_write", protos::pbzero::VmstatCounters::VMSTAT_NR_VMSCAN_WRITE},
+ {"nr_vmscan_immediate_reclaim",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM},
+ {"nr_writeback_temp",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_WRITEBACK_TEMP},
+ {"nr_isolated_anon",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_ISOLATED_ANON},
+ {"nr_isolated_file",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_ISOLATED_FILE},
+ {"nr_shmem", protos::pbzero::VmstatCounters::VMSTAT_NR_SHMEM},
+ {"nr_dirtied", protos::pbzero::VmstatCounters::VMSTAT_NR_DIRTIED},
+ {"nr_written", protos::pbzero::VmstatCounters::VMSTAT_NR_WRITTEN},
+ {"nr_pages_scanned",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_PAGES_SCANNED},
+ {"workingset_refault",
+ protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_REFAULT},
+ {"workingset_activate",
+ protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_ACTIVATE},
+ {"workingset_nodereclaim",
+ protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_NODERECLAIM},
+ {"nr_anon_transparent_hugepages",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES},
+ {"nr_free_cma", protos::pbzero::VmstatCounters::VMSTAT_NR_FREE_CMA},
+ {"nr_swapcache", protos::pbzero::VmstatCounters::VMSTAT_NR_SWAPCACHE},
+ {"nr_dirty_threshold",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_DIRTY_THRESHOLD},
+ {"nr_dirty_background_threshold",
+ protos::pbzero::VmstatCounters::VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD},
+ {"pgpgin", protos::pbzero::VmstatCounters::VMSTAT_PGPGIN},
+ {"pgpgout", protos::pbzero::VmstatCounters::VMSTAT_PGPGOUT},
+ {"pgpgoutclean", protos::pbzero::VmstatCounters::VMSTAT_PGPGOUTCLEAN},
+ {"pswpin", protos::pbzero::VmstatCounters::VMSTAT_PSWPIN},
+ {"pswpout", protos::pbzero::VmstatCounters::VMSTAT_PSWPOUT},
+ {"pgalloc_dma", protos::pbzero::VmstatCounters::VMSTAT_PGALLOC_DMA},
+ {"pgalloc_normal", protos::pbzero::VmstatCounters::VMSTAT_PGALLOC_NORMAL},
+ {"pgalloc_movable", protos::pbzero::VmstatCounters::VMSTAT_PGALLOC_MOVABLE},
+ {"pgfree", protos::pbzero::VmstatCounters::VMSTAT_PGFREE},
+ {"pgactivate", protos::pbzero::VmstatCounters::VMSTAT_PGACTIVATE},
+ {"pgdeactivate", protos::pbzero::VmstatCounters::VMSTAT_PGDEACTIVATE},
+ {"pgfault", protos::pbzero::VmstatCounters::VMSTAT_PGFAULT},
+ {"pgmajfault", protos::pbzero::VmstatCounters::VMSTAT_PGMAJFAULT},
+ {"pgrefill_dma", protos::pbzero::VmstatCounters::VMSTAT_PGREFILL_DMA},
+ {"pgrefill_normal", protos::pbzero::VmstatCounters::VMSTAT_PGREFILL_NORMAL},
+ {"pgrefill_movable",
+ protos::pbzero::VmstatCounters::VMSTAT_PGREFILL_MOVABLE},
+ {"pgsteal_kswapd_dma",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_KSWAPD_DMA},
+ {"pgsteal_kswapd_normal",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_KSWAPD_NORMAL},
+ {"pgsteal_kswapd_movable",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_KSWAPD_MOVABLE},
+ {"pgsteal_direct_dma",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_DIRECT_DMA},
+ {"pgsteal_direct_normal",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_DIRECT_NORMAL},
+ {"pgsteal_direct_movable",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_DIRECT_MOVABLE},
+ {"pgscan_kswapd_dma",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_KSWAPD_DMA},
+ {"pgscan_kswapd_normal",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_KSWAPD_NORMAL},
+ {"pgscan_kswapd_movable",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_KSWAPD_MOVABLE},
+ {"pgscan_direct_dma",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT_DMA},
+ {"pgscan_direct_normal",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT_NORMAL},
+ {"pgscan_direct_movable",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT_MOVABLE},
+ {"pgscan_direct_throttle",
+ protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT_THROTTLE},
+ {"pginodesteal", protos::pbzero::VmstatCounters::VMSTAT_PGINODESTEAL},
+ {"slabs_scanned", protos::pbzero::VmstatCounters::VMSTAT_SLABS_SCANNED},
+ {"kswapd_inodesteal",
+ protos::pbzero::VmstatCounters::VMSTAT_KSWAPD_INODESTEAL},
+ {"kswapd_low_wmark_hit_quickly",
+ protos::pbzero::VmstatCounters::VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY},
+ {"kswapd_high_wmark_hit_quickly",
+ protos::pbzero::VmstatCounters::VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY},
+ {"pageoutrun", protos::pbzero::VmstatCounters::VMSTAT_PAGEOUTRUN},
+ {"allocstall", protos::pbzero::VmstatCounters::VMSTAT_ALLOCSTALL},
+ {"pgrotated", protos::pbzero::VmstatCounters::VMSTAT_PGROTATED},
+ {"drop_pagecache", protos::pbzero::VmstatCounters::VMSTAT_DROP_PAGECACHE},
+ {"drop_slab", protos::pbzero::VmstatCounters::VMSTAT_DROP_SLAB},
+ {"pgmigrate_success",
+ protos::pbzero::VmstatCounters::VMSTAT_PGMIGRATE_SUCCESS},
+ {"pgmigrate_fail", protos::pbzero::VmstatCounters::VMSTAT_PGMIGRATE_FAIL},
+ {"compact_migrate_scanned",
+ protos::pbzero::VmstatCounters::VMSTAT_COMPACT_MIGRATE_SCANNED},
+ {"compact_free_scanned",
+ protos::pbzero::VmstatCounters::VMSTAT_COMPACT_FREE_SCANNED},
+ {"compact_isolated",
+ protos::pbzero::VmstatCounters::VMSTAT_COMPACT_ISOLATED},
+ {"compact_stall", protos::pbzero::VmstatCounters::VMSTAT_COMPACT_STALL},
+ {"compact_fail", protos::pbzero::VmstatCounters::VMSTAT_COMPACT_FAIL},
+ {"compact_success", protos::pbzero::VmstatCounters::VMSTAT_COMPACT_SUCCESS},
+ {"compact_daemon_wake",
+ protos::pbzero::VmstatCounters::VMSTAT_COMPACT_DAEMON_WAKE},
+ {"unevictable_pgs_culled",
+ protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_CULLED},
+ {"unevictable_pgs_scanned",
+ protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_SCANNED},
+ {"unevictable_pgs_rescued",
+ protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_RESCUED},
+ {"unevictable_pgs_mlocked",
+ protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_MLOCKED},
+ {"unevictable_pgs_munlocked",
+ protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_MUNLOCKED},
+ {"unevictable_pgs_cleared",
+ protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_CLEARED},
+ {"unevictable_pgs_stranded",
+ protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_STRANDED},
+};
+
+// Returns a lookup table of meminfo counter names addressable by counter id.
+inline std::vector<const char*> BuildMeminfoCounterNames() {
+ int max_id = 0;
+ for (size_t i = 0; i < base::ArraySize(kMeminfoKeys); i++)
+ max_id = std::max(max_id, kMeminfoKeys[i].id);
+ std::vector<const char*> v;
+ v.resize(static_cast<size_t>(max_id) + 1);
+ for (size_t i = 0; i < base::ArraySize(kMeminfoKeys); i++)
+ v[static_cast<size_t>(kMeminfoKeys[i].id)] = kMeminfoKeys[i].str;
+ return v;
+}
+
+inline std::vector<const char*> BuildVmstatCounterNames() {
+ int max_id = 0;
+ for (size_t i = 0; i < base::ArraySize(kVmstatKeys); i++)
+ max_id = std::max(max_id, kVmstatKeys[i].id);
+ std::vector<const char*> v;
+ v.resize(static_cast<size_t>(max_id) + 1);
+ for (size_t i = 0; i < base::ArraySize(kVmstatKeys); i++)
+ v[static_cast<size_t>(kVmstatKeys[i].id)] = kVmstatKeys[i].str;
+ return v;
+}
+
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_TRACED_SYS_STATS_COUNTERS_H_
diff --git a/include/perfetto/tracing/core/chrome_config.h b/include/perfetto/tracing/core/chrome_config.h
index ceac1a6..693546d 100644
--- a/include/perfetto/tracing/core/chrome_config.h
+++ b/include/perfetto/tracing/core/chrome_config.h
@@ -69,4 +69,5 @@
};
} // namespace perfetto
+
#endif // INCLUDE_PERFETTO_TRACING_CORE_CHROME_CONFIG_H_
diff --git a/include/perfetto/tracing/core/commit_data_request.h b/include/perfetto/tracing/core/commit_data_request.h
index 3f0042f..d112d01 100644
--- a/include/perfetto/tracing/core/commit_data_request.h
+++ b/include/perfetto/tracing/core/commit_data_request.h
@@ -205,4 +205,5 @@
};
} // namespace perfetto
+
#endif // INCLUDE_PERFETTO_TRACING_CORE_COMMIT_DATA_REQUEST_H_
diff --git a/include/perfetto/tracing/core/data_source_config.h b/include/perfetto/tracing/core/data_source_config.h
index fda2fb0..e816948 100644
--- a/include/perfetto/tracing/core/data_source_config.h
+++ b/include/perfetto/tracing/core/data_source_config.h
@@ -39,6 +39,7 @@
#include "perfetto/tracing/core/ftrace_config.h"
#include "perfetto/tracing/core/inode_file_config.h"
#include "perfetto/tracing/core/process_stats_config.h"
+#include "perfetto/tracing/core/sys_stats_config.h"
#include "perfetto/tracing/core/test_config.h"
// Forward declarations for protobuf types.
@@ -50,6 +51,7 @@
class InodeFileConfig;
class InodeFileConfig_MountPointMappingEntry;
class ProcessStatsConfig;
+class SysStatsConfig;
class TestConfig;
} // namespace protos
} // namespace perfetto
@@ -99,6 +101,9 @@
return &process_stats_config_;
}
+ const SysStatsConfig& sys_stats_config() const { return sys_stats_config_; }
+ SysStatsConfig* mutable_sys_stats_config() { return &sys_stats_config_; }
+
const std::string& legacy_config() const { return legacy_config_; }
void set_legacy_config(const std::string& value) { legacy_config_ = value; }
@@ -114,6 +119,7 @@
ChromeConfig chrome_config_ = {};
InodeFileConfig inode_file_config_ = {};
ProcessStatsConfig process_stats_config_ = {};
+ SysStatsConfig sys_stats_config_ = {};
std::string legacy_config_ = {};
TestConfig for_testing_ = {};
@@ -123,4 +129,5 @@
};
} // namespace perfetto
+
#endif // INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_CONFIG_H_
diff --git a/include/perfetto/tracing/core/data_source_descriptor.h b/include/perfetto/tracing/core/data_source_descriptor.h
index 1678e79..db4e0de 100644
--- a/include/perfetto/tracing/core/data_source_descriptor.h
+++ b/include/perfetto/tracing/core/data_source_descriptor.h
@@ -73,4 +73,5 @@
};
} // namespace perfetto
+
#endif // INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_DESCRIPTOR_H_
diff --git a/include/perfetto/tracing/core/ftrace_config.h b/include/perfetto/tracing/core/ftrace_config.h
index 5ed5715..794314a 100644
--- a/include/perfetto/tracing/core/ftrace_config.h
+++ b/include/perfetto/tracing/core/ftrace_config.h
@@ -105,4 +105,5 @@
};
} // namespace perfetto
+
#endif // INCLUDE_PERFETTO_TRACING_CORE_FTRACE_CONFIG_H_
diff --git a/include/perfetto/tracing/core/inode_file_config.h b/include/perfetto/tracing/core/inode_file_config.h
index e376624..34f3e0a 100644
--- a/include/perfetto/tracing/core/inode_file_config.h
+++ b/include/perfetto/tracing/core/inode_file_config.h
@@ -140,4 +140,5 @@
};
} // namespace perfetto
+
#endif // INCLUDE_PERFETTO_TRACING_CORE_INODE_FILE_CONFIG_H_
diff --git a/include/perfetto/tracing/core/process_stats_config.h b/include/perfetto/tracing/core/process_stats_config.h
index c89ee86..7adf410 100644
--- a/include/perfetto/tracing/core/process_stats_config.h
+++ b/include/perfetto/tracing/core/process_stats_config.h
@@ -90,4 +90,5 @@
};
} // namespace perfetto
+
#endif // INCLUDE_PERFETTO_TRACING_CORE_PROCESS_STATS_CONFIG_H_
diff --git a/include/perfetto/tracing/core/sys_stats_config.h b/include/perfetto/tracing/core/sys_stats_config.h
new file mode 100644
index 0000000..a5deb9b
--- /dev/null
+++ b/include/perfetto/tracing/core/sys_stats_config.h
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/*******************************************************************************
+ * AUTOGENERATED - DO NOT EDIT
+ *******************************************************************************
+ * This file has been generated from the protobuf message
+ * perfetto/config/sys_stats/sys_stats_config.proto
+ * by
+ * ../../tools/proto_to_cpp/proto_to_cpp.cc.
+ * If you need to make changes here, change the .proto file and then run
+ * ./tools/gen_tracing_cpp_headers_from_protos.py
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_SYS_STATS_CONFIG_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_SYS_STATS_CONFIG_H_
+
+#include <stdint.h>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "perfetto/base/export.h"
+
+#include "perfetto/tracing/core/sys_stats_counters.h"
+
+// Forward declarations for protobuf types.
+namespace perfetto {
+namespace protos {
+class SysStatsConfig;
+}
+} // namespace perfetto
+
+namespace perfetto {
+
+class PERFETTO_EXPORT SysStatsConfig {
+ public:
+ enum MeminfoCounters {
+ MEMINFO_UNSPECIFIED = 0,
+ MEMINFO_MEM_TOTAL = 1,
+ MEMINFO_MEM_FREE = 2,
+ MEMINFO_MEM_AVAILABLE = 3,
+ MEMINFO_BUFFERS = 4,
+ MEMINFO_CACHED = 5,
+ MEMINFO_SWAP_CACHED = 6,
+ MEMINFO_ACTIVE = 7,
+ MEMINFO_INACTIVE = 8,
+ MEMINFO_ACTIVE_ANON = 9,
+ MEMINFO_INACTIVE_ANON = 10,
+ MEMINFO_ACTIVE_FILE = 11,
+ MEMINFO_INACTIVE_FILE = 12,
+ MEMINFO_UNEVICTABLE = 13,
+ MEMINFO_MLOCKED = 14,
+ MEMINFO_SWAP_TOTAL = 15,
+ MEMINFO_SWAP_FREE = 16,
+ MEMINFO_DIRTY = 17,
+ MEMINFO_WRITEBACK = 18,
+ MEMINFO_ANON_PAGES = 19,
+ MEMINFO_MAPPED = 20,
+ MEMINFO_SHMEM = 21,
+ MEMINFO_SLAB = 22,
+ MEMINFO_SLAB_RECLAIMABLE = 23,
+ MEMINFO_SLAB_UNRECLAIMABLE = 24,
+ MEMINFO_KERNEL_STACK = 25,
+ MEMINFO_PAGE_TABLES = 26,
+ MEMINFO_COMMIT_LIMIT = 27,
+ MEMINFO_COMMITED_AS = 28,
+ MEMINFO_VMALLOC_TOTAL = 29,
+ MEMINFO_VMALLOC_USED = 30,
+ MEMINFO_VMALLOC_CHUNK = 31,
+ MEMINFO_CMA_TOTAL = 32,
+ MEMINFO_CMA_FREE = 33,
+ };
+ enum VmstatCounters {
+ VMSTAT_UNSPECIFIED = 0,
+ VMSTAT_NR_FREE_PAGES = 1,
+ VMSTAT_NR_ALLOC_BATCH = 2,
+ VMSTAT_NR_INACTIVE_ANON = 3,
+ VMSTAT_NR_ACTIVE_ANON = 4,
+ VMSTAT_NR_INACTIVE_FILE = 5,
+ VMSTAT_NR_ACTIVE_FILE = 6,
+ VMSTAT_NR_UNEVICTABLE = 7,
+ VMSTAT_NR_MLOCK = 8,
+ VMSTAT_NR_ANON_PAGES = 9,
+ VMSTAT_NR_MAPPED = 10,
+ VMSTAT_NR_FILE_PAGES = 11,
+ VMSTAT_NR_DIRTY = 12,
+ VMSTAT_NR_WRITEBACK = 13,
+ VMSTAT_NR_SLAB_RECLAIMABLE = 14,
+ VMSTAT_NR_SLAB_UNRECLAIMABLE = 15,
+ VMSTAT_NR_PAGE_TABLE_PAGES = 16,
+ VMSTAT_NR_KERNEL_STACK = 17,
+ VMSTAT_NR_OVERHEAD = 18,
+ VMSTAT_NR_UNSTABLE = 19,
+ VMSTAT_NR_BOUNCE = 20,
+ VMSTAT_NR_VMSCAN_WRITE = 21,
+ VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM = 22,
+ VMSTAT_NR_WRITEBACK_TEMP = 23,
+ VMSTAT_NR_ISOLATED_ANON = 24,
+ VMSTAT_NR_ISOLATED_FILE = 25,
+ VMSTAT_NR_SHMEM = 26,
+ VMSTAT_NR_DIRTIED = 27,
+ VMSTAT_NR_WRITTEN = 28,
+ VMSTAT_NR_PAGES_SCANNED = 29,
+ VMSTAT_WORKINGSET_REFAULT = 30,
+ VMSTAT_WORKINGSET_ACTIVATE = 31,
+ VMSTAT_WORKINGSET_NODERECLAIM = 32,
+ VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES = 33,
+ VMSTAT_NR_FREE_CMA = 34,
+ VMSTAT_NR_SWAPCACHE = 35,
+ VMSTAT_NR_DIRTY_THRESHOLD = 36,
+ VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD = 37,
+ VMSTAT_PGPGIN = 38,
+ VMSTAT_PGPGOUT = 39,
+ VMSTAT_PGPGOUTCLEAN = 40,
+ VMSTAT_PSWPIN = 41,
+ VMSTAT_PSWPOUT = 42,
+ VMSTAT_PGALLOC_DMA = 43,
+ VMSTAT_PGALLOC_NORMAL = 44,
+ VMSTAT_PGALLOC_MOVABLE = 45,
+ VMSTAT_PGFREE = 46,
+ VMSTAT_PGACTIVATE = 47,
+ VMSTAT_PGDEACTIVATE = 48,
+ VMSTAT_PGFAULT = 49,
+ VMSTAT_PGMAJFAULT = 50,
+ VMSTAT_PGREFILL_DMA = 51,
+ VMSTAT_PGREFILL_NORMAL = 52,
+ VMSTAT_PGREFILL_MOVABLE = 53,
+ VMSTAT_PGSTEAL_KSWAPD_DMA = 54,
+ VMSTAT_PGSTEAL_KSWAPD_NORMAL = 55,
+ VMSTAT_PGSTEAL_KSWAPD_MOVABLE = 56,
+ VMSTAT_PGSTEAL_DIRECT_DMA = 57,
+ VMSTAT_PGSTEAL_DIRECT_NORMAL = 58,
+ VMSTAT_PGSTEAL_DIRECT_MOVABLE = 59,
+ VMSTAT_PGSCAN_KSWAPD_DMA = 60,
+ VMSTAT_PGSCAN_KSWAPD_NORMAL = 61,
+ VMSTAT_PGSCAN_KSWAPD_MOVABLE = 62,
+ VMSTAT_PGSCAN_DIRECT_DMA = 63,
+ VMSTAT_PGSCAN_DIRECT_NORMAL = 64,
+ VMSTAT_PGSCAN_DIRECT_MOVABLE = 65,
+ VMSTAT_PGSCAN_DIRECT_THROTTLE = 66,
+ VMSTAT_PGINODESTEAL = 67,
+ VMSTAT_SLABS_SCANNED = 68,
+ VMSTAT_KSWAPD_INODESTEAL = 69,
+ VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY = 70,
+ VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY = 71,
+ VMSTAT_PAGEOUTRUN = 72,
+ VMSTAT_ALLOCSTALL = 73,
+ VMSTAT_PGROTATED = 74,
+ VMSTAT_DROP_PAGECACHE = 75,
+ VMSTAT_DROP_SLAB = 76,
+ VMSTAT_PGMIGRATE_SUCCESS = 77,
+ VMSTAT_PGMIGRATE_FAIL = 78,
+ VMSTAT_COMPACT_MIGRATE_SCANNED = 79,
+ VMSTAT_COMPACT_FREE_SCANNED = 80,
+ VMSTAT_COMPACT_ISOLATED = 81,
+ VMSTAT_COMPACT_STALL = 82,
+ VMSTAT_COMPACT_FAIL = 83,
+ VMSTAT_COMPACT_SUCCESS = 84,
+ VMSTAT_COMPACT_DAEMON_WAKE = 85,
+ VMSTAT_UNEVICTABLE_PGS_CULLED = 86,
+ VMSTAT_UNEVICTABLE_PGS_SCANNED = 87,
+ VMSTAT_UNEVICTABLE_PGS_RESCUED = 88,
+ VMSTAT_UNEVICTABLE_PGS_MLOCKED = 89,
+ VMSTAT_UNEVICTABLE_PGS_MUNLOCKED = 90,
+ VMSTAT_UNEVICTABLE_PGS_CLEARED = 91,
+ VMSTAT_UNEVICTABLE_PGS_STRANDED = 92,
+ };
+ enum StatCounters {
+ STAT_UNSPECIFIED = 0,
+ STAT_CPU_TIMES = 1,
+ STAT_IRQ_COUNTS = 2,
+ STAT_SOFTIRQ_COUNTS = 3,
+ STAT_FORK_COUNT = 4,
+ };
+ SysStatsConfig();
+ ~SysStatsConfig();
+ SysStatsConfig(SysStatsConfig&&) noexcept;
+ SysStatsConfig& operator=(SysStatsConfig&&);
+ SysStatsConfig(const SysStatsConfig&);
+ SysStatsConfig& operator=(const SysStatsConfig&);
+
+ // Conversion methods from/to the corresponding protobuf types.
+ void FromProto(const perfetto::protos::SysStatsConfig&);
+ void ToProto(perfetto::protos::SysStatsConfig*) const;
+
+ uint32_t meminfo_period_ms() const { return meminfo_period_ms_; }
+ void set_meminfo_period_ms(uint32_t value) { meminfo_period_ms_ = value; }
+
+ int meminfo_counters_size() const {
+ return static_cast<int>(meminfo_counters_.size());
+ }
+ const std::vector<MeminfoCounters>& meminfo_counters() const {
+ return meminfo_counters_;
+ }
+ MeminfoCounters* add_meminfo_counters() {
+ meminfo_counters_.emplace_back();
+ return &meminfo_counters_.back();
+ }
+
+ uint32_t vmstat_period_ms() const { return vmstat_period_ms_; }
+ void set_vmstat_period_ms(uint32_t value) { vmstat_period_ms_ = value; }
+
+ int vmstat_counters_size() const {
+ return static_cast<int>(vmstat_counters_.size());
+ }
+ const std::vector<VmstatCounters>& vmstat_counters() const {
+ return vmstat_counters_;
+ }
+ VmstatCounters* add_vmstat_counters() {
+ vmstat_counters_.emplace_back();
+ return &vmstat_counters_.back();
+ }
+
+ uint32_t stat_period_ms() const { return stat_period_ms_; }
+ void set_stat_period_ms(uint32_t value) { stat_period_ms_ = value; }
+
+ int stat_counters_size() const {
+ return static_cast<int>(stat_counters_.size());
+ }
+ const std::vector<StatCounters>& stat_counters() const {
+ return stat_counters_;
+ }
+ StatCounters* add_stat_counters() {
+ stat_counters_.emplace_back();
+ return &stat_counters_.back();
+ }
+
+ private:
+ uint32_t meminfo_period_ms_ = {};
+ std::vector<MeminfoCounters> meminfo_counters_;
+ uint32_t vmstat_period_ms_ = {};
+ std::vector<VmstatCounters> vmstat_counters_;
+ uint32_t stat_period_ms_ = {};
+ std::vector<StatCounters> stat_counters_;
+
+ // Allows to preserve unknown protobuf fields for compatibility
+ // with future versions of .proto files.
+ std::string unknown_fields_;
+};
+
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_TRACING_CORE_SYS_STATS_CONFIG_H_
diff --git a/include/perfetto/tracing/core/sys_stats_counters.h b/include/perfetto/tracing/core/sys_stats_counters.h
new file mode 100644
index 0000000..e27b5f2
--- /dev/null
+++ b/include/perfetto/tracing/core/sys_stats_counters.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/*******************************************************************************
+ * AUTOGENERATED - DO NOT EDIT
+ *******************************************************************************
+ * This file has been generated from the protobuf message
+ * perfetto/common/sys_stats_counters.proto
+ * by
+ * ../../tools/proto_to_cpp/proto_to_cpp.cc.
+ * If you need to make changes here, change the .proto file and then run
+ * ./tools/gen_tracing_cpp_headers_from_protos.py
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_SYS_STATS_COUNTERS_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_SYS_STATS_COUNTERS_H_
+
+#include <stdint.h>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "perfetto/base/export.h"
+
+// Forward declarations for protobuf types.
+namespace perfetto {
+namespace protos {}
+} // namespace perfetto
+
+namespace perfetto {} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_TRACING_CORE_SYS_STATS_COUNTERS_H_
diff --git a/include/perfetto/tracing/core/test_config.h b/include/perfetto/tracing/core/test_config.h
index 4fdfe8e..24e272d 100644
--- a/include/perfetto/tracing/core/test_config.h
+++ b/include/perfetto/tracing/core/test_config.h
@@ -89,4 +89,5 @@
};
} // namespace perfetto
+
#endif // INCLUDE_PERFETTO_TRACING_CORE_TEST_CONFIG_H_
diff --git a/include/perfetto/tracing/core/trace_config.h b/include/perfetto/tracing/core/trace_config.h
index d94b72a..df0a89e 100644
--- a/include/perfetto/tracing/core/trace_config.h
+++ b/include/perfetto/tracing/core/trace_config.h
@@ -49,6 +49,7 @@
class InodeFileConfig;
class InodeFileConfig_MountPointMappingEntry;
class ProcessStatsConfig;
+class SysStatsConfig;
class TestConfig;
class TraceConfig_ProducerConfig;
class TraceConfig_StatsdMetadata;
@@ -319,4 +320,5 @@
};
} // namespace perfetto
+
#endif // INCLUDE_PERFETTO_TRACING_CORE_TRACE_CONFIG_H_
diff --git a/protos/perfetto/common/BUILD.gn b/protos/perfetto/common/BUILD.gn
index 9a07e5a..38603fd 100644
--- a/protos/perfetto/common/BUILD.gn
+++ b/protos/perfetto/common/BUILD.gn
@@ -14,14 +14,25 @@
import("../../../gn/perfetto.gni")
import("../../../gn/proto_library.gni")
+import("../../../src/protozero/protozero_library.gni")
+
+common_sources = [
+ "commit_data_request.proto",
+ "sys_stats_counters.proto",
+]
# Proto messages that are required by the IPC service definitions but have also
# a C++ counterpart in tracing/core (i.e. are used also for the non-IPC cases).
-proto_library("common") {
+proto_library("lite") {
generate_python = false
proto_in_dir = "$perfetto_root_path/protos"
proto_out_dir = "$perfetto_root_path/protos"
- sources = [
- "commit_data_request.proto",
- ]
+ sources = common_sources
+}
+
+protozero_library("zero") {
+ proto_in_dir = "$perfetto_root_path/protos"
+ proto_out_dir = "$perfetto_root_path/protos"
+ sources = common_sources
+ generator_plugin_options = "wrapper_namespace=pbzero"
}
diff --git a/protos/perfetto/common/sys_stats_counters.proto b/protos/perfetto/common/sys_stats_counters.proto
new file mode 100644
index 0000000..2e482e7
--- /dev/null
+++ b/protos/perfetto/common/sys_stats_counters.proto
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+
+package perfetto.protos;
+
+// When editing entries here remember also to update "sys_stats_counters.h" with
+// the corresponding string definitions for the actual /proc files parser.
+
+// Counter definitions for Linux's /proc/meminfo.
+enum MeminfoCounters {
+ MEMINFO_UNSPECIFIED = 0;
+ MEMINFO_MEM_TOTAL = 1;
+ MEMINFO_MEM_FREE = 2;
+ MEMINFO_MEM_AVAILABLE = 3;
+ MEMINFO_BUFFERS = 4;
+ MEMINFO_CACHED = 5;
+ MEMINFO_SWAP_CACHED = 6;
+ MEMINFO_ACTIVE = 7;
+ MEMINFO_INACTIVE = 8;
+ MEMINFO_ACTIVE_ANON = 9;
+ MEMINFO_INACTIVE_ANON = 10;
+ MEMINFO_ACTIVE_FILE = 11;
+ MEMINFO_INACTIVE_FILE = 12;
+ MEMINFO_UNEVICTABLE = 13;
+ MEMINFO_MLOCKED = 14;
+ MEMINFO_SWAP_TOTAL = 15;
+ MEMINFO_SWAP_FREE = 16;
+ MEMINFO_DIRTY = 17;
+ MEMINFO_WRITEBACK = 18;
+ MEMINFO_ANON_PAGES = 19;
+ MEMINFO_MAPPED = 20;
+ MEMINFO_SHMEM = 21;
+ MEMINFO_SLAB = 22;
+ MEMINFO_SLAB_RECLAIMABLE = 23;
+ MEMINFO_SLAB_UNRECLAIMABLE = 24;
+ MEMINFO_KERNEL_STACK = 25;
+ MEMINFO_PAGE_TABLES = 26;
+ MEMINFO_COMMIT_LIMIT = 27;
+ MEMINFO_COMMITED_AS = 28;
+ MEMINFO_VMALLOC_TOTAL = 29;
+ MEMINFO_VMALLOC_USED = 30;
+ MEMINFO_VMALLOC_CHUNK = 31;
+ MEMINFO_CMA_TOTAL = 32;
+ MEMINFO_CMA_FREE = 33;
+}
+
+// Counter definitions for Linux's /proc/vmstat.
+enum VmstatCounters {
+ VMSTAT_UNSPECIFIED = 0;
+ VMSTAT_NR_FREE_PAGES = 1;
+ VMSTAT_NR_ALLOC_BATCH = 2;
+ VMSTAT_NR_INACTIVE_ANON = 3;
+ VMSTAT_NR_ACTIVE_ANON = 4;
+ VMSTAT_NR_INACTIVE_FILE = 5;
+ VMSTAT_NR_ACTIVE_FILE = 6;
+ VMSTAT_NR_UNEVICTABLE = 7;
+ VMSTAT_NR_MLOCK = 8;
+ VMSTAT_NR_ANON_PAGES = 9;
+ VMSTAT_NR_MAPPED = 10;
+ VMSTAT_NR_FILE_PAGES = 11;
+ VMSTAT_NR_DIRTY = 12;
+ VMSTAT_NR_WRITEBACK = 13;
+ VMSTAT_NR_SLAB_RECLAIMABLE = 14;
+ VMSTAT_NR_SLAB_UNRECLAIMABLE = 15;
+ VMSTAT_NR_PAGE_TABLE_PAGES = 16;
+ VMSTAT_NR_KERNEL_STACK = 17;
+ VMSTAT_NR_OVERHEAD = 18;
+ VMSTAT_NR_UNSTABLE = 19;
+ VMSTAT_NR_BOUNCE = 20;
+ VMSTAT_NR_VMSCAN_WRITE = 21;
+ VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM = 22;
+ VMSTAT_NR_WRITEBACK_TEMP = 23;
+ VMSTAT_NR_ISOLATED_ANON = 24;
+ VMSTAT_NR_ISOLATED_FILE = 25;
+ VMSTAT_NR_SHMEM = 26;
+ VMSTAT_NR_DIRTIED = 27;
+ VMSTAT_NR_WRITTEN = 28;
+ VMSTAT_NR_PAGES_SCANNED = 29;
+ VMSTAT_WORKINGSET_REFAULT = 30;
+ VMSTAT_WORKINGSET_ACTIVATE = 31;
+ VMSTAT_WORKINGSET_NODERECLAIM = 32;
+ VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES = 33;
+ VMSTAT_NR_FREE_CMA = 34;
+ VMSTAT_NR_SWAPCACHE = 35;
+ VMSTAT_NR_DIRTY_THRESHOLD = 36;
+ VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD = 37;
+ VMSTAT_PGPGIN = 38;
+ VMSTAT_PGPGOUT = 39;
+ VMSTAT_PGPGOUTCLEAN = 40;
+ VMSTAT_PSWPIN = 41;
+ VMSTAT_PSWPOUT = 42;
+ VMSTAT_PGALLOC_DMA = 43;
+ VMSTAT_PGALLOC_NORMAL = 44;
+ VMSTAT_PGALLOC_MOVABLE = 45;
+ VMSTAT_PGFREE = 46;
+ VMSTAT_PGACTIVATE = 47;
+ VMSTAT_PGDEACTIVATE = 48;
+ VMSTAT_PGFAULT = 49;
+ VMSTAT_PGMAJFAULT = 50;
+ VMSTAT_PGREFILL_DMA = 51;
+ VMSTAT_PGREFILL_NORMAL = 52;
+ VMSTAT_PGREFILL_MOVABLE = 53;
+ VMSTAT_PGSTEAL_KSWAPD_DMA = 54;
+ VMSTAT_PGSTEAL_KSWAPD_NORMAL = 55;
+ VMSTAT_PGSTEAL_KSWAPD_MOVABLE = 56;
+ VMSTAT_PGSTEAL_DIRECT_DMA = 57;
+ VMSTAT_PGSTEAL_DIRECT_NORMAL = 58;
+ VMSTAT_PGSTEAL_DIRECT_MOVABLE = 59;
+ VMSTAT_PGSCAN_KSWAPD_DMA = 60;
+ VMSTAT_PGSCAN_KSWAPD_NORMAL = 61;
+ VMSTAT_PGSCAN_KSWAPD_MOVABLE = 62;
+ VMSTAT_PGSCAN_DIRECT_DMA = 63;
+ VMSTAT_PGSCAN_DIRECT_NORMAL = 64;
+ VMSTAT_PGSCAN_DIRECT_MOVABLE = 65;
+ VMSTAT_PGSCAN_DIRECT_THROTTLE = 66;
+ VMSTAT_PGINODESTEAL = 67;
+ VMSTAT_SLABS_SCANNED = 68;
+ VMSTAT_KSWAPD_INODESTEAL = 69;
+ VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY = 70;
+ VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY = 71;
+ VMSTAT_PAGEOUTRUN = 72;
+ VMSTAT_ALLOCSTALL = 73;
+ VMSTAT_PGROTATED = 74;
+ VMSTAT_DROP_PAGECACHE = 75;
+ VMSTAT_DROP_SLAB = 76;
+ VMSTAT_PGMIGRATE_SUCCESS = 77;
+ VMSTAT_PGMIGRATE_FAIL = 78;
+ VMSTAT_COMPACT_MIGRATE_SCANNED = 79;
+ VMSTAT_COMPACT_FREE_SCANNED = 80;
+ VMSTAT_COMPACT_ISOLATED = 81;
+ VMSTAT_COMPACT_STALL = 82;
+ VMSTAT_COMPACT_FAIL = 83;
+ VMSTAT_COMPACT_SUCCESS = 84;
+ VMSTAT_COMPACT_DAEMON_WAKE = 85;
+ VMSTAT_UNEVICTABLE_PGS_CULLED = 86;
+ VMSTAT_UNEVICTABLE_PGS_SCANNED = 87;
+ VMSTAT_UNEVICTABLE_PGS_RESCUED = 88;
+ VMSTAT_UNEVICTABLE_PGS_MLOCKED = 89;
+ VMSTAT_UNEVICTABLE_PGS_MUNLOCKED = 90;
+ VMSTAT_UNEVICTABLE_PGS_CLEARED = 91;
+ VMSTAT_UNEVICTABLE_PGS_STRANDED = 92;
+}
\ No newline at end of file
diff --git a/protos/perfetto/config/BUILD.gn b/protos/perfetto/config/BUILD.gn
index 74fa6c1..db89822 100644
--- a/protos/perfetto/config/BUILD.gn
+++ b/protos/perfetto/config/BUILD.gn
@@ -16,10 +16,13 @@
import("../../../gn/proto_library.gni")
import("../../../src/protozero/protozero_library.gni")
-proto_library("config") {
+proto_library("lite") {
generate_python = false
proto_in_dir = "$perfetto_root_path/protos"
proto_out_dir = "$perfetto_root_path/protos"
+ deps = [
+ "../common:lite",
+ ]
sources = [
"chrome/chrome_config.proto",
"data_source_config.proto",
@@ -27,14 +30,18 @@
"ftrace/ftrace_config.proto",
"inode_file/inode_file_config.proto",
"process_stats/process_stats_config.proto",
+ "sys_stats/sys_stats_config.proto",
"test_config.proto",
"trace_config.proto",
]
}
-protozero_library("config_zero") {
+protozero_library("zero") {
proto_in_dir = "$perfetto_root_path/protos"
proto_out_dir = "$perfetto_root_path/protos"
+ deps = [
+ "../common:zero",
+ ]
sources = [
"chrome/chrome_config.proto",
"data_source_config.proto",
@@ -42,6 +49,7 @@
"ftrace/ftrace_config.proto",
"inode_file/inode_file_config.proto",
"process_stats/process_stats_config.proto",
+ "sys_stats/sys_stats_config.proto",
"test_config.proto",
"trace_config.proto",
]
diff --git a/protos/perfetto/config/data_source_config.proto b/protos/perfetto/config/data_source_config.proto
index 35b8fe1..1688179 100644
--- a/protos/perfetto/config/data_source_config.proto
+++ b/protos/perfetto/config/data_source_config.proto
@@ -23,7 +23,9 @@
import "perfetto/config/ftrace/ftrace_config.proto";
import "perfetto/config/inode_file/inode_file_config.proto";
import "perfetto/config/process_stats/process_stats_config.proto";
+import "perfetto/config/sys_stats/sys_stats_config.proto";
import "perfetto/config/test_config.proto";
+
// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
// to reflect changes in the corresponding C++ headers.
@@ -60,6 +62,7 @@
optional ChromeConfig chrome_config = 101;
optional InodeFileConfig inode_file_config = 102;
optional ProcessStatsConfig process_stats_config = 103;
+ optional SysStatsConfig sys_stats_config = 104;
// This is a fallback mechanism to send a free-form text config to the
// producer. In theory this should never be needed. All the code that
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index e99a626..91f4aad 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -11,6 +11,147 @@
package perfetto.protos;
+// Begin of protos/perfetto/common/sys_stats_counters.proto
+
+// When editing entries here remember also to update "sys_stats_counters.h" with
+// the corresponding string definitions for the actual /proc files parser.
+
+// Counter definitions for Linux's /proc/meminfo.
+enum MeminfoCounters {
+ MEMINFO_UNSPECIFIED = 0;
+ MEMINFO_MEM_TOTAL = 1;
+ MEMINFO_MEM_FREE = 2;
+ MEMINFO_MEM_AVAILABLE = 3;
+ MEMINFO_BUFFERS = 4;
+ MEMINFO_CACHED = 5;
+ MEMINFO_SWAP_CACHED = 6;
+ MEMINFO_ACTIVE = 7;
+ MEMINFO_INACTIVE = 8;
+ MEMINFO_ACTIVE_ANON = 9;
+ MEMINFO_INACTIVE_ANON = 10;
+ MEMINFO_ACTIVE_FILE = 11;
+ MEMINFO_INACTIVE_FILE = 12;
+ MEMINFO_UNEVICTABLE = 13;
+ MEMINFO_MLOCKED = 14;
+ MEMINFO_SWAP_TOTAL = 15;
+ MEMINFO_SWAP_FREE = 16;
+ MEMINFO_DIRTY = 17;
+ MEMINFO_WRITEBACK = 18;
+ MEMINFO_ANON_PAGES = 19;
+ MEMINFO_MAPPED = 20;
+ MEMINFO_SHMEM = 21;
+ MEMINFO_SLAB = 22;
+ MEMINFO_SLAB_RECLAIMABLE = 23;
+ MEMINFO_SLAB_UNRECLAIMABLE = 24;
+ MEMINFO_KERNEL_STACK = 25;
+ MEMINFO_PAGE_TABLES = 26;
+ MEMINFO_COMMIT_LIMIT = 27;
+ MEMINFO_COMMITED_AS = 28;
+ MEMINFO_VMALLOC_TOTAL = 29;
+ MEMINFO_VMALLOC_USED = 30;
+ MEMINFO_VMALLOC_CHUNK = 31;
+ MEMINFO_CMA_TOTAL = 32;
+ MEMINFO_CMA_FREE = 33;
+}
+
+// Counter definitions for Linux's /proc/vmstat.
+enum VmstatCounters {
+ VMSTAT_UNSPECIFIED = 0;
+ VMSTAT_NR_FREE_PAGES = 1;
+ VMSTAT_NR_ALLOC_BATCH = 2;
+ VMSTAT_NR_INACTIVE_ANON = 3;
+ VMSTAT_NR_ACTIVE_ANON = 4;
+ VMSTAT_NR_INACTIVE_FILE = 5;
+ VMSTAT_NR_ACTIVE_FILE = 6;
+ VMSTAT_NR_UNEVICTABLE = 7;
+ VMSTAT_NR_MLOCK = 8;
+ VMSTAT_NR_ANON_PAGES = 9;
+ VMSTAT_NR_MAPPED = 10;
+ VMSTAT_NR_FILE_PAGES = 11;
+ VMSTAT_NR_DIRTY = 12;
+ VMSTAT_NR_WRITEBACK = 13;
+ VMSTAT_NR_SLAB_RECLAIMABLE = 14;
+ VMSTAT_NR_SLAB_UNRECLAIMABLE = 15;
+ VMSTAT_NR_PAGE_TABLE_PAGES = 16;
+ VMSTAT_NR_KERNEL_STACK = 17;
+ VMSTAT_NR_OVERHEAD = 18;
+ VMSTAT_NR_UNSTABLE = 19;
+ VMSTAT_NR_BOUNCE = 20;
+ VMSTAT_NR_VMSCAN_WRITE = 21;
+ VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM = 22;
+ VMSTAT_NR_WRITEBACK_TEMP = 23;
+ VMSTAT_NR_ISOLATED_ANON = 24;
+ VMSTAT_NR_ISOLATED_FILE = 25;
+ VMSTAT_NR_SHMEM = 26;
+ VMSTAT_NR_DIRTIED = 27;
+ VMSTAT_NR_WRITTEN = 28;
+ VMSTAT_NR_PAGES_SCANNED = 29;
+ VMSTAT_WORKINGSET_REFAULT = 30;
+ VMSTAT_WORKINGSET_ACTIVATE = 31;
+ VMSTAT_WORKINGSET_NODERECLAIM = 32;
+ VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES = 33;
+ VMSTAT_NR_FREE_CMA = 34;
+ VMSTAT_NR_SWAPCACHE = 35;
+ VMSTAT_NR_DIRTY_THRESHOLD = 36;
+ VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD = 37;
+ VMSTAT_PGPGIN = 38;
+ VMSTAT_PGPGOUT = 39;
+ VMSTAT_PGPGOUTCLEAN = 40;
+ VMSTAT_PSWPIN = 41;
+ VMSTAT_PSWPOUT = 42;
+ VMSTAT_PGALLOC_DMA = 43;
+ VMSTAT_PGALLOC_NORMAL = 44;
+ VMSTAT_PGALLOC_MOVABLE = 45;
+ VMSTAT_PGFREE = 46;
+ VMSTAT_PGACTIVATE = 47;
+ VMSTAT_PGDEACTIVATE = 48;
+ VMSTAT_PGFAULT = 49;
+ VMSTAT_PGMAJFAULT = 50;
+ VMSTAT_PGREFILL_DMA = 51;
+ VMSTAT_PGREFILL_NORMAL = 52;
+ VMSTAT_PGREFILL_MOVABLE = 53;
+ VMSTAT_PGSTEAL_KSWAPD_DMA = 54;
+ VMSTAT_PGSTEAL_KSWAPD_NORMAL = 55;
+ VMSTAT_PGSTEAL_KSWAPD_MOVABLE = 56;
+ VMSTAT_PGSTEAL_DIRECT_DMA = 57;
+ VMSTAT_PGSTEAL_DIRECT_NORMAL = 58;
+ VMSTAT_PGSTEAL_DIRECT_MOVABLE = 59;
+ VMSTAT_PGSCAN_KSWAPD_DMA = 60;
+ VMSTAT_PGSCAN_KSWAPD_NORMAL = 61;
+ VMSTAT_PGSCAN_KSWAPD_MOVABLE = 62;
+ VMSTAT_PGSCAN_DIRECT_DMA = 63;
+ VMSTAT_PGSCAN_DIRECT_NORMAL = 64;
+ VMSTAT_PGSCAN_DIRECT_MOVABLE = 65;
+ VMSTAT_PGSCAN_DIRECT_THROTTLE = 66;
+ VMSTAT_PGINODESTEAL = 67;
+ VMSTAT_SLABS_SCANNED = 68;
+ VMSTAT_KSWAPD_INODESTEAL = 69;
+ VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY = 70;
+ VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY = 71;
+ VMSTAT_PAGEOUTRUN = 72;
+ VMSTAT_ALLOCSTALL = 73;
+ VMSTAT_PGROTATED = 74;
+ VMSTAT_DROP_PAGECACHE = 75;
+ VMSTAT_DROP_SLAB = 76;
+ VMSTAT_PGMIGRATE_SUCCESS = 77;
+ VMSTAT_PGMIGRATE_FAIL = 78;
+ VMSTAT_COMPACT_MIGRATE_SCANNED = 79;
+ VMSTAT_COMPACT_FREE_SCANNED = 80;
+ VMSTAT_COMPACT_ISOLATED = 81;
+ VMSTAT_COMPACT_STALL = 82;
+ VMSTAT_COMPACT_FAIL = 83;
+ VMSTAT_COMPACT_SUCCESS = 84;
+ VMSTAT_COMPACT_DAEMON_WAKE = 85;
+ VMSTAT_UNEVICTABLE_PGS_CULLED = 86;
+ VMSTAT_UNEVICTABLE_PGS_SCANNED = 87;
+ VMSTAT_UNEVICTABLE_PGS_RESCUED = 88;
+ VMSTAT_UNEVICTABLE_PGS_MLOCKED = 89;
+ VMSTAT_UNEVICTABLE_PGS_MUNLOCKED = 90;
+ VMSTAT_UNEVICTABLE_PGS_CLEARED = 91;
+ VMSTAT_UNEVICTABLE_PGS_STRANDED = 92;
+}
+// End of protos/perfetto/common/sys_stats_counters.proto
+
// Begin of protos/perfetto/config/chrome/chrome_config.proto
// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
@@ -22,6 +163,79 @@
// End of protos/perfetto/config/chrome/chrome_config.proto
+// Begin of protos/perfetto/config/data_source_config.proto
+
+
+// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
+// to reflect changes in the corresponding C++ headers.
+
+// The configuration that is passed to each data source when starting tracing.
+message DataSourceConfig {
+ // Data source unique name, e.g., "linux.ftrace". This must match
+ // the name passed by the data source when it registers (see
+ // RegisterDataSource()).
+ optional string name = 1;
+
+ // The index of the logging buffer where TracePacket(s) will be stored.
+ // This field doesn't make a major difference for the Producer(s). The final
+ // logging buffers, in fact, are completely owned by the Service. We just ask
+ // the Producer to copy this number into the chunk headers it emits, so that
+ // the Service can quickly identify the buffer where to move the chunks into
+ // without expensive lookups on its fastpath.
+ optional uint32 target_buffer = 2;
+
+ // Set by the service to indicate the duration of the trace.
+ // DO NOT SET in consumer as this will be overridden by the service.
+ optional uint32 trace_duration_ms = 3;
+
+ // Set by the service to indicate which tracing session the data source
+ // belongs to. The intended use case for this is checking if two data sources,
+ // one of which produces metadata for the other one, belong to the same trace
+ // session and hence should be linked together.
+ // This field was introduced in Aug 2018 after Android P.
+ optional uint64 tracing_session_id = 4;
+
+ // Keeep the lower IDs (up to 99) for fields that are *not* specific to
+ // data-sources and needs to be processed by the traced daemon.
+
+ optional FtraceConfig ftrace_config = 100;
+ optional ChromeConfig chrome_config = 101;
+ optional InodeFileConfig inode_file_config = 102;
+ optional ProcessStatsConfig process_stats_config = 103;
+ optional SysStatsConfig sys_stats_config = 104;
+
+ // This is a fallback mechanism to send a free-form text config to the
+ // producer. In theory this should never be needed. All the code that
+ // is part of the platform (i.e. traced service) is supposed to *not* truncate
+ // the trace config proto and propagate unknown fields. However, if anything
+ // in the pipeline (client or backend) ends up breaking this forward compat
+ // plan, this field will become the escape hatch to allow future data sources
+ // to get some meaningful configuration.
+ optional string legacy_config = 1000;
+
+ // This field is only used for testing.
+ optional TestConfig for_testing =
+ 536870911; // 2^29 - 1, max field id for protos.
+}
+
+// End of protos/perfetto/config/data_source_config.proto
+
+// Begin of protos/perfetto/config/ftrace/ftrace_config.proto
+
+// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
+// to reflect changes in the corresponding C++ headers.
+
+message FtraceConfig {
+ repeated string ftrace_events = 1;
+ repeated string atrace_categories = 2;
+ repeated string atrace_apps = 3;
+ // *Per-CPU* buffer size.
+ optional uint32 buffer_size_kb = 10;
+ optional uint32 drain_period_ms = 11;
+}
+
+// End of protos/perfetto/config/ftrace/ftrace_config.proto
+
// Begin of protos/perfetto/config/inode_file/inode_file_config.proto
// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
@@ -85,76 +299,45 @@
// End of protos/perfetto/config/process_stats/process_stats_config.proto
-// Begin of protos/perfetto/config/data_source_config.proto
+// Begin of protos/perfetto/config/sys_stats/sys_stats_config.proto
+
// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
// to reflect changes in the corresponding C++ headers.
-// The configuration that is passed to each data source when starting tracing.
-message DataSourceConfig {
- // Data source unique name, e.g., "linux.ftrace". This must match
- // the name passed by the data source when it registers (see
- // RegisterDataSource()).
- optional string name = 1;
+// This file defines the configuration for the Linux /proc poller data source,
+// which injects counters in the trace.
+// Counters that are needed in the trace must be explicitly listed in the
+// *_counters fields. This is to avoid spamming the trace with all counters
+// at all times.
+// The sampling rate is configurable. All polling rates (*_period_ms) need
+// to be integer multiples of each other.
+// OK: [10ms, 10ms, 10ms], [10ms, 20ms, 10ms], [10ms, 20ms, 60ms]
+// Not OK: [10ms, 10ms, 11ms], [10ms, 15ms, 20ms]
+message SysStatsConfig {
+ // Polls /proc/meminfo every X ms, if non-zero.
+ optional uint32 meminfo_period_ms = 1;
- // The index of the logging buffer where TracePacket(s) will be stored.
- // This field doesn't make a major difference for the Producer(s). The final
- // logging buffers, in fact, are completely owned by the Service. We just ask
- // the Producer to copy this number into the chunk headers it emits, so that
- // the Service can quickly identify the buffer where to move the chunks into
- // without expensive lookups on its fastpath.
- optional uint32 target_buffer = 2;
+ // Only the counters specified below are reported.
+ repeated MeminfoCounters meminfo_counters = 2;
- // Set by the service to indicate the duration of the trace.
- // DO NOT SET in consumer as this will be overridden by the service.
- optional uint32 trace_duration_ms = 3;
+ // Polls /proc/vmstat every X ms, if non-zero.
+ optional uint32 vmstat_period_ms = 3;
+ repeated VmstatCounters vmstat_counters = 4;
- // Set by the service to indicate which tracing session the data source
- // belongs to. The intended use case for this is checking if two data sources,
- // one of which produces metadata for the other one, belong to the same trace
- // session and hence should be linked together.
- // This field was introduced in Aug 2018 after Android P.
- optional uint64 tracing_session_id = 4;
-
- // Keeep the lower IDs (up to 99) for fields that are *not* specific to
- // data-sources and needs to be processed by the traced daemon.
-
- optional FtraceConfig ftrace_config = 100;
- optional ChromeConfig chrome_config = 101;
- optional InodeFileConfig inode_file_config = 102;
- optional ProcessStatsConfig process_stats_config = 103;
-
- // This is a fallback mechanism to send a free-form text config to the
- // producer. In theory this should never be needed. All the code that
- // is part of the platform (i.e. traced service) is supposed to *not* truncate
- // the trace config proto and propagate unknown fields. However, if anything
- // in the pipeline (client or backend) ends up breaking this forward compat
- // plan, this field will become the escape hatch to allow future data sources
- // to get some meaningful configuration.
- optional string legacy_config = 1000;
-
- // This field is only used for testing.
- optional TestConfig for_testing =
- 536870911; // 2^29 - 1, max field id for protos.
+ // Pols /proc/stat every X ms, if non-zero.
+ optional uint32 stat_period_ms = 5;
+ enum StatCounters {
+ STAT_UNSPECIFIED = 0;
+ STAT_CPU_TIMES = 1;
+ STAT_IRQ_COUNTS = 2;
+ STAT_SOFTIRQ_COUNTS = 3;
+ STAT_FORK_COUNT = 4;
+ }
+ repeated StatCounters stat_counters = 6;
}
-// End of protos/perfetto/config/data_source_config.proto
-
-// Begin of protos/perfetto/config/ftrace/ftrace_config.proto
-
-// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
-// to reflect changes in the corresponding C++ headers.
-
-message FtraceConfig {
- repeated string ftrace_events = 1;
- repeated string atrace_categories = 2;
- repeated string atrace_apps = 3;
- // *Per-CPU* buffer size.
- optional uint32 buffer_size_kb = 10;
- optional uint32 drain_period_ms = 11;
-}
-
-// End of protos/perfetto/config/ftrace/ftrace_config.proto
+// End of protos/perfetto/config/sys_stats/sys_stats_config.proto
// Begin of protos/perfetto/config/test_config.proto
diff --git a/protos/perfetto/config/sys_stats/sys_stats_config.proto b/protos/perfetto/config/sys_stats/sys_stats_config.proto
new file mode 100644
index 0000000..ef958b3
--- /dev/null
+++ b/protos/perfetto/config/sys_stats/sys_stats_config.proto
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+
+package perfetto.protos;
+
+import "perfetto/common/sys_stats_counters.proto";
+
+// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
+// to reflect changes in the corresponding C++ headers.
+
+// This file defines the configuration for the Linux /proc poller data source,
+// which injects counters in the trace.
+// Counters that are needed in the trace must be explicitly listed in the
+// *_counters fields. This is to avoid spamming the trace with all counters
+// at all times.
+// The sampling rate is configurable. All polling rates (*_period_ms) need
+// to be integer multiples of each other.
+// OK: [10ms, 10ms, 10ms], [10ms, 20ms, 10ms], [10ms, 20ms, 60ms]
+// Not OK: [10ms, 10ms, 11ms], [10ms, 15ms, 20ms]
+message SysStatsConfig {
+ // Polls /proc/meminfo every X ms, if non-zero.
+ optional uint32 meminfo_period_ms = 1;
+
+ // Only the counters specified below are reported.
+ repeated MeminfoCounters meminfo_counters = 2;
+
+ // Polls /proc/vmstat every X ms, if non-zero.
+ optional uint32 vmstat_period_ms = 3;
+ repeated VmstatCounters vmstat_counters = 4;
+
+ // Pols /proc/stat every X ms, if non-zero.
+ optional uint32 stat_period_ms = 5;
+ enum StatCounters {
+ STAT_UNSPECIFIED = 0;
+ STAT_CPU_TIMES = 1;
+ STAT_IRQ_COUNTS = 2;
+ STAT_SOFTIRQ_COUNTS = 3;
+ STAT_FORK_COUNT = 4;
+ }
+ repeated StatCounters stat_counters = 6;
+}
diff --git a/protos/perfetto/ipc/BUILD.gn b/protos/perfetto/ipc/BUILD.gn
index e9055be..cd78bc1 100644
--- a/protos/perfetto/ipc/BUILD.gn
+++ b/protos/perfetto/ipc/BUILD.gn
@@ -18,8 +18,8 @@
# IPC service definitions.
ipc_library("ipc") {
deps = [
- "../common",
- "../config",
+ "../common:lite",
+ "../config:lite",
]
proto_in_dir = "$perfetto_root_path/protos"
proto_out_dir = "$perfetto_root_path/protos"
diff --git a/protos/perfetto/trace/BUILD.gn b/protos/perfetto/trace/BUILD.gn
index 60d8259..aa1fe9a 100644
--- a/protos/perfetto/trace/BUILD.gn
+++ b/protos/perfetto/trace/BUILD.gn
@@ -34,11 +34,12 @@
# Protozero generated stubs, for writers.
protozero_library("zero") {
deps = [
- "../config:config_zero",
+ "../config:zero",
"chrome:zero",
"filesystem:zero",
"ftrace:zero",
"ps:zero",
+ "sys_stats:zero",
]
sources = proto_sources_minimal + proto_sources
proto_in_dir = "$perfetto_root_path/protos"
@@ -51,11 +52,12 @@
generate_python = false
deps = [
":minimal_lite",
- "../config:config",
+ "../config:lite",
"chrome:lite",
"filesystem:lite",
"ftrace:lite",
"ps:lite",
+ "sys_stats:lite",
]
if (!build_with_chromium) {
generate_descriptor = "$perfetto_root_path/protos/trace/trace.descriptor"
@@ -69,7 +71,7 @@
proto_library("minimal_lite") {
generate_python = false
deps = [
- "../config:config",
+ "../config:lite",
]
sources = proto_sources_minimal
proto_in_dir = "$perfetto_root_path/protos"
@@ -81,7 +83,7 @@
generate_python = false
deps = [
":minimal_lite",
- "../config:config",
+ "../config:lite",
]
sources = proto_sources_trusted
proto_in_dir = "$perfetto_root_path/protos"
diff --git a/protos/perfetto/trace/chrome/BUILD.gn b/protos/perfetto/trace/chrome/BUILD.gn
index 4a6735f..b5191a6 100644
--- a/protos/perfetto/trace/chrome/BUILD.gn
+++ b/protos/perfetto/trace/chrome/BUILD.gn
@@ -37,7 +37,7 @@
deps = [
":lite",
"../:minimal_lite",
- "../../config:config",
+ "../../config:lite",
]
sources = minimal_chrome_proto_names
proto_in_dir = "$perfetto_root_path/protos"
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index b83ecf0..7fb6490 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -11,6 +11,147 @@
package perfetto.protos;
+// Begin of protos/perfetto/common/sys_stats_counters.proto
+
+// When editing entries here remember also to update "sys_stats_counters.h" with
+// the corresponding string definitions for the actual /proc files parser.
+
+// Counter definitions for Linux's /proc/meminfo.
+enum MeminfoCounters {
+ MEMINFO_UNSPECIFIED = 0;
+ MEMINFO_MEM_TOTAL = 1;
+ MEMINFO_MEM_FREE = 2;
+ MEMINFO_MEM_AVAILABLE = 3;
+ MEMINFO_BUFFERS = 4;
+ MEMINFO_CACHED = 5;
+ MEMINFO_SWAP_CACHED = 6;
+ MEMINFO_ACTIVE = 7;
+ MEMINFO_INACTIVE = 8;
+ MEMINFO_ACTIVE_ANON = 9;
+ MEMINFO_INACTIVE_ANON = 10;
+ MEMINFO_ACTIVE_FILE = 11;
+ MEMINFO_INACTIVE_FILE = 12;
+ MEMINFO_UNEVICTABLE = 13;
+ MEMINFO_MLOCKED = 14;
+ MEMINFO_SWAP_TOTAL = 15;
+ MEMINFO_SWAP_FREE = 16;
+ MEMINFO_DIRTY = 17;
+ MEMINFO_WRITEBACK = 18;
+ MEMINFO_ANON_PAGES = 19;
+ MEMINFO_MAPPED = 20;
+ MEMINFO_SHMEM = 21;
+ MEMINFO_SLAB = 22;
+ MEMINFO_SLAB_RECLAIMABLE = 23;
+ MEMINFO_SLAB_UNRECLAIMABLE = 24;
+ MEMINFO_KERNEL_STACK = 25;
+ MEMINFO_PAGE_TABLES = 26;
+ MEMINFO_COMMIT_LIMIT = 27;
+ MEMINFO_COMMITED_AS = 28;
+ MEMINFO_VMALLOC_TOTAL = 29;
+ MEMINFO_VMALLOC_USED = 30;
+ MEMINFO_VMALLOC_CHUNK = 31;
+ MEMINFO_CMA_TOTAL = 32;
+ MEMINFO_CMA_FREE = 33;
+}
+
+// Counter definitions for Linux's /proc/vmstat.
+enum VmstatCounters {
+ VMSTAT_UNSPECIFIED = 0;
+ VMSTAT_NR_FREE_PAGES = 1;
+ VMSTAT_NR_ALLOC_BATCH = 2;
+ VMSTAT_NR_INACTIVE_ANON = 3;
+ VMSTAT_NR_ACTIVE_ANON = 4;
+ VMSTAT_NR_INACTIVE_FILE = 5;
+ VMSTAT_NR_ACTIVE_FILE = 6;
+ VMSTAT_NR_UNEVICTABLE = 7;
+ VMSTAT_NR_MLOCK = 8;
+ VMSTAT_NR_ANON_PAGES = 9;
+ VMSTAT_NR_MAPPED = 10;
+ VMSTAT_NR_FILE_PAGES = 11;
+ VMSTAT_NR_DIRTY = 12;
+ VMSTAT_NR_WRITEBACK = 13;
+ VMSTAT_NR_SLAB_RECLAIMABLE = 14;
+ VMSTAT_NR_SLAB_UNRECLAIMABLE = 15;
+ VMSTAT_NR_PAGE_TABLE_PAGES = 16;
+ VMSTAT_NR_KERNEL_STACK = 17;
+ VMSTAT_NR_OVERHEAD = 18;
+ VMSTAT_NR_UNSTABLE = 19;
+ VMSTAT_NR_BOUNCE = 20;
+ VMSTAT_NR_VMSCAN_WRITE = 21;
+ VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM = 22;
+ VMSTAT_NR_WRITEBACK_TEMP = 23;
+ VMSTAT_NR_ISOLATED_ANON = 24;
+ VMSTAT_NR_ISOLATED_FILE = 25;
+ VMSTAT_NR_SHMEM = 26;
+ VMSTAT_NR_DIRTIED = 27;
+ VMSTAT_NR_WRITTEN = 28;
+ VMSTAT_NR_PAGES_SCANNED = 29;
+ VMSTAT_WORKINGSET_REFAULT = 30;
+ VMSTAT_WORKINGSET_ACTIVATE = 31;
+ VMSTAT_WORKINGSET_NODERECLAIM = 32;
+ VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES = 33;
+ VMSTAT_NR_FREE_CMA = 34;
+ VMSTAT_NR_SWAPCACHE = 35;
+ VMSTAT_NR_DIRTY_THRESHOLD = 36;
+ VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD = 37;
+ VMSTAT_PGPGIN = 38;
+ VMSTAT_PGPGOUT = 39;
+ VMSTAT_PGPGOUTCLEAN = 40;
+ VMSTAT_PSWPIN = 41;
+ VMSTAT_PSWPOUT = 42;
+ VMSTAT_PGALLOC_DMA = 43;
+ VMSTAT_PGALLOC_NORMAL = 44;
+ VMSTAT_PGALLOC_MOVABLE = 45;
+ VMSTAT_PGFREE = 46;
+ VMSTAT_PGACTIVATE = 47;
+ VMSTAT_PGDEACTIVATE = 48;
+ VMSTAT_PGFAULT = 49;
+ VMSTAT_PGMAJFAULT = 50;
+ VMSTAT_PGREFILL_DMA = 51;
+ VMSTAT_PGREFILL_NORMAL = 52;
+ VMSTAT_PGREFILL_MOVABLE = 53;
+ VMSTAT_PGSTEAL_KSWAPD_DMA = 54;
+ VMSTAT_PGSTEAL_KSWAPD_NORMAL = 55;
+ VMSTAT_PGSTEAL_KSWAPD_MOVABLE = 56;
+ VMSTAT_PGSTEAL_DIRECT_DMA = 57;
+ VMSTAT_PGSTEAL_DIRECT_NORMAL = 58;
+ VMSTAT_PGSTEAL_DIRECT_MOVABLE = 59;
+ VMSTAT_PGSCAN_KSWAPD_DMA = 60;
+ VMSTAT_PGSCAN_KSWAPD_NORMAL = 61;
+ VMSTAT_PGSCAN_KSWAPD_MOVABLE = 62;
+ VMSTAT_PGSCAN_DIRECT_DMA = 63;
+ VMSTAT_PGSCAN_DIRECT_NORMAL = 64;
+ VMSTAT_PGSCAN_DIRECT_MOVABLE = 65;
+ VMSTAT_PGSCAN_DIRECT_THROTTLE = 66;
+ VMSTAT_PGINODESTEAL = 67;
+ VMSTAT_SLABS_SCANNED = 68;
+ VMSTAT_KSWAPD_INODESTEAL = 69;
+ VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY = 70;
+ VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY = 71;
+ VMSTAT_PAGEOUTRUN = 72;
+ VMSTAT_ALLOCSTALL = 73;
+ VMSTAT_PGROTATED = 74;
+ VMSTAT_DROP_PAGECACHE = 75;
+ VMSTAT_DROP_SLAB = 76;
+ VMSTAT_PGMIGRATE_SUCCESS = 77;
+ VMSTAT_PGMIGRATE_FAIL = 78;
+ VMSTAT_COMPACT_MIGRATE_SCANNED = 79;
+ VMSTAT_COMPACT_FREE_SCANNED = 80;
+ VMSTAT_COMPACT_ISOLATED = 81;
+ VMSTAT_COMPACT_STALL = 82;
+ VMSTAT_COMPACT_FAIL = 83;
+ VMSTAT_COMPACT_SUCCESS = 84;
+ VMSTAT_COMPACT_DAEMON_WAKE = 85;
+ VMSTAT_UNEVICTABLE_PGS_CULLED = 86;
+ VMSTAT_UNEVICTABLE_PGS_SCANNED = 87;
+ VMSTAT_UNEVICTABLE_PGS_RESCUED = 88;
+ VMSTAT_UNEVICTABLE_PGS_MLOCKED = 89;
+ VMSTAT_UNEVICTABLE_PGS_MUNLOCKED = 90;
+ VMSTAT_UNEVICTABLE_PGS_CLEARED = 91;
+ VMSTAT_UNEVICTABLE_PGS_STRANDED = 92;
+}
+// End of protos/perfetto/common/sys_stats_counters.proto
+
// Begin of protos/perfetto/trace/trace.proto
message Trace {
@@ -30,14 +171,19 @@
// The root object emitted by Perfetto. A perfetto trace is just a stream of
// TracePacket(s).
//
-// Next id: 7.
+// Next id: 9.
message TracePacket {
+ // TODO: in future we should add a timestamp_clock_domain field to
+ // allow mixing timestamps from different clock domains.
+ optional uint64 timestamp = 8; // Timestamp [ns].
+
oneof data {
FtraceEventBundle ftrace_events = 1;
ProcessTree process_tree = 2;
InodeFileMap inode_file_map = 4;
// removed field with id 5
- // removed field with id 6
+ ClockSnapshot clock_snapshot = 6;
+ SysStats sys_stats = 7;
// IDs up to 32 are reserved for events that are quite frequent because they
// take only one byte to encode their preamble.
@@ -55,6 +201,7 @@
// This field is only used for testing.
// removed field with id 536870911 // 2^29 - 1, max field id for protos.
}
+
// Trusted user id of the producer which generated this packet. Keep in sync
// with TrustedPacket.trusted_uid.
oneof optional_trusted_uid { int32 trusted_uid = 3; };
@@ -443,6 +590,86 @@
// End of protos/perfetto/trace/ps/process_tree.proto
+// Begin of protos/perfetto/trace/clock_snapshot.proto
+
+// A snapshot of clock readings to allow for trace alignment.
+message ClockSnapshot {
+ message Clock {
+ enum Type {
+ UNKNOWN = 0;
+ REALTIME = 1;
+ REALTIME_COARSE = 2;
+ MONOTONIC = 3;
+ MONOTONIC_COARSE = 4;
+ MONOTONIC_RAW = 5;
+ BOOTTIME = 6;
+ PROCESS_CPUTIME = 7;
+ THREAD_CPUTIME = 8;
+ }
+ optional Type type = 1;
+ optional uint64 timestamp = 2;
+ }
+ repeated Clock clocks = 1;
+}
+
+// End of protos/perfetto/trace/clock_snapshot.proto
+
+// Begin of protos/perfetto/trace/sys_stats/sys_stats.proto
+
+
+// Various Linux system stat counters from /proc.
+// The fields in this message can be reported at different rates and with
+// different granularity. See sys_stats_config.proto.
+message SysStats {
+ // Counters from /proc/meminfo. Values are in KB.
+ message MeminfoValue {
+ optional MeminfoCounters key = 1;
+ optional uint64 value = 2;
+ };
+ repeated MeminfoValue meminfo = 1;
+
+ // Counter from /proc/vmstat. Units are often pages, not KB.
+ message VmstatValue {
+ optional VmstatCounters key = 1;
+ optional uint64 value = 2;
+ };
+ repeated VmstatValue vmstat = 2;
+
+ // Times in each mode, since boot. Unit: nanoseconds.
+ message CpuTimes {
+ optional uint32 cpu_id = 1;
+ optional uint64 user_ns = 2; // Time spent in user mode.
+ optional uint64 user_ice_ns = 3; // Time spent in user mode (low prio).
+ optional uint64 system_mode_ns = 4; // Time spent in system mode.
+ optional uint64 idle_ns = 5; // Time spent in the idle task.
+ optional uint64 io_wait_ns = 6; // Time spent waiting for I/O.
+ optional uint64 irq_ns = 7; // Time spent servicing interrupts.
+ optional uint64 softirq_ns = 8; // Time spent servicing softirqs.
+ }
+ repeated CpuTimes cpu_stat = 3; // One entry per cpu.
+
+ // Num processes forked since boot.
+ // Populated only if FORK_COUNT in config.stat_counters.
+ optional uint64 num_forks = 4;
+
+ message InterruptCount {
+ optional int32 irq = 1;
+ optional uint64 count = 2;
+ }
+
+ // Number of interrupts, broken by IRQ number.
+ // Populated only if IRQ_COUNTS in config.stat_counters.
+ optional uint64 num_irq_total = 5; // Total num of irqs serviced since boot.
+ repeated InterruptCount num_irq = 6;
+
+ // Number of softirqs, broken by softirq number.
+ // Populated only if SOFTIRQ_COUNTS in config.stat_counters.
+ optional uint64 num_softirq_total = 7; // Total num of softirqs since boot.
+ repeated InterruptCount num_softirq = 8; // Per-softirq count.
+}
+
+// End of protos/perfetto/trace/sys_stats/sys_stats.proto
+
// Begin of protos/perfetto/trace/ftrace/print.proto
message PrintFtraceEvent {
diff --git a/protos/perfetto/trace/sys_stats/BUILD.gn b/protos/perfetto/trace/sys_stats/BUILD.gn
new file mode 100644
index 0000000..bb7f93b
--- /dev/null
+++ b/protos/perfetto/trace/sys_stats/BUILD.gn
@@ -0,0 +1,38 @@
+# 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.
+
+import("../../../../gn/perfetto.gni")
+import("../../../../src/protozero/protozero_library.gni")
+
+sys_stats_proto_names = [ "sys_stats.proto" ]
+
+proto_library("lite") {
+ generate_python = false
+ deps = [
+ "../../common:lite",
+ ]
+ sources = sys_stats_proto_names
+ proto_in_dir = "$perfetto_root_path/protos"
+ proto_out_dir = "$perfetto_root_path/protos"
+}
+
+protozero_library("zero") {
+ deps = [
+ "../../common:zero",
+ ]
+ sources = sys_stats_proto_names
+ proto_in_dir = "$perfetto_root_path/protos"
+ proto_out_dir = "$perfetto_root_path/protos"
+ generator_plugin_options = "wrapper_namespace=pbzero"
+}
diff --git a/protos/perfetto/trace/sys_stats/sys_stats.proto b/protos/perfetto/trace/sys_stats/sys_stats.proto
new file mode 100644
index 0000000..7b298bf
--- /dev/null
+++ b/protos/perfetto/trace/sys_stats/sys_stats.proto
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+package perfetto.protos;
+
+import "perfetto/common/sys_stats_counters.proto";
+
+// Various Linux system stat counters from /proc.
+// The fields in this message can be reported at different rates and with
+// different granularity. See sys_stats_config.proto.
+message SysStats {
+ // Counters from /proc/meminfo. Values are in KB.
+ message MeminfoValue {
+ optional MeminfoCounters key = 1;
+ optional uint64 value = 2;
+ };
+ repeated MeminfoValue meminfo = 1;
+
+ // Counter from /proc/vmstat. Units are often pages, not KB.
+ message VmstatValue {
+ optional VmstatCounters key = 1;
+ optional uint64 value = 2;
+ };
+ repeated VmstatValue vmstat = 2;
+
+ // Times in each mode, since boot. Unit: nanoseconds.
+ message CpuTimes {
+ optional uint32 cpu_id = 1;
+ optional uint64 user_ns = 2; // Time spent in user mode.
+ optional uint64 user_ice_ns = 3; // Time spent in user mode (low prio).
+ optional uint64 system_mode_ns = 4; // Time spent in system mode.
+ optional uint64 idle_ns = 5; // Time spent in the idle task.
+ optional uint64 io_wait_ns = 6; // Time spent waiting for I/O.
+ optional uint64 irq_ns = 7; // Time spent servicing interrupts.
+ optional uint64 softirq_ns = 8; // Time spent servicing softirqs.
+ }
+ repeated CpuTimes cpu_stat = 3; // One entry per cpu.
+
+ // Num processes forked since boot.
+ // Populated only if FORK_COUNT in config.stat_counters.
+ optional uint64 num_forks = 4;
+
+ message InterruptCount {
+ optional int32 irq = 1;
+ optional uint64 count = 2;
+ }
+
+ // Number of interrupts, broken by IRQ number.
+ // Populated only if IRQ_COUNTS in config.stat_counters.
+ optional uint64 num_irq_total = 5; // Total num of irqs serviced since boot.
+ repeated InterruptCount num_irq = 6;
+
+ // Number of softirqs, broken by softirq number.
+ // Populated only if SOFTIRQ_COUNTS in config.stat_counters.
+ optional uint64 num_softirq_total = 7; // Total num of softirqs since boot.
+ repeated InterruptCount num_softirq = 8; // Per-softirq count.
+}
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index 553ade2..e6fe149 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -24,6 +24,7 @@
import "perfetto/trace/ftrace/ftrace_event_bundle.proto";
import "perfetto/trace/ftrace/ftrace_stats.proto";
import "perfetto/trace/ps/process_tree.proto";
+import "perfetto/trace/sys_stats/sys_stats.proto";
import "perfetto/trace/test_event.proto";
import "perfetto/trace/trace_stats.proto";
@@ -32,14 +33,19 @@
// The root object emitted by Perfetto. A perfetto trace is just a stream of
// TracePacket(s).
//
-// Next id: 7.
+// Next id: 9.
message TracePacket {
+ // TODO(primiano): in future we should add a timestamp_clock_domain field to
+ // allow mixing timestamps from different clock domains.
+ optional uint64 timestamp = 8; // Timestamp [ns].
+
oneof data {
FtraceEventBundle ftrace_events = 1;
ProcessTree process_tree = 2;
InodeFileMap inode_file_map = 4;
ChromeEventBundle chrome_events = 5;
ClockSnapshot clock_snapshot = 6;
+ SysStats sys_stats = 7;
// IDs up to 32 are reserved for events that are quite frequent because they
// take only one byte to encode their preamble.
@@ -57,6 +63,7 @@
// This field is only used for testing.
TestEvent for_testing = 536870911; // 2^29 - 1, max field id for protos.
}
+
// Trusted user id of the producer which generated this packet. Keep in sync
// with TrustedPacket.trusted_uid.
oneof optional_trusted_uid { int32 trusted_uid = 3; };
diff --git a/src/perfetto_cmd/BUILD.gn b/src/perfetto_cmd/BUILD.gn
index 9e893e4..d71b1ed 100644
--- a/src/perfetto_cmd/BUILD.gn
+++ b/src/perfetto_cmd/BUILD.gn
@@ -22,7 +22,7 @@
]
deps = [
"../../gn:default_deps",
- "../../protos/perfetto/config",
+ "../../protos/perfetto/config:lite",
"../base",
"../protozero",
"../tracing:ipc_consumer",
diff --git a/src/protozero/scattered_stream_delegate_for_testing.cc b/src/protozero/scattered_stream_delegate_for_testing.cc
index 0409a06..ce474ff 100644
--- a/src/protozero/scattered_stream_delegate_for_testing.cc
+++ b/src/protozero/scattered_stream_delegate_for_testing.cc
@@ -38,23 +38,17 @@
return {begin, begin + chunk_size_};
}
-std::unique_ptr<uint8_t[]> ScatteredStreamDelegateForTesting::StitchChunks(
- size_t size) {
- std::unique_ptr<uint8_t[]> buffer =
- std::unique_ptr<uint8_t[]>(new uint8_t[size]);
- size_t remaining = size;
+std::vector<uint8_t> ScatteredStreamDelegateForTesting::StitchChunks() {
+ std::vector<uint8_t> buffer;
size_t i = 0;
for (const auto& chunk : chunks_) {
- size_t chunk_size = remaining;
- if (i < chunks_used_size_.size()) {
- chunk_size = chunks_used_size_[i];
- }
+ size_t chunk_size = (i < chunks_used_size_.size())
+ ? chunks_used_size_[i]
+ : (chunk_size_ - writer_->bytes_available());
PERFETTO_CHECK(chunk_size <= chunk_size_);
- memcpy(buffer.get() + size - remaining, chunk.get(), chunk_size);
- remaining -= chunk_size;
+ buffer.insert(buffer.end(), chunk.get(), chunk.get() + chunk_size);
i++;
}
-
return buffer;
}
diff --git a/src/protozero/scattered_stream_delegate_for_testing.h b/src/protozero/scattered_stream_delegate_for_testing.h
index 93b6874..365ad43 100644
--- a/src/protozero/scattered_stream_delegate_for_testing.h
+++ b/src/protozero/scattered_stream_delegate_for_testing.h
@@ -35,7 +35,7 @@
protozero::ContiguousMemoryRange GetNewBuffer() override;
// Stitch all the chunks into a single contiguous buffer.
- std::unique_ptr<uint8_t[]> StitchChunks(size_t size);
+ std::vector<uint8_t> StitchChunks();
const std::vector<std::unique_ptr<uint8_t[]>>& chunks() const {
return chunks_;
diff --git a/src/trace_processor/proto_trace_parser.cc b/src/trace_processor/proto_trace_parser.cc
index 8593a26..bf42b3f 100644
--- a/src/trace_processor/proto_trace_parser.cc
+++ b/src/trace_processor/proto_trace_parser.cc
@@ -16,6 +16,8 @@
#include "src/trace_processor/proto_trace_parser.h"
+#include <string.h>
+
#include <string>
#include "perfetto/base/logging.h"
@@ -86,7 +88,7 @@
out->name = base::StringView(s + name_index, name_length);
size_t value_index = name_index + name_length + 1;
char value_str[32];
- std::strcpy(value_str, s + value_index);
+ strcpy(value_str, s + value_index);
out->value = std::stod(value_str);
return true;
}
diff --git a/src/trace_processor/trace_storage.h b/src/trace_processor/trace_storage.h
index fe2651b..c462d19 100644
--- a/src/trace_processor/trace_storage.h
+++ b/src/trace_processor/trace_storage.h
@@ -220,7 +220,7 @@
}
Thread* GetMutableThread(UniqueTid utid) {
- PERFETTO_DCHECK(utid >= 0 && utid < unique_threads_.size());
+ PERFETTO_DCHECK(utid < unique_threads_.size());
return &unique_threads_[utid];
}
@@ -242,7 +242,7 @@
const Thread& GetThread(UniqueTid utid) const {
// Allow utid == 0 for idle thread retrieval.
- PERFETTO_DCHECK(utid >= 0 && utid < unique_threads_.size());
+ PERFETTO_DCHECK(utid < unique_threads_.size());
return unique_threads_[utid];
}
diff --git a/src/traced/probes/BUILD.gn b/src/traced/probes/BUILD.gn
index babc591..fd01252 100644
--- a/src/traced/probes/BUILD.gn
+++ b/src/traced/probes/BUILD.gn
@@ -40,6 +40,7 @@
"../../tracing:tracing",
"filesystem",
"ps",
+ "sys_stats",
]
sources = [
"probes_producer.cc",
@@ -69,5 +70,6 @@
"../../tracing:test_support",
"filesystem:unittests",
"ps:unittests",
+ "sys_stats:unittests",
]
}
diff --git a/src/traced/probes/ftrace/cpu_reader_unittest.cc b/src/traced/probes/ftrace/cpu_reader_unittest.cc
index 6938547..048eb41 100644
--- a/src/traced/probes/ftrace/cpu_reader_unittest.cc
+++ b/src/traced/probes/ftrace/cpu_reader_unittest.cc
@@ -88,10 +88,8 @@
// on success and nullptr on failure.
std::unique_ptr<ProtoT> ParseProto() {
auto bundle = std::unique_ptr<ProtoT>(new ProtoT());
- size_t msg_size =
- delegate_.chunks().size() * chunk_size_ - stream_.bytes_available();
- std::unique_ptr<uint8_t[]> buffer = delegate_.StitchChunks(msg_size);
- if (!bundle->ParseFromArray(buffer.get(), static_cast<int>(msg_size)))
+ std::vector<uint8_t> buffer = delegate_.StitchChunks();
+ if (!bundle->ParseFromArray(buffer.data(), static_cast<int>(buffer.size())))
return nullptr;
return bundle;
}
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index e56eb73..cc90242 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -50,6 +50,7 @@
constexpr char kFtraceSourceName[] = "linux.ftrace";
constexpr char kProcessStatsSourceName[] = "linux.process_stats";
constexpr char kInodeMapSourceName[] = "linux.inode_file_map";
+constexpr char kSysStatsSourceName[] = "linux.sys_stats";
} // namespace.
@@ -74,17 +75,29 @@
ResetConnectionBackoff();
PERFETTO_LOG("Connected to the service");
- DataSourceDescriptor ftrace_descriptor;
- ftrace_descriptor.set_name(kFtraceSourceName);
- endpoint_->RegisterDataSource(ftrace_descriptor);
+ {
+ DataSourceDescriptor desc;
+ desc.set_name(kFtraceSourceName);
+ endpoint_->RegisterDataSource(desc);
+ }
- DataSourceDescriptor process_stats_descriptor;
- process_stats_descriptor.set_name(kProcessStatsSourceName);
- endpoint_->RegisterDataSource(process_stats_descriptor);
+ {
+ DataSourceDescriptor desc;
+ desc.set_name(kProcessStatsSourceName);
+ endpoint_->RegisterDataSource(desc);
+ }
- DataSourceDescriptor inode_map_descriptor;
- inode_map_descriptor.set_name(kInodeMapSourceName);
- endpoint_->RegisterDataSource(inode_map_descriptor);
+ {
+ DataSourceDescriptor desc;
+ desc.set_name(kInodeMapSourceName);
+ endpoint_->RegisterDataSource(desc);
+ }
+
+ {
+ DataSourceDescriptor desc;
+ desc.set_name(kSysStatsSourceName);
+ endpoint_->RegisterDataSource(desc);
+ }
}
void ProbesProducer::OnDisconnect() {
@@ -129,6 +142,8 @@
data_source = CreateInodeFileDataSource(session_id, instance_id, config);
} else if (config.name() == kProcessStatsSourceName) {
data_source = CreateProcessStatsDataSource(session_id, instance_id, config);
+ } else if (config.name() == kSysStatsSourceName) {
+ data_source = CreateSysStatsDataSource(session_id, instance_id, config);
}
if (!data_source) {
@@ -214,6 +229,18 @@
return std::move(data_source);
}
+std::unique_ptr<SysStatsDataSource> ProbesProducer::CreateSysStatsDataSource(
+ TracingSessionID session_id,
+ DataSourceInstanceID id,
+ const DataSourceConfig& config) {
+ base::ignore_result(id);
+ auto buffer_id = static_cast<BufferID>(config.target_buffer());
+ auto data_source = std::unique_ptr<SysStatsDataSource>(
+ new SysStatsDataSource(task_runner_, session_id,
+ endpoint_->CreateTraceWriter(buffer_id), config));
+ return data_source;
+}
+
void ProbesProducer::TearDownDataSourceInstance(DataSourceInstanceID id) {
PERFETTO_LOG("Producer stop (id=%" PRIu64 ")", id);
auto it = data_sources_.find(id);
@@ -290,6 +317,8 @@
case ProcessStatsDataSource::kTypeId:
ps_data_source = static_cast<ProcessStatsDataSource*>(ds);
break;
+ case SysStatsDataSource::kTypeId:
+ break;
default:
PERFETTO_DCHECK(false);
} // switch (type_id)
diff --git a/src/traced/probes/probes_producer.h b/src/traced/probes/probes_producer.h
index 46e0f57..c3670ce 100644
--- a/src/traced/probes/probes_producer.h
+++ b/src/traced/probes/probes_producer.h
@@ -31,6 +31,7 @@
#include "src/traced/probes/ftrace/ftrace_controller.h"
#include "src/traced/probes/ftrace/ftrace_metadata.h"
#include "src/traced/probes/ps/process_stats_data_source.h"
+#include "src/traced/probes/sys_stats/sys_stats_data_source.h"
#include "perfetto/trace/filesystem/inode_file_map.pbzero.h"
@@ -74,6 +75,10 @@
TracingSessionID session_id,
DataSourceInstanceID id,
DataSourceConfig config);
+ std::unique_ptr<SysStatsDataSource> CreateSysStatsDataSource(
+ TracingSessionID session_id,
+ DataSourceInstanceID id,
+ const DataSourceConfig& config);
private:
enum State {
diff --git a/src/traced/probes/sys_stats/BUILD.gn b/src/traced/probes/sys_stats/BUILD.gn
new file mode 100644
index 0000000..16ae4e0
--- /dev/null
+++ b/src/traced/probes/sys_stats/BUILD.gn
@@ -0,0 +1,48 @@
+# 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.
+
+source_set("sys_stats") {
+ public_deps = [
+ "../../../tracing",
+ ]
+ deps = [
+ "..:data_source",
+ "../../../../gn:default_deps",
+ "../../../../include/perfetto/traced",
+ "../../../../include/perfetto/traced:sys_stats_counters",
+ "../../../../protos/perfetto/config:lite",
+ "../../../../protos/perfetto/trace/sys_stats:zero",
+ "../../../base",
+ ]
+ sources = [
+ "sys_stats_data_source.cc",
+ "sys_stats_data_source.h",
+ ]
+}
+
+source_set("unittests") {
+ testonly = true
+ deps = [
+ ":sys_stats",
+ "../../../../gn:default_deps",
+ "../../../../gn:gtest_deps",
+ "../../../../protos/perfetto/config:lite",
+ "../../../../protos/perfetto/trace:lite",
+ "../../../../src/base:test_support",
+ "../../../../src/tracing:test_support",
+ ]
+ sources = [
+ "sys_stats_data_source_unittest.cc",
+ ]
+}
diff --git a/src/traced/probes/sys_stats/sys_stats_data_source.cc b/src/traced/probes/sys_stats/sys_stats_data_source.cc
new file mode 100644
index 0000000..ebc3733
--- /dev/null
+++ b/src/traced/probes/sys_stats/sys_stats_data_source.cc
@@ -0,0 +1,304 @@
+/*
+ * 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/traced/probes/sys_stats/sys_stats_data_source.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <array>
+#include <limits>
+#include <utility>
+
+#include "perfetto/base/file_utils.h"
+#include "perfetto/base/metatrace.h"
+#include "perfetto/base/scoped_file.h"
+#include "perfetto/base/string_splitter.h"
+#include "perfetto/base/task_runner.h"
+#include "perfetto/base/time.h"
+#include "perfetto/base/utils.h"
+#include "perfetto/traced/sys_stats_counters.h"
+#include "perfetto/tracing/core/sys_stats_config.h"
+
+#include "perfetto/common/sys_stats_counters.pbzero.h"
+#include "perfetto/config/sys_stats/sys_stats_config.pb.h"
+#include "perfetto/trace/sys_stats/sys_stats.pbzero.h"
+#include "perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+
+namespace {
+constexpr size_t kReadBufSize = 1024 * 16;
+
+base::ScopedFile OpenReadOnly(const char* path) {
+ base::ScopedFile fd;
+ fd.reset(open(path, O_RDONLY | O_CLOEXEC));
+ if (!fd)
+ PERFETTO_PLOG("Failed opening %s", path);
+ return fd;
+}
+
+} // namespace
+
+// static
+constexpr int SysStatsDataSource::kTypeId;
+
+SysStatsDataSource::SysStatsDataSource(base::TaskRunner* task_runner,
+ TracingSessionID session_id,
+ std::unique_ptr<TraceWriter> writer,
+ const DataSourceConfig& ds_config,
+ OpenFunction open_fn)
+ : ProbesDataSource(session_id, kTypeId),
+ task_runner_(task_runner),
+ writer_(std::move(writer)),
+ weak_factory_(this) {
+ const auto& config = ds_config.sys_stats_config();
+
+ ns_per_user_hz_ = 1000000000ull / static_cast<uint64_t>(sysconf(_SC_CLK_TCK));
+
+ open_fn = open_fn ? open_fn : OpenReadOnly;
+ meminfo_fd_ = open_fn("/proc/meminfo");
+ vmstat_fd_ = open_fn("/proc/vmstat");
+ stat_fd_ = open_fn("/proc/stat");
+
+ read_buf_ = base::PageAllocator::Allocate(kReadBufSize);
+
+ // Build a lookup map that allows to quickly translate strings like "MemTotal"
+ // into the corresponding enum value, only for the counters enabled in the
+ // config.
+ for (const auto& counter_id : config.meminfo_counters()) {
+ for (size_t i = 0; i < base::ArraySize(kMeminfoKeys); i++) {
+ const auto& k = kMeminfoKeys[i];
+ if (static_cast<int>(k.id) == static_cast<int>(counter_id))
+ meminfo_counters_.emplace(k.str, k.id);
+ }
+ }
+
+ for (const auto& counter_id : config.vmstat_counters()) {
+ for (size_t i = 0; i < base::ArraySize(kVmstatKeys); i++) {
+ const auto& k = kVmstatKeys[i];
+ if (static_cast<int>(k.id) == static_cast<int>(counter_id))
+ vmstat_counters_.emplace(k.str, k.id);
+ }
+ }
+
+ for (const auto& counter_id : config.stat_counters()) {
+ stat_enabled_fields_ |= 1 << counter_id;
+ }
+
+ std::array<uint32_t, 3> periods_ms{};
+ std::array<uint32_t, 3> ticks{};
+ static_assert(periods_ms.size() == ticks.size(), "must have same size");
+ periods_ms[0] = config.meminfo_period_ms();
+ periods_ms[1] = config.vmstat_period_ms();
+ periods_ms[2] = config.stat_period_ms();
+ tick_period_ms_ = 0;
+ for (uint32_t ms : periods_ms) {
+ if (ms && (ms < tick_period_ms_ || tick_period_ms_ == 0))
+ tick_period_ms_ = ms;
+ }
+ if (tick_period_ms_ == 0)
+ return; // No polling configured.
+
+ for (size_t i = 0; i < periods_ms.size(); i++) {
+ auto ms = periods_ms[i];
+ if (ms && ms % tick_period_ms_ != 0) {
+ PERFETTO_ELOG("SysStat periods are not integer multiples of each other");
+ return;
+ }
+ ticks[i] = ms / tick_period_ms_;
+ }
+ meminfo_ticks_ = ticks[0];
+ vmstat_ticks_ = ticks[1];
+ stat_ticks_ = ticks[2];
+ auto weak_this = GetWeakPtr();
+ task_runner_->PostTask(std::bind(&SysStatsDataSource::Tick, weak_this));
+}
+
+// static
+void SysStatsDataSource::Tick(base::WeakPtr<SysStatsDataSource> weak_this) {
+ if (!weak_this)
+ return;
+ SysStatsDataSource& thiz = *weak_this;
+
+ uint32_t period_ms = thiz.tick_period_ms_;
+ uint32_t delay_ms = period_ms - (base::GetWallTimeMs().count() % period_ms);
+ thiz.task_runner_->PostDelayedTask(
+ std::bind(&SysStatsDataSource::Tick, weak_this), delay_ms);
+ thiz.ReadSysStats();
+}
+
+SysStatsDataSource::~SysStatsDataSource() = default;
+
+void SysStatsDataSource::ReadSysStats() {
+ PERFETTO_METATRACE("ReadSysStats", 0);
+ auto packet = writer_->NewTracePacket();
+
+ packet->set_timestamp(static_cast<uint64_t>(base::GetBootTimeNs().count()));
+ auto* sys_stats = packet->set_sys_stats();
+
+ if (meminfo_ticks_ && tick_ % meminfo_ticks_ == 0)
+ ReadMeminfo(sys_stats);
+
+ if (vmstat_ticks_ && tick_ % vmstat_ticks_ == 0)
+ ReadVmstat(sys_stats);
+
+ if (stat_ticks_ && tick_ % stat_ticks_ == 0)
+ ReadStat(sys_stats);
+
+ tick_++;
+}
+
+void SysStatsDataSource::ReadMeminfo(protos::pbzero::SysStats* sys_stats) {
+ size_t rsize = ReadFile(&meminfo_fd_, "/proc/meminfo");
+ if (!rsize)
+ return;
+ char* buf = static_cast<char*>(read_buf_.get());
+ for (base::StringSplitter lines(buf, rsize, '\n'); lines.Next();) {
+ base::StringSplitter words(&lines, ' ');
+ if (!words.Next())
+ continue;
+ // Extract the meminfo key, dropping trailing ':' (e.g., "MemTotal: NN KB").
+ words.cur_token()[words.cur_token_size() - 1] = '\0';
+ auto it = meminfo_counters_.find(words.cur_token());
+ if (it == meminfo_counters_.end())
+ continue;
+ int counter_id = it->second;
+ if (!words.Next())
+ continue;
+ auto value = static_cast<uint64_t>(strtoll(words.cur_token(), nullptr, 10));
+ auto* meminfo = sys_stats->add_meminfo();
+ meminfo->set_key(static_cast<protos::pbzero::MeminfoCounters>(counter_id));
+ meminfo->set_value(value);
+ }
+}
+
+void SysStatsDataSource::ReadVmstat(protos::pbzero::SysStats* sys_stats) {
+ size_t rsize = ReadFile(&vmstat_fd_, "/proc/vmstat");
+ if (!rsize)
+ return;
+ char* buf = static_cast<char*>(read_buf_.get());
+ for (base::StringSplitter lines(buf, rsize, '\n'); lines.Next();) {
+ base::StringSplitter words(&lines, ' ');
+ if (!words.Next())
+ continue;
+ auto it = vmstat_counters_.find(words.cur_token());
+ if (it == vmstat_counters_.end())
+ continue;
+ int counter_id = it->second;
+ if (!words.Next())
+ continue;
+ auto value = static_cast<uint64_t>(strtoll(words.cur_token(), nullptr, 10));
+ auto* vmstat = sys_stats->add_vmstat();
+ vmstat->set_key(static_cast<protos::pbzero::VmstatCounters>(counter_id));
+ vmstat->set_value(value);
+ }
+}
+
+void SysStatsDataSource::ReadStat(protos::pbzero::SysStats* sys_stats) {
+ size_t rsize = ReadFile(&stat_fd_, "/proc/stat");
+ if (!rsize)
+ return;
+ char* buf = static_cast<char*>(read_buf_.get());
+ for (base::StringSplitter lines(buf, rsize, '\n'); lines.Next();) {
+ base::StringSplitter words(&lines, ' ');
+ if (!words.Next())
+ continue;
+
+ // Per-CPU stats.
+ if ((stat_enabled_fields_ & (1 << SysStatsConfig::STAT_CPU_TIMES)) &&
+ words.cur_token_size() > 3 && !strncmp(words.cur_token(), "cpu", 3)) {
+ long cpu_id = strtol(words.cur_token() + 3, nullptr, 10);
+ std::array<uint64_t, 7> cpu_times{};
+ for (size_t i = 0; i < cpu_times.size() && words.Next(); i++) {
+ cpu_times[i] =
+ static_cast<uint64_t>(strtoll(words.cur_token(), nullptr, 10));
+ }
+ auto* cpu_stat = sys_stats->add_cpu_stat();
+ cpu_stat->set_cpu_id(static_cast<uint32_t>(cpu_id));
+ cpu_stat->set_user_ns(cpu_times[0] * ns_per_user_hz_);
+ cpu_stat->set_user_ice_ns(cpu_times[1] * ns_per_user_hz_);
+ cpu_stat->set_system_mode_ns(cpu_times[2] * ns_per_user_hz_);
+ cpu_stat->set_idle_ns(cpu_times[3] * ns_per_user_hz_);
+ cpu_stat->set_io_wait_ns(cpu_times[4] * ns_per_user_hz_);
+ cpu_stat->set_irq_ns(cpu_times[5] * ns_per_user_hz_);
+ cpu_stat->set_softirq_ns(cpu_times[6] * ns_per_user_hz_);
+ }
+ // IRQ counters
+ else if ((stat_enabled_fields_ & (1 << SysStatsConfig::STAT_IRQ_COUNTS)) &&
+ !strcmp(words.cur_token(), "intr")) {
+ for (size_t i = 0; words.Next(); i++) {
+ auto v = static_cast<uint64_t>(strtoll(words.cur_token(), nullptr, 10));
+ if (i == 0) {
+ sys_stats->set_num_irq_total(v);
+ } else {
+ auto* irq_stat = sys_stats->add_num_irq();
+ irq_stat->set_irq(static_cast<int32_t>(i - 1));
+ irq_stat->set_count(v);
+ }
+ }
+ }
+ // Softirq counters.
+ else if ((stat_enabled_fields_ &
+ (1 << SysStatsConfig::STAT_SOFTIRQ_COUNTS)) &&
+ !strcmp(words.cur_token(), "softirq")) {
+ for (size_t i = 0; words.Next(); i++) {
+ auto v = static_cast<uint64_t>(strtoll(words.cur_token(), nullptr, 10));
+ if (i == 0) {
+ sys_stats->set_num_softirq_total(v);
+ } else {
+ auto* softirq_stat = sys_stats->add_num_softirq();
+ softirq_stat->set_irq(static_cast<int32_t>(i - 1));
+ softirq_stat->set_count(v);
+ }
+ }
+ }
+ // Number of forked processes since boot.
+ else if ((stat_enabled_fields_ & (1 << SysStatsConfig::STAT_FORK_COUNT)) &&
+ !strcmp(words.cur_token(), "processes")) {
+ if (words.Next()) {
+ sys_stats->set_num_forks(
+ static_cast<uint64_t>(strtoll(words.cur_token(), nullptr, 10)));
+ }
+ }
+
+ } // for (line)
+}
+
+base::WeakPtr<SysStatsDataSource> SysStatsDataSource::GetWeakPtr() const {
+ return weak_factory_.GetWeakPtr();
+}
+
+void SysStatsDataSource::Flush() {
+ writer_->Flush();
+}
+
+size_t SysStatsDataSource::ReadFile(base::ScopedFile* fd, const char* path) {
+ if (!*fd)
+ return 0;
+ ssize_t res = pread(**fd, read_buf_.get(), kReadBufSize - 1, 0);
+ if (res <= 0) {
+ PERFETTO_PLOG("Failed reading %s", path);
+ fd->reset();
+ return 0;
+ }
+ size_t rsize = static_cast<size_t>(res);
+ static_cast<char*>(read_buf_.get())[rsize] = '\0';
+ return rsize + 1; // Include null terminator in the count.
+}
+
+} // namespace perfetto
diff --git a/src/traced/probes/sys_stats/sys_stats_data_source.h b/src/traced/probes/sys_stats/sys_stats_data_source.h
new file mode 100644
index 0000000..a5ea4f7
--- /dev/null
+++ b/src/traced/probes/sys_stats/sys_stats_data_source.h
@@ -0,0 +1,104 @@
+/*
+ * 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_TRACED_PROBES_SYS_STATS_SYS_STATS_DATA_SOURCE_H_
+#define SRC_TRACED_PROBES_SYS_STATS_SYS_STATS_DATA_SOURCE_H_
+
+#include <string.h>
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "perfetto/base/page_allocator.h"
+#include "perfetto/base/scoped_file.h"
+#include "perfetto/base/weak_ptr.h"
+#include "perfetto/tracing/core/basic_types.h"
+#include "perfetto/tracing/core/data_source_config.h"
+#include "perfetto/tracing/core/trace_writer.h"
+#include "src/traced/probes/probes_data_source.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}
+
+namespace protos {
+namespace pbzero {
+class SysStats;
+}
+} // namespace protos
+
+class SysStatsDataSource : public ProbesDataSource {
+ public:
+ static constexpr int kTypeId = 4;
+ using OpenFunction = base::ScopedFile (*)(const char*);
+ SysStatsDataSource(base::TaskRunner*,
+ TracingSessionID,
+ std::unique_ptr<TraceWriter> writer,
+ const DataSourceConfig&,
+ OpenFunction = nullptr);
+ ~SysStatsDataSource() override;
+
+ // ProbesDataSource implementation.
+ void Flush() override;
+
+ base::WeakPtr<SysStatsDataSource> GetWeakPtr() const;
+
+ void set_ns_per_user_hz_for_testing(uint64_t ns) { ns_per_user_hz_ = ns; }
+ uint32_t tick_for_testing() const { return tick_; }
+
+ private:
+ struct CStrCmp {
+ bool operator()(const char* a, const char* b) const {
+ return strcmp(a, b) < 0;
+ }
+ };
+
+ static void Tick(base::WeakPtr<SysStatsDataSource>);
+
+ SysStatsDataSource(const SysStatsDataSource&) = delete;
+ SysStatsDataSource& operator=(const SysStatsDataSource&) = delete;
+ void ReadSysStats(); // Virtual for testing.
+ void ReadMeminfo(protos::pbzero::SysStats* sys_stats);
+ void ReadVmstat(protos::pbzero::SysStats* sys_stats);
+ void ReadStat(protos::pbzero::SysStats* sys_stats);
+ size_t ReadFile(base::ScopedFile*, const char* path);
+
+ base::TaskRunner* const task_runner_;
+ std::unique_ptr<TraceWriter> writer_;
+ base::ScopedFile meminfo_fd_;
+ base::ScopedFile vmstat_fd_;
+ base::ScopedFile stat_fd_;
+ base::PageAllocator::UniquePtr read_buf_;
+ TraceWriter::TracePacketHandle cur_packet_;
+ std::map<const char*, int, CStrCmp> meminfo_counters_;
+ std::map<const char*, int, CStrCmp> vmstat_counters_;
+ uint64_t ns_per_user_hz_ = 0;
+ uint32_t tick_ = 0;
+ uint32_t tick_period_ms_ = 0;
+ uint32_t meminfo_ticks_ = 0;
+ uint32_t vmstat_ticks_ = 0;
+ uint32_t stat_ticks_ = 0;
+ uint32_t stat_enabled_fields_ = 0;
+
+ base::WeakPtrFactory<SysStatsDataSource> weak_factory_; // Keep last.
+};
+
+} // namespace perfetto
+
+#endif // SRC_TRACED_PROBES_SYS_STATS_SYS_STATS_DATA_SOURCE_H_
diff --git a/src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc b/src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc
new file mode 100644
index 0000000..e2c18d9
--- /dev/null
+++ b/src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc
@@ -0,0 +1,370 @@
+/*
+ * 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 <unistd.h>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "perfetto/base/temp_file.h"
+#include "src/base/test/test_task_runner.h"
+#include "src/traced/probes/sys_stats/sys_stats_data_source.h"
+#include "src/tracing/core/trace_writer_for_testing.h"
+
+#include "perfetto/config/sys_stats/sys_stats_config.pb.h"
+#include "perfetto/trace/trace_packet.pb.h"
+#include "perfetto/trace/trace_packet.pbzero.h"
+
+using ::testing::_;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::UnorderedElementsAre;
+
+namespace perfetto {
+namespace {
+
+const char kMockMeminfo[] = R"(
+MemTotal: 3744240 kB
+MemFree: 73328 kB
+MemAvailable: 629896 kB
+Buffers: 19296 kB
+Cached: 731032 kB
+SwapCached: 4936 kB
+Active: 1616348 kB
+Inactive: 745492 kB
+Active(anon): 1322636 kB
+Inactive(anon): 449172 kB
+Active(file): 293712 kB
+Inactive(file): 296320 kB
+Unevictable: 142152 kB
+Mlocked: 142152 kB
+SwapTotal: 524284 kB
+SwapFree: 128 kB
+Dirty: 0 kB
+Writeback: 0 kB
+AnonPages: 1751140 kB
+Mapped: 508372 kB
+Shmem: 18604 kB
+Slab: 240352 kB
+SReclaimable: 64684 kB
+SUnreclaim: 175668 kB
+KernelStack: 62672 kB
+PageTables: 70108 kB
+NFS_Unstable: 0 kB
+Bounce: 0 kB
+WritebackTmp: 0 kB
+CommitLimit: 2396404 kB
+Committed_AS: 81911488 kB
+VmallocTotal: 258867136 kB
+VmallocUsed: 0 kB
+VmallocChunk: 0 kB
+CmaTotal: 196608 kB
+CmaFree: 60 kB)";
+
+const char kMockVmstat[] = R"(
+nr_free_pages 16449
+nr_alloc_batch 79
+nr_inactive_anon 112545
+nr_active_anon 322027
+nr_inactive_file 75904
+nr_active_file 87939
+nr_unevictable 35538
+nr_mlock 35538
+nr_anon_pages 429005
+nr_mapped 125844
+nr_file_pages 205523
+nr_dirty 23
+nr_writeback 0
+nr_slab_reclaimable 15840
+nr_slab_unreclaimable 43912
+nr_page_table_pages 17158
+nr_kernel_stack 3822
+nr_overhead 0
+nr_unstable 0
+nr_bounce 0
+nr_vmscan_write 558690
+nr_vmscan_immediate_reclaim 14853
+nr_writeback_temp 0
+nr_isolated_anon 0
+nr_isolated_file 0
+nr_shmem 5027
+nr_dirtied 6732417
+nr_written 6945513
+nr_pages_scanned 0
+workingset_refault 32784684
+workingset_activate 8200928
+workingset_nodereclaim 0
+nr_anon_transparent_hugepages 0
+nr_free_cma 0
+nr_swapcache 1254
+nr_dirty_threshold 33922
+nr_dirty_background_threshold 8449
+pgpgin 161257156
+pgpgout 35973852
+pgpgoutclean 37181384
+pswpin 185308
+pswpout 557662
+pgalloc_dma 79259070
+pgalloc_normal 88265512
+pgalloc_movable 0
+pgfree 175051592
+pgactivate 11897892
+pgdeactivate 20412230
+pgfault 181696234
+pgmajfault 1060871
+pgrefill_dma 12970047
+pgrefill_normal 14391564
+pgrefill_movable 0
+pgsteal_kswapd_dma 19471476
+pgsteal_kswapd_normal 21138380
+pgsteal_kswapd_movable 0
+pgsteal_direct_dma 40625
+pgsteal_direct_normal 50912
+pgsteal_direct_movable 0
+pgscan_kswapd_dma 23544417
+pgscan_kswapd_normal 25623715
+pgscan_kswapd_movable 0
+pgscan_direct_dma 50369
+pgscan_direct_normal 66284
+pgscan_direct_movable 0
+pgscan_direct_throttle 0
+pginodesteal 0
+slabs_scanned 39582828
+kswapd_inodesteal 110199
+kswapd_low_wmark_hit_quickly 21321
+kswapd_high_wmark_hit_quickly 4112
+pageoutrun 37666
+allocstall 1587
+pgrotated 12086
+drop_pagecache 0
+drop_slab 0
+pgmigrate_success 5923482
+pgmigrate_fail 3439
+compact_migrate_scanned 92906456
+compact_free_scanned 467077168
+compact_isolated 13456528
+compact_stall 197
+compact_fail 42
+compact_success 155
+compact_daemon_wake 2131
+unevictable_pgs_culled 50170
+unevictable_pgs_scanned 0
+unevictable_pgs_rescued 14640
+unevictable_pgs_mlocked 52520
+unevictable_pgs_munlocked 14640
+unevictable_pgs_cleared 2342
+unevictable_pgs_stranded 2342)";
+
+const char kMockStat[] = R"(
+cpu 2655987 822682 2352153 8801203 41917 322733 175055 0 0 0
+cpu0 762178 198125 902284 8678856 41716 152974 68262 0 0 0
+cpu1 613833 243394 504323 15194 96 60625 28785 0 0 0
+cpu2 207349 95060 248856 17351 42 32148 26108 0 0 0
+cpu3 138474 92158 174852 17537 48 25076 25035 0 0 0
+cpu4 278720 34689 141048 18117 1 20782 5873 0 0 0
+cpu5 235376 33907 85098 18278 2 10049 3774 0 0 0
+cpu6 239568 67149 155814 17890 5 11518 3807 0 0 0
+cpu7 180484 58196 139874 17975 3 9556 13407 0 0 0
+intr 238128517 0 0 0 63500984 0 6253792 6 4 5 0 0 0 0 0 0 0 160331 0 0 14 0 0 0 0 0 0 0 0 0 0 0 20430 2279 11 11 83272 0 0 0 0 0 0 0 5754 220829 0 154753 908545 1824602 7314228 0 0 0 6898259 0 0 10 0 0 2 0 0 0 0 0 0 0 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 575816 1447531 134022 0 0 0 0 0 435008 319921 2755476 0 0 0 0 91 310212 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 4 0 0 545 901 554 9 3377 4184 12 10 588851 0 2 1109045 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 8 0 0 0 0 0 0 0 0 0 0 0 0 497 0 0 0 0 0 26172 0 0 0 0 0 0 0 1362 0 0 0 0 0 0 0 424 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 23427 0 0 0 0 1 1298 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 108 0 0 0 0 86 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1784935 407979 2140 10562241 52374 74699 6976 84926 222 169088 0 0 0 0 174 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2789 51543 0 83 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 8 0 13 11 17 1393 0 0 0 0 0 0 0 0 0 0 26 0 0 2 106 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11150 0 13 0 1 390 6 0 6 4 0 0 0 0 352 284743 2 0 0 24 3 0 3 0 0 0 12 0 668788 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 680 0 0
+ctxt 373122860
+btime 1536912218
+processes 243320
+procs_running 1
+procs_blocked 0
+softirq 84611084 10220177 28299167 155083 3035679 6390543 66234 4396819 15604187 0 16443195)";
+
+base::ScopedFile MockOpenReadOnly(const char* path) {
+ base::TempFile tmp_ = base::TempFile::CreateUnlinked();
+ if (!strcmp(path, "/proc/meminfo")) {
+ EXPECT_GT(pwrite(tmp_.fd(), kMockMeminfo, strlen(kMockMeminfo), 0), 0);
+ } else if (!strcmp(path, "/proc/vmstat")) {
+ EXPECT_GT(pwrite(tmp_.fd(), kMockVmstat, strlen(kMockVmstat), 0), 0);
+ } else if (!strcmp(path, "/proc/stat")) {
+ EXPECT_GT(pwrite(tmp_.fd(), kMockStat, strlen(kMockStat), 0), 0);
+ } else {
+ PERFETTO_FATAL("Unexpected file opened %s", path);
+ }
+ return tmp_.ReleaseFD();
+}
+
+class SysStatsDataSourceTest : public ::testing::Test {
+ protected:
+ std::unique_ptr<SysStatsDataSource> GetSysStatsDataSource(
+ const DataSourceConfig& cfg) {
+ auto writer =
+ std::unique_ptr<TraceWriterForTesting>(new TraceWriterForTesting());
+ writer_raw_ = writer.get();
+ auto instance = std::unique_ptr<SysStatsDataSource>(new SysStatsDataSource(
+ &task_runner_, 0, std::move(writer), cfg, MockOpenReadOnly));
+ instance->set_ns_per_user_hz_for_testing(1000000000ull / 100); // 100 Hz.
+ return instance;
+ }
+
+ void Poller(SysStatsDataSource* ds, std::function<void()> checkpoint) {
+ if (ds->tick_for_testing())
+ checkpoint();
+ else
+ task_runner_.PostDelayedTask(
+ [ds, checkpoint, this] { Poller(ds, checkpoint); }, 1);
+ }
+
+ void WaitTick(SysStatsDataSource* data_source) {
+ auto checkpoint = task_runner_.CreateCheckpoint("on_tick");
+ Poller(data_source, checkpoint);
+ task_runner_.RunUntilCheckpoint("on_tick");
+ }
+
+ TraceWriterForTesting* writer_raw_ = nullptr;
+ base::TestTaskRunner task_runner_;
+};
+
+TEST_F(SysStatsDataSourceTest, Meminfo) {
+ using C = protos::MeminfoCounters;
+ protos::DataSourceConfig config;
+ config.mutable_sys_stats_config()->set_meminfo_period_ms(1);
+ config.mutable_sys_stats_config()->add_meminfo_counters(C::MEMINFO_MEM_TOTAL);
+ config.mutable_sys_stats_config()->add_meminfo_counters(C::MEMINFO_MEM_FREE);
+ config.mutable_sys_stats_config()->add_meminfo_counters(
+ C::MEMINFO_ACTIVE_ANON);
+ config.mutable_sys_stats_config()->add_meminfo_counters(
+ C::MEMINFO_INACTIVE_FILE);
+ config.mutable_sys_stats_config()->add_meminfo_counters(C::MEMINFO_CMA_FREE);
+ DataSourceConfig config_obj;
+ config_obj.FromProto(config);
+ auto data_source = GetSysStatsDataSource(config_obj);
+
+ WaitTick(data_source.get());
+
+ std::unique_ptr<protos::TracePacket> packet = writer_raw_->ParseProto();
+ ASSERT_TRUE(packet->has_sys_stats());
+ const auto& sys_stats = packet->sys_stats();
+ EXPECT_EQ(sys_stats.vmstat_size(), 0);
+ EXPECT_EQ(sys_stats.cpu_stat_size(), 0);
+
+ using KV = std::pair<int, uint64_t>;
+ std::vector<KV> kvs;
+ for (const auto& kv : sys_stats.meminfo())
+ kvs.push_back({kv.key(), kv.value()});
+
+ EXPECT_THAT(kvs,
+ UnorderedElementsAre(KV{C::MEMINFO_MEM_TOTAL, 3744240}, //
+ KV{C::MEMINFO_MEM_FREE, 73328}, //
+ KV{C::MEMINFO_ACTIVE_ANON, 1322636}, //
+ KV{C::MEMINFO_INACTIVE_FILE, 296320}, //
+ KV{C::MEMINFO_CMA_FREE, 60}));
+}
+
+TEST_F(SysStatsDataSourceTest, Vmstat) {
+ using C = protos::VmstatCounters;
+ protos::DataSourceConfig config;
+ config.mutable_sys_stats_config()->set_vmstat_period_ms(1);
+ config.mutable_sys_stats_config()->add_vmstat_counters(
+ C::VMSTAT_NR_FREE_PAGES);
+ config.mutable_sys_stats_config()->add_vmstat_counters(C::VMSTAT_PGACTIVATE);
+ config.mutable_sys_stats_config()->add_vmstat_counters(
+ C::VMSTAT_PGMIGRATE_FAIL);
+ DataSourceConfig config_obj;
+ config_obj.FromProto(config);
+ auto data_source = GetSysStatsDataSource(config_obj);
+
+ WaitTick(data_source.get());
+
+ std::unique_ptr<protos::TracePacket> packet = writer_raw_->ParseProto();
+ ASSERT_TRUE(packet->has_sys_stats());
+ const auto& sys_stats = packet->sys_stats();
+ EXPECT_EQ(sys_stats.meminfo_size(), 0);
+ EXPECT_EQ(sys_stats.cpu_stat_size(), 0);
+
+ using KV = std::pair<int, uint64_t>;
+ std::vector<KV> kvs;
+ for (const auto& kv : sys_stats.vmstat())
+ kvs.push_back({kv.key(), kv.value()});
+
+ EXPECT_THAT(kvs, UnorderedElementsAre(KV{C::VMSTAT_NR_FREE_PAGES, 16449}, //
+ KV{C::VMSTAT_PGACTIVATE, 11897892}, //
+ KV{C::VMSTAT_PGMIGRATE_FAIL, 3439}));
+}
+
+TEST_F(SysStatsDataSourceTest, StatAll) {
+ using C = protos::SysStatsConfig;
+ protos::DataSourceConfig config;
+ config.mutable_sys_stats_config()->set_stat_period_ms(1);
+ config.mutable_sys_stats_config()->add_stat_counters(C::STAT_CPU_TIMES);
+ config.mutable_sys_stats_config()->add_stat_counters(C::STAT_IRQ_COUNTS);
+ config.mutable_sys_stats_config()->add_stat_counters(C::STAT_SOFTIRQ_COUNTS);
+ config.mutable_sys_stats_config()->add_stat_counters(C::STAT_FORK_COUNT);
+ DataSourceConfig config_obj;
+ config_obj.FromProto(config);
+ auto data_source = GetSysStatsDataSource(config_obj);
+
+ WaitTick(data_source.get());
+
+ std::unique_ptr<protos::TracePacket> packet = writer_raw_->ParseProto();
+ ASSERT_TRUE(packet);
+ ASSERT_TRUE(packet->has_sys_stats());
+ const auto& sys_stats = packet->sys_stats();
+ EXPECT_EQ(sys_stats.meminfo_size(), 0);
+ EXPECT_EQ(sys_stats.vmstat_size(), 0);
+
+ ASSERT_EQ(sys_stats.cpu_stat_size(), 8);
+ EXPECT_EQ(sys_stats.cpu_stat(0).user_ns(), 762178 * 10000000ull);
+ EXPECT_EQ(sys_stats.cpu_stat(0).system_mode_ns(), 902284 * 10000000ull);
+ EXPECT_EQ(sys_stats.cpu_stat(0).softirq_ns(), 68262 * 10000000ull);
+ EXPECT_EQ(sys_stats.cpu_stat(7).user_ns(), 180484 * 10000000ull);
+ EXPECT_EQ(sys_stats.cpu_stat(7).system_mode_ns(), 139874 * 10000000ull);
+ EXPECT_EQ(sys_stats.cpu_stat(7).softirq_ns(), 13407 * 10000000ull);
+
+ EXPECT_EQ(sys_stats.num_forks(), 243320);
+
+ EXPECT_EQ(sys_stats.num_irq_total(), 238128517);
+ ASSERT_EQ(sys_stats.num_irq_size(), 793);
+ EXPECT_EQ(sys_stats.num_irq(0).count(), 0);
+ EXPECT_EQ(sys_stats.num_irq(3).count(), 63500984);
+ EXPECT_EQ(sys_stats.num_irq(790).count(), 680);
+
+ EXPECT_EQ(sys_stats.num_softirq_total(), 84611084);
+ ASSERT_EQ(sys_stats.num_softirq_size(), 10);
+ EXPECT_EQ(sys_stats.num_softirq(0).count(), 10220177);
+ EXPECT_EQ(sys_stats.num_softirq(9).count(), 16443195);
+
+ EXPECT_EQ(sys_stats.num_softirq_total(), 84611084);
+}
+
+TEST_F(SysStatsDataSourceTest, StatForksOnly) {
+ using C = protos::SysStatsConfig;
+ protos::DataSourceConfig config;
+ config.mutable_sys_stats_config()->set_stat_period_ms(1);
+ config.mutable_sys_stats_config()->add_stat_counters(C::STAT_FORK_COUNT);
+ DataSourceConfig config_obj;
+ config_obj.FromProto(config);
+ auto data_source = GetSysStatsDataSource(config_obj);
+
+ WaitTick(data_source.get());
+
+ std::unique_ptr<protos::TracePacket> packet = writer_raw_->ParseProto();
+ ASSERT_TRUE(packet->has_sys_stats());
+ const auto& sys_stats = packet->sys_stats();
+ EXPECT_EQ(sys_stats.meminfo_size(), 0);
+ EXPECT_EQ(sys_stats.vmstat_size(), 0);
+ ASSERT_EQ(sys_stats.cpu_stat_size(), 0);
+ EXPECT_EQ(sys_stats.num_forks(), 243320);
+ EXPECT_EQ(sys_stats.num_irq_total(), 0);
+ ASSERT_EQ(sys_stats.num_irq_size(), 0);
+ EXPECT_EQ(sys_stats.num_softirq_total(), 0);
+ ASSERT_EQ(sys_stats.num_softirq_size(), 0);
+}
+
+} // namespace
+} // namespace perfetto
diff --git a/src/tracing/BUILD.gn b/src/tracing/BUILD.gn
index 2e8831f..4455bfb 100644
--- a/src/tracing/BUILD.gn
+++ b/src/tracing/BUILD.gn
@@ -19,7 +19,7 @@
source_set("tracing") {
public_deps = [
"../../include/perfetto/tracing/core",
- "../../protos/perfetto/common",
+ "../../protos/perfetto/common:lite",
"../../protos/perfetto/trace:minimal_lite",
"../../protos/perfetto/trace:trusted_lite",
"../../protos/perfetto/trace:zero",
@@ -27,7 +27,7 @@
deps = [
"../../gn:default_deps",
"../../gn:gtest_prod_config",
- "../../protos/perfetto/config",
+ "../../protos/perfetto/config:lite",
"../base",
"../protozero",
]
@@ -51,6 +51,7 @@
"core/shared_memory_arbiter_impl.h",
"core/sliced_protobuf_input_stream.cc",
"core/sliced_protobuf_input_stream.h",
+ "core/sys_stats_config.cc",
"core/test_config.cc",
"core/trace_buffer.cc",
"core/trace_buffer.h",
@@ -71,7 +72,7 @@
":tracing",
"../../gn:default_deps",
"../../gn:gtest_deps",
- "../../protos/perfetto/config",
+ "../../protos/perfetto/config:lite",
"../../protos/perfetto/trace:lite",
"../../protos/perfetto/trace:zero",
"../base",
diff --git a/src/tracing/core/data_source_config.cc b/src/tracing/core/data_source_config.cc
index 0addd0e..405b430 100644
--- a/src/tracing/core/data_source_config.cc
+++ b/src/tracing/core/data_source_config.cc
@@ -32,6 +32,7 @@
#include "perfetto/config/ftrace/ftrace_config.pb.h"
#include "perfetto/config/inode_file/inode_file_config.pb.h"
#include "perfetto/config/process_stats/process_stats_config.pb.h"
+#include "perfetto/config/sys_stats/sys_stats_config.pb.h"
#include "perfetto/config/test_config.pb.h"
namespace perfetto {
@@ -72,6 +73,8 @@
process_stats_config_.FromProto(proto.process_stats_config());
+ sys_stats_config_.FromProto(proto.sys_stats_config());
+
static_assert(sizeof(legacy_config_) == sizeof(proto.legacy_config()),
"size mismatch");
legacy_config_ = static_cast<decltype(legacy_config_)>(proto.legacy_config());
@@ -112,6 +115,8 @@
process_stats_config_.ToProto(proto->mutable_process_stats_config());
+ sys_stats_config_.ToProto(proto->mutable_sys_stats_config());
+
static_assert(sizeof(legacy_config_) == sizeof(proto->legacy_config()),
"size mismatch");
proto->set_legacy_config(
diff --git a/src/tracing/core/sys_stats_config.cc b/src/tracing/core/sys_stats_config.cc
new file mode 100644
index 0000000..444fc84
--- /dev/null
+++ b/src/tracing/core/sys_stats_config.cc
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/*******************************************************************************
+ * AUTOGENERATED - DO NOT EDIT
+ *******************************************************************************
+ * This file has been generated from the protobuf message
+ * perfetto/config/sys_stats/sys_stats_config.proto
+ * by
+ * ../../tools/proto_to_cpp/proto_to_cpp.cc.
+ * If you need to make changes here, change the .proto file and then run
+ * ./tools/gen_tracing_cpp_headers_from_protos.py
+ */
+
+#include "perfetto/tracing/core/sys_stats_config.h"
+
+#include "perfetto/common/sys_stats_counters.pb.h"
+#include "perfetto/config/sys_stats/sys_stats_config.pb.h"
+
+namespace perfetto {
+
+SysStatsConfig::SysStatsConfig() = default;
+SysStatsConfig::~SysStatsConfig() = default;
+SysStatsConfig::SysStatsConfig(const SysStatsConfig&) = default;
+SysStatsConfig& SysStatsConfig::operator=(const SysStatsConfig&) = default;
+SysStatsConfig::SysStatsConfig(SysStatsConfig&&) noexcept = default;
+SysStatsConfig& SysStatsConfig::operator=(SysStatsConfig&&) = default;
+
+void SysStatsConfig::FromProto(const perfetto::protos::SysStatsConfig& proto) {
+ static_assert(sizeof(meminfo_period_ms_) == sizeof(proto.meminfo_period_ms()),
+ "size mismatch");
+ meminfo_period_ms_ =
+ static_cast<decltype(meminfo_period_ms_)>(proto.meminfo_period_ms());
+
+ meminfo_counters_.clear();
+ for (const auto& field : proto.meminfo_counters()) {
+ meminfo_counters_.emplace_back();
+ static_assert(
+ sizeof(meminfo_counters_.back()) == sizeof(proto.meminfo_counters(0)),
+ "size mismatch");
+ meminfo_counters_.back() =
+ static_cast<decltype(meminfo_counters_)::value_type>(field);
+ }
+
+ static_assert(sizeof(vmstat_period_ms_) == sizeof(proto.vmstat_period_ms()),
+ "size mismatch");
+ vmstat_period_ms_ =
+ static_cast<decltype(vmstat_period_ms_)>(proto.vmstat_period_ms());
+
+ vmstat_counters_.clear();
+ for (const auto& field : proto.vmstat_counters()) {
+ vmstat_counters_.emplace_back();
+ static_assert(
+ sizeof(vmstat_counters_.back()) == sizeof(proto.vmstat_counters(0)),
+ "size mismatch");
+ vmstat_counters_.back() =
+ static_cast<decltype(vmstat_counters_)::value_type>(field);
+ }
+
+ static_assert(sizeof(stat_period_ms_) == sizeof(proto.stat_period_ms()),
+ "size mismatch");
+ stat_period_ms_ =
+ static_cast<decltype(stat_period_ms_)>(proto.stat_period_ms());
+
+ stat_counters_.clear();
+ for (const auto& field : proto.stat_counters()) {
+ stat_counters_.emplace_back();
+ static_assert(
+ sizeof(stat_counters_.back()) == sizeof(proto.stat_counters(0)),
+ "size mismatch");
+ stat_counters_.back() =
+ static_cast<decltype(stat_counters_)::value_type>(field);
+ }
+ unknown_fields_ = proto.unknown_fields();
+}
+
+void SysStatsConfig::ToProto(perfetto::protos::SysStatsConfig* proto) const {
+ proto->Clear();
+
+ static_assert(
+ sizeof(meminfo_period_ms_) == sizeof(proto->meminfo_period_ms()),
+ "size mismatch");
+ proto->set_meminfo_period_ms(
+ static_cast<decltype(proto->meminfo_period_ms())>(meminfo_period_ms_));
+
+ for (const auto& it : meminfo_counters_) {
+ proto->add_meminfo_counters(
+ static_cast<decltype(proto->meminfo_counters(0))>(it));
+ static_assert(sizeof(it) == sizeof(proto->meminfo_counters(0)),
+ "size mismatch");
+ }
+
+ static_assert(sizeof(vmstat_period_ms_) == sizeof(proto->vmstat_period_ms()),
+ "size mismatch");
+ proto->set_vmstat_period_ms(
+ static_cast<decltype(proto->vmstat_period_ms())>(vmstat_period_ms_));
+
+ for (const auto& it : vmstat_counters_) {
+ proto->add_vmstat_counters(
+ static_cast<decltype(proto->vmstat_counters(0))>(it));
+ static_assert(sizeof(it) == sizeof(proto->vmstat_counters(0)),
+ "size mismatch");
+ }
+
+ static_assert(sizeof(stat_period_ms_) == sizeof(proto->stat_period_ms()),
+ "size mismatch");
+ proto->set_stat_period_ms(
+ static_cast<decltype(proto->stat_period_ms())>(stat_period_ms_));
+
+ for (const auto& it : stat_counters_) {
+ proto->add_stat_counters(
+ static_cast<decltype(proto->stat_counters(0))>(it));
+ static_assert(sizeof(it) == sizeof(proto->stat_counters(0)),
+ "size mismatch");
+ }
+ *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
+} // namespace perfetto
diff --git a/src/tracing/core/sys_stats_counters.cc b/src/tracing/core/sys_stats_counters.cc
new file mode 100644
index 0000000..6edb5b1
--- /dev/null
+++ b/src/tracing/core/sys_stats_counters.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/*******************************************************************************
+ * AUTOGENERATED - DO NOT EDIT
+ *******************************************************************************
+ * This file has been generated from the protobuf message
+ * perfetto/common/sys_stats_counters.proto
+ * by
+ * ../../tools/proto_to_cpp/proto_to_cpp.cc.
+ * If you need to make changes here, change the .proto file and then run
+ * ./tools/gen_tracing_cpp_headers_from_protos.py
+ */
+
+#include "perfetto/tracing/core/sys_stats_counters.h"
+
+#include "perfetto/common/sys_stats_counters.pb.h"
+
+namespace perfetto {} // namespace perfetto
diff --git a/src/tracing/core/trace_writer_for_testing.cc b/src/tracing/core/trace_writer_for_testing.cc
index 1b7e531..3f95c0f 100644
--- a/src/tracing/core/trace_writer_for_testing.cc
+++ b/src/tracing/core/trace_writer_for_testing.cc
@@ -44,12 +44,9 @@
std::unique_ptr<protos::TracePacket> TraceWriterForTesting::ParseProto() {
PERFETTO_CHECK(cur_packet_->is_finalized());
- size_t chunk_size_ = base::kPageSize;
auto packet = std::unique_ptr<protos::TracePacket>(new protos::TracePacket());
- size_t msg_size =
- delegate_.chunks().size() * chunk_size_ - stream_.bytes_available();
- std::unique_ptr<uint8_t[]> buffer = delegate_.StitchChunks(msg_size);
- if (!packet->ParseFromArray(buffer.get(), static_cast<int>(msg_size)))
+ std::vector<uint8_t> buffer = delegate_.StitchChunks();
+ if (!packet->ParseFromArray(buffer.data(), static_cast<int>(buffer.size())))
return nullptr;
return packet;
}
diff --git a/test/configs/BUILD.gn b/test/configs/BUILD.gn
index 1505529..cbc0970 100644
--- a/test/configs/BUILD.gn
+++ b/test/configs/BUILD.gn
@@ -30,6 +30,7 @@
"long_trace.cfg",
"processes.cfg",
"summary.cfg",
+ "sys_stats.cfg",
]
outputs = [
diff --git a/test/configs/sys_stats.cfg b/test/configs/sys_stats.cfg
new file mode 100644
index 0000000..fd4f6ea
--- /dev/null
+++ b/test/configs/sys_stats.cfg
@@ -0,0 +1,89 @@
+# Example config for a trace that polls system counters.
+
+duration_ms: 2000
+
+buffers {
+ size_kb: 16384
+ fill_policy: RING_BUFFER
+}
+
+buffers {
+ size_kb: 16384
+ fill_policy: RING_BUFFER
+}
+
+# Enable various data sources as usual.
+data_sources {
+ config {
+ name: "linux.ftrace"
+ target_buffer: 0
+ ftrace_config {
+ # These parameters affect only the kernel trace buffer size and how
+ # frequently it gets moved into the userspace buffer defined above.
+ buffer_size_kb: 16384
+ drain_period_ms: 250
+ ftrace_events: "cpu_frequency"
+ ftrace_events: "cpu_idle"
+ ftrace_events: "sched_switch"
+ ftrace_events: "tracing_mark_write"
+ }
+ }
+}
+
+data_sources {
+ config {
+ name: "linux.process_stats"
+ target_buffer: 0
+ }
+}
+
+data_sources {
+ config {
+ name: "linux.sys_stats"
+ target_buffer: 1
+ sys_stats_config {
+ meminfo_period_ms: 100
+ meminfo_counters: MEMINFO_MEM_AVAILABLE
+ meminfo_counters: MEMINFO_BUFFERS
+ meminfo_counters: MEMINFO_CACHED
+ meminfo_counters: MEMINFO_SWAP_CACHED
+ meminfo_counters: MEMINFO_ACTIVE
+ meminfo_counters: MEMINFO_INACTIVE
+ meminfo_counters: MEMINFO_ACTIVE_ANON
+ meminfo_counters: MEMINFO_INACTIVE_ANON
+ meminfo_counters: MEMINFO_ACTIVE_FILE
+ meminfo_counters: MEMINFO_INACTIVE_FILE
+ meminfo_counters: MEMINFO_UNEVICTABLE
+
+ vmstat_period_ms: 100
+ vmstat_counters: VMSTAT_NR_FREE_PAGES
+ vmstat_counters: VMSTAT_NR_ALLOC_BATCH
+ vmstat_counters: VMSTAT_NR_INACTIVE_ANON
+ vmstat_counters: VMSTAT_NR_ACTIVE_ANON
+ vmstat_counters: VMSTAT_NR_INACTIVE_FILE
+ vmstat_counters: VMSTAT_NR_ACTIVE_FILE
+ vmstat_counters: VMSTAT_NR_UNEVICTABLE
+ vmstat_counters: VMSTAT_NR_MLOCK
+ vmstat_counters: VMSTAT_NR_ANON_PAGES
+ vmstat_counters: VMSTAT_NR_MAPPED
+ vmstat_counters: VMSTAT_NR_FILE_PAGES
+ vmstat_counters: VMSTAT_NR_DIRTY
+ vmstat_counters: VMSTAT_NR_WRITEBACK
+ vmstat_counters: VMSTAT_NR_SLAB_RECLAIMABLE
+ vmstat_counters: VMSTAT_NR_SLAB_UNRECLAIMABLE
+ vmstat_counters: VMSTAT_NR_PAGE_TABLE_PAGES
+ vmstat_counters: VMSTAT_NR_KERNEL_STACK
+ vmstat_counters: VMSTAT_NR_OVERHEAD
+ vmstat_counters: VMSTAT_NR_UNSTABLE
+ vmstat_counters: VMSTAT_NR_BOUNCE
+ vmstat_counters: VMSTAT_NR_VMSCAN_WRITE
+ vmstat_counters: VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM
+ vmstat_counters: VMSTAT_NR_WRITEBACK_TEMP
+
+ stat_period_ms: 100
+ stat_counters: STAT_CPU_TIMES
+ stat_counters: STAT_IRQ_COUNTS
+ stat_counters: STAT_FORK_COUNT
+ }
+ }
+}
\ No newline at end of file
diff --git a/tools/gen_merged_protos b/tools/gen_merged_protos
index 77bab2b..8d42fcd 100755
--- a/tools/gen_merged_protos
+++ b/tools/gen_merged_protos
@@ -22,11 +22,13 @@
import sys
CONFIG_PROTOS = (
+ 'protos/perfetto/common/sys_stats_counters.proto',
'protos/perfetto/config/chrome/chrome_config.proto',
- 'protos/perfetto/config/inode_file/inode_file_config.proto',
- 'protos/perfetto/config/process_stats/process_stats_config.proto',
'protos/perfetto/config/data_source_config.proto',
'protos/perfetto/config/ftrace/ftrace_config.proto',
+ 'protos/perfetto/config/inode_file/inode_file_config.proto',
+ 'protos/perfetto/config/process_stats/process_stats_config.proto',
+ 'protos/perfetto/config/sys_stats/sys_stats_config.proto',
'protos/perfetto/config/test_config.proto',
'protos/perfetto/config/trace_config.proto',
)
@@ -34,12 +36,15 @@
MERGED_CONFIG_PROTO = 'protos/perfetto/config/perfetto_config.proto'
TRACE_PROTOS = (
+ 'protos/perfetto/common/sys_stats_counters.proto',
'protos/perfetto/trace/trace.proto',
'protos/perfetto/trace/trace_packet.proto',
'protos/perfetto/trace/ftrace/ftrace_event_bundle.proto',
'protos/perfetto/trace/ftrace/ftrace_event.proto',
'protos/perfetto/trace/filesystem/inode_file_map.proto',
'protos/perfetto/trace/ps/process_tree.proto',
+ 'protos/perfetto/trace/clock_snapshot.proto',
+ 'protos/perfetto/trace/sys_stats/sys_stats.proto',
# Print proto is special: it doesn't have a enable file so is
# not present in genfs_contexts.
diff --git a/tools/gen_tracing_cpp_headers_from_protos.py b/tools/gen_tracing_cpp_headers_from_protos.py
index ce7fdb6..901d73e 100755
--- a/tools/gen_tracing_cpp_headers_from_protos.py
+++ b/tools/gen_tracing_cpp_headers_from_protos.py
@@ -22,11 +22,13 @@
'perfetto/config/data_source_config.proto',
'perfetto/config/inode_file/inode_file_config.proto',
'perfetto/config/process_stats/process_stats_config.proto',
+ 'perfetto/config/sys_stats/sys_stats_config.proto',
'perfetto/config/data_source_descriptor.proto',
'perfetto/config/ftrace/ftrace_config.proto',
'perfetto/config/trace_config.proto',
'perfetto/config/test_config.proto',
'perfetto/common/commit_data_request.proto',
+ 'perfetto/common/sys_stats_counters.proto',
)
HEADER_PATH = 'include/perfetto/tracing/core'
diff --git a/tools/proto_to_cpp/proto_to_cpp.cc b/tools/proto_to_cpp/proto_to_cpp.cc
index 2a77542..ac773ea 100644
--- a/tools/proto_to_cpp/proto_to_cpp.cc
+++ b/tools/proto_to_cpp/proto_to_cpp.cc
@@ -270,7 +270,7 @@
cpp_printer.Print("} // namespace perfetto\n");
header_printer.Print("} // namespace perfetto\n");
- header_printer.Print("#endif // $g$\n", "g", include_guard);
+ header_printer.Print("\n#endif // $g$\n", "g", include_guard);
}
void ProtoToCpp::GenHeader(const Descriptor* msg, Printer* p) {
diff --git a/tools/trace_to_text/BUILD.gn b/tools/trace_to_text/BUILD.gn
index 56b24bc..ba7cd9f 100644
--- a/tools/trace_to_text/BUILD.gn
+++ b/tools/trace_to_text/BUILD.gn
@@ -20,6 +20,7 @@
"../../gn:default_deps",
"../../gn:protobuf_full_deps",
"../../include/perfetto/base",
+ "../../include/perfetto/traced:sys_stats_counters",
"../../protos/perfetto/trace:lite",
"../../protos/perfetto/trace/ftrace:lite",
]
diff --git a/tools/trace_to_text/main.cc b/tools/trace_to_text/main.cc
index b775326..709d139 100644
--- a/tools/trace_to_text/main.cc
+++ b/tools/trace_to_text/main.cc
@@ -43,6 +43,7 @@
#include "perfetto/trace/ftrace/ftrace_stats.pb.h"
#include "perfetto/trace/trace.pb.h"
#include "perfetto/trace/trace_packet.pb.h"
+#include "perfetto/traced/sys_stats_counters.h"
#include "tools/trace_to_text/ftrace_event_formatter.h"
#include "tools/trace_to_text/ftrace_inode_handler.h"
@@ -92,6 +93,7 @@
using protos::FtraceStats;
using protos::FtraceStats_Phase_START_OF_TRACE;
using protos::FtraceStats_Phase_END_OF_TRACE;
+using protos::SysStats;
using Entry = protos::InodeFileMap::Entry;
using Process = protos::ProcessTree::Process;
@@ -176,17 +178,46 @@
bool wrap_in_json) {
std::multimap<uint64_t, std::string> sorted;
- ForEachPacketInTrace(input, [&sorted](const protos::TracePacket& packet) {
- if (!packet.has_ftrace_events())
- return;
+ std::vector<const char*> meminfo_strs = BuildMeminfoCounterNames();
+ std::vector<const char*> vmstat_strs = BuildVmstatCounterNames();
- const FtraceEventBundle& bundle = packet.ftrace_events();
- for (const FtraceEvent& event : bundle.event()) {
- std::string line =
- FormatFtraceEvent(event.timestamp(), bundle.cpu(), event);
- if (line == "")
- continue;
- sorted.emplace(event.timestamp(), line);
+ ForEachPacketInTrace(input, [&sorted, &meminfo_strs, &vmstat_strs](
+ const protos::TracePacket& packet) {
+ if (packet.has_ftrace_events()) {
+ const FtraceEventBundle& bundle = packet.ftrace_events();
+ for (const FtraceEvent& event : bundle.event()) {
+ std::string line =
+ FormatFtraceEvent(event.timestamp(), bundle.cpu(), event);
+ if (line == "")
+ continue;
+ sorted.emplace(event.timestamp(), line);
+ }
+ } // packet.has_ftrace_events
+
+ if (packet.has_sys_stats()) {
+ const SysStats& sys_stats = packet.sys_stats();
+ for (const auto& meminfo : sys_stats.meminfo()) {
+ FtraceEvent event;
+ uint64_t ts = static_cast<uint64_t>(packet.timestamp());
+ char str[256];
+ event.set_timestamp(ts);
+ event.set_pid(1);
+ sprintf(str, "C|1|%s|%" PRIu64, meminfo_strs[meminfo.key()],
+ static_cast<uint64_t>(meminfo.value()));
+ event.mutable_print()->set_buf(str);
+ sorted.emplace(ts, FormatFtraceEvent(ts, 0, event));
+ }
+ for (const auto& vmstat : sys_stats.vmstat()) {
+ FtraceEvent event;
+ uint64_t ts = static_cast<uint64_t>(packet.timestamp());
+ char str[256];
+ event.set_timestamp(ts);
+ event.set_pid(1);
+ sprintf(str, "C|1|%s|%" PRIu64, vmstat_strs[vmstat.key()],
+ static_cast<uint64_t>(vmstat.value()));
+ event.mutable_print()->set_buf(str);
+ sorted.emplace(ts, FormatFtraceEvent(ts, 0, event));
+ }
}
});