aboutsummaryrefslogtreecommitdiff
path: root/experiments/run_binder_transaction_tracing.py
diff options
context:
space:
mode:
Diffstat (limited to 'experiments/run_binder_transaction_tracing.py')
-rwxr-xr-xexperiments/run_binder_transaction_tracing.py131
1 files changed, 131 insertions, 0 deletions
diff --git a/experiments/run_binder_transaction_tracing.py b/experiments/run_binder_transaction_tracing.py
new file mode 100755
index 0000000..d8f0949
--- /dev/null
+++ b/experiments/run_binder_transaction_tracing.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: Apache-2.0
+#
+# Copyright (C) 2017, ARM Limited, Google, and contributors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+from time import sleep
+import os
+import re
+import argparse
+import pandas as pd
+import matplotlib.pyplot as plt
+from android import System
+from env import TestEnv
+
+# Setup target configuration
+conf = {
+ # Target platform and board
+ "platform" : 'android',
+ # Useful for reading names of little/big cluster
+ # and energy model info, its device specific and use
+ # only if needed for analysis
+ # "board" : 'pixel',
+ # Device
+ # By default the device connected is detected, but if more than 1
+ # device, override the following to get a specific device.
+ # "device" : "HT66N0300080",
+ # Folder where all the results will be collected
+ "results_dir" : "BinderTransactionTracing",
+ # Define devlib modules to load
+ "modules" : [
+ 'cpufreq', # enable CPUFreq support
+ 'cpuidle', # enable cpuidle support
+ # 'cgroups' # Enable for cgroup support
+ ],
+ "emeter" : {
+ 'instrument': 'monsoon',
+ 'conf': { }
+ },
+ "systrace": {
+ 'extra_categories': ['binder_driver'],
+ "extra_events": ["binder_transaction_alloc_buf"],
+ },
+ # Tools required by the experiments
+ "tools" : [ 'taskset'],
+
+ "skip_nrg_model" : True,
+}
+
+te = TestEnv(conf, wipe=False)
+target = te.target
+
+def run_page_stats(duration, frequency):
+ procs = {}
+ for i in range(int(duration/frequency)):
+ ss = target.execute("cat /d/binder/stats")
+ proc_dump = re.split("\nproc ", ss)[1:]
+
+ for proc in proc_dump[1:]:
+ lines = proc.split("\n ")
+ proc_id = lines[0]
+ page = re.search("pages: (\d+:\d+:\d+)", proc)
+ active, lru, free = map(int, page.group(1).split(":"))
+ if proc_id not in procs:
+ procs[proc_id] = {"alloc": [], "lru": []}
+ procs[proc_id]["alloc"].append(active + lru)
+ procs[proc_id]["lru"].append(lru)
+
+ sleep(frequency)
+ for proc in procs:
+ df = pd.DataFrame(data={"alloc": procs[proc]["alloc"],
+ "lru": procs[proc]["lru"]})
+ df.plot(title="proc " + proc)
+ plt.show()
+
+def experiment(duration_s, cmd, frequency):
+ """
+ Starts systrace and run a command on target if specified. If
+ no command is given, collect the trace for duration_s seconds.
+
+ :param duration_s: duration to collect systrace
+ :type duration_s: int
+
+ :param cmd: command to execute on the target
+ :type cmd: string
+
+ :param frequency: sampling frequency for page stats
+ :type frequency: float
+ """
+ systrace_output = System.systrace_start(
+ te, os.path.join(te.res_dir, 'trace.html'), conf=conf)
+ systrace_output.expect("Starting tracing")
+
+ if frequency:
+ run_page_stats(duration_s, frequency)
+ elif cmd:
+ target.execute(cmd)
+ else:
+ sleep(duration_s)
+
+ systrace_output.sendline("")
+ System.systrace_wait(te, systrace_output)
+ te.platform_dump(te.res_dir)
+
+parser = argparse.ArgumentParser(
+ description="Collect systrace for binder events while executing"
+ "a command on the target or wait for duration_s seconds")
+
+parser.add_argument("--duration", "-d", type=int, default=0,
+ help="How long to collect the trace in seconds.")
+parser.add_argument("--command", "-c", type=str, default="",
+ help="Command to execute on the target.")
+parser.add_argument("--pagestats", "-p", nargs="?", type=float, default=None,
+ const=0.1, help="Run binder page stats analysis."
+ "Optional argument for sample interval in seconds.")
+
+if __name__ == "__main__":
+ args = parser.parse_args()
+ experiment(args.duration, args.command, args.pagestats)