Signal thread to terminate by closing write fd of msg pipe.
Receive THREAD_MSG__READY message as the confirmation of the
thread's termination. Stop threads created for parallel trace
streaming prior their stats processing.

Signed-off-by: Alexey Bayduraev <alexey.v.baydur...@linux.intel.com>
---
 tools/perf/builtin-record.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index ecb6bf33ed85..4612314853c1 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -110,6 +110,16 @@ struct thread_data {
 
 static __thread struct thread_data *thread;
 
+enum thread_msg {
+       THREAD_MSG__UNDEFINED = 0,
+       THREAD_MSG__READY,
+       THREAD_MSG__MAX,
+};
+
+static const char *thread_msg_tags[THREAD_MSG__MAX] = {
+       "UNDEFINED", "READY"
+};
+
 struct record {
        struct perf_tool        tool;
        struct record_opts      opts;
@@ -1820,6 +1830,23 @@ static void hit_auxtrace_snapshot_trigger(struct record 
*rec)
        }
 }
 
+static int record__terminate_thread(struct thread_data *thread_data)
+{
+       int res;
+       enum thread_msg ack = THREAD_MSG__UNDEFINED;
+       pid_t tid = thread_data->tid;
+
+       close(thread_data->pipes.msg[1]);
+       res = read(thread_data->pipes.ack[0], &ack, sizeof(ack));
+       if (res != -1)
+               pr_debug2("threads[%d]: sent %s\n", tid, thread_msg_tags[ack]);
+       else
+               pr_err("threads[%d]: failed to recv msg=%s from tid=%d\n",
+                      thread->tid, thread_msg_tags[ack], tid);
+
+       return 0;
+}
+
 static int record__start_threads(struct record *rec)
 {
        struct thread_data *thread_data = rec->thread_data;
@@ -1836,6 +1863,9 @@ static int record__stop_threads(struct record *rec, 
unsigned long *waking)
        int t;
        struct thread_data *thread_data = rec->thread_data;
 
+       for (t = 1; t < rec->nr_threads; t++)
+               record__terminate_thread(&thread_data[t]);
+
        for (t = 0; t < rec->nr_threads; t++) {
                rec->samples += thread_data[t].samples;
                *waking += thread_data[t].waking;
-- 
2.19.0


Reply via email to