diff mbox series

[3/3] perf bench futex: sync waker threads

Message ID 20171127042101.3659-4-dave@stgolabs.net
State New
Headers show
Series None | expand

Commit Message

Davidlohr Bueso Nov. 27, 2017, 4:21 a.m. UTC
From: James Yang <james.yang@arm.com>


Waker threads in the futex wake-parallel benchmark are started by a
loop using pthread_create().  However, there is no synchronization
for when the waker threads wake the waiting threads.  Comparison of
the waker threads' measurement timestamps show they are not all
running concurrently because older waker threads finish their task
before newer waker threads even start.

This patch uses a barrier to better synchronize the waker threads.

Cc: Kim Phillips <Kim.Phillips@arm.com>
Signed-off-by: James Yang <james.yang@arm.com

Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>

---
 tools/perf/bench/futex-wake-parallel.c | 9 +++++++++
 1 file changed, 9 insertions(+)

-- 
2.13.6
diff mbox series

Patch

diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c
index c04e207ea37c..55bff8673d31 100644
--- a/tools/perf/bench/futex-wake-parallel.c
+++ b/tools/perf/bench/futex-wake-parallel.c
@@ -43,6 +43,7 @@  static bool affine_wakers = false;
 static unsigned int nblocked_threads = 0, nwaking_threads = 0;
 static pthread_mutex_t thread_lock;
 static pthread_cond_t thread_parent, thread_worker;
+static pthread_barrier_t barrier;
 static struct stats waketime_stats, wakeup_stats;
 static unsigned int threads_starting;
 static int futex_flag = 0;
@@ -66,6 +67,8 @@  static void *waking_workerfn(void *arg)
 	struct thread_data *waker = (struct thread_data *) arg;
 	struct timeval start, end;
 
+	pthread_barrier_wait(&barrier);
+
 	gettimeofday(&start, NULL);
 
 	waker->nwoken = futex_wake(&futex, nwakes, futex_flag);
@@ -87,6 +90,8 @@  static void wakeup_threads(struct thread_data *td, pthread_attr_t thread_attr,
 
 	pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
 
+	pthread_barrier_init(&barrier, NULL, nwaking_threads + 1);
+
 	/* create and block all threads */
 	for (i = 0; i < nwaking_threads; i++) {
 		/*
@@ -110,9 +115,13 @@  static void wakeup_threads(struct thread_data *td, pthread_attr_t thread_attr,
 			err(EXIT_FAILURE, "pthread_create");
 	}
 
+	pthread_barrier_wait(&barrier);
+
 	for (i = 0; i < nwaking_threads; i++)
 		if (pthread_join(td[i].worker, NULL))
 			err(EXIT_FAILURE, "pthread_join");
+
+	pthread_barrier_destroy(&barrier);
 }
 
 static void *blocked_workerfn(void *arg __maybe_unused)