This source file includes following definitions.
- hwloc_hpux_find_ldom
- hwloc_hpux_find_spu
- hwloc_hpux_set_proc_cpubind
- hwloc_hpux_set_thisproc_cpubind
- hwloc_hpux_set_thread_cpubind
- hwloc_hpux_set_thisthread_cpubind
- hwloc_hpux_alloc_membind
- hwloc_look_hpux
- hwloc_set_hpux_hooks
- hwloc_hpux_component_instantiate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <private/autogen/config.h>
19
20 #include <sys/types.h>
21 #ifdef HAVE_UNISTD_H
22 #include <unistd.h>
23 #endif
24 #include <string.h>
25 #include <errno.h>
26 #include <stdio.h>
27
28 #include <hwloc.h>
29 #include <private/private.h>
30 #include <private/debug.h>
31
32 #include <sys/mpctl.h>
33 #include <sys/mman.h>
34 #include <pthread.h>
35
36 static ldom_t
37 hwloc_hpux_find_ldom(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set)
38 {
39 int has_numa = sysconf(_SC_CCNUMA_SUPPORT) == 1;
40 hwloc_obj_t obj;
41
42 if (!has_numa)
43 return -1;
44
45 obj = hwloc_get_first_largest_obj_inside_cpuset(topology, hwloc_set);
46 if (!hwloc_bitmap_isequal(obj->cpuset, hwloc_set))
47
48 return -1;
49
50 while (obj->type != HWLOC_OBJ_NUMANODE) {
51
52 if (!obj->first_child
53 || !obj->first_child->cpuset
54 || !hwloc_bitmap_isequal(obj->cpuset, obj->first_child->cpuset))
55 return -1;
56 obj = obj->first_child;
57 }
58
59 return obj->os_index;
60 }
61
62 static spu_t
63 hwloc_hpux_find_spu(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t hwloc_set)
64 {
65 spu_t cpu;
66
67 cpu = hwloc_bitmap_first(hwloc_set);
68 if (cpu != -1 && hwloc_bitmap_weight(hwloc_set) == 1)
69 return cpu;
70 return -1;
71 }
72
73
74 static int
75 hwloc_hpux_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t hwloc_set, int flags)
76 {
77 ldom_t ldom;
78 spu_t cpu;
79
80
81 mpctl(MPC_SETLDOM, MPC_LDOMFLOAT, pid);
82 mpctl(MPC_SETPROCESS, MPC_SPUFLOAT, pid);
83
84 if (hwloc_bitmap_isequal(hwloc_set, hwloc_topology_get_complete_cpuset(topology)))
85 return 0;
86
87 ldom = hwloc_hpux_find_ldom(topology, hwloc_set);
88 if (ldom != -1)
89 return mpctl(MPC_SETLDOM, ldom, pid);
90
91 cpu = hwloc_hpux_find_spu(topology, hwloc_set);
92 if (cpu != -1)
93 return mpctl((flags & HWLOC_CPUBIND_STRICT) ? MPC_SETPROCESS_FORCE : MPC_SETPROCESS, cpu, pid);
94
95 errno = EXDEV;
96 return -1;
97 }
98
99 static int
100 hwloc_hpux_set_thisproc_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
101 {
102 return hwloc_hpux_set_proc_cpubind(topology, MPC_SELFPID, hwloc_set, flags);
103 }
104
105 #ifdef hwloc_thread_t
106 static int
107 hwloc_hpux_set_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t pthread, hwloc_const_bitmap_t hwloc_set, int flags)
108 {
109 ldom_t ldom, ldom2;
110 spu_t cpu, cpu2;
111
112
113 pthread_ldom_bind_np(&ldom2, PTHREAD_LDOMFLOAT_NP, pthread);
114 pthread_processor_bind_np(PTHREAD_BIND_ADVISORY_NP, &cpu2, PTHREAD_SPUFLOAT_NP, pthread);
115
116 if (hwloc_bitmap_isequal(hwloc_set, hwloc_topology_get_complete_cpuset(topology)))
117 return 0;
118
119 ldom = hwloc_hpux_find_ldom(topology, hwloc_set);
120 if (ldom != -1)
121 return pthread_ldom_bind_np(&ldom2, ldom, pthread);
122
123 cpu = hwloc_hpux_find_spu(topology, hwloc_set);
124 if (cpu != -1)
125 return pthread_processor_bind_np((flags & HWLOC_CPUBIND_STRICT) ? PTHREAD_BIND_FORCED_NP : PTHREAD_BIND_ADVISORY_NP, &cpu2, cpu, pthread);
126
127 errno = EXDEV;
128 return -1;
129 }
130
131 static int
132 hwloc_hpux_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
133 {
134 return hwloc_hpux_set_thread_cpubind(topology, PTHREAD_SELFTID_NP, hwloc_set, flags);
135 }
136 #endif
137
138
139
140 #ifdef MAP_MEM_FIRST_TOUCH
141 static void*
142 hwloc_hpux_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t _nodeset, hwloc_membind_policy_t policy, int flags)
143 {
144 hwloc_const_nodeset_t nodeset;
145 int mmap_flags;
146 void *p;
147
148
149 nodeset = hwloc_topology_get_complete_nodeset(topology);
150 if (policy != HWLOC_MEMBIND_DEFAULT
151 && !hwloc_bitmap_isequal(nodeset, _nodeset)) {
152 errno = EXDEV;
153 return hwloc_alloc_or_fail(topology, len, flags);
154 }
155
156 switch (policy) {
157 case HWLOC_MEMBIND_DEFAULT:
158 case HWLOC_MEMBIND_BIND:
159 mmap_flags = 0;
160 break;
161 case HWLOC_MEMBIND_FIRSTTOUCH:
162 mmap_flags = MAP_MEM_FIRST_TOUCH;
163 break;
164 case HWLOC_MEMBIND_INTERLEAVE:
165 mmap_flags = MAP_MEM_INTERLEAVED;
166 break;
167 default:
168 errno = ENOSYS;
169 return NULL;
170 }
171
172 p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | mmap_flags, -1, 0);
173 return p == MAP_FAILED ? NULL : p;
174 }
175 #endif
176
177 static int
178 hwloc_look_hpux(struct hwloc_backend *backend)
179 {
180 struct hwloc_topology *topology = backend->topology;
181 int has_numa = sysconf(_SC_CCNUMA_SUPPORT) == 1;
182 spu_t currentcpu;
183 ldom_t currentnode;
184 int i, nbnodes = 0;
185
186 if (topology->levels[0][0]->cpuset)
187
188 return -1;
189
190 hwloc_alloc_root_sets(topology->levels[0][0]);
191
192 if (has_numa) {
193 nbnodes = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ?
194 MPC_GETNUMLDOMS_SYS : MPC_GETNUMLDOMS, 0, 0);
195 }
196 hwloc_debug("%d nodes\n", nbnodes);
197
198 hwloc_obj_t nodes[nbnodes], obj;
199
200 if (has_numa) {
201 i = 0;
202 currentnode = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ?
203 MPC_GETFIRSTLDOM_SYS : MPC_GETFIRSTLDOM, 0, 0);
204 while (currentnode != -1 && i < nbnodes) {
205 hwloc_debug("node %d is %d\n", i, currentnode);
206 nodes[i] = obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_NUMANODE, (unsigned) currentnode);
207 obj->cpuset = hwloc_bitmap_alloc();
208 obj->nodeset = hwloc_bitmap_alloc();
209 hwloc_bitmap_set(obj->nodeset, currentnode);
210
211
212
213 currentnode = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ?
214 MPC_GETNEXTLDOM_SYS : MPC_GETNEXTLDOM, currentnode, 0);
215 i++;
216 }
217 }
218
219 i = 0;
220 currentcpu = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ?
221 MPC_GETFIRSTSPU_SYS : MPC_GETFIRSTSPU, 0,0);
222 while (currentcpu != -1) {
223 obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PU, (unsigned) currentcpu);
224 obj->cpuset = hwloc_bitmap_alloc();
225 hwloc_bitmap_set(obj->cpuset, currentcpu);
226
227 hwloc_debug("cpu %d\n", currentcpu);
228
229 if (has_numa) {
230
231 currentnode = mpctl(MPC_SPUTOLDOM, currentcpu, 0);
232
233 if (i >= nbnodes || (ldom_t) nodes[i]->os_index != currentnode)
234 for (i = 0; i < nbnodes; i++)
235 if ((ldom_t) nodes[i]->os_index == currentnode)
236 break;
237 if (i < nbnodes) {
238 hwloc_bitmap_set(nodes[i]->cpuset, currentcpu);
239 hwloc_debug("is in node %d\n", i);
240 } else {
241 hwloc_debug("%s", "is in no node?!\n");
242 }
243 }
244
245
246 hwloc_insert_object_by_cpuset(topology, obj);
247
248 currentcpu = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ?
249 MPC_GETNEXTSPU_SYS : MPC_GETNEXTSPU, currentcpu, 0);
250 }
251
252 if (has_numa) {
253
254 for (i = 0 ; i < nbnodes ; i++)
255 hwloc_insert_object_by_cpuset(topology, nodes[i]);
256 }
257
258 topology->support.discovery->pu = 1;
259 if (has_numa)
260 topology->support.discovery->numa = 1;
261
262 hwloc_obj_add_info(topology->levels[0][0], "Backend", "HP-UX");
263 hwloc_add_uname_info(topology, NULL);
264 return 0;
265 }
266
267 void
268 hwloc_set_hpux_hooks(struct hwloc_binding_hooks *hooks,
269 struct hwloc_topology_support *support __hwloc_attribute_unused)
270 {
271 hooks->set_proc_cpubind = hwloc_hpux_set_proc_cpubind;
272 hooks->set_thisproc_cpubind = hwloc_hpux_set_thisproc_cpubind;
273 #ifdef hwloc_thread_t
274 hooks->set_thread_cpubind = hwloc_hpux_set_thread_cpubind;
275 hooks->set_thisthread_cpubind = hwloc_hpux_set_thisthread_cpubind;
276 #endif
277 #ifdef MAP_MEM_FIRST_TOUCH
278 hooks->alloc_membind = hwloc_hpux_alloc_membind;
279 hooks->alloc = hwloc_alloc_mmap;
280 hooks->free_membind = hwloc_free_mmap;
281 support->membind->firsttouch_membind = 1;
282 support->membind->bind_membind = 1;
283 support->membind->interleave_membind = 1;
284 #endif
285 }
286
287 static struct hwloc_backend *
288 hwloc_hpux_component_instantiate(struct hwloc_disc_component *component,
289 const void *_data1 __hwloc_attribute_unused,
290 const void *_data2 __hwloc_attribute_unused,
291 const void *_data3 __hwloc_attribute_unused)
292 {
293 struct hwloc_backend *backend;
294 backend = hwloc_backend_alloc(component);
295 if (!backend)
296 return NULL;
297 backend->discover = hwloc_look_hpux;
298 return backend;
299 }
300
301 static struct hwloc_disc_component hwloc_hpux_disc_component = {
302 HWLOC_DISC_COMPONENT_TYPE_CPU,
303 "hpux",
304 HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
305 hwloc_hpux_component_instantiate,
306 50,
307 1,
308 NULL
309 };
310
311 const struct hwloc_component hwloc_hpux_component = {
312 HWLOC_COMPONENT_ABI,
313 NULL, NULL,
314 HWLOC_COMPONENT_TYPE_DISC,
315 0,
316 &hwloc_hpux_disc_component
317 };