From 4859e818fbd23cfe6691ae7fb42d764a15cc3b01 Mon Sep 17 00:00:00 2001
From: Robert Freeman <rob.freeman@arm.com>
Date: Mon, 29 Mar 2021 15:38:38 +0100
Subject: [PATCH] collector/perf: Only kill sleep if running perf stat

The stop() command of the PerfCollector kills all sleep commands in
the target, saying "We hope that no other important sleep is
on-going".  This is only needed if we are running "perf stat",
simpleperf does not need this.  Background the
perf/simpleperf command and only kill all sleeps in that specific case.
---
 devlib/collector/perf.py | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/devlib/collector/perf.py b/devlib/collector/perf.py
index 1599963..771ead9 100644
--- a/devlib/collector/perf.py
+++ b/devlib/collector/perf.py
@@ -24,7 +24,7 @@ from devlib.collector import (CollectorBase, CollectorOutput,
 from devlib.utils.misc import ensure_file_directory_exists as _f
 
 
-PERF_COMMAND_TEMPLATE = '{binary} {command} {options} {events} sleep 1000 > {outfile} 2>&1 '
+PERF_STAT_COMMAND_TEMPLATE = '{binary} {command} {options} {events} {sleep_cmd} > {outfile} 2>&1 '
 PERF_REPORT_COMMAND_TEMPLATE= '{binary} report {options} -i {datafile} > {outfile} 2>&1 '
 PERF_RECORD_COMMAND_TEMPLATE= '{binary} record {options} {events} -o {outfile}'
 
@@ -141,14 +141,15 @@ class PerfCollector(CollectorBase):
 
     def start(self):
         for command in self.commands:
-            self.target.kick_off(command, as_root=self.target.is_rooted)
+            self.target.background(command, as_root=self.target.is_rooted)
 
     def stop(self):
         self.target.killall(self.perf_type, signal='SIGINT',
                             as_root=self.target.is_rooted)
-        # perf doesn't transmit the signal to its sleep call so handled here:
-        self.target.killall('sleep', as_root=self.target.is_rooted)
-        # NB: we hope that no other "important" sleep is on-going
+        if self.perf_type == "perf" and self.command == "stat":
+            # perf doesn't transmit the signal to its sleep call so handled here:
+            self.target.killall('sleep', as_root=self.target.is_rooted)
+            # NB: we hope that no other "important" sleep is on-going
 
     def set_output(self, output_path):
         self.output_path = output_path
@@ -188,10 +189,12 @@ class PerfCollector(CollectorBase):
 
     def _build_perf_stat_command(self, options, events, label):
         event_string = ' '.join(['-e {}'.format(e) for e in events])
-        command = PERF_COMMAND_TEMPLATE.format(binary = self.binary,
+        sleep_cmd = 'sleep 1000' if self.perf_type == 'perf' else ''
+        command = PERF_STAT_COMMAND_TEMPLATE.format(binary = self.binary,
                                                command = self.command,
                                                options = options or '',
                                                events = event_string,
+                                               sleep_cmd = sleep_cmd,
                                                outfile = self._get_target_file(label, 'out'))
         return command