diff options
author | Davidlohr Bueso <dave@stgolabs.net> | 2017-11-26 23:20:59 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2017-11-30 12:02:05 -0500 |
commit | 3b2323c2c1c4acf8961cfcdddcee9889daaa21e3 (patch) | |
tree | a366e8b5137d89f10885ff7d0e6ade8ed0cbf047 | |
parent | 17a68b835921c4664929376447cae5e3374ce2a7 (diff) |
perf bench futex: Use cpumaps
It was reported that the whole futex bench breaks when dealing with
non-contiguously numbered cpus.
$ echo 0 | sudo tee /sys/devices/system/cpu/cpu3/online
$ ./perf bench futex all
perf: pthread_create: Operation not permitted
Run summary [PID 14934]: 7 threads, each ....
James had implemented an approach with cpumaps that use an in house
flavor. Instead of re-inventing the wheel, I've redone the patch such
that we use the perf's util/cpumap.c interface instead.
Applies to all futex benchmarks.
Suggested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Originally-from: James Yang <james.yang@arm.com>
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Kim Phillips <kim.phillips@arm.com>
Link: http://lkml.kernel.org/r/20171127042101.3659-2-dave@stgolabs.net
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/bench/futex-hash.c | 19 | ||||
-rw-r--r-- | tools/perf/bench/futex-lock-pi.c | 23 | ||||
-rw-r--r-- | tools/perf/bench/futex-requeue.c | 22 | ||||
-rw-r--r-- | tools/perf/bench/futex-wake-parallel.c | 24 | ||||
-rw-r--r-- | tools/perf/bench/futex-wake.c | 18 |
5 files changed, 65 insertions, 41 deletions
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index 58ae6ed8f38b..2defb6df7fd0 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <subcmd/parse-options.h> | 24 | #include <subcmd/parse-options.h> |
25 | #include "bench.h" | 25 | #include "bench.h" |
26 | #include "futex.h" | 26 | #include "futex.h" |
27 | #include "cpumap.h" | ||
27 | 28 | ||
28 | #include <err.h> | 29 | #include <err.h> |
29 | #include <sys/time.h> | 30 | #include <sys/time.h> |
@@ -118,11 +119,12 @@ static void print_summary(void) | |||
118 | int bench_futex_hash(int argc, const char **argv) | 119 | int bench_futex_hash(int argc, const char **argv) |
119 | { | 120 | { |
120 | int ret = 0; | 121 | int ret = 0; |
121 | cpu_set_t cpu; | 122 | cpu_set_t cpuset; |
122 | struct sigaction act; | 123 | struct sigaction act; |
123 | unsigned int i, ncpus; | 124 | unsigned int i; |
124 | pthread_attr_t thread_attr; | 125 | pthread_attr_t thread_attr; |
125 | struct worker *worker = NULL; | 126 | struct worker *worker = NULL; |
127 | struct cpu_map *cpu; | ||
126 | 128 | ||
127 | argc = parse_options(argc, argv, options, bench_futex_hash_usage, 0); | 129 | argc = parse_options(argc, argv, options, bench_futex_hash_usage, 0); |
128 | if (argc) { | 130 | if (argc) { |
@@ -130,14 +132,16 @@ int bench_futex_hash(int argc, const char **argv) | |||
130 | exit(EXIT_FAILURE); | 132 | exit(EXIT_FAILURE); |
131 | } | 133 | } |
132 | 134 | ||
133 | ncpus = sysconf(_SC_NPROCESSORS_ONLN); | 135 | cpu = cpu_map__new(NULL); |
136 | if (!cpu) | ||
137 | goto errmem; | ||
134 | 138 | ||
135 | sigfillset(&act.sa_mask); | 139 | sigfillset(&act.sa_mask); |
136 | act.sa_sigaction = toggle_done; | 140 | act.sa_sigaction = toggle_done; |
137 | sigaction(SIGINT, &act, NULL); | 141 | sigaction(SIGINT, &act, NULL); |
138 | 142 | ||
139 | if (!nthreads) /* default to the number of CPUs */ | 143 | if (!nthreads) /* default to the number of CPUs */ |
140 | nthreads = ncpus; | 144 | nthreads = cpu->nr; |
141 | 145 | ||
142 | worker = calloc(nthreads, sizeof(*worker)); | 146 | worker = calloc(nthreads, sizeof(*worker)); |
143 | if (!worker) | 147 | if (!worker) |
@@ -163,10 +167,10 @@ int bench_futex_hash(int argc, const char **argv) | |||
163 | if (!worker[i].futex) | 167 | if (!worker[i].futex) |
164 | goto errmem; | 168 | goto errmem; |
165 | 169 | ||
166 | CPU_ZERO(&cpu); | 170 | CPU_ZERO(&cpuset); |
167 | CPU_SET(i % ncpus, &cpu); | 171 | CPU_SET(cpu->map[i % cpu->nr], &cpuset); |
168 | 172 | ||
169 | ret = pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpu); | 173 | ret = pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset); |
170 | if (ret) | 174 | if (ret) |
171 | err(EXIT_FAILURE, "pthread_attr_setaffinity_np"); | 175 | err(EXIT_FAILURE, "pthread_attr_setaffinity_np"); |
172 | 176 | ||
@@ -217,6 +221,7 @@ int bench_futex_hash(int argc, const char **argv) | |||
217 | print_summary(); | 221 | print_summary(); |
218 | 222 | ||
219 | free(worker); | 223 | free(worker); |
224 | free(cpu); | ||
220 | return ret; | 225 | return ret; |
221 | errmem: | 226 | errmem: |
222 | err(EXIT_FAILURE, "calloc"); | 227 | err(EXIT_FAILURE, "calloc"); |
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index 08653ae8a8c4..8e9c4753e304 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <errno.h> | 15 | #include <errno.h> |
16 | #include "bench.h" | 16 | #include "bench.h" |
17 | #include "futex.h" | 17 | #include "futex.h" |
18 | #include "cpumap.h" | ||
18 | 19 | ||
19 | #include <err.h> | 20 | #include <err.h> |
20 | #include <stdlib.h> | 21 | #include <stdlib.h> |
@@ -32,7 +33,7 @@ static struct worker *worker; | |||
32 | static unsigned int nsecs = 10; | 33 | static unsigned int nsecs = 10; |
33 | static bool silent = false, multi = false; | 34 | static bool silent = false, multi = false; |
34 | static bool done = false, fshared = false; | 35 | static bool done = false, fshared = false; |
35 | static unsigned int ncpus, nthreads = 0; | 36 | static unsigned int nthreads = 0; |
36 | static int futex_flag = 0; | 37 | static int futex_flag = 0; |
37 | struct timeval start, end, runtime; | 38 | struct timeval start, end, runtime; |
38 | static pthread_mutex_t thread_lock; | 39 | static pthread_mutex_t thread_lock; |
@@ -113,9 +114,10 @@ static void *workerfn(void *arg) | |||
113 | return NULL; | 114 | return NULL; |
114 | } | 115 | } |
115 | 116 | ||
116 | static void create_threads(struct worker *w, pthread_attr_t thread_attr) | 117 | static void create_threads(struct worker *w, pthread_attr_t thread_attr, |
118 | struct cpu_map *cpu) | ||
117 | { | 119 | { |
118 | cpu_set_t cpu; | 120 | cpu_set_t cpuset; |
119 | unsigned int i; | 121 | unsigned int i; |
120 | 122 | ||
121 | threads_starting = nthreads; | 123 | threads_starting = nthreads; |
@@ -130,10 +132,10 @@ static void create_threads(struct worker *w, pthread_attr_t thread_attr) | |||
130 | } else | 132 | } else |
131 | worker[i].futex = &global_futex; | 133 | worker[i].futex = &global_futex; |
132 | 134 | ||
133 | CPU_ZERO(&cpu); | 135 | CPU_ZERO(&cpuset); |
134 | CPU_SET(i % ncpus, &cpu); | 136 | CPU_SET(cpu->map[i % cpu->nr], &cpuset); |
135 | 137 | ||
136 | if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpu)) | 138 | if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset)) |
137 | err(EXIT_FAILURE, "pthread_attr_setaffinity_np"); | 139 | err(EXIT_FAILURE, "pthread_attr_setaffinity_np"); |
138 | 140 | ||
139 | if (pthread_create(&w[i].thread, &thread_attr, workerfn, &worker[i])) | 141 | if (pthread_create(&w[i].thread, &thread_attr, workerfn, &worker[i])) |
@@ -147,19 +149,22 @@ int bench_futex_lock_pi(int argc, const char **argv) | |||
147 | unsigned int i; | 149 | unsigned int i; |
148 | struct sigaction act; | 150 | struct sigaction act; |
149 | pthread_attr_t thread_attr; | 151 | pthread_attr_t thread_attr; |
152 | struct cpu_map *cpu; | ||
150 | 153 | ||
151 | argc = parse_options(argc, argv, options, bench_futex_lock_pi_usage, 0); | 154 | argc = parse_options(argc, argv, options, bench_futex_lock_pi_usage, 0); |
152 | if (argc) | 155 | if (argc) |
153 | goto err; | 156 | goto err; |
154 | 157 | ||
155 | ncpus = sysconf(_SC_NPROCESSORS_ONLN); | 158 | cpu = cpu_map__new(NULL); |
159 | if (!cpu) | ||
160 | err(EXIT_FAILURE, "calloc"); | ||
156 | 161 | ||
157 | sigfillset(&act.sa_mask); | 162 | sigfillset(&act.sa_mask); |
158 | act.sa_sigaction = toggle_done; | 163 | act.sa_sigaction = toggle_done; |
159 | sigaction(SIGINT, &act, NULL); | 164 | sigaction(SIGINT, &act, NULL); |
160 | 165 | ||
161 | if (!nthreads) | 166 | if (!nthreads) |
162 | nthreads = ncpus; | 167 | nthreads = cpu->nr; |
163 | 168 | ||
164 | worker = calloc(nthreads, sizeof(*worker)); | 169 | worker = calloc(nthreads, sizeof(*worker)); |
165 | if (!worker) | 170 | if (!worker) |
@@ -180,7 +185,7 @@ int bench_futex_lock_pi(int argc, const char **argv) | |||
180 | pthread_attr_init(&thread_attr); | 185 | pthread_attr_init(&thread_attr); |
181 | gettimeofday(&start, NULL); | 186 | gettimeofday(&start, NULL); |
182 | 187 | ||
183 | create_threads(worker, thread_attr); | 188 | create_threads(worker, thread_attr, cpu); |
184 | pthread_attr_destroy(&thread_attr); | 189 | pthread_attr_destroy(&thread_attr); |
185 | 190 | ||
186 | pthread_mutex_lock(&thread_lock); | 191 | pthread_mutex_lock(&thread_lock); |
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 1058c194608a..fc692efa0c05 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <errno.h> | 22 | #include <errno.h> |
23 | #include "bench.h" | 23 | #include "bench.h" |
24 | #include "futex.h" | 24 | #include "futex.h" |
25 | #include "cpumap.h" | ||
25 | 26 | ||
26 | #include <err.h> | 27 | #include <err.h> |
27 | #include <stdlib.h> | 28 | #include <stdlib.h> |
@@ -40,7 +41,7 @@ static bool done = false, silent = false, fshared = false; | |||
40 | static pthread_mutex_t thread_lock; | 41 | static pthread_mutex_t thread_lock; |
41 | static pthread_cond_t thread_parent, thread_worker; | 42 | static pthread_cond_t thread_parent, thread_worker; |
42 | static struct stats requeuetime_stats, requeued_stats; | 43 | static struct stats requeuetime_stats, requeued_stats; |
43 | static unsigned int ncpus, threads_starting, nthreads = 0; | 44 | static unsigned int threads_starting, nthreads = 0; |
44 | static int futex_flag = 0; | 45 | static int futex_flag = 0; |
45 | 46 | ||
46 | static const struct option options[] = { | 47 | static const struct option options[] = { |
@@ -83,19 +84,19 @@ static void *workerfn(void *arg __maybe_unused) | |||
83 | } | 84 | } |
84 | 85 | ||
85 | static void block_threads(pthread_t *w, | 86 | static void block_threads(pthread_t *w, |
86 | pthread_attr_t thread_attr) | 87 | pthread_attr_t thread_attr, struct cpu_map *cpu) |
87 | { | 88 | { |
88 | cpu_set_t cpu; | 89 | cpu_set_t cpuset; |
89 | unsigned int i; | 90 | unsigned int i; |
90 | 91 | ||
91 | threads_starting = nthreads; | 92 | threads_starting = nthreads; |
92 | 93 | ||
93 | /* create and block all threads */ | 94 | /* create and block all threads */ |
94 | for (i = 0; i < nthreads; i++) { | 95 | for (i = 0; i < nthreads; i++) { |
95 | CPU_ZERO(&cpu); | 96 | CPU_ZERO(&cpuset); |
96 | CPU_SET(i % ncpus, &cpu); | 97 | CPU_SET(cpu->map[i % cpu->nr], &cpuset); |
97 | 98 | ||
98 | if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpu)) | 99 | if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset)) |
99 | err(EXIT_FAILURE, "pthread_attr_setaffinity_np"); | 100 | err(EXIT_FAILURE, "pthread_attr_setaffinity_np"); |
100 | 101 | ||
101 | if (pthread_create(&w[i], &thread_attr, workerfn, NULL)) | 102 | if (pthread_create(&w[i], &thread_attr, workerfn, NULL)) |
@@ -116,19 +117,22 @@ int bench_futex_requeue(int argc, const char **argv) | |||
116 | unsigned int i, j; | 117 | unsigned int i, j; |
117 | struct sigaction act; | 118 | struct sigaction act; |
118 | pthread_attr_t thread_attr; | 119 | pthread_attr_t thread_attr; |
120 | struct cpu_map *cpu; | ||
119 | 121 | ||
120 | argc = parse_options(argc, argv, options, bench_futex_requeue_usage, 0); | 122 | argc = parse_options(argc, argv, options, bench_futex_requeue_usage, 0); |
121 | if (argc) | 123 | if (argc) |
122 | goto err; | 124 | goto err; |
123 | 125 | ||
124 | ncpus = sysconf(_SC_NPROCESSORS_ONLN); | 126 | cpu = cpu_map__new(NULL); |
127 | if (!cpu) | ||
128 | err(EXIT_FAILURE, "cpu_map__new"); | ||
125 | 129 | ||
126 | sigfillset(&act.sa_mask); | 130 | sigfillset(&act.sa_mask); |
127 | act.sa_sigaction = toggle_done; | 131 | act.sa_sigaction = toggle_done; |
128 | sigaction(SIGINT, &act, NULL); | 132 | sigaction(SIGINT, &act, NULL); |
129 | 133 | ||
130 | if (!nthreads) | 134 | if (!nthreads) |
131 | nthreads = ncpus; | 135 | nthreads = cpu->nr; |
132 | 136 | ||
133 | worker = calloc(nthreads, sizeof(*worker)); | 137 | worker = calloc(nthreads, sizeof(*worker)); |
134 | if (!worker) | 138 | if (!worker) |
@@ -156,7 +160,7 @@ int bench_futex_requeue(int argc, const char **argv) | |||
156 | struct timeval start, end, runtime; | 160 | struct timeval start, end, runtime; |
157 | 161 | ||
158 | /* create, launch & block all threads */ | 162 | /* create, launch & block all threads */ |
159 | block_threads(worker, thread_attr); | 163 | block_threads(worker, thread_attr, cpu); |
160 | 164 | ||
161 | /* make sure all threads are already blocked */ | 165 | /* make sure all threads are already blocked */ |
162 | pthread_mutex_lock(&thread_lock); | 166 | pthread_mutex_lock(&thread_lock); |
diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c index b4732dad9f89..4488c27e8a43 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <errno.h> | 21 | #include <errno.h> |
22 | #include "bench.h" | 22 | #include "bench.h" |
23 | #include "futex.h" | 23 | #include "futex.h" |
24 | #include "cpumap.h" | ||
24 | 25 | ||
25 | #include <err.h> | 26 | #include <err.h> |
26 | #include <stdlib.h> | 27 | #include <stdlib.h> |
@@ -43,7 +44,7 @@ static unsigned int nblocked_threads = 0, nwaking_threads = 0; | |||
43 | static pthread_mutex_t thread_lock; | 44 | static pthread_mutex_t thread_lock; |
44 | static pthread_cond_t thread_parent, thread_worker; | 45 | static pthread_cond_t thread_parent, thread_worker; |
45 | static struct stats waketime_stats, wakeup_stats; | 46 | static struct stats waketime_stats, wakeup_stats; |
46 | static unsigned int ncpus, threads_starting; | 47 | static unsigned int threads_starting; |
47 | static int futex_flag = 0; | 48 | static int futex_flag = 0; |
48 | 49 | ||
49 | static const struct option options[] = { | 50 | static const struct option options[] = { |
@@ -119,19 +120,20 @@ static void *blocked_workerfn(void *arg __maybe_unused) | |||
119 | return NULL; | 120 | return NULL; |
120 | } | 121 | } |
121 | 122 | ||
122 | static void block_threads(pthread_t *w, pthread_attr_t thread_attr) | 123 | static void block_threads(pthread_t *w, pthread_attr_t thread_attr, |
124 | struct cpu_map *cpu) | ||
123 | { | 125 | { |
124 | cpu_set_t cpu; | 126 | cpu_set_t cpuset; |
125 | unsigned int i; | 127 | unsigned int i; |
126 | 128 | ||
127 | threads_starting = nblocked_threads; | 129 | threads_starting = nblocked_threads; |
128 | 130 | ||
129 | /* create and block all threads */ | 131 | /* create and block all threads */ |
130 | for (i = 0; i < nblocked_threads; i++) { | 132 | for (i = 0; i < nblocked_threads; i++) { |
131 | CPU_ZERO(&cpu); | 133 | CPU_ZERO(&cpuset); |
132 | CPU_SET(i % ncpus, &cpu); | 134 | CPU_SET(cpu->map[i % cpu->nr], &cpuset); |
133 | 135 | ||
134 | if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpu)) | 136 | if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset)) |
135 | err(EXIT_FAILURE, "pthread_attr_setaffinity_np"); | 137 | err(EXIT_FAILURE, "pthread_attr_setaffinity_np"); |
136 | 138 | ||
137 | if (pthread_create(&w[i], &thread_attr, blocked_workerfn, NULL)) | 139 | if (pthread_create(&w[i], &thread_attr, blocked_workerfn, NULL)) |
@@ -205,6 +207,7 @@ int bench_futex_wake_parallel(int argc, const char **argv) | |||
205 | struct sigaction act; | 207 | struct sigaction act; |
206 | pthread_attr_t thread_attr; | 208 | pthread_attr_t thread_attr; |
207 | struct thread_data *waking_worker; | 209 | struct thread_data *waking_worker; |
210 | struct cpu_map *cpu; | ||
208 | 211 | ||
209 | argc = parse_options(argc, argv, options, | 212 | argc = parse_options(argc, argv, options, |
210 | bench_futex_wake_parallel_usage, 0); | 213 | bench_futex_wake_parallel_usage, 0); |
@@ -217,9 +220,12 @@ int bench_futex_wake_parallel(int argc, const char **argv) | |||
217 | act.sa_sigaction = toggle_done; | 220 | act.sa_sigaction = toggle_done; |
218 | sigaction(SIGINT, &act, NULL); | 221 | sigaction(SIGINT, &act, NULL); |
219 | 222 | ||
220 | ncpus = sysconf(_SC_NPROCESSORS_ONLN); | 223 | cpu = cpu_map__new(NULL); |
224 | if (!cpu) | ||
225 | err(EXIT_FAILURE, "calloc"); | ||
226 | |||
221 | if (!nblocked_threads) | 227 | if (!nblocked_threads) |
222 | nblocked_threads = ncpus; | 228 | nblocked_threads = cpu->nr; |
223 | 229 | ||
224 | /* some sanity checks */ | 230 | /* some sanity checks */ |
225 | if (nwaking_threads > nblocked_threads || !nwaking_threads) | 231 | if (nwaking_threads > nblocked_threads || !nwaking_threads) |
@@ -259,7 +265,7 @@ int bench_futex_wake_parallel(int argc, const char **argv) | |||
259 | err(EXIT_FAILURE, "calloc"); | 265 | err(EXIT_FAILURE, "calloc"); |
260 | 266 | ||
261 | /* create, launch & block all threads */ | 267 | /* create, launch & block all threads */ |
262 | block_threads(blocked_worker, thread_attr); | 268 | block_threads(blocked_worker, thread_attr, cpu); |
263 | 269 | ||
264 | /* make sure all threads are already blocked */ | 270 | /* make sure all threads are already blocked */ |
265 | pthread_mutex_lock(&thread_lock); | 271 | pthread_mutex_lock(&thread_lock); |
diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 8c5c0b6b5c97..e8181ad7d088 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <errno.h> | 22 | #include <errno.h> |
23 | #include "bench.h" | 23 | #include "bench.h" |
24 | #include "futex.h" | 24 | #include "futex.h" |
25 | #include "cpumap.h" | ||
25 | 26 | ||
26 | #include <err.h> | 27 | #include <err.h> |
27 | #include <stdlib.h> | 28 | #include <stdlib.h> |
@@ -89,19 +90,19 @@ static void print_summary(void) | |||
89 | } | 90 | } |
90 | 91 | ||
91 | static void block_threads(pthread_t *w, | 92 | static void block_threads(pthread_t *w, |
92 | pthread_attr_t thread_attr) | 93 | pthread_attr_t thread_attr, struct cpu_map *cpu) |
93 | { | 94 | { |
94 | cpu_set_t cpu; | 95 | cpu_set_t cpuset; |
95 | unsigned int i; | 96 | unsigned int i; |
96 | 97 | ||
97 | threads_starting = nthreads; | 98 | threads_starting = nthreads; |
98 | 99 | ||
99 | /* create and block all threads */ | 100 | /* create and block all threads */ |
100 | for (i = 0; i < nthreads; i++) { | 101 | for (i = 0; i < nthreads; i++) { |
101 | CPU_ZERO(&cpu); | 102 | CPU_ZERO(&cpuset); |
102 | CPU_SET(i % ncpus, &cpu); | 103 | CPU_SET(cpu->map[i % cpu->nr], &cpuset); |
103 | 104 | ||
104 | if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpu)) | 105 | if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset)) |
105 | err(EXIT_FAILURE, "pthread_attr_setaffinity_np"); | 106 | err(EXIT_FAILURE, "pthread_attr_setaffinity_np"); |
106 | 107 | ||
107 | if (pthread_create(&w[i], &thread_attr, workerfn, NULL)) | 108 | if (pthread_create(&w[i], &thread_attr, workerfn, NULL)) |
@@ -122,6 +123,7 @@ int bench_futex_wake(int argc, const char **argv) | |||
122 | unsigned int i, j; | 123 | unsigned int i, j; |
123 | struct sigaction act; | 124 | struct sigaction act; |
124 | pthread_attr_t thread_attr; | 125 | pthread_attr_t thread_attr; |
126 | struct cpu_map *cpu; | ||
125 | 127 | ||
126 | argc = parse_options(argc, argv, options, bench_futex_wake_usage, 0); | 128 | argc = parse_options(argc, argv, options, bench_futex_wake_usage, 0); |
127 | if (argc) { | 129 | if (argc) { |
@@ -129,7 +131,9 @@ int bench_futex_wake(int argc, const char **argv) | |||
129 | exit(EXIT_FAILURE); | 131 | exit(EXIT_FAILURE); |
130 | } | 132 | } |
131 | 133 | ||
132 | ncpus = sysconf(_SC_NPROCESSORS_ONLN); | 134 | cpu = cpu_map__new(NULL); |
135 | if (!cpu) | ||
136 | err(EXIT_FAILURE, "calloc"); | ||
133 | 137 | ||
134 | sigfillset(&act.sa_mask); | 138 | sigfillset(&act.sa_mask); |
135 | act.sa_sigaction = toggle_done; | 139 | act.sa_sigaction = toggle_done; |
@@ -161,7 +165,7 @@ int bench_futex_wake(int argc, const char **argv) | |||
161 | struct timeval start, end, runtime; | 165 | struct timeval start, end, runtime; |
162 | 166 | ||
163 | /* create, launch & block all threads */ | 167 | /* create, launch & block all threads */ |
164 | block_threads(worker, thread_attr); | 168 | block_threads(worker, thread_attr, cpu); |
165 | 169 | ||
166 | /* make sure all threads are already blocked */ | 170 | /* make sure all threads are already blocked */ |
167 | pthread_mutex_lock(&thread_lock); | 171 | pthread_mutex_lock(&thread_lock); |