diff options
Diffstat (limited to 'tools/perf/bench/futex-requeue.c')
-rw-r--r-- | tools/perf/bench/futex-requeue.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 732403bfd31a..bedff6b5b3cf 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,16 +161,20 @@ 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 | if (nrequeued > nthreads) | ||
176 | nrequeued = nthreads; | ||
177 | |||
169 | update_stats(&requeued_stats, nrequeued); | 178 | update_stats(&requeued_stats, nrequeued); |
170 | update_stats(&requeuetime_stats, runtime.tv_usec); | 179 | update_stats(&requeuetime_stats, runtime.tv_usec); |
171 | 180 | ||
@@ -175,7 +184,7 @@ int bench_futex_requeue(int argc, const char **argv, | |||
175 | } | 184 | } |
176 | 185 | ||
177 | /* everybody should be blocked on futex2, wake'em up */ | 186 | /* everybody should be blocked on futex2, wake'em up */ |
178 | nrequeued = futex_wake(&futex2, nthreads, FUTEX_PRIVATE_FLAG); | 187 | nrequeued = futex_wake(&futex2, nthreads, futex_flag); |
179 | if (nthreads != nrequeued) | 188 | if (nthreads != nrequeued) |
180 | warnx("couldn't wakeup all tasks (%d/%d)", nrequeued, nthreads); | 189 | warnx("couldn't wakeup all tasks (%d/%d)", nrequeued, nthreads); |
181 | 190 | ||
@@ -184,7 +193,6 @@ int bench_futex_requeue(int argc, const char **argv, | |||
184 | if (ret) | 193 | if (ret) |
185 | err(EXIT_FAILURE, "pthread_join"); | 194 | err(EXIT_FAILURE, "pthread_join"); |
186 | } | 195 | } |
187 | |||
188 | } | 196 | } |
189 | 197 | ||
190 | /* cleanup & report results */ | 198 | /* cleanup & report results */ |