| 291 | } |
| 292 | |
| 293 | void * |
| 294 | ThreadAffinityInitializer::alloc_numa_stack(EThread *t, size_t stacksize) |
| 295 | { |
| 296 | hwloc_membind_policy_t mem_policy = HWLOC_MEMBIND_DEFAULT; |
| 297 | hwloc_nodeset_t nodeset = hwloc_bitmap_alloc(); |
| 298 | int num_nodes = 0; |
| 299 | void *stack = nullptr; |
| 300 | hwloc_obj_t obj = hwloc_get_obj_by_type(ink_get_topology(), obj_type, t->id % obj_count); |
| 301 | |
| 302 | // Find the NUMA node set that correlates to our next thread CPU set |
| 303 | hwloc_cpuset_to_nodeset(ink_get_topology(), obj->cpuset, nodeset); |
| 304 | // How many NUMA nodes will we be needing to allocate across? |
| 305 | num_nodes = hwloc_get_nbobjs_inside_cpuset_by_type(ink_get_topology(), obj->cpuset, HWLOC_OBJ_NODE); |
| 306 | |
| 307 | if (num_nodes == 1) { |
| 308 | // The preferred memory policy. The thread lives in one NUMA node. |
| 309 | mem_policy = HWLOC_MEMBIND_BIND; |
| 310 | } else if (num_nodes > 1) { |
| 311 | // If we have mode than one NUMA node we should interleave over them. |
| 312 | mem_policy = HWLOC_MEMBIND_INTERLEAVE; |
| 313 | } |
| 314 | |
| 315 | if (mem_policy != HWLOC_MEMBIND_DEFAULT) { |
| 316 | // Let's temporarily set the memory binding to our destination NUMA node |
| 317 | #if HWLOC_API_VERSION >= 0x20000 |
| 318 | hwloc_set_membind(ink_get_topology(), nodeset, mem_policy, HWLOC_MEMBIND_THREAD | HWLOC_MEMBIND_BYNODESET); |
| 319 | #else |
| 320 | hwloc_set_membind_nodeset(ink_get_topology(), nodeset, mem_policy, HWLOC_MEMBIND_THREAD); |
| 321 | #endif |
| 322 | } |
| 323 | |
| 324 | // Alloc our stack |
| 325 | stack = this->do_alloc_stack(stacksize); |
| 326 | |
| 327 | if (mem_policy != HWLOC_MEMBIND_DEFAULT) { |
| 328 | // Now let's set it back to default for this thread. |
| 329 | #if HWLOC_API_VERSION >= 0x20000 |
| 330 | hwloc_set_membind(ink_get_topology(), hwloc_topology_get_topology_nodeset(ink_get_topology()), HWLOC_MEMBIND_DEFAULT, |
| 331 | HWLOC_MEMBIND_THREAD | HWLOC_MEMBIND_BYNODESET); |
| 332 | #else |
| 333 | hwloc_set_membind_nodeset(ink_get_topology(), hwloc_topology_get_topology_nodeset(ink_get_topology()), HWLOC_MEMBIND_DEFAULT, |
| 334 | HWLOC_MEMBIND_THREAD); |
| 335 | #endif |
| 336 | } |
| 337 | |
| 338 | hwloc_bitmap_free(nodeset); |
| 339 | |
| 340 | return stack; |
| 341 | } |
| 342 | |
| 343 | void * |
| 344 | ThreadAffinityInitializer::alloc_stack(EThread *t, size_t stacksize) |
no test coverage detected