diff options
author | Davidlohr Bueso <dave@stgolabs.net> | 2014-09-29 12:41:07 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-09-29 14:43:21 -0400 |
commit | 86c87e13f8a5dffc6cc7b0f37340f815dc172945 (patch) | |
tree | 4f391df8bf01d696425805dac591696ea9f4471a /tools/perf/bench | |
parent | 2c82c3ad56921c47f28af9eb8ed96b6d99b47623 (diff) |
perf bench futex: Support operations for shared futexes
Unlike futex-hash, requeuing and wakeup benchmarks do not support shared
futexes, limiting the usefulness of the programs. Correct this, and
allow using the local -S parameter. The default remains using private
futexes.
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Cc: Davidlohr Bueso <dbueso@suse.de>
Link: http://lkml.kernel.org/r/1412008868-22328-1-git-send-email-dave@stgolabs.net
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/bench')
-rw-r--r-- | tools/perf/bench/futex-hash.c | 7 | ||||
-rw-r--r-- | tools/perf/bench/futex-requeue.c | 24 | ||||
-rw-r--r-- | tools/perf/bench/futex-wake.c | 15 |
3 files changed, 30 insertions, 16 deletions
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index a84206e9c4aa..fc9bebd2cca0 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c | |||
@@ -26,6 +26,7 @@ static unsigned int nsecs = 10; | |||
26 | /* amount of futexes per thread */ | 26 | /* amount of futexes per thread */ |
27 | static unsigned int nfutexes = 1024; | 27 | static unsigned int nfutexes = 1024; |
28 | static bool fshared = false, done = false, silent = false; | 28 | static bool fshared = false, done = false, silent = false; |
29 | static int futex_flag = 0; | ||
29 | 30 | ||
30 | struct timeval start, end, runtime; | 31 | struct timeval start, end, runtime; |
31 | static pthread_mutex_t thread_lock; | 32 | static pthread_mutex_t thread_lock; |
@@ -75,8 +76,7 @@ static void *workerfn(void *arg) | |||
75 | * such as internal waitqueue handling, thus enlarging | 76 | * such as internal waitqueue handling, thus enlarging |
76 | * the critical region protected by hb->lock. | 77 | * the critical region protected by hb->lock. |
77 | */ | 78 | */ |
78 | ret = futex_wait(&w->futex[i], 1234, NULL, | 79 | ret = futex_wait(&w->futex[i], 1234, NULL, futex_flag); |
79 | fshared ? 0 : FUTEX_PRIVATE_FLAG); | ||
80 | if (!silent && | 80 | if (!silent && |
81 | (!ret || errno != EAGAIN || errno != EWOULDBLOCK)) | 81 | (!ret || errno != EAGAIN || errno != EWOULDBLOCK)) |
82 | warn("Non-expected futex return call"); | 82 | warn("Non-expected futex return call"); |
@@ -135,6 +135,9 @@ int bench_futex_hash(int argc, const char **argv, | |||
135 | if (!worker) | 135 | if (!worker) |
136 | goto errmem; | 136 | goto errmem; |
137 | 137 | ||
138 | if (!fshared) | ||
139 | futex_flag = FUTEX_PRIVATE_FLAG; | ||
140 | |||
138 | printf("Run summary [PID %d]: %d threads, each operating on %d [%s] futexes for %d secs.\n\n", | 141 | printf("Run summary [PID %d]: %d threads, each operating on %d [%s] futexes for %d secs.\n\n", |
139 | getpid(), nthreads, nfutexes, fshared ? "shared":"private", nsecs); | 142 | getpid(), nthreads, nfutexes, fshared ? "shared":"private", nsecs); |
140 | 143 | ||
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 732403bfd31a..9837a8831406 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c | |||
@@ -30,16 +30,18 @@ static u_int32_t futex1 = 0, futex2 = 0; | |||
30 | static unsigned int nrequeue = 1; | 30 | static unsigned int nrequeue = 1; |
31 | 31 | ||
32 | static pthread_t *worker; | 32 | static pthread_t *worker; |
33 | static bool done = 0, silent = 0; | 33 | static bool done = false, silent = false, fshared = false; |
34 | static pthread_mutex_t thread_lock; | 34 | static pthread_mutex_t thread_lock; |
35 | static pthread_cond_t thread_parent, thread_worker; | 35 | static pthread_cond_t thread_parent, thread_worker; |
36 | static struct stats requeuetime_stats, requeued_stats; | 36 | static struct stats requeuetime_stats, requeued_stats; |
37 | static unsigned int ncpus, threads_starting, nthreads = 0; | 37 | static unsigned int ncpus, threads_starting, nthreads = 0; |
38 | static int futex_flag = 0; | ||
38 | 39 | ||
39 | static const struct option options[] = { | 40 | static const struct option options[] = { |
40 | OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), | 41 | OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), |
41 | OPT_UINTEGER('q', "nrequeue", &nrequeue, "Specify amount of threads to requeue at once"), | 42 | OPT_UINTEGER('q', "nrequeue", &nrequeue, "Specify amount of threads to requeue at once"), |
42 | OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), | 43 | OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), |
44 | OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), | ||
43 | OPT_END() | 45 | OPT_END() |
44 | }; | 46 | }; |
45 | 47 | ||
@@ -70,7 +72,7 @@ static void *workerfn(void *arg __maybe_unused) | |||
70 | pthread_cond_wait(&thread_worker, &thread_lock); | 72 | pthread_cond_wait(&thread_worker, &thread_lock); |
71 | pthread_mutex_unlock(&thread_lock); | 73 | pthread_mutex_unlock(&thread_lock); |
72 | 74 | ||
73 | futex_wait(&futex1, 0, NULL, FUTEX_PRIVATE_FLAG); | 75 | futex_wait(&futex1, 0, NULL, futex_flag); |
74 | return NULL; | 76 | return NULL; |
75 | } | 77 | } |
76 | 78 | ||
@@ -127,9 +129,12 @@ int bench_futex_requeue(int argc, const char **argv, | |||
127 | if (!worker) | 129 | if (!worker) |
128 | err(EXIT_FAILURE, "calloc"); | 130 | err(EXIT_FAILURE, "calloc"); |
129 | 131 | ||
130 | printf("Run summary [PID %d]: Requeuing %d threads (from %p to %p), " | 132 | if (!fshared) |
131 | "%d at a time.\n\n", | 133 | futex_flag = FUTEX_PRIVATE_FLAG; |
132 | getpid(), nthreads, &futex1, &futex2, nrequeue); | 134 | |
135 | printf("Run summary [PID %d]: Requeuing %d threads (from [%s] %p to %p), " | ||
136 | "%d at a time.\n\n", getpid(), nthreads, | ||
137 | fshared ? "shared":"private", &futex1, &futex2, nrequeue); | ||
133 | 138 | ||
134 | init_stats(&requeued_stats); | 139 | init_stats(&requeued_stats); |
135 | init_stats(&requeuetime_stats); | 140 | init_stats(&requeuetime_stats); |
@@ -156,13 +161,14 @@ int bench_futex_requeue(int argc, const char **argv, | |||
156 | 161 | ||
157 | /* Ok, all threads are patiently blocked, start requeueing */ | 162 | /* Ok, all threads are patiently blocked, start requeueing */ |
158 | gettimeofday(&start, NULL); | 163 | gettimeofday(&start, NULL); |
159 | for (nrequeued = 0; nrequeued < nthreads; nrequeued += nrequeue) | 164 | for (nrequeued = 0; nrequeued < nthreads; nrequeued += nrequeue) { |
160 | /* | 165 | /* |
161 | * Do not wakeup any tasks blocked on futex1, allowing | 166 | * Do not wakeup any tasks blocked on futex1, allowing |
162 | * us to really measure futex_wait functionality. | 167 | * us to really measure futex_wait functionality. |
163 | */ | 168 | */ |
164 | futex_cmp_requeue(&futex1, 0, &futex2, 0, nrequeue, | 169 | futex_cmp_requeue(&futex1, 0, &futex2, 0, |
165 | FUTEX_PRIVATE_FLAG); | 170 | nrequeue, futex_flag); |
171 | } | ||
166 | gettimeofday(&end, NULL); | 172 | gettimeofday(&end, NULL); |
167 | timersub(&end, &start, &runtime); | 173 | timersub(&end, &start, &runtime); |
168 | 174 | ||
@@ -175,7 +181,7 @@ int bench_futex_requeue(int argc, const char **argv, | |||
175 | } | 181 | } |
176 | 182 | ||
177 | /* everybody should be blocked on futex2, wake'em up */ | 183 | /* everybody should be blocked on futex2, wake'em up */ |
178 | nrequeued = futex_wake(&futex2, nthreads, FUTEX_PRIVATE_FLAG); | 184 | nrequeued = futex_wake(&futex2, nthreads, futex_flag); |
179 | if (nthreads != nrequeued) | 185 | if (nthreads != nrequeued) |
180 | warnx("couldn't wakeup all tasks (%d/%d)", nrequeued, nthreads); | 186 | warnx("couldn't wakeup all tasks (%d/%d)", nrequeued, nthreads); |
181 | 187 | ||
diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 50022cbce87e..929f762be47e 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c | |||
@@ -31,16 +31,18 @@ static u_int32_t futex1 = 0; | |||
31 | static unsigned int nwakes = 1; | 31 | static unsigned int nwakes = 1; |
32 | 32 | ||
33 | pthread_t *worker; | 33 | pthread_t *worker; |
34 | static bool done = false, silent = false; | 34 | static bool done = false, silent = false, fshared = false; |
35 | static pthread_mutex_t thread_lock; | 35 | static pthread_mutex_t thread_lock; |
36 | static pthread_cond_t thread_parent, thread_worker; | 36 | static pthread_cond_t thread_parent, thread_worker; |
37 | static struct stats waketime_stats, wakeup_stats; | 37 | static struct stats waketime_stats, wakeup_stats; |
38 | static unsigned int ncpus, threads_starting, nthreads = 0; | 38 | static unsigned int ncpus, threads_starting, nthreads = 0; |
39 | static int futex_flag = 0; | ||
39 | 40 | ||
40 | static const struct option options[] = { | 41 | static const struct option options[] = { |
41 | OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), | 42 | OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), |
42 | OPT_UINTEGER('w', "nwakes", &nwakes, "Specify amount of threads to wake at once"), | 43 | OPT_UINTEGER('w', "nwakes", &nwakes, "Specify amount of threads to wake at once"), |
43 | OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), | 44 | OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), |
45 | OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), | ||
44 | OPT_END() | 46 | OPT_END() |
45 | }; | 47 | }; |
46 | 48 | ||
@@ -58,7 +60,7 @@ static void *workerfn(void *arg __maybe_unused) | |||
58 | pthread_cond_wait(&thread_worker, &thread_lock); | 60 | pthread_cond_wait(&thread_worker, &thread_lock); |
59 | pthread_mutex_unlock(&thread_lock); | 61 | pthread_mutex_unlock(&thread_lock); |
60 | 62 | ||
61 | futex_wait(&futex1, 0, NULL, FUTEX_PRIVATE_FLAG); | 63 | futex_wait(&futex1, 0, NULL, futex_flag); |
62 | return NULL; | 64 | return NULL; |
63 | } | 65 | } |
64 | 66 | ||
@@ -130,9 +132,12 @@ int bench_futex_wake(int argc, const char **argv, | |||
130 | if (!worker) | 132 | if (!worker) |
131 | err(EXIT_FAILURE, "calloc"); | 133 | err(EXIT_FAILURE, "calloc"); |
132 | 134 | ||
133 | printf("Run summary [PID %d]: blocking on %d threads (at futex %p), " | 135 | if (!fshared) |
136 | futex_flag = FUTEX_PRIVATE_FLAG; | ||
137 | |||
138 | printf("Run summary [PID %d]: blocking on %d threads (at [%s] futex %p), " | ||
134 | "waking up %d at a time.\n\n", | 139 | "waking up %d at a time.\n\n", |
135 | getpid(), nthreads, &futex1, nwakes); | 140 | getpid(), nthreads, fshared ? "shared":"private", &futex1, nwakes); |
136 | 141 | ||
137 | init_stats(&wakeup_stats); | 142 | init_stats(&wakeup_stats); |
138 | init_stats(&waketime_stats); | 143 | init_stats(&waketime_stats); |
@@ -160,7 +165,7 @@ int bench_futex_wake(int argc, const char **argv, | |||
160 | /* Ok, all threads are patiently blocked, start waking folks up */ | 165 | /* Ok, all threads are patiently blocked, start waking folks up */ |
161 | gettimeofday(&start, NULL); | 166 | gettimeofday(&start, NULL); |
162 | while (nwoken != nthreads) | 167 | while (nwoken != nthreads) |
163 | nwoken += futex_wake(&futex1, nwakes, FUTEX_PRIVATE_FLAG); | 168 | nwoken += futex_wake(&futex1, nwakes, futex_flag); |
164 | gettimeofday(&end, NULL); | 169 | gettimeofday(&end, NULL); |
165 | timersub(&end, &start, &runtime); | 170 | timersub(&end, &start, &runtime); |
166 | 171 | ||