[PATCH 44/49] perf record: Wait for all threads being started
From: Jiri Olsa
Date: Tue Jan 09 2018 - 10:39:38 EST
Ensure all threads are started and ready before
we enable events. Using pthread_cond_t signaling
logic for that.
Link: http://lkml.kernel.org/n/tip-z4x5ikp8v7e3flpxoo4bv1un@xxxxxxxxxxxxxx
Signed-off-by: Jiri Olsa <jolsa@xxxxxxxxxx>
---
tools/perf/builtin-record.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 5457eacf8821..22307796f84d 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -102,6 +102,9 @@ struct record {
unsigned long long samples;
struct record_thread *threads;
int threads_cnt;
+ int threads_signal_cnt;
+ pthread_mutex_t threads_signal_mutex;
+ pthread_cond_t threads_signal_cond;
unsigned long waking;
};
@@ -1114,6 +1117,9 @@ record__threads_config(struct record *rec)
ret = record__threads_create_poll(rec);
+ pthread_mutex_init(&rec->threads_signal_mutex, NULL);
+ pthread_cond_init(&rec->threads_signal_cond, NULL);
+
out:
if (ret)
record__threads_clean(rec);
@@ -1150,6 +1156,26 @@ record_thread__process(struct record *rec)
return NULL;
}
+static void signal_main(struct record *rec)
+{
+ pthread_mutex_lock(&rec->threads_signal_mutex);
+ rec->threads_signal_cnt++;
+ pthread_cond_signal(&rec->threads_signal_cond);
+ pthread_mutex_unlock(&rec->threads_signal_mutex);
+}
+
+static void wait_for_signal(struct record *rec)
+{
+ pthread_mutex_lock(&rec->threads_signal_mutex);
+
+ while (rec->threads_signal_cnt < rec->threads_cnt) {
+ pthread_cond_wait(&rec->threads_signal_cond,
+ &rec->threads_signal_mutex);
+ }
+
+ pthread_mutex_unlock(&rec->threads_signal_mutex);
+}
+
static void *worker(void *arg)
{
struct record_thread *th = arg;
@@ -1158,6 +1184,8 @@ static void *worker(void *arg)
thread = th;
thread->state = RECORD_THREAD__RUNNING;
+ signal_main(rec);
+
return record_thread__process(rec);
}
@@ -1166,12 +1194,17 @@ static int record__threads_start(struct record *rec)
struct record_thread *threads = rec->threads;
int i, err = 0;
+ rec->threads_signal_cnt = 1;
+
for (i = 1; !err && i < rec->threads_cnt; i++) {
struct record_thread *th = threads + i;
err = pthread_create(&th->pt, NULL, worker, th);
}
+ if (rec->threads_cnt > 1)
+ wait_for_signal(rec);
+
return err;
}
--
2.13.6