Skip to contentSkip to conversation

perf stat: Poll for monitored tasks being alive

PATCH In review Jiri Olsa 3 participants 3 messages Oct 22, 2018 – Oct 26, 2018 perf events

lore
Share & tools
lore

Jiri Olsa

author reviewer
#0 lore raw

PATCH 1/1 perf stat: Poll for monitored tasks being alive

Adding the check for tasks we monitor via -p/-t options, and finish stat if there's no longer task to monitor.

---
 tools/perf/builtin-stat.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
tools/perf/builtin-stat.c +24 -0
index b86aba1c8028..d1028d7755bb 100644
@@ -409,6 +409,28 @@ static struct perf_evsel *perf_evsel__reset_weak_group(struct perf_evsel *evsel)
 	return leader;
 }
 
+static bool is_target_alive(struct target *_target,
+			    struct thread_map *threads)
+{
+	struct stat st;
+	int i;
+
+	if (!target__has_task(_target))
+		return true;
+
+	for (i = 0; i < threads->nr; i++) {
+		char path[PATH_MAX];
+
+		scnprintf(path, PATH_MAX, "%s/%d", procfs__mountpoint(),
+			  threads->map[i].pid);
+
+		if (!stat(path, &st))
+			return true;
+	}
+
+	return false;
+}
+
 static int __run_perf_stat(int argc, const char **argv, int run_idx)
 {
 	int interval = stat_config.interval;
@@ -579,6 +601,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
 		enable_counters();
 		while (!done) {
 			nanosleep(&ts, NULL);
+			if (!is_target_alive(&target, evsel_list->threads))
+				break;
 			if (timeout)
 				break;
 			if (interval) {
Signature · 1 line
2.17.2
#1 lore raw

Em Mon, Oct 22, 2018 at 11:30:15AM +0200, Jiri Olsa escreveu:

Quoted 2 lines

Adding the check for tasks we monitor via -p/-t options, and finish stat if there's no longer task to monitor.

Wonder if instead of doing all those scnprintf, etc, we couldn't have a perf ring buffer with a dummy event and then ask for PERF_RECORD_EXIT on it, poll it, etc.

Thought about using getpgid(pid) but thagt also involves radix tree lookups, so should also be more expensive than asking the kernel perf to tell us about the exits.

Anyway, that can be done on top, if someone is interested, applying.

- Arnaldo

Quoted 52 lines
---
 tools/perf/builtin-stat.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
tools/perf/builtin-stat.c +24 -0
index b86aba1c8028..d1028d7755bb 100644
@@ -409,6 +409,28 @@ static struct perf_evsel *perf_evsel__reset_weak_group(struct perf_evsel *evsel)
 	return leader;
 }
 
+static bool is_target_alive(struct target *_target,
+			    struct thread_map *threads)
+{
+	struct stat st;
+	int i;
+
+	if (!target__has_task(_target))
+		return true;
+
+	for (i = 0; i < threads->nr; i++) {
+		char path[PATH_MAX];
+
+		scnprintf(path, PATH_MAX, "%s/%d", procfs__mountpoint(),
+			  threads->map[i].pid);
+
+		if (!stat(path, &st))
+			return true;
+	}
+
+	return false;
+}
+
 static int __run_perf_stat(int argc, const char **argv, int run_idx)
 {
 	int interval = stat_config.interval;
@@ -579,6 +601,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
 		enable_counters();
 		while (!done) {
 			nanosleep(&ts, NULL);
+			if (!is_target_alive(&target, evsel_list->threads))
+				break;
 			if (timeout)
 				break;
 			if (interval) {
Signature · 1 line
2.17.2
#2 lore raw
In reply to Jiri Olsa
perf stat: Poll for monitored tasks being alive
Commit-ID:  cbb5df7e96070f1f728ff7885443646ebba703d4
Gitweb:     https://git.kernel.org/tip/cbb5df7e96070f1f728ff7885443646ebba703d4
Author:     Jiri Olsa <[email protected]>
AuthorDate: Mon, 22 Oct 2018 11:30:15 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 22 Oct 2018 12:37:52 -0300

perf stat: Poll for monitored tasks being alive

Adding the check for tasks we monitor via -p/-t options, and finish stat if there's no longer task to monitor.

---
 tools/perf/builtin-stat.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
tools/perf/builtin-stat.c +24 -0
index b86aba1c8028..d1028d7755bb 100644
@@ -409,6 +409,28 @@ static struct perf_evsel *perf_evsel__reset_weak_group(struct perf_evsel *evsel)
 	return leader;
 }
 
+static bool is_target_alive(struct target *_target,
+			    struct thread_map *threads)
+{
+	struct stat st;
+	int i;
+
+	if (!target__has_task(_target))
+		return true;
+
+	for (i = 0; i < threads->nr; i++) {
+		char path[PATH_MAX];
+
+		scnprintf(path, PATH_MAX, "%s/%d", procfs__mountpoint(),
+			  threads->map[i].pid);
+
+		if (!stat(path, &st))
+			return true;
+	}
+
+	return false;
+}
+
 static int __run_perf_stat(int argc, const char **argv, int run_idx)
 {
 	int interval = stat_config.interval;
@@ -579,6 +601,8 @@ try_again:
 		enable_counters();
 		while (!done) {
 			nanosleep(&ts, NULL);
+			if (!is_target_alive(&target, evsel_list->threads))
+				break;
 			if (timeout)
 				break;
 			if (interval) {