Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Davidlohr Bueso and committed by
Arnaldo Carvalho de Melo
86c87e13 2c82c3ad

+30 -16
+5 -2
tools/perf/bench/futex-hash.c
··· 26 26 /* amount of futexes per thread */ 27 27 static unsigned int nfutexes = 1024; 28 28 static bool fshared = false, done = false, silent = false; 29 + static int futex_flag = 0; 29 30 30 31 struct timeval start, end, runtime; 31 32 static pthread_mutex_t thread_lock; ··· 76 75 * such as internal waitqueue handling, thus enlarging 77 76 * the critical region protected by hb->lock. 78 77 */ 79 - ret = futex_wait(&w->futex[i], 1234, NULL, 80 - fshared ? 0 : FUTEX_PRIVATE_FLAG); 78 + ret = futex_wait(&w->futex[i], 1234, NULL, futex_flag); 81 79 if (!silent && 82 80 (!ret || errno != EAGAIN || errno != EWOULDBLOCK)) 83 81 warn("Non-expected futex return call"); ··· 134 134 worker = calloc(nthreads, sizeof(*worker)); 135 135 if (!worker) 136 136 goto errmem; 137 + 138 + if (!fshared) 139 + futex_flag = FUTEX_PRIVATE_FLAG; 137 140 138 141 printf("Run summary [PID %d]: %d threads, each operating on %d [%s] futexes for %d secs.\n\n", 139 142 getpid(), nthreads, nfutexes, fshared ? "shared":"private", nsecs);
+15 -9
tools/perf/bench/futex-requeue.c
··· 30 30 static unsigned int nrequeue = 1; 31 31 32 32 static pthread_t *worker; 33 - static bool done = 0, silent = 0; 33 + static bool done = false, silent = false, fshared = false; 34 34 static pthread_mutex_t thread_lock; 35 35 static pthread_cond_t thread_parent, thread_worker; 36 36 static struct stats requeuetime_stats, requeued_stats; 37 37 static unsigned int ncpus, threads_starting, nthreads = 0; 38 + static int futex_flag = 0; 38 39 39 40 static const struct option options[] = { 40 41 OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), 41 42 OPT_UINTEGER('q', "nrequeue", &nrequeue, "Specify amount of threads to requeue at once"), 42 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 45 OPT_END() 44 46 }; 45 47 ··· 72 70 pthread_cond_wait(&thread_worker, &thread_lock); 73 71 pthread_mutex_unlock(&thread_lock); 74 72 75 - futex_wait(&futex1, 0, NULL, FUTEX_PRIVATE_FLAG); 73 + futex_wait(&futex1, 0, NULL, futex_flag); 76 74 return NULL; 77 75 } 78 76 ··· 129 127 if (!worker) 130 128 err(EXIT_FAILURE, "calloc"); 131 129 132 - printf("Run summary [PID %d]: Requeuing %d threads (from %p to %p), " 133 - "%d at a time.\n\n", 134 - getpid(), nthreads, &futex1, &futex2, nrequeue); 130 + if (!fshared) 131 + futex_flag = FUTEX_PRIVATE_FLAG; 132 + 133 + printf("Run summary [PID %d]: Requeuing %d threads (from [%s] %p to %p), " 134 + "%d at a time.\n\n", getpid(), nthreads, 135 + fshared ? "shared":"private", &futex1, &futex2, nrequeue); 135 136 136 137 init_stats(&requeued_stats); 137 138 init_stats(&requeuetime_stats); ··· 161 156 162 157 /* Ok, all threads are patiently blocked, start requeueing */ 163 158 gettimeofday(&start, NULL); 164 - for (nrequeued = 0; nrequeued < nthreads; nrequeued += nrequeue) 159 + for (nrequeued = 0; nrequeued < nthreads; nrequeued += nrequeue) { 165 160 /* 166 161 * Do not wakeup any tasks blocked on futex1, allowing 167 162 * us to really measure futex_wait functionality. 168 163 */ 169 - futex_cmp_requeue(&futex1, 0, &futex2, 0, nrequeue, 170 - FUTEX_PRIVATE_FLAG); 164 + futex_cmp_requeue(&futex1, 0, &futex2, 0, 165 + nrequeue, futex_flag); 166 + } 171 167 gettimeofday(&end, NULL); 172 168 timersub(&end, &start, &runtime); 173 169 ··· 181 175 } 182 176 183 177 /* everybody should be blocked on futex2, wake'em up */ 184 - nrequeued = futex_wake(&futex2, nthreads, FUTEX_PRIVATE_FLAG); 178 + nrequeued = futex_wake(&futex2, nthreads, futex_flag); 185 179 if (nthreads != nrequeued) 186 180 warnx("couldn't wakeup all tasks (%d/%d)", nrequeued, nthreads); 187 181
+10 -5
tools/perf/bench/futex-wake.c
··· 31 31 static unsigned int nwakes = 1; 32 32 33 33 pthread_t *worker; 34 - static bool done = false, silent = false; 34 + static bool done = false, silent = false, fshared = false; 35 35 static pthread_mutex_t thread_lock; 36 36 static pthread_cond_t thread_parent, thread_worker; 37 37 static struct stats waketime_stats, wakeup_stats; 38 38 static unsigned int ncpus, threads_starting, nthreads = 0; 39 + static int futex_flag = 0; 39 40 40 41 static const struct option options[] = { 41 42 OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), 42 43 OPT_UINTEGER('w', "nwakes", &nwakes, "Specify amount of threads to wake at once"), 43 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 46 OPT_END() 45 47 }; 46 48 ··· 60 58 pthread_cond_wait(&thread_worker, &thread_lock); 61 59 pthread_mutex_unlock(&thread_lock); 62 60 63 - futex_wait(&futex1, 0, NULL, FUTEX_PRIVATE_FLAG); 61 + futex_wait(&futex1, 0, NULL, futex_flag); 64 62 return NULL; 65 63 } 66 64 ··· 132 130 if (!worker) 133 131 err(EXIT_FAILURE, "calloc"); 134 132 135 - printf("Run summary [PID %d]: blocking on %d threads (at futex %p), " 133 + if (!fshared) 134 + futex_flag = FUTEX_PRIVATE_FLAG; 135 + 136 + printf("Run summary [PID %d]: blocking on %d threads (at [%s] futex %p), " 136 137 "waking up %d at a time.\n\n", 137 - getpid(), nthreads, &futex1, nwakes); 138 + getpid(), nthreads, fshared ? "shared":"private", &futex1, nwakes); 138 139 139 140 init_stats(&wakeup_stats); 140 141 init_stats(&waketime_stats); ··· 165 160 /* Ok, all threads are patiently blocked, start waking folks up */ 166 161 gettimeofday(&start, NULL); 167 162 while (nwoken != nthreads) 168 - nwoken += futex_wake(&futex1, nwakes, FUTEX_PRIVATE_FLAG); 163 + nwoken += futex_wake(&futex1, nwakes, futex_flag); 169 164 gettimeofday(&end, NULL); 170 165 timersub(&end, &start, &runtime); 171 166