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 }