/src/hwloc/include/private/private.h
Line | Count | Source |
1 | | /* |
2 | | * SPDX-License-Identifier: BSD-3-Clause |
3 | | * Copyright © 2009 CNRS |
4 | | * Copyright © 2009-2026 Inria. All rights reserved. |
5 | | * Copyright © 2009-2012, 2020 Université Bordeaux |
6 | | * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. |
7 | | * See COPYING in top-level directory. |
8 | | */ |
9 | | |
10 | | /* Internal types and helpers. */ |
11 | | |
12 | | |
13 | | #ifdef HWLOC_INSIDE_PLUGIN |
14 | | /* |
15 | | * these declarations are internal only, they are not available to plugins |
16 | | * (many functions below are internal static symbols). |
17 | | */ |
18 | | #error This file should not be used in plugins |
19 | | #endif |
20 | | |
21 | | |
22 | | #ifndef HWLOC_PRIVATE_H |
23 | | #define HWLOC_PRIVATE_H |
24 | | |
25 | | #include "private/autogen/config.h" |
26 | | #include "hwloc.h" |
27 | | #include "hwloc/bitmap.h" |
28 | | #include "private/components.h" |
29 | | #include "private/misc.h" |
30 | | |
31 | | #include <sys/types.h> |
32 | | #ifdef HAVE_UNISTD_H |
33 | | #include <unistd.h> |
34 | | #endif |
35 | | #ifdef HAVE_STDINT_H |
36 | | #include <stdint.h> |
37 | | #endif |
38 | | #ifdef HAVE_SYS_UTSNAME_H |
39 | | #include <sys/utsname.h> |
40 | | #endif |
41 | | #include <string.h> |
42 | | |
43 | | #define HWLOC_TOPOLOGY_ABI 0x30000 /* version of the layout of struct topology */ |
44 | | |
45 | | struct hwloc_internal_location_s { |
46 | | enum hwloc_location_type_e type; |
47 | | union { |
48 | | struct { |
49 | | hwloc_obj_t obj; /* cached between refreshes */ |
50 | | uint64_t gp_index; |
51 | | hwloc_obj_type_t type; |
52 | | } object; /* if type == HWLOC_LOCATION_TYPE_OBJECT */ |
53 | | hwloc_cpuset_t cpuset; /* if type == HWLOC_LOCATION_TYPE_CPUSET */ |
54 | | } location; |
55 | | }; |
56 | | |
57 | | /***************************************************** |
58 | | * WARNING: |
59 | | * changes below in this structure (and its children) |
60 | | * should cause a bump of HWLOC_TOPOLOGY_ABI. |
61 | | *****************************************************/ |
62 | | |
63 | | enum hwloc_topology_state_e { |
64 | | HWLOC_TOPOLOGY_STATE_IS_THISSYSTEM = (1UL<<0), |
65 | | HWLOC_TOPOLOGY_STATE_IS_LOADED = (1UL<<1), |
66 | | HWLOC_TOPOLOGY_STATE_IS_LOADING = (1UL<<2), |
67 | | HWLOC_TOPOLOGY_STATE_IS_INIT = (1UL<<3) |
68 | | }; |
69 | | |
70 | | struct hwloc_topology { |
71 | | unsigned topology_abi; |
72 | | |
73 | | unsigned nb_levels; /* Number of horizontal levels */ |
74 | | unsigned nb_levels_allocated; /* Number of levels allocated and zeroed in level_nbobjects and levels below */ |
75 | | unsigned *level_nbobjects; /* Number of objects on each horizontal level */ |
76 | | struct hwloc_obj ***levels; /* Direct access to levels, levels[l = 0 .. nblevels-1][0..level_nbobjects[l]] */ |
77 | | unsigned long flags; |
78 | | int type_depth[HWLOC_OBJ_TYPE_MAX]; |
79 | | enum hwloc_type_filter_e type_filter[HWLOC_OBJ_TYPE_MAX]; |
80 | | unsigned char is_xml; /* shortcut to only component being XML */ |
81 | | unsigned long state; /* OR'ed enum hwloc_topology_state_e */ |
82 | | unsigned long modified; /* >0 if objects were added/removed recently, which means a reconnect is needed, |
83 | | * not inside "state" in case we want to store bits, numbers, etc. |
84 | | */ |
85 | | hwloc_pid_t pid; /* Process ID the topology is view from, 0 for self */ |
86 | | void *userdata; |
87 | | uint64_t next_gp_index; |
88 | | |
89 | | void *adopted_shmem_addr; |
90 | | size_t adopted_shmem_length; |
91 | | |
92 | | #define HWLOC_NR_SLEVELS 6 |
93 | | #define HWLOC_SLEVEL_NUMANODE 0 |
94 | | #define HWLOC_SLEVEL_BRIDGE 1 |
95 | | #define HWLOC_SLEVEL_PCIDEV 2 |
96 | | #define HWLOC_SLEVEL_OSDEV 3 |
97 | | #define HWLOC_SLEVEL_MISC 4 |
98 | | #define HWLOC_SLEVEL_MEMCACHE 5 |
99 | | /* order must match negative depth, it's asserted in setup_defaults() */ |
100 | | #define HWLOC_SLEVEL_FROM_DEPTH(x) (HWLOC_TYPE_DEPTH_NUMANODE-(x)) |
101 | | #define HWLOC_SLEVEL_TO_DEPTH(x) (HWLOC_TYPE_DEPTH_NUMANODE-(x)) |
102 | | struct hwloc_special_level_s { |
103 | | unsigned nbobjs; |
104 | | struct hwloc_obj **objs; |
105 | | struct hwloc_obj *first, *last; /* Temporarily used while listing object before building the objs array */ |
106 | | } slevels[HWLOC_NR_SLEVELS]; |
107 | | |
108 | | hwloc_bitmap_t allowed_cpuset; |
109 | | hwloc_bitmap_t allowed_nodeset; |
110 | | |
111 | | struct hwloc_binding_hooks { |
112 | | /* These are actually rather OS hooks since some of them are not about binding */ |
113 | | int (*set_thisproc_cpubind)(hwloc_topology_t topology, hwloc_const_cpuset_t set, int flags); |
114 | | int (*get_thisproc_cpubind)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags); |
115 | | int (*set_thisthread_cpubind)(hwloc_topology_t topology, hwloc_const_cpuset_t set, int flags); |
116 | | int (*get_thisthread_cpubind)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags); |
117 | | int (*set_proc_cpubind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_cpuset_t set, int flags); |
118 | | int (*get_proc_cpubind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags); |
119 | | #ifdef hwloc_thread_t |
120 | | int (*set_thread_cpubind)(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_const_cpuset_t set, int flags); |
121 | | int (*get_thread_cpubind)(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_cpuset_t set, int flags); |
122 | | #endif |
123 | | |
124 | | int (*get_thisproc_last_cpu_location)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags); |
125 | | int (*get_thisthread_last_cpu_location)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags); |
126 | | int (*get_proc_last_cpu_location)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags); |
127 | | |
128 | | int (*set_thisproc_membind)(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags); |
129 | | int (*get_thisproc_membind)(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags); |
130 | | int (*set_thisthread_membind)(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags); |
131 | | int (*get_thisthread_membind)(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags); |
132 | | int (*set_proc_membind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags); |
133 | | int (*get_proc_membind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags); |
134 | | int (*set_area_membind)(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags); |
135 | | int (*get_area_membind)(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags); |
136 | | int (*get_area_memlocation)(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, int flags); |
137 | | /* This has to return the same kind of pointer as alloc_membind, so that free_membind can be used on it */ |
138 | | void *(*alloc)(hwloc_topology_t topology, size_t len); |
139 | | /* alloc_membind has to always succeed if !(flags & HWLOC_MEMBIND_STRICT). |
140 | | * see hwloc_alloc_or_fail which is convenient for that. */ |
141 | | void *(*alloc_membind)(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags); |
142 | | int (*free_membind)(hwloc_topology_t topology, void *addr, size_t len); |
143 | | |
144 | | int (*get_allowed_resources)(hwloc_topology_t topology); |
145 | | } binding_hooks; |
146 | | |
147 | | struct hwloc_topology_support support; |
148 | | |
149 | | struct hwloc_infos_s infos; |
150 | | |
151 | | void (*userdata_export_cb)(void *reserved, struct hwloc_topology *topology, struct hwloc_obj *obj); |
152 | | void (*userdata_import_cb)(struct hwloc_topology *topology, struct hwloc_obj *obj, const char *name, const void *buffer, size_t length); |
153 | | int userdata_not_decoded; |
154 | | |
155 | | struct hwloc_internal_distances_s { |
156 | | char *name; /* FIXME: needs an API to set it from user */ |
157 | | |
158 | | unsigned id; /* to match the container id field of public distances structure |
159 | | * not exported to XML, regenerated during _add() |
160 | | */ |
161 | | |
162 | | /* if all objects have the same type, different_types is NULL and unique_type is valid. |
163 | | * otherwise unique_type is HWLOC_OBJ_TYPE_NONE and different_types contains individual objects types. |
164 | | */ |
165 | | hwloc_obj_type_t unique_type; |
166 | | hwloc_obj_type_t *different_types; |
167 | | |
168 | | /* add union hwloc_obj_attr_u if we ever support groups */ |
169 | | unsigned nbobjs; |
170 | | uint64_t *indexes; /* array of OS or GP indexes before we can convert them into objs. |
171 | | * OS indexes for distances covering only PUs or only NUMAnodes. |
172 | | */ |
173 | | #define HWLOC_DIST_TYPE_USE_OS_INDEX(_type) ((_type) == HWLOC_OBJ_PU || (_type == HWLOC_OBJ_NUMANODE)) |
174 | | uint64_t *values; /* distance matrices, ordered according to the above indexes/objs array. |
175 | | * distance from i to j is stored in slot i*nbnodes+j. |
176 | | */ |
177 | | unsigned long kind; |
178 | | |
179 | | #define HWLOC_INTERNAL_DIST_FLAG_OBJS_VALID (1U<<0) /* if the objs array is valid below */ |
180 | | #define HWLOC_INTERNAL_DIST_FLAG_NOT_COMMITTED (1U<<1) /* if the distances isn't in the list yet */ |
181 | | unsigned iflags; |
182 | | |
183 | | /* objects are currently stored in physical_index order */ |
184 | | hwloc_obj_t *objs; /* array of objects */ |
185 | | |
186 | | struct hwloc_internal_distances_s *prev, *next; |
187 | | } *first_dist, *last_dist; |
188 | | unsigned next_dist_id; |
189 | | |
190 | | /* memory attributes */ |
191 | | unsigned nr_memattrs; |
192 | | struct hwloc_internal_memattr_s { |
193 | | /* memattr info */ |
194 | | char *name; /* TODO unit is implicit, in the documentation of standard attributes, or in the name? */ |
195 | | unsigned long flags; |
196 | | #define HWLOC_IMATTR_FLAG_STATIC_NAME (1U<<0) /* no need to free name */ |
197 | | #define HWLOC_IMATTR_FLAG_CACHE_VALID (1U<<1) /* target and initiator are valid */ |
198 | | #define HWLOC_IMATTR_FLAG_CONVENIENCE (1U<<2) /* convenience attribute reporting values from non-memattr attributes (R/O and no actual targets stored) */ |
199 | | unsigned iflags; |
200 | | |
201 | | /* array of values */ |
202 | | unsigned nr_targets; |
203 | | struct hwloc_internal_memattr_target_s { |
204 | | /* target object */ |
205 | | hwloc_obj_t obj; /* cached between refreshes */ |
206 | | hwloc_obj_type_t type; |
207 | | unsigned os_index; /* only used temporarily during discovery when there's no obj/gp_index yet */ |
208 | | hwloc_uint64_t gp_index; |
209 | | |
210 | | /* value if there are no initiator for this attr */ |
211 | | hwloc_uint64_t noinitiator_value; |
212 | | /* initiators otherwise */ |
213 | | unsigned nr_initiators; |
214 | | struct hwloc_internal_memattr_initiator_s { |
215 | | struct hwloc_internal_location_s initiator; |
216 | | hwloc_uint64_t value; |
217 | | } *initiators; |
218 | | } *targets; |
219 | | } *memattrs; |
220 | | |
221 | | /* hybridcpus */ |
222 | | unsigned nr_cpukinds; |
223 | | unsigned nr_cpukinds_allocated; |
224 | | struct hwloc_internal_cpukind_s { |
225 | | hwloc_cpuset_t cpuset; |
226 | | #define HWLOC_CPUKIND_EFFICIENCY_UNKNOWN -1 |
227 | | int efficiency; |
228 | | int forced_efficiency; /* returned by the hardware or OS if any */ |
229 | | hwloc_uint64_t ranking_value; /* internal value for ranking */ |
230 | | struct hwloc_infos_s infos; |
231 | | } *cpukinds; |
232 | | |
233 | | int grouping; |
234 | | int grouping_verbose; |
235 | | unsigned grouping_nbaccuracies; |
236 | | float grouping_accuracies[5]; |
237 | | unsigned grouping_next_subkind; |
238 | | |
239 | | /* pci localities */ |
240 | | /* FIXME: reuse for finding specific buses */ |
241 | | /* FIXME: save to XML */ |
242 | | struct hwloc_pci_locality_s { |
243 | | unsigned domain; |
244 | | unsigned bus_min; |
245 | | unsigned bus_max; |
246 | | hwloc_cpuset_t cpuset; |
247 | | hwloc_obj_t parent; /* may need to refreshed from cpuset on topology changes */ |
248 | | struct hwloc_pci_locality_s *prev, *next; |
249 | | } *first_pci_locality, *last_pci_locality; /* contains unsorted forced localities first, then sorted real ones */ |
250 | | |
251 | | /* list of enabled backends. */ |
252 | | struct hwloc_backend * backends; |
253 | | struct hwloc_backend * get_pci_busid_cpuset_backend; /* first backend that provides get_pci_busid_cpuset() callback */ |
254 | | unsigned backend_phases; |
255 | | unsigned backend_excluded_phases; |
256 | | |
257 | | /* memory allocator for topology objects */ |
258 | | struct hwloc_tma * tma; |
259 | | |
260 | | /***************************************************** |
261 | | * WARNING: |
262 | | * changes above in this structure (and its children) |
263 | | * should cause a bump of HWLOC_TOPOLOGY_ABI. |
264 | | *****************************************************/ |
265 | | |
266 | | /* |
267 | | * temporary variables during discovery |
268 | | */ |
269 | | |
270 | | /* set to 1 at the beginning of load() if the filter of any cpu cache type (L1 to L3i) is not NONE, |
271 | | * may be checked by backends before querying caches |
272 | | * (when they don't know the level of caches they are querying). |
273 | | */ |
274 | | int want_some_cpu_caches; |
275 | | |
276 | | /* machine-wide memory. |
277 | | * temporarily stored there by OSes that only provide this without NUMA information, |
278 | | * and actually used later by the core. |
279 | | */ |
280 | | struct hwloc_numanode_attr_s machine_memory; |
281 | | |
282 | | /* component blacklisting */ |
283 | | unsigned nr_blacklisted_components; |
284 | | struct hwloc_topology_forced_component_s { |
285 | | struct hwloc_disc_component *component; |
286 | | unsigned phases; |
287 | | } *blacklisted_components; |
288 | | }; |
289 | | |
290 | | extern void hwloc_alloc_root_sets(hwloc_obj_t root); |
291 | | extern void hwloc_setup_pu_level(struct hwloc_topology *topology, unsigned nb_pus); |
292 | | extern int hwloc_get_sysctlbyname(const char *name, int64_t *n); |
293 | | extern int hwloc_get_sysctl(int name[], unsigned namelen, int64_t *n); |
294 | | |
295 | | /* returns the number of CPU from the OS (only valid if thissystem) */ |
296 | | #define HWLOC_FALLBACK_NBPROCESSORS_INCLUDE_OFFLINE 1 /* by default we try to get only the online CPUs */ |
297 | | extern int hwloc_fallback_nbprocessors(unsigned flags); |
298 | | /* returns the memory size from the OS (only valid if thissystem) */ |
299 | | extern int64_t hwloc_fallback_memsize(void); |
300 | | |
301 | | extern int hwloc__object_cpusets_compare_first(hwloc_obj_t obj1, hwloc_obj_t obj2); |
302 | | extern void hwloc__reorder_children(hwloc_obj_t parent); |
303 | | |
304 | | extern void hwloc_topology_setup_defaults(struct hwloc_topology *topology); |
305 | | extern void hwloc_topology_clear(struct hwloc_topology *topology); |
306 | | |
307 | | #define _HWLOC_RECONNECT_FLAG_KEEPSTRUCTURE (1UL<<0) |
308 | | extern int hwloc__reconnect(struct hwloc_topology *topology, unsigned long flags); |
309 | | |
310 | | /* insert memory object as memory child of normal parent */ |
311 | | extern struct hwloc_obj * hwloc__attach_memory_object(struct hwloc_topology *topology, hwloc_obj_t parent, |
312 | | hwloc_obj_t obj, const char *reason); |
313 | | |
314 | | extern hwloc_obj_t hwloc_get_obj_by_type_and_gp_index(hwloc_topology_t topology, hwloc_obj_type_t type, uint64_t gp_index); |
315 | | |
316 | | extern void hwloc_pci_init(struct hwloc_topology *topology); |
317 | | extern void hwloc_pci_prepare(struct hwloc_topology *topology); |
318 | | extern void hwloc_pci_refresh(struct hwloc_topology *topology); |
319 | | extern int hwloc_pci_dup(hwloc_topology_t new, hwloc_topology_t old); |
320 | | extern void hwloc_pci_exit(struct hwloc_topology *topology); |
321 | | |
322 | | extern void hwloc_pci_xml_import_locality(struct hwloc_topology *topology, unsigned domain, unsigned bus_min, unsigned bus_max, hwloc_obj_t parent, hwloc_cpuset_t cpuset); |
323 | | extern void hwloc_pci_xml_import_refresh_localities(struct hwloc_topology *topology); |
324 | | |
325 | | extern int hwloc__add_info(struct hwloc_infos_s *infos, const char *name, const char *value); |
326 | | extern int hwloc__replace_infos(struct hwloc_infos_s *infos, const char *name, const char *value); |
327 | | extern int hwloc__remove_infos(struct hwloc_infos_s *infos, const char *name, const char *value); |
328 | | extern int hwloc__move_infos(struct hwloc_infos_s *dst_infos, struct hwloc_infos_s *src_infos); |
329 | | extern int hwloc__tma_dup_infos(struct hwloc_tma *tma, struct hwloc_infos_s *dst_infos, struct hwloc_infos_s *src_infos); |
330 | | extern void hwloc__free_infos(struct hwloc_infos_s *infos); |
331 | | static __hwloc_inline void hwloc__init_infos(struct hwloc_infos_s *infos) |
332 | 0 | { |
333 | 0 | infos->array = NULL; |
334 | 0 | infos->count = 0; |
335 | 0 | infos->allocated = 0; |
336 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc__init_infos Unexecuted instantiation: base64.c:hwloc__init_infos |
337 | | static __hwloc_inline void hwloc__init_infos_static(struct hwloc_infos_s *infos, unsigned count, struct hwloc_info_s *static_array) |
338 | 0 | { |
339 | 0 | infos->array = static_array; |
340 | 0 | infos->count = count; |
341 | 0 | infos->allocated = 0; /* means we won't free */ |
342 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc__init_infos_static Unexecuted instantiation: base64.c:hwloc__init_infos_static |
343 | | |
344 | | /* set native OS binding hooks */ |
345 | | extern void hwloc_set_native_binding_hooks(struct hwloc_binding_hooks *hooks, struct hwloc_topology_support *support); |
346 | | /* set either native OS binding hooks (if thissystem), or dummy ones */ |
347 | | extern void hwloc_set_binding_hooks(struct hwloc_topology *topology); |
348 | | |
349 | | #if defined(HWLOC_LINUX_SYS) |
350 | | extern void hwloc_set_linuxfs_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support); |
351 | | #endif /* HWLOC_LINUX_SYS */ |
352 | | |
353 | | #ifdef HWLOC_SOLARIS_SYS |
354 | | extern void hwloc_set_solaris_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support); |
355 | | #endif /* HWLOC_SOLARIS_SYS */ |
356 | | |
357 | | #ifdef HWLOC_AIX_SYS |
358 | | extern void hwloc_set_aix_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support); |
359 | | #endif /* HWLOC_AIX_SYS */ |
360 | | |
361 | | #ifdef HWLOC_WIN_SYS |
362 | | extern void hwloc_set_windows_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support); |
363 | | #endif /* HWLOC_WIN_SYS */ |
364 | | |
365 | | #ifdef HWLOC_DARWIN_SYS |
366 | | extern void hwloc_set_darwin_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support); |
367 | | #endif /* HWLOC_DARWIN_SYS */ |
368 | | |
369 | | #ifdef HWLOC_FREEBSD_SYS |
370 | | extern void hwloc_set_freebsd_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support); |
371 | | #endif /* HWLOC_FREEBSD_SYS */ |
372 | | |
373 | | #ifdef HWLOC_NETBSD_SYS |
374 | | extern void hwloc_set_netbsd_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support); |
375 | | #endif /* HWLOC_NETBSD_SYS */ |
376 | | |
377 | | extern int hwloc_look_hardwired_fujitsu_k(struct hwloc_topology *topology); |
378 | | extern int hwloc_look_hardwired_fujitsu_fx10(struct hwloc_topology *topology); |
379 | | extern int hwloc_look_hardwired_fujitsu_fx100(struct hwloc_topology *topology); |
380 | | |
381 | | /* Insert uname-specific names/values in the object infos array. |
382 | | * If cached_uname isn't NULL, it is used as a struct utsname instead of recalling uname. |
383 | | * Any field that starts with \0 is ignored. |
384 | | */ |
385 | | extern void hwloc_add_uname_info(struct hwloc_topology *topology, void *cached_uname); |
386 | | |
387 | | /* Insert PageSizes topology info from legacy sysconf&co */ |
388 | | extern void hwloc_fallback_add_pagesize_info(struct hwloc_topology *topology); |
389 | | |
390 | | #if (defined HWLOC_LINUX_SYS) |
391 | | /* Linux may need more than a long when loading a 64bit sysfs dump (eg with 16GB pages) on a 32bit machine */ |
392 | | typedef uint64_t hwloc_pagesize_arrayelt_t; |
393 | | #else |
394 | | /* at least Solaris and FreeBSD want a size_t */ |
395 | | typedef size_t hwloc_pagesize_arrayelt_t; |
396 | | #endif |
397 | | |
398 | | /* Insert PageSizes topology info from the array of sizes */ |
399 | | extern int hwloc__add_pagesize_info_from_array(struct hwloc_topology *topology, hwloc_pagesize_arrayelt_t *sizes, unsigned nr); |
400 | | |
401 | | /* Free obj and its attributes assuming it's not linked to a parent and doesn't have any child */ |
402 | | extern void hwloc_free_unlinked_object(hwloc_obj_t obj); |
403 | | |
404 | | /* Free obj and its children, assuming it's not linked to a parent */ |
405 | | extern void hwloc_free_object_and_children(hwloc_obj_t obj); |
406 | | |
407 | | /* Free obj, its next siblings, and their children, assuming they're not linked to a parent */ |
408 | | extern void hwloc_free_object_siblings_and_children(hwloc_obj_t obj); |
409 | | |
410 | | /* This can be used for the alloc field to get allocated data that can be freed by free() */ |
411 | | void *hwloc_alloc_heap(hwloc_topology_t topology, size_t len); |
412 | | |
413 | | /* This can be used for the alloc field to get allocated data that can be freed by munmap() */ |
414 | | void *hwloc_alloc_mmap(hwloc_topology_t topology, size_t len); |
415 | | |
416 | | /* This can be used for the free_membind field to free data using free() */ |
417 | | int hwloc_free_heap(hwloc_topology_t topology, void *addr, size_t len); |
418 | | |
419 | | /* This can be used for the free_membind field to free data using munmap() */ |
420 | | int hwloc_free_mmap(hwloc_topology_t topology, void *addr, size_t len); |
421 | | |
422 | | /* Allocates unbound memory or fail, depending on whether STRICT is requested |
423 | | * or not */ |
424 | | static __hwloc_inline void * |
425 | | hwloc_alloc_or_fail(hwloc_topology_t topology, size_t len, int flags) |
426 | 0 | { |
427 | 0 | if (flags & HWLOC_MEMBIND_STRICT) |
428 | 0 | return NULL; |
429 | 0 | return hwloc_alloc(topology, len); |
430 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc_alloc_or_fail Unexecuted instantiation: base64.c:hwloc_alloc_or_fail |
431 | | |
432 | | extern void hwloc_internal_distances_init(hwloc_topology_t topology); |
433 | | extern void hwloc_internal_distances_prepare(hwloc_topology_t topology); |
434 | | extern void hwloc_internal_distances_destroy(hwloc_topology_t topology); |
435 | | extern int hwloc_internal_distances_dup(hwloc_topology_t new, hwloc_topology_t old); |
436 | | extern void hwloc_internal_distances_refresh(hwloc_topology_t topology); |
437 | | extern void hwloc_internal_distances_invalidate_cached_objs(hwloc_topology_t topology); |
438 | | |
439 | | /* these distances_add() functions are higher-level than those in hwloc/plugins.h |
440 | | * but they may change in the future, hence they are not exported to plugins. |
441 | | */ |
442 | | extern int hwloc_internal_distances_add_by_index(hwloc_topology_t topology, const char *name, hwloc_obj_type_t unique_type, hwloc_obj_type_t *different_types, unsigned nbobjs, uint64_t *indexes, uint64_t *values, unsigned long kind, unsigned long flags); |
443 | | extern int hwloc_internal_distances_add(hwloc_topology_t topology, const char *name, unsigned nbobjs, hwloc_obj_t *objs, uint64_t *values, unsigned long kind, unsigned long flags); |
444 | | |
445 | | extern void hwloc_internal_memattrs_init(hwloc_topology_t topology); |
446 | | extern void hwloc_internal_memattrs_prepare(hwloc_topology_t topology); |
447 | | extern void hwloc_internal_memattrs_destroy(hwloc_topology_t topology); |
448 | | extern void hwloc_internal_memattrs_need_refresh(hwloc_topology_t topology); |
449 | | extern void hwloc_internal_memattrs_refresh(hwloc_topology_t topology); |
450 | | extern int hwloc_internal_memattrs_dup(hwloc_topology_t new, hwloc_topology_t old); |
451 | | extern int hwloc_internal_memattr_set_value(hwloc_topology_t topology, hwloc_memattr_id_t id, hwloc_obj_type_t target_type, hwloc_uint64_t target_gp_index, unsigned target_os_index, struct hwloc_internal_location_s *initiator, hwloc_uint64_t value); |
452 | | extern int hwloc_internal_memattrs_guess_memory_tiers(hwloc_topology_t topology, int force_subtype); |
453 | | |
454 | | extern void hwloc_internal_cpukinds_init(hwloc_topology_t topology); |
455 | | extern int hwloc_internal_cpukinds_rank(hwloc_topology_t topology); |
456 | | extern void hwloc_internal_cpukinds_destroy(hwloc_topology_t topology); |
457 | | extern int hwloc_internal_cpukinds_dup(hwloc_topology_t new, hwloc_topology_t old); |
458 | | #define HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY (1<<0) |
459 | | extern int hwloc_internal_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t cpuset, int forced_efficiency, const struct hwloc_infos_s *infos, unsigned long flags); |
460 | | extern void hwloc_internal_cpukinds_restrict(hwloc_topology_t topology); |
461 | | |
462 | | /* encode src buffer into target buffer. |
463 | | * targsize must be at least 4*((srclength+2)/3)+1. |
464 | | * target will be 0-terminated. |
465 | | */ |
466 | | extern int hwloc_encode_to_base64(const char *src, size_t srclength, char *target, size_t targsize); |
467 | | /* decode src buffer into target buffer. |
468 | | * src is 0-terminated. |
469 | | * targsize must be at least srclength*3/4+1 (srclength not including \0) |
470 | | * but only srclength*3/4 characters will be meaningful |
471 | | * (the next one may be partially written during decoding, but it should be ignored). |
472 | | */ |
473 | | extern int hwloc_decode_from_base64(char const *src, char *target, size_t targsize); |
474 | | |
475 | | /* On some systems, snprintf returns the size of written data, not the actually |
476 | | * required size. Sometimes it returns -1 on truncation too. |
477 | | * And sometimes it doesn't like NULL output buffers. |
478 | | * http://www.gnu.org/software/gnulib/manual/html_node/snprintf.html |
479 | | * |
480 | | * hwloc_snprintf behaves properly, but it's a bit overkill on the vast majority |
481 | | * of platforms, so don't enable it unless really needed. |
482 | | */ |
483 | | #ifdef HWLOC_HAVE_CORRECT_SNPRINTF |
484 | | #define hwloc_snprintf snprintf |
485 | | #else |
486 | | extern int hwloc_snprintf(char *str, size_t size, const char *format, ...) __hwloc_attribute_format(printf, 3, 4); |
487 | | #endif |
488 | | |
489 | | /* uses HWLOC_OBJ_SNPRINTF_FLAG_ flags */ |
490 | | static __hwloc_inline int hwloc_memory_size_snprintf(char *buffer, size_t bufsize, unsigned long long size, unsigned long flags) |
491 | 0 | { |
492 | 0 | /* no units */ |
493 | 0 | if (flags & HWLOC_OBJ_SNPRINTF_FLAG_NO_UNITS) { |
494 | 0 | return snprintf(buffer, bufsize, "%llu", size); |
495 | 0 | } |
496 | 0 |
|
497 | 0 | /* old deprecated format (KiB value with KB units) */ |
498 | 0 | if (flags & HWLOC_OBJ_SNPRINTF_FLAG_OLD_VERBOSE) { |
499 | 0 | return snprintf(buffer, bufsize, "%llu%s", ((size>>9)+1)>>1, "KB"); |
500 | 0 | } |
501 | 0 |
|
502 | 0 | /* units 1000 */ |
503 | 0 | if (flags & HWLOC_OBJ_SNPRINTF_FLAG_UNITS_1000) { |
504 | 0 | if (size < 10000000ULL) { |
505 | 0 | return snprintf(buffer, bufsize, "%llu%s", ((size/500)+1)/2, "KB"); |
506 | 0 | } else if (size < 10000000000ULL) { |
507 | 0 | return snprintf(buffer, bufsize, "%llu%s", ((size/500000)+1)/2, "MB"); |
508 | 0 | } else if (size < 10000000000000ULL) { |
509 | 0 | return snprintf(buffer, bufsize, "%llu%s", ((size/500000000)+1)/2, "GB"); |
510 | 0 | } else { |
511 | 0 | return snprintf(buffer, bufsize, "%llu%s", ((size/500000000000ULL)+1)/2, "TB"); |
512 | 0 | } |
513 | 0 | } |
514 | 0 |
|
515 | 0 | /* units 1024 */ |
516 | 0 | if (size < (10ULL<<20)) { |
517 | 0 | return snprintf(buffer, bufsize, "%llu%s", ((size>>9)+1)>>1, "KiB"); |
518 | 0 | } else if (size < (10ULL<<30)) { |
519 | 0 | return snprintf(buffer, bufsize, "%llu%s", ((size>>19)+1)>>1, "MiB"); |
520 | 0 | } else if (size < (10ULL<<40)) { |
521 | 0 | return snprintf(buffer, bufsize, "%llu%s", ((size>>29)+1)>>1, "GiB"); |
522 | 0 | } else { |
523 | 0 | return snprintf(buffer, bufsize, "%llu%s", ((size>>39)+1)>>1, "TiB"); |
524 | 0 | } |
525 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc_memory_size_snprintf Unexecuted instantiation: base64.c:hwloc_memory_size_snprintf |
526 | | |
527 | | /* Return the name of the currently running program, if supported. |
528 | | * If not NULL, must be freed by the caller. |
529 | | */ |
530 | | extern char * hwloc_progname(struct hwloc_topology *topology); |
531 | | |
532 | | /* obj->attr->group.kind internal values. |
533 | | * the core will keep the smallest ones when merging two groups, |
534 | | * that's why user-given kinds are first. |
535 | | */ |
536 | | /* first, user-given groups, should remain as long as possible */ |
537 | | #define HWLOC_GROUP_KIND_USER 0 /* user-given, user may use subkind too */ |
538 | | #define HWLOC_GROUP_KIND_SYNTHETIC 10 /* subkind is group depth within synthetic description */ |
539 | | /* then, hardware-specific groups */ |
540 | | #define HWLOC_GROUP_KIND_INTEL_KNL_SUBNUMA_CLUSTER 100 /* no subkind */ |
541 | | #define HWLOC_GROUP_KIND_INTEL_EXTTOPOENUM_UNKNOWN 101 /* subkind is unknown level */ |
542 | | #define HWLOC_GROUP_KIND_INTEL_MODULE 102 /* no subkind */ |
543 | | #define HWLOC_GROUP_KIND_INTEL_TILE 103 /* no subkind */ |
544 | | #define HWLOC_GROUP_KIND_INTEL_DIE 104 /* no subkind */ |
545 | | #define HWLOC_GROUP_KIND_S390_BOOK 110 /* subkind 0 is book, subkind 1 is drawer (group of books) */ |
546 | | #define HWLOC_GROUP_KIND_AMD_COMPUTE_UNIT 120 /* no subkind */ |
547 | | #define HWLOC_GROUP_KIND_AMD_COMPLEX 121 /* no subkind */ |
548 | | /* then, OS-specific groups */ |
549 | | #define HWLOC_GROUP_KIND_SOLARIS_PG_HW_PERF 200 /* subkind is group width */ |
550 | | #define HWLOC_GROUP_KIND_AIX_SDL_UNKNOWN 210 /* subkind is SDL level */ |
551 | | #define HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP 220 /* no subkind */ |
552 | | #define HWLOC_GROUP_KIND_WINDOWS_RELATIONSHIP_UNKNOWN 221 /* no subkind */ |
553 | | #define HWLOC_GROUP_KIND_LINUX_CLUSTER 222 /* no subkind */ |
554 | | /* distance groups */ |
555 | | #define HWLOC_GROUP_KIND_DISTANCE 900 /* subkind is round of adding these groups during distance based grouping */ |
556 | | /* finally, hwloc-specific groups required to insert something else, should disappear as soon as possible */ |
557 | | #define HWLOC_GROUP_KIND_IO 1000 /* no subkind */ |
558 | | #define HWLOC_GROUP_KIND_MEMORY 1001 /* no subkind */ |
559 | | |
560 | | /* memory allocator for topology objects */ |
561 | | struct hwloc_tma { |
562 | | void * (*malloc)(struct hwloc_tma *, size_t); |
563 | | void *data; |
564 | | int dontfree; /* when set, free() or realloc() cannot be used, and tma->malloc() cannot fail */ |
565 | | }; |
566 | | |
567 | | static __hwloc_inline void * |
568 | | hwloc_tma_malloc(struct hwloc_tma *tma, |
569 | | size_t size) |
570 | 0 | { |
571 | 0 | if (tma) { |
572 | 0 | return tma->malloc(tma, size); |
573 | 0 | } else { |
574 | 0 | return malloc(size); |
575 | 0 | } |
576 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc_tma_malloc Unexecuted instantiation: base64.c:hwloc_tma_malloc |
577 | | |
578 | | static __hwloc_inline void * |
579 | | hwloc_tma_calloc(struct hwloc_tma *tma, |
580 | | size_t size) |
581 | 0 | { |
582 | 0 | char *ptr = hwloc_tma_malloc(tma, size); |
583 | 0 | if (ptr) |
584 | 0 | memset(ptr, 0, size); |
585 | 0 | return ptr; |
586 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc_tma_calloc Unexecuted instantiation: base64.c:hwloc_tma_calloc |
587 | | |
588 | | static __hwloc_inline char * |
589 | | hwloc_tma_strdup(struct hwloc_tma *tma, |
590 | | const char *src) |
591 | 0 | { |
592 | 0 | size_t len = strlen(src); |
593 | 0 | char *ptr = hwloc_tma_malloc(tma, len+1); |
594 | 0 | if (ptr) |
595 | 0 | memcpy(ptr, src, len+1); |
596 | 0 | return ptr; |
597 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc_tma_strdup Unexecuted instantiation: base64.c:hwloc_tma_strdup |
598 | | |
599 | | /* bitmap allocator to be used inside hwloc */ |
600 | | extern hwloc_bitmap_t hwloc_bitmap_tma_dup(struct hwloc_tma *tma, hwloc_const_bitmap_t old); |
601 | | |
602 | | extern int hwloc__topology_dup(hwloc_topology_t *newp, hwloc_topology_t old, struct hwloc_tma *tma); |
603 | | extern void hwloc__topology_disadopt(hwloc_topology_t topology); |
604 | | |
605 | | #endif /* HWLOC_PRIVATE_H */ |