This source file includes following definitions.
- hwloc_fix_cpubind
- hwloc_set_cpubind
- hwloc_get_cpubind
- hwloc_set_proc_cpubind
- hwloc_get_proc_cpubind
- hwloc_set_thread_cpubind
- hwloc_get_thread_cpubind
- hwloc_get_last_cpu_location
- hwloc_get_proc_last_cpu_location
- hwloc_fix_membind
- hwloc_fix_membind_cpuset
- hwloc__check_membind_policy
- hwloc_set_membind_by_nodeset
- hwloc_set_membind
- hwloc_get_membind_by_nodeset
- hwloc_get_membind
- hwloc_set_proc_membind_by_nodeset
- hwloc_set_proc_membind
- hwloc_get_proc_membind_by_nodeset
- hwloc_get_proc_membind
- hwloc_set_area_membind_by_nodeset
- hwloc_set_area_membind
- hwloc_get_area_membind_by_nodeset
- hwloc_get_area_membind
- hwloc_get_area_memlocation_by_nodeset
- hwloc_get_area_memlocation
- hwloc_alloc_heap
- hwloc_alloc_mmap
- hwloc_free_heap
- hwloc_free_mmap
- hwloc_alloc
- hwloc_alloc_membind_by_nodeset
- hwloc_alloc_membind
- hwloc_free
- dontset_return_complete_cpuset
- dontset_thisthread_cpubind
- dontget_thisthread_cpubind
- dontset_thisproc_cpubind
- dontget_thisproc_cpubind
- dontset_proc_cpubind
- dontget_proc_cpubind
- dontset_thread_cpubind
- dontget_thread_cpubind
- dontset_return_complete_nodeset
- dontset_thisproc_membind
- dontget_thisproc_membind
- dontset_thisthread_membind
- dontget_thisthread_membind
- dontset_proc_membind
- dontget_proc_membind
- dontset_area_membind
- dontget_area_membind
- dontget_area_memlocation
- dontalloc_membind
- dontfree_membind
- hwloc_set_dummy_hooks
- hwloc_set_native_binding_hooks
- hwloc_set_binding_hooks
1
2
3
4
5
6
7
8
9 #include <private/autogen/config.h>
10 #include <hwloc.h>
11 #include <private/private.h>
12 #include <hwloc/helper.h>
13 #ifdef HAVE_SYS_MMAN_H
14 # include <sys/mman.h>
15 #endif
16
17 #if defined(hwloc_getpagesize) && !defined(HAVE_POSIX_MEMALIGN) && defined(HAVE_MEMALIGN) && defined(HAVE_MALLOC_H)
18 #include <malloc.h>
19 #endif
20 #ifdef HAVE_UNISTD_H
21 #include <unistd.h>
22 #endif
23 #include <stdlib.h>
24 #include <errno.h>
25
26
27
28
29
30
31
32
33 #define HWLOC_CPUBIND_ALLFLAGS (HWLOC_CPUBIND_PROCESS|HWLOC_CPUBIND_THREAD|HWLOC_CPUBIND_STRICT|HWLOC_CPUBIND_NOMEMBIND)
34
35 static hwloc_const_bitmap_t
36 hwloc_fix_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t set)
37 {
38 hwloc_const_bitmap_t topology_set = hwloc_topology_get_topology_cpuset(topology);
39 hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology);
40
41 if (hwloc_bitmap_iszero(set)) {
42 errno = EINVAL;
43 return NULL;
44 }
45
46 if (!hwloc_bitmap_isincluded(set, complete_set)) {
47 errno = EINVAL;
48 return NULL;
49 }
50
51 if (hwloc_bitmap_isincluded(topology_set, set))
52 set = complete_set;
53
54 return set;
55 }
56
57 int
58 hwloc_set_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t set, int flags)
59 {
60 if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
61 errno = EINVAL;
62 return -1;
63 }
64
65 set = hwloc_fix_cpubind(topology, set);
66 if (!set)
67 return -1;
68
69 if (flags & HWLOC_CPUBIND_PROCESS) {
70 if (topology->binding_hooks.set_thisproc_cpubind)
71 return topology->binding_hooks.set_thisproc_cpubind(topology, set, flags);
72 } else if (flags & HWLOC_CPUBIND_THREAD) {
73 if (topology->binding_hooks.set_thisthread_cpubind)
74 return topology->binding_hooks.set_thisthread_cpubind(topology, set, flags);
75 } else {
76 if (topology->binding_hooks.set_thisproc_cpubind) {
77 int err = topology->binding_hooks.set_thisproc_cpubind(topology, set, flags);
78 if (err >= 0 || errno != ENOSYS)
79 return err;
80
81 }
82 if (topology->binding_hooks.set_thisthread_cpubind)
83 return topology->binding_hooks.set_thisthread_cpubind(topology, set, flags);
84 }
85
86 errno = ENOSYS;
87 return -1;
88 }
89
90 int
91 hwloc_get_cpubind(hwloc_topology_t topology, hwloc_bitmap_t set, int flags)
92 {
93 if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
94 errno = EINVAL;
95 return -1;
96 }
97
98 if (flags & HWLOC_CPUBIND_PROCESS) {
99 if (topology->binding_hooks.get_thisproc_cpubind)
100 return topology->binding_hooks.get_thisproc_cpubind(topology, set, flags);
101 } else if (flags & HWLOC_CPUBIND_THREAD) {
102 if (topology->binding_hooks.get_thisthread_cpubind)
103 return topology->binding_hooks.get_thisthread_cpubind(topology, set, flags);
104 } else {
105 if (topology->binding_hooks.get_thisproc_cpubind) {
106 int err = topology->binding_hooks.get_thisproc_cpubind(topology, set, flags);
107 if (err >= 0 || errno != ENOSYS)
108 return err;
109
110 }
111 if (topology->binding_hooks.get_thisthread_cpubind)
112 return topology->binding_hooks.get_thisthread_cpubind(topology, set, flags);
113 }
114
115 errno = ENOSYS;
116 return -1;
117 }
118
119 int
120 hwloc_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t set, int flags)
121 {
122 if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
123 errno = EINVAL;
124 return -1;
125 }
126
127 set = hwloc_fix_cpubind(topology, set);
128 if (!set)
129 return -1;
130
131 if (topology->binding_hooks.set_proc_cpubind)
132 return topology->binding_hooks.set_proc_cpubind(topology, pid, set, flags);
133
134 errno = ENOSYS;
135 return -1;
136 }
137
138 int
139 hwloc_get_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, int flags)
140 {
141 if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
142 errno = EINVAL;
143 return -1;
144 }
145
146 if (topology->binding_hooks.get_proc_cpubind)
147 return topology->binding_hooks.get_proc_cpubind(topology, pid, set, flags);
148
149 errno = ENOSYS;
150 return -1;
151 }
152
153 #ifdef hwloc_thread_t
154 int
155 hwloc_set_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_const_bitmap_t set, int flags)
156 {
157 if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
158 errno = EINVAL;
159 return -1;
160 }
161
162 set = hwloc_fix_cpubind(topology, set);
163 if (!set)
164 return -1;
165
166 if (topology->binding_hooks.set_thread_cpubind)
167 return topology->binding_hooks.set_thread_cpubind(topology, tid, set, flags);
168
169 errno = ENOSYS;
170 return -1;
171 }
172
173 int
174 hwloc_get_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_bitmap_t set, int flags)
175 {
176 if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
177 errno = EINVAL;
178 return -1;
179 }
180
181 if (topology->binding_hooks.get_thread_cpubind)
182 return topology->binding_hooks.get_thread_cpubind(topology, tid, set, flags);
183
184 errno = ENOSYS;
185 return -1;
186 }
187 #endif
188
189 int
190 hwloc_get_last_cpu_location(hwloc_topology_t topology, hwloc_bitmap_t set, int flags)
191 {
192 if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
193 errno = EINVAL;
194 return -1;
195 }
196
197 if (flags & HWLOC_CPUBIND_PROCESS) {
198 if (topology->binding_hooks.get_thisproc_last_cpu_location)
199 return topology->binding_hooks.get_thisproc_last_cpu_location(topology, set, flags);
200 } else if (flags & HWLOC_CPUBIND_THREAD) {
201 if (topology->binding_hooks.get_thisthread_last_cpu_location)
202 return topology->binding_hooks.get_thisthread_last_cpu_location(topology, set, flags);
203 } else {
204 if (topology->binding_hooks.get_thisproc_last_cpu_location) {
205 int err = topology->binding_hooks.get_thisproc_last_cpu_location(topology, set, flags);
206 if (err >= 0 || errno != ENOSYS)
207 return err;
208
209 }
210 if (topology->binding_hooks.get_thisthread_last_cpu_location)
211 return topology->binding_hooks.get_thisthread_last_cpu_location(topology, set, flags);
212 }
213
214 errno = ENOSYS;
215 return -1;
216 }
217
218 int
219 hwloc_get_proc_last_cpu_location(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, int flags)
220 {
221 if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
222 errno = EINVAL;
223 return -1;
224 }
225
226 if (topology->binding_hooks.get_proc_last_cpu_location)
227 return topology->binding_hooks.get_proc_last_cpu_location(topology, pid, set, flags);
228
229 errno = ENOSYS;
230 return -1;
231 }
232
233 #define HWLOC_MEMBIND_ALLFLAGS (HWLOC_MEMBIND_PROCESS|HWLOC_MEMBIND_THREAD|HWLOC_MEMBIND_STRICT|HWLOC_MEMBIND_MIGRATE|HWLOC_MEMBIND_NOCPUBIND|HWLOC_MEMBIND_BYNODESET)
234
235 static hwloc_const_nodeset_t
236 hwloc_fix_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
237 {
238 hwloc_const_bitmap_t topology_nodeset = hwloc_topology_get_topology_nodeset(topology);
239 hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology);
240
241 if (hwloc_bitmap_iszero(nodeset)) {
242 errno = EINVAL;
243 return NULL;
244 }
245
246 if (!hwloc_bitmap_isincluded(nodeset, complete_nodeset)) {
247 errno = EINVAL;
248 return NULL;
249 }
250
251 if (hwloc_bitmap_isincluded(topology_nodeset, nodeset))
252 return complete_nodeset;
253
254 return nodeset;
255 }
256
257 static int
258 hwloc_fix_membind_cpuset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_const_cpuset_t cpuset)
259 {
260 hwloc_const_bitmap_t topology_set = hwloc_topology_get_topology_cpuset(topology);
261 hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology);
262 hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology);
263
264 if (hwloc_bitmap_iszero(cpuset)) {
265 errno = EINVAL;
266 return -1;
267 }
268
269 if (!hwloc_bitmap_isincluded(cpuset, complete_set)) {
270 errno = EINVAL;
271 return -1;
272 }
273
274 if (hwloc_bitmap_isincluded(topology_set, cpuset)) {
275 hwloc_bitmap_copy(nodeset, complete_nodeset);
276 return 0;
277 }
278
279 hwloc_cpuset_to_nodeset(topology, cpuset, nodeset);
280 return 0;
281 }
282
283 static __hwloc_inline int hwloc__check_membind_policy(hwloc_membind_policy_t policy)
284 {
285 if (policy == HWLOC_MEMBIND_DEFAULT
286 || policy == HWLOC_MEMBIND_FIRSTTOUCH
287 || policy == HWLOC_MEMBIND_BIND
288 || policy == HWLOC_MEMBIND_INTERLEAVE
289 || policy == HWLOC_MEMBIND_NEXTTOUCH)
290 return 0;
291 return -1;
292 }
293
294 static int
295 hwloc_set_membind_by_nodeset(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
296 {
297 if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
298 errno = EINVAL;
299 return -1;
300 }
301
302 nodeset = hwloc_fix_membind(topology, nodeset);
303 if (!nodeset)
304 return -1;
305
306 if (flags & HWLOC_MEMBIND_PROCESS) {
307 if (topology->binding_hooks.set_thisproc_membind)
308 return topology->binding_hooks.set_thisproc_membind(topology, nodeset, policy, flags);
309 } else if (flags & HWLOC_MEMBIND_THREAD) {
310 if (topology->binding_hooks.set_thisthread_membind)
311 return topology->binding_hooks.set_thisthread_membind(topology, nodeset, policy, flags);
312 } else {
313 if (topology->binding_hooks.set_thisproc_membind) {
314 int err = topology->binding_hooks.set_thisproc_membind(topology, nodeset, policy, flags);
315 if (err >= 0 || errno != ENOSYS)
316 return err;
317
318 }
319 if (topology->binding_hooks.set_thisthread_membind)
320 return topology->binding_hooks.set_thisthread_membind(topology, nodeset, policy, flags);
321 }
322
323 errno = ENOSYS;
324 return -1;
325 }
326
327 int
328 hwloc_set_membind(hwloc_topology_t topology, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags)
329 {
330 int ret;
331
332 if (flags & HWLOC_MEMBIND_BYNODESET) {
333 ret = hwloc_set_membind_by_nodeset(topology, set, policy, flags);
334 } else {
335 hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
336 if (hwloc_fix_membind_cpuset(topology, nodeset, set))
337 ret = -1;
338 else
339 ret = hwloc_set_membind_by_nodeset(topology, nodeset, policy, flags);
340 hwloc_bitmap_free(nodeset);
341 }
342 return ret;
343 }
344
345 static int
346 hwloc_get_membind_by_nodeset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
347 {
348 if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
349 errno = EINVAL;
350 return -1;
351 }
352
353 if (flags & HWLOC_MEMBIND_PROCESS) {
354 if (topology->binding_hooks.get_thisproc_membind)
355 return topology->binding_hooks.get_thisproc_membind(topology, nodeset, policy, flags);
356 } else if (flags & HWLOC_MEMBIND_THREAD) {
357 if (topology->binding_hooks.get_thisthread_membind)
358 return topology->binding_hooks.get_thisthread_membind(topology, nodeset, policy, flags);
359 } else {
360 if (topology->binding_hooks.get_thisproc_membind) {
361 int err = topology->binding_hooks.get_thisproc_membind(topology, nodeset, policy, flags);
362 if (err >= 0 || errno != ENOSYS)
363 return err;
364
365 }
366 if (topology->binding_hooks.get_thisthread_membind)
367 return topology->binding_hooks.get_thisthread_membind(topology, nodeset, policy, flags);
368 }
369
370 errno = ENOSYS;
371 return -1;
372 }
373
374 int
375 hwloc_get_membind(hwloc_topology_t topology, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags)
376 {
377 int ret;
378
379 if (flags & HWLOC_MEMBIND_BYNODESET) {
380 ret = hwloc_get_membind_by_nodeset(topology, set, policy, flags);
381 } else {
382 hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
383 ret = hwloc_get_membind_by_nodeset(topology, nodeset, policy, flags);
384 if (!ret)
385 hwloc_cpuset_from_nodeset(topology, set, nodeset);
386 hwloc_bitmap_free(nodeset);
387 }
388
389 return ret;
390 }
391
392 static int
393 hwloc_set_proc_membind_by_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
394 {
395 if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
396 errno = EINVAL;
397 return -1;
398 }
399
400 nodeset = hwloc_fix_membind(topology, nodeset);
401 if (!nodeset)
402 return -1;
403
404 if (topology->binding_hooks.set_proc_membind)
405 return topology->binding_hooks.set_proc_membind(topology, pid, nodeset, policy, flags);
406
407 errno = ENOSYS;
408 return -1;
409 }
410
411
412 int
413 hwloc_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags)
414 {
415 int ret;
416
417 if (flags & HWLOC_MEMBIND_BYNODESET) {
418 ret = hwloc_set_proc_membind_by_nodeset(topology, pid, set, policy, flags);
419 } else {
420 hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
421 if (hwloc_fix_membind_cpuset(topology, nodeset, set))
422 ret = -1;
423 else
424 ret = hwloc_set_proc_membind_by_nodeset(topology, pid, nodeset, policy, flags);
425 hwloc_bitmap_free(nodeset);
426 }
427
428 return ret;
429 }
430
431 static int
432 hwloc_get_proc_membind_by_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
433 {
434 if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
435 errno = EINVAL;
436 return -1;
437 }
438
439 if (topology->binding_hooks.get_proc_membind)
440 return topology->binding_hooks.get_proc_membind(topology, pid, nodeset, policy, flags);
441
442 errno = ENOSYS;
443 return -1;
444 }
445
446 int
447 hwloc_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags)
448 {
449 int ret;
450
451 if (flags & HWLOC_MEMBIND_BYNODESET) {
452 ret = hwloc_get_proc_membind_by_nodeset(topology, pid, set, policy, flags);
453 } else {
454 hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
455 ret = hwloc_get_proc_membind_by_nodeset(topology, pid, nodeset, policy, flags);
456 if (!ret)
457 hwloc_cpuset_from_nodeset(topology, set, nodeset);
458 hwloc_bitmap_free(nodeset);
459 }
460
461 return ret;
462 }
463
464 static int
465 hwloc_set_area_membind_by_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
466 {
467 if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
468 errno = EINVAL;
469 return -1;
470 }
471
472 if (!len)
473
474 return 0;
475
476 nodeset = hwloc_fix_membind(topology, nodeset);
477 if (!nodeset)
478 return -1;
479
480 if (topology->binding_hooks.set_area_membind)
481 return topology->binding_hooks.set_area_membind(topology, addr, len, nodeset, policy, flags);
482
483 errno = ENOSYS;
484 return -1;
485 }
486
487 int
488 hwloc_set_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags)
489 {
490 int ret;
491
492 if (flags & HWLOC_MEMBIND_BYNODESET) {
493 ret = hwloc_set_area_membind_by_nodeset(topology, addr, len, set, policy, flags);
494 } else {
495 hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
496 if (hwloc_fix_membind_cpuset(topology, nodeset, set))
497 ret = -1;
498 else
499 ret = hwloc_set_area_membind_by_nodeset(topology, addr, len, nodeset, policy, flags);
500 hwloc_bitmap_free(nodeset);
501 }
502
503 return ret;
504 }
505
506 static int
507 hwloc_get_area_membind_by_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
508 {
509 if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
510 errno = EINVAL;
511 return -1;
512 }
513
514 if (!len) {
515
516 errno = EINVAL;
517 return -1;
518 }
519
520 if (topology->binding_hooks.get_area_membind)
521 return topology->binding_hooks.get_area_membind(topology, addr, len, nodeset, policy, flags);
522
523 errno = ENOSYS;
524 return -1;
525 }
526
527 int
528 hwloc_get_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags)
529 {
530 int ret;
531
532 if (flags & HWLOC_MEMBIND_BYNODESET) {
533 ret = hwloc_get_area_membind_by_nodeset(topology, addr, len, set, policy, flags);
534 } else {
535 hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
536 ret = hwloc_get_area_membind_by_nodeset(topology, addr, len, nodeset, policy, flags);
537 if (!ret)
538 hwloc_cpuset_from_nodeset(topology, set, nodeset);
539 hwloc_bitmap_free(nodeset);
540 }
541
542 return ret;
543 }
544
545 static int
546 hwloc_get_area_memlocation_by_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, int flags)
547 {
548 if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
549 errno = EINVAL;
550 return -1;
551 }
552
553 if (!len)
554
555 return 0;
556
557 if (topology->binding_hooks.get_area_memlocation)
558 return topology->binding_hooks.get_area_memlocation(topology, addr, len, nodeset, flags);
559
560 errno = ENOSYS;
561 return -1;
562 }
563
564 int
565 hwloc_get_area_memlocation(hwloc_topology_t topology, const void *addr, size_t len, hwloc_cpuset_t set, int flags)
566 {
567 int ret;
568
569 if (flags & HWLOC_MEMBIND_BYNODESET) {
570 ret = hwloc_get_area_memlocation_by_nodeset(topology, addr, len, set, flags);
571 } else {
572 hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
573 ret = hwloc_get_area_memlocation_by_nodeset(topology, addr, len, nodeset, flags);
574 if (!ret)
575 hwloc_cpuset_from_nodeset(topology, set, nodeset);
576 hwloc_bitmap_free(nodeset);
577 }
578
579 return ret;
580 }
581
582 void *
583 hwloc_alloc_heap(hwloc_topology_t topology __hwloc_attribute_unused, size_t len)
584 {
585 void *p = NULL;
586 #if defined(hwloc_getpagesize) && defined(HAVE_POSIX_MEMALIGN)
587 errno = posix_memalign(&p, hwloc_getpagesize(), len);
588 if (errno)
589 p = NULL;
590 #elif defined(hwloc_getpagesize) && defined(HAVE_MEMALIGN)
591 p = memalign(hwloc_getpagesize(), len);
592 #else
593 p = malloc(len);
594 #endif
595 return p;
596 }
597
598 #ifdef MAP_ANONYMOUS
599 void *
600 hwloc_alloc_mmap(hwloc_topology_t topology __hwloc_attribute_unused, size_t len)
601 {
602 void * buffer = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
603 return buffer == MAP_FAILED ? NULL : buffer;
604 }
605 #endif
606
607 int
608 hwloc_free_heap(hwloc_topology_t topology __hwloc_attribute_unused, void *addr, size_t len __hwloc_attribute_unused)
609 {
610 free(addr);
611 return 0;
612 }
613
614 #ifdef MAP_ANONYMOUS
615 int
616 hwloc_free_mmap(hwloc_topology_t topology __hwloc_attribute_unused, void *addr, size_t len)
617 {
618 if (!addr)
619 return 0;
620 return munmap(addr, len);
621 }
622 #endif
623
624 void *
625 hwloc_alloc(hwloc_topology_t topology, size_t len)
626 {
627 if (topology->binding_hooks.alloc)
628 return topology->binding_hooks.alloc(topology, len);
629 return hwloc_alloc_heap(topology, len);
630 }
631
632 static void *
633 hwloc_alloc_membind_by_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
634 {
635 void *p;
636
637 if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
638 errno = EINVAL;
639 return NULL;
640 }
641
642 nodeset = hwloc_fix_membind(topology, nodeset);
643 if (!nodeset)
644 goto fallback;
645 if (flags & HWLOC_MEMBIND_MIGRATE) {
646 errno = EINVAL;
647 goto fallback;
648 }
649
650 if (topology->binding_hooks.alloc_membind)
651 return topology->binding_hooks.alloc_membind(topology, len, nodeset, policy, flags);
652 else if (topology->binding_hooks.set_area_membind) {
653 p = hwloc_alloc(topology, len);
654 if (!p)
655 return NULL;
656 if (topology->binding_hooks.set_area_membind(topology, p, len, nodeset, policy, flags) && flags & HWLOC_MEMBIND_STRICT) {
657 int error = errno;
658 free(p);
659 errno = error;
660 return NULL;
661 }
662 return p;
663 } else {
664 errno = ENOSYS;
665 }
666
667 fallback:
668 if (flags & HWLOC_MEMBIND_STRICT)
669
670 return NULL;
671
672 return hwloc_alloc(topology, len);
673 }
674
675 void *
676 hwloc_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags)
677 {
678 void *ret;
679
680 if (flags & HWLOC_MEMBIND_BYNODESET) {
681 ret = hwloc_alloc_membind_by_nodeset(topology, len, set, policy, flags);
682 } else {
683 hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
684 if (hwloc_fix_membind_cpuset(topology, nodeset, set)) {
685 if (flags & HWLOC_MEMBIND_STRICT)
686 ret = NULL;
687 else
688 ret = hwloc_alloc(topology, len);
689 } else
690 ret = hwloc_alloc_membind_by_nodeset(topology, len, nodeset, policy, flags);
691 hwloc_bitmap_free(nodeset);
692 }
693
694 return ret;
695 }
696
697 int
698 hwloc_free(hwloc_topology_t topology, void *addr, size_t len)
699 {
700 if (topology->binding_hooks.free_membind)
701 return topology->binding_hooks.free_membind(topology, addr, len);
702 return hwloc_free_heap(topology, addr, len);
703 }
704
705
706
707
708
709 static int dontset_return_complete_cpuset(hwloc_topology_t topology, hwloc_cpuset_t set)
710 {
711 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
712 return 0;
713 }
714
715 static int dontset_thisthread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
716 {
717 return 0;
718 }
719 static int dontget_thisthread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, int flags __hwloc_attribute_unused)
720 {
721 return dontset_return_complete_cpuset(topology, set);
722 }
723 static int dontset_thisproc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
724 {
725 return 0;
726 }
727 static int dontget_thisproc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, int flags __hwloc_attribute_unused)
728 {
729 return dontset_return_complete_cpuset(topology, set);
730 }
731 static int dontset_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
732 {
733 return 0;
734 }
735 static int dontget_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_bitmap_t cpuset, int flags __hwloc_attribute_unused)
736 {
737 return dontset_return_complete_cpuset(topology, cpuset);
738 }
739 #ifdef hwloc_thread_t
740 static int dontset_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
741 {
742 return 0;
743 }
744 static int dontget_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid __hwloc_attribute_unused, hwloc_bitmap_t cpuset, int flags __hwloc_attribute_unused)
745 {
746 return dontset_return_complete_cpuset(topology, cpuset);
747 }
748 #endif
749
750 static int dontset_return_complete_nodeset(hwloc_topology_t topology, hwloc_nodeset_t set, hwloc_membind_policy_t *policy)
751 {
752 hwloc_bitmap_copy(set, hwloc_topology_get_complete_nodeset(topology));
753 *policy = HWLOC_MEMBIND_MIXED;
754 return 0;
755 }
756
757 static int dontset_thisproc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
758 {
759 return 0;
760 }
761 static int dontget_thisproc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
762 {
763 return dontset_return_complete_nodeset(topology, set, policy);
764 }
765
766 static int dontset_thisthread_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
767 {
768 return 0;
769 }
770 static int dontget_thisthread_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
771 {
772 return dontset_return_complete_nodeset(topology, set, policy);
773 }
774
775 static int dontset_proc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
776 {
777 return 0;
778 }
779 static int dontget_proc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
780 {
781 return dontset_return_complete_nodeset(topology, set, policy);
782 }
783
784 static int dontset_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
785 {
786 return 0;
787 }
788 static int dontget_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
789 {
790 return dontset_return_complete_nodeset(topology, set, policy);
791 }
792 static int dontget_area_memlocation(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_bitmap_t set, int flags __hwloc_attribute_unused)
793 {
794 hwloc_membind_policy_t policy;
795 return dontset_return_complete_nodeset(topology, set, &policy);
796 }
797
798 static void * dontalloc_membind(hwloc_topology_t topology __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
799 {
800 return malloc(size);
801 }
802 static int dontfree_membind(hwloc_topology_t topology __hwloc_attribute_unused, void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused)
803 {
804 free(addr);
805 return 0;
806 }
807
808 static void hwloc_set_dummy_hooks(struct hwloc_binding_hooks *hooks,
809 struct hwloc_topology_support *support __hwloc_attribute_unused)
810 {
811 hooks->set_thisproc_cpubind = dontset_thisproc_cpubind;
812 hooks->get_thisproc_cpubind = dontget_thisproc_cpubind;
813 hooks->set_thisthread_cpubind = dontset_thisthread_cpubind;
814 hooks->get_thisthread_cpubind = dontget_thisthread_cpubind;
815 hooks->set_proc_cpubind = dontset_proc_cpubind;
816 hooks->get_proc_cpubind = dontget_proc_cpubind;
817 #ifdef hwloc_thread_t
818 hooks->set_thread_cpubind = dontset_thread_cpubind;
819 hooks->get_thread_cpubind = dontget_thread_cpubind;
820 #endif
821 hooks->get_thisproc_last_cpu_location = dontget_thisproc_cpubind;
822 hooks->get_thisthread_last_cpu_location = dontget_thisthread_cpubind;
823 hooks->get_proc_last_cpu_location = dontget_proc_cpubind;
824
825 hooks->set_thisproc_membind = dontset_thisproc_membind;
826 hooks->get_thisproc_membind = dontget_thisproc_membind;
827 hooks->set_thisthread_membind = dontset_thisthread_membind;
828 hooks->get_thisthread_membind = dontget_thisthread_membind;
829 hooks->set_proc_membind = dontset_proc_membind;
830 hooks->get_proc_membind = dontget_proc_membind;
831 hooks->set_area_membind = dontset_area_membind;
832 hooks->get_area_membind = dontget_area_membind;
833 hooks->get_area_memlocation = dontget_area_memlocation;
834 hooks->alloc_membind = dontalloc_membind;
835 hooks->free_membind = dontfree_membind;
836 }
837
838 void
839 hwloc_set_native_binding_hooks(struct hwloc_binding_hooks *hooks, struct hwloc_topology_support *support)
840 {
841 # ifdef HWLOC_LINUX_SYS
842 hwloc_set_linuxfs_hooks(hooks, support);
843 # endif
844
845 # ifdef HWLOC_BGQ_SYS
846 hwloc_set_bgq_hooks(hooks, support);
847 # endif
848
849 # ifdef HWLOC_AIX_SYS
850 hwloc_set_aix_hooks(hooks, support);
851 # endif
852
853 # ifdef HWLOC_SOLARIS_SYS
854 hwloc_set_solaris_hooks(hooks, support);
855 # endif
856
857 # ifdef HWLOC_WIN_SYS
858 hwloc_set_windows_hooks(hooks, support);
859 # endif
860
861 # ifdef HWLOC_DARWIN_SYS
862 hwloc_set_darwin_hooks(hooks, support);
863 # endif
864
865 # ifdef HWLOC_FREEBSD_SYS
866 hwloc_set_freebsd_hooks(hooks, support);
867 # endif
868
869 # ifdef HWLOC_NETBSD_SYS
870 hwloc_set_netbsd_hooks(hooks, support);
871 # endif
872
873 # ifdef HWLOC_HPUX_SYS
874 hwloc_set_hpux_hooks(hooks, support);
875 # endif
876 }
877
878
879 void
880 hwloc_set_binding_hooks(struct hwloc_topology *topology)
881 {
882 if (topology->is_thissystem) {
883 hwloc_set_native_binding_hooks(&topology->binding_hooks, &topology->support);
884
885 } else {
886
887 hwloc_set_dummy_hooks(&topology->binding_hooks, &topology->support);
888 }
889
890
891
892
893
894 if (topology->is_thissystem) {
895 #define DO(which,kind) \
896 if (topology->binding_hooks.kind) \
897 topology->support.which##bind->kind = 1;
898 DO(cpu,set_thisproc_cpubind);
899 DO(cpu,get_thisproc_cpubind);
900 DO(cpu,set_proc_cpubind);
901 DO(cpu,get_proc_cpubind);
902 DO(cpu,set_thisthread_cpubind);
903 DO(cpu,get_thisthread_cpubind);
904 #ifdef hwloc_thread_t
905 DO(cpu,set_thread_cpubind);
906 DO(cpu,get_thread_cpubind);
907 #endif
908 DO(cpu,get_thisproc_last_cpu_location);
909 DO(cpu,get_proc_last_cpu_location);
910 DO(cpu,get_thisthread_last_cpu_location);
911 DO(mem,set_thisproc_membind);
912 DO(mem,get_thisproc_membind);
913 DO(mem,set_thisthread_membind);
914 DO(mem,get_thisthread_membind);
915 DO(mem,set_proc_membind);
916 DO(mem,get_proc_membind);
917 DO(mem,set_area_membind);
918 DO(mem,get_area_membind);
919 DO(mem,get_area_memlocation);
920 DO(mem,alloc_membind);
921 }
922 }