hwlocality_sys/
lib.rs

1#![allow(non_camel_case_types, unknown_lints)]
2#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg, doc_cfg_hide))]
3#![cfg_attr(docsrs, doc(cfg_hide(doc)))]
4// Last allow-by-default lint review performed as of Rust 1.72
5#![deny(
6    clippy::as_ptr_cast_mut,
7    clippy::as_underscore,
8    clippy::assertions_on_result_states,
9    clippy::bool_to_int_with_if,
10    clippy::borrow_as_ptr,
11    clippy::branches_sharing_code,
12    clippy::cargo_common_metadata,
13    clippy::case_sensitive_file_extension_comparisons,
14    clippy::cast_lossless,
15    clippy::cast_possible_truncation,
16    clippy::cast_possible_wrap,
17    clippy::cast_precision_loss,
18    clippy::cast_ptr_alignment,
19    clippy::cast_sign_loss,
20    clippy::checked_conversions,
21    clippy::clear_with_drain,
22    clippy::clone_on_ref_ptr,
23    clippy::cloned_instead_of_copied,
24    clippy::cognitive_complexity,
25    clippy::collection_is_never_read,
26    clippy::create_dir,
27    clippy::debug_assert_with_mut_call,
28    clippy::decimal_literal_representation,
29    clippy::derive_partial_eq_without_eq,
30    clippy::doc_link_with_quotes,
31    clippy::doc_markdown,
32    clippy::empty_drop,
33    clippy::empty_enum,
34    clippy::empty_line_after_doc_comments,
35    clippy::empty_line_after_outer_attr,
36    clippy::empty_structs_with_brackets,
37    clippy::enum_glob_use,
38    clippy::equatable_if_let,
39    clippy::exit,
40    clippy::expl_impl_clone_on_copy,
41    clippy::explicit_deref_methods,
42    clippy::explicit_into_iter_loop,
43    clippy::explicit_iter_loop,
44    clippy::fallible_impl_from,
45    clippy::filter_map_next,
46    clippy::flat_map_option,
47    clippy::float_cmp,
48    clippy::float_cmp_const,
49    clippy::fn_to_numeric_cast_any,
50    clippy::format_push_string,
51    clippy::from_iter_instead_of_collect,
52    clippy::get_unwrap,
53    clippy::if_not_else,
54    clippy::if_then_some_else_none,
55    clippy::implicit_clone,
56    clippy::implicit_hasher,
57    clippy::imprecise_flops,
58    clippy::index_refutable_slice,
59    clippy::inline_always,
60    clippy::invalid_upcast_comparisons,
61    clippy::iter_not_returning_iterator,
62    clippy::iter_on_empty_collections,
63    clippy::iter_on_single_items,
64    clippy::large_digit_groups,
65    clippy::large_stack_arrays,
66    clippy::large_types_passed_by_value,
67    clippy::linkedlist,
68    clippy::macro_use_imports,
69    clippy::manual_assert,
70    clippy::manual_clamp,
71    clippy::manual_instant_elapsed,
72    clippy::manual_let_else,
73    clippy::manual_ok_or,
74    clippy::manual_string_new,
75    clippy::many_single_char_names,
76    clippy::map_unwrap_or,
77    clippy::match_bool,
78    clippy::match_same_arms,
79    clippy::match_wildcard_for_single_variants,
80    clippy::mismatching_type_param_order,
81    clippy::missing_assert_message,
82    clippy::missing_docs_in_private_items,
83    clippy::missing_errors_doc,
84    clippy::missing_fields_in_debug,
85    clippy::mixed_read_write_in_expression,
86    clippy::mut_mut,
87    clippy::mutex_atomic,
88    clippy::mutex_integer,
89    clippy::naive_bytecount,
90    clippy::needless_collect,
91    clippy::needless_continue,
92    clippy::needless_for_each,
93    clippy::negative_feature_names,
94    clippy::no_mangle_with_rust_abi,
95    clippy::non_send_fields_in_send_ty,
96    clippy::nonstandard_macro_braces,
97    clippy::option_if_let_else,
98    clippy::option_option,
99    clippy::or_fun_call,
100    clippy::partial_pub_fields,
101    clippy::path_buf_push_overwrite,
102    clippy::print_stdout,
103    clippy::ptr_as_ptr,
104    clippy::ptr_cast_constness,
105    clippy::pub_without_shorthand,
106    clippy::range_minus_one,
107    clippy::range_plus_one,
108    clippy::rc_buffer,
109    clippy::rc_mutex,
110    clippy::redundant_clone,
111    clippy::redundant_closure_for_method_calls,
112    clippy::redundant_feature_names,
113    clippy::ref_option_ref,
114    clippy::ref_patterns,
115    clippy::rest_pat_in_fully_bound_structs,
116    clippy::same_functions_in_if_condition,
117    clippy::self_named_module_files,
118    clippy::semicolon_inside_block,
119    clippy::semicolon_outside_block,
120    clippy::significant_drop_in_scrutinee,
121    clippy::similar_names,
122    clippy::single_match_else,
123    clippy::str_to_string,
124    clippy::string_add,
125    clippy::string_lit_as_bytes,
126    clippy::string_to_string,
127    clippy::suboptimal_flops,
128    clippy::suspicious_operation_groupings,
129    clippy::tests_outside_test_module,
130    clippy::todo,
131    clippy::too_many_lines,
132    clippy::trailing_empty_array,
133    clippy::transmute_ptr_to_ptr,
134    clippy::trivial_regex,
135    clippy::trivially_copy_pass_by_ref,
136    clippy::try_err,
137    clippy::type_repetition_in_bounds,
138    clippy::undocumented_unsafe_blocks,
139    clippy::unicode_not_nfc,
140    clippy::unimplemented,
141    clippy::uninlined_format_args,
142    clippy::unnecessary_box_returns,
143    clippy::unnecessary_join,
144    clippy::unnecessary_safety_comment,
145    clippy::unnecessary_safety_doc,
146    clippy::unnecessary_self_imports,
147    clippy::unnecessary_struct_initialization,
148    clippy::unnecessary_wraps,
149    clippy::unneeded_field_pattern,
150    clippy::unnested_or_patterns,
151    clippy::unreadable_literal,
152    clippy::unsafe_derive_deserialize,
153    clippy::unused_async,
154    clippy::unused_peekable,
155    clippy::unused_rounding,
156    clippy::unwrap_used,
157    clippy::use_self,
158    clippy::used_underscore_binding,
159    clippy::useless_let_if_seq,
160    clippy::verbose_bit_mask,
161    clippy::verbose_file_reads,
162    clippy::wildcard_dependencies,
163    clippy::wildcard_enum_match_arm,
164    clippy::wildcard_imports,
165    clippy::zero_sized_map_values,
166    invalid_reference_casting,
167    macro_use_extern_crate,
168    missing_abi,
169    missing_copy_implementations,
170    missing_debug_implementations,
171    // FIXME: Bring back missing_docs,
172    non_ascii_idents,
173    rust_2018_compatibility,
174    rust_2021_compatibility,
175    rustdoc::bare_urls,
176    rustdoc::broken_intra_doc_links,
177    rustdoc::invalid_codeblock_attributes,
178    rustdoc::invalid_html_tags,
179    rustdoc::invalid_rust_codeblocks,
180    rustdoc::missing_crate_level_docs,
181    rustdoc::private_intra_doc_links,
182    rustdoc::unescaped_backticks,
183    trivial_casts,
184    trivial_numeric_casts,
185    unreachable_pub,
186    unsafe_op_in_unsafe_fn,
187    variant_size_differences
188)]
189#![warn(
190    clippy::dbg_macro,
191    clippy::print_stderr,
192    clippy::use_debug,
193    future_incompatible,
194    keyword_idents,
195    let_underscore,
196    meta_variable_misuse,
197    noop_method_call,
198    rust_2018_idioms,
199    unused
200)]
201#![doc = include_str!("../README.md")]
202
203#[cfg(target_os = "linux")]
204use libc::pid_t;
205#[cfg(doc)]
206use std::panic::UnwindSafe;
207use std::{
208    cell::UnsafeCell,
209    ffi::{c_char, c_float, c_int, c_uchar, c_uint, c_ulong, c_ushort, c_void},
210    fmt::Debug,
211    marker::{PhantomData, PhantomPinned},
212    panic::RefUnwindSafe,
213    ptr,
214};
215
216// === Things which are not part of the main hwloc documentation
217
218/// pid_t placeholder for rustdoc
219#[cfg(all(doc, not(target_os = "linux")))]
220pub type pid_t = c_int;
221
222/// Rust model of a C incomplete type (struct declaration without a definition)
223///
224/// From <https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs>
225///
226/// This type purposely implements no traits, not even Debug, because you should
227/// never, ever deal with it directly, only with raw pointers to it that you
228/// blindly pass to the hwloc API.
229#[repr(C)]
230struct IncompleteType {
231    /// Stolen from
232    /// <https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs>
233    ///
234    /// No idea why the original author thought the `_marker` field is not
235    /// sufficient, but the authors of this book tend to be more well-versed
236    /// into compiler black magic than I do, so let's keep it that way...
237    _data: [u8; 0],
238
239    /// Ensures `RefUnwindSafe`, `Send`, `Sync`, `Unpin` and `UndindSafe` are
240    /// not implemented
241    _marker: PhantomData<(*mut u8, PhantomPinned, &'static UnsafeCell<u8>)>,
242}
243
244/// Thread identifier (OS-specific)
245///
246/// This is `HANDLE` on Windows and `libc::pthread_t` on most other platforms,
247/// except on musl where it must be hardcoded to `c_ulong` to [preserve
248/// sanity](https://elixir.bootlin.com/musl/v1.2.4/source/include/alltypes.h.in#L53).
249#[cfg(target_os = "windows")]
250#[cfg_attr(docsrs, doc(cfg(all())))]
251pub type hwloc_thread_t = windows_sys::Win32::Foundation::HANDLE;
252
253/// Process identifier (OS-specific)
254///
255/// This is `u32` on Windows and `libc::pid_t` on all other platforms.
256#[cfg(target_os = "windows")]
257#[cfg_attr(docsrs, doc(cfg(all())))]
258pub type hwloc_pid_t = u32;
259
260/// Thread identifier (OS-specific)
261///
262/// This is `HANDLE` on Windows and `libc::pthread_t` on most other platforms,
263/// except on musl where it must be hardcoded to `c_ulong` to [preserve
264/// sanity](https://elixir.bootlin.com/musl/v1.2.4/source/include/alltypes.h.in#L53)
265#[cfg(not(any(target_os = "windows", target_env = "musl")))]
266#[cfg_attr(docsrs, doc(cfg(all())))]
267pub type hwloc_thread_t = libc::pthread_t;
268
269/// Thread identifier (OS-specific)
270///
271/// This is `HANDLE` on Windows and `libc::pthread_t` on most other platforms,
272/// except on musl where it must be hardcoded to `c_ulong` to [preserve
273/// sanity](https://elixir.bootlin.com/musl/v1.2.4/source/include/alltypes.h.in#L53)
274#[cfg(target_env = "musl")]
275#[cfg_attr(docsrs, doc(cfg(all())))]
276pub type hwloc_thread_t = c_ulong;
277
278/// Process identifier (OS-specific)
279///
280/// This is `u32` on Windows and `libc::pid_t` on all other platforms.
281#[cfg(not(target_os = "windows"))]
282#[cfg_attr(docsrs, doc(cfg(all())))]
283pub type hwloc_pid_t = libc::pid_t;
284
285// === Object Sets: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__object__sets.html
286
287/// A non-modifiable [`hwloc_cpuset_t`]
288pub type hwloc_const_cpuset_t = hwloc_const_bitmap_t;
289
290/// A non-modifiable [`hwloc_nodeset_t`]
291pub type hwloc_const_nodeset_t = hwloc_const_bitmap_t;
292
293/// A CPU set is a bitmap whose bits are set according to CPU physical OS indexes
294///
295/// It may be consulted and modified with the bitmap API as any [`hwloc_bitmap_t`].
296pub type hwloc_cpuset_t = hwloc_bitmap_t;
297
298/// A node set is a bitmap whose bits are set according to NUMA memory node
299/// physical OS indexes
300///
301/// It may be consulted and modified with the bitmap API as any
302/// [`hwloc_bitmap_t`].
303///
304/// When binding memory on a system without any NUMA node, the single main
305/// memory bank is considered as NUMA node `#0`.
306///
307/// See also [Converting between CPU sets and node
308/// sets](https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__helper__nodeset__convert.html).
309pub type hwloc_nodeset_t = hwloc_bitmap_t;
310
311// === Object Types: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__object__types.html
312
313/// Value returned by [`hwloc_compare_types()`] when types can not be compared
314pub const HWLOC_TYPE_UNORDERED: c_int = c_int::MAX;
315
316/// Type of one side (upstream or downstream) of an I/O bridge
317///
318/// We can't use Rust enums to model C enums in FFI because that results in
319/// undefined behavior if the C API gets new enum variants and sends them to us.
320#[doc(alias = "hwloc_obj_bridge_type_e")]
321pub type hwloc_obj_bridge_type_t = c_uint;
322
323/// Host-side of a bridge, only possible upstream
324pub const HWLOC_OBJ_BRIDGE_HOST: hwloc_obj_bridge_type_t = 0;
325
326/// PCI-side of a bridge
327pub const HWLOC_OBJ_BRIDGE_PCI: hwloc_obj_bridge_type_t = 1;
328
329/// Cache type
330///
331/// We can't use Rust enums to model C enums in FFI because that results in
332/// undefined behavior if the C API gets new enum variants and sends them to us.
333#[doc(alias = "hwloc_obj_cache_type_e")]
334pub type hwloc_obj_cache_type_t = c_uint;
335
336/// Unified cache
337pub const HWLOC_OBJ_CACHE_UNIFIED: hwloc_obj_cache_type_t = 0;
338
339/// Data cache
340pub const HWLOC_OBJ_CACHE_DATA: hwloc_obj_cache_type_t = 1;
341
342/// Instruction cache (filtered out by default)
343pub const HWLOC_OBJ_CACHE_INSTRUCTION: hwloc_obj_cache_type_t = 2;
344
345/// Type of a OS device
346///
347/// We can't use Rust enums to model C enums in FFI because that results in
348/// undefined behavior if the C API gets new enum variants and sends them to us.
349#[doc(alias = "hwloc_obj_osdev_type_e")]
350pub type hwloc_obj_osdev_type_t = c_uint;
351
352/// Operating system storage device (e.g. block)
353///
354/// For instance "sda" or "dax2.0" on Linux.
355#[doc(alias = "HWLOC_OBJ_OSDEV_BLOCK")]
356pub const HWLOC_OBJ_OSDEV_STORAGE: hwloc_obj_osdev_type_t = 0;
357
358/// Operating system GPU device
359///
360/// For instance ":0.0" for a GL display, "card0" for a Linux DRM device.
361pub const HWLOC_OBJ_OSDEV_GPU: hwloc_obj_osdev_type_t = 1;
362
363/// Operating system network device
364///
365/// For instance the "eth0" interface on Linux.
366pub const HWLOC_OBJ_OSDEV_NETWORK: hwloc_obj_osdev_type_t = 2;
367
368#[allow(clippy::doc_markdown)]
369/// Operating system openfabrics device
370///
371/// For instance the "mlx4_0" InfiniBand HCA, "hfi1_0" Omni-Path interface,
372/// or "bxi0" Atos/Bull BXI HCA on Linux.
373pub const HWLOC_OBJ_OSDEV_OPENFABRICS: hwloc_obj_osdev_type_t = 3;
374
375#[allow(clippy::doc_markdown)]
376/// Operating system dma engine device
377///
378/// For instance the "dma0chan0" DMA channel on Linux.
379pub const HWLOC_OBJ_OSDEV_DMA: hwloc_obj_osdev_type_t = 4;
380
381#[allow(clippy::doc_markdown)]
382/// Operating system co-processor device
383///
384/// For instance "opencl0d0" for a OpenCL device, "cuda0" for a CUDA device.
385pub const HWLOC_OBJ_OSDEV_COPROC: hwloc_obj_osdev_type_t = 5;
386
387#[allow(clippy::doc_markdown)]
388/// Operating system memory device
389///
390/// For instance DAX file for non-volatile or high-bandwidth memory, like
391/// "dax2.0" on Linux.
392#[cfg(feature = "hwloc-3_0_0")]
393pub const HWLOC_OBJ_OSDEV_MEMORY: hwloc_obj_osdev_type_t = 6;
394
395/// Type of topology object
396///
397/// We can't use Rust enums to model C enums in FFI because that results in
398/// undefined behavior if the C API gets new enum variants and sends them to us.
399#[doc(alias = "hwloc_obj_type_e")]
400pub type hwloc_obj_type_t = c_uint;
401
402/// The root object, a set of processors and memory with cache coherency
403///
404/// This type is always used for the root object of a topology, and never
405/// used anywhere else. Hence it never has a parent.
406pub const HWLOC_OBJ_MACHINE: hwloc_obj_type_t = 0;
407
408/// Physical package, what goes into a physical motherboard socket
409///
410/// Usually contains multiple cores, and possibly some dies.
411pub const HWLOC_OBJ_PACKAGE: hwloc_obj_type_t = 1;
412
413/// A computation unit (may be shared by several PUs aka logical processors)
414pub const HWLOC_OBJ_CORE: hwloc_obj_type_t = 2;
415
416/// Processing Unit, or (Logical) Processor
417///
418/// An execution unit (may share a core with some other logical
419/// processors, e.g. in the case of an SMT core).
420///
421/// This is the leaf of the CPU resource hierarchy, it can only have Misc
422/// children.
423///
424/// It is always reported even when other objects are not detected. However,
425/// an incorrect number of PUs may be reported if
426/// [`hwloc_topology_discovery_support::pu`] is not set.
427pub const HWLOC_OBJ_PU: hwloc_obj_type_t = 3;
428
429/// Level 1 Data (or Unified) Cache
430pub const HWLOC_OBJ_L1CACHE: hwloc_obj_type_t = 4;
431
432/// Level 2 Data (or Unified) Cache
433pub const HWLOC_OBJ_L2CACHE: hwloc_obj_type_t = 5;
434
435/// Level 3 Data (or Unified) Cache
436pub const HWLOC_OBJ_L3CACHE: hwloc_obj_type_t = 6;
437
438/// Level 4 Data (or Unified) Cache
439pub const HWLOC_OBJ_L4CACHE: hwloc_obj_type_t = 7;
440
441/// Level 5 Data (or Unified) Cache
442// NOTE: If hwloc adds more cache levels, update the hwlocality::cache module accordingly
443pub const HWLOC_OBJ_L5CACHE: hwloc_obj_type_t = 8;
444
445/// Level 1 Instruction cache (filtered out by default)
446pub const HWLOC_OBJ_L1ICACHE: hwloc_obj_type_t = 9;
447
448/// Level 2 Instruction cache (filtered out by default)
449pub const HWLOC_OBJ_L2ICACHE: hwloc_obj_type_t = 10;
450
451/// Level 3 Instruction cache (filtered out by default)
452pub const HWLOC_OBJ_L3ICACHE: hwloc_obj_type_t = 11;
453
454/// Group object
455///
456/// Objects which do not fit in the above but are detected by hwloc and
457/// are useful to take into account for affinity. For instance, some
458/// operating systems expose their arbitrary processors aggregation this
459/// way. And hwloc may insert such objects to group NUMA nodes according
460/// to their distances. See also [What are these Group objects in my
461/// topology?](https://hwloc.readthedocs.io/en/v2.9/faq.html#faq_groups).
462///
463/// These objects are ignored when they do not bring any structure (see
464/// [`HWLOC_TYPE_FILTER_KEEP_STRUCTURE`])
465pub const HWLOC_OBJ_GROUP: hwloc_obj_type_t = 12;
466
467/// NUMA node
468///
469/// An object that contains memory that is directly and byte-accessible to
470/// the host processors. It is usually close to some cores
471/// (the corresponding objects are descendants of the NUMA node object in
472/// the hwloc tree).
473///
474/// This is the smallest object representing Memory resources, it cannot
475/// have any child except Misc objects. However it may have Memory-side
476/// cache parents.
477///
478/// There is always at least one such object in the topology even if the machine
479/// is not NUMA. However, an incorrect number of NUMA nodes may be reported if
480/// [`hwloc_topology_discovery_support::numa`] is not set.
481///
482/// Memory objects are not listed in the main children list, but rather in the
483/// dedicated Memory children list. They also have a special depth
484/// [`HWLOC_TYPE_DEPTH_NUMANODE`] instead of a normal depth just like other
485/// objects in the main tree.
486pub const HWLOC_OBJ_NUMANODE: hwloc_obj_type_t = 13;
487
488/// Bridge (filtered out by default)
489///
490/// Any bridge that connects the host or an I/O bus, to another I/O bus.
491///
492/// Bridges are not added to the topology unless their filtering is changed
493/// (see [`hwloc_topology_set_type_filter()`] and
494/// [`hwloc_topology_set_io_types_filter()`]).
495///
496/// I/O objects are not listed in the main children list, but rather in the
497/// dedicated Memory children list. They have NULL CPU and node sets. They
498/// also have a special depth [`HWLOC_TYPE_DEPTH_BRIDGE`] instead of a normal
499/// depth just like other objects in the main tree.
500pub const HWLOC_OBJ_BRIDGE: hwloc_obj_type_t = 14;
501
502/// PCI device (filtered out by default)
503///
504/// PCI devices are not added to the topology unless their filtering is
505/// changed (see [`hwloc_topology_set_type_filter()`] and
506/// [`hwloc_topology_set_io_types_filter()`]).
507///
508/// I/O objects are not listed in the main children list, but rather in the
509/// dedicated I/O children list. They have NULL CPU and node sets. They also
510/// have a special depth [`HWLOC_TYPE_DEPTH_PCI_DEVICE`] instead of a normal
511/// depth just like other objects in the main tree.
512pub const HWLOC_OBJ_PCI_DEVICE: hwloc_obj_type_t = 15;
513
514/// Operating system device (filtered out by default)
515///
516/// OS devices are not added to the topology unless their filtering is
517/// changed (see [`hwloc_topology_set_type_filter()`] and
518/// [`hwloc_topology_set_io_types_filter()`]).
519///
520/// I/O objects are not listed in the main children list, but rather in the
521/// dedicated I/O children list. They have NULL CPU and node sets. They also
522/// have a special depth [`HWLOC_TYPE_DEPTH_OS_DEVICE`] instead of a normal
523/// depth just like other objects in the main tree.
524pub const HWLOC_OBJ_OS_DEVICE: hwloc_obj_type_t = 16;
525
526/// Miscellaneous object (filtered out by default)
527///
528/// Objects without particular meaning, that can e.g. be added by the
529/// application for its own use, or by hwloc for miscellaneous objects such
530/// as memory modules (DIMMs).
531///
532/// They are not added to the topology unless their filtering is
533/// changed (see [`hwloc_topology_set_type_filter()`]).
534///
535/// Misc objects have no CPU and node sets, and may only have other Misc objects
536/// as children. They are not part of the main children list, but rather reside
537/// in the dedicated Misc children list. They have NULL CPU and node sets.
538/// They also have a special depth [`HWLOC_TYPE_DEPTH_MISC`] instead of a normal
539/// depth just like other objects in the main tree.
540pub const HWLOC_OBJ_MISC: hwloc_obj_type_t = 17;
541
542/// Memory-side cache (filtered out by default)
543///
544/// A cache in front of a specific NUMA node. This object always has at
545/// least one NUMA node as a memory child.
546///
547/// Memory objects are not listed in the main children list, but rather in
548/// the dedicated Memory children list. They also have a special depth
549/// [`HWLOC_TYPE_DEPTH_MEMCACHE`] instead of a normal depth just like other
550/// objects in the main tree.
551#[cfg(feature = "hwloc-2_1_0")]
552pub const HWLOC_OBJ_MEMCACHE: hwloc_obj_type_t = 18;
553
554/// Die within a physical package
555///
556/// A subpart of the physical package, that contains multiple cores.
557#[cfg(feature = "hwloc-2_1_0")]
558pub const HWLOC_OBJ_DIE: hwloc_obj_type_t = 19;
559
560// === Object Structure and Attributes: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__objects.html
561
562/// Hardware topology object
563///
564/// This type does not implement [`Default`] because hwloc all but guarantees
565/// that some inner pointers of this struct will not be null.
566#[derive(Copy, Clone, Debug)]
567#[repr(C)]
568pub struct hwloc_obj {
569    /// Type of object
570    #[doc(alias = "hwloc_obj::type")]
571    pub ty: hwloc_obj_type_t,
572
573    /// Subtype string to better describe the type field
574    ///
575    /// See <https://hwloc.readthedocs.io/en/v2.9/attributes.html#attributes_normal>
576    /// for a list of subtype strings that hwloc can emit.
577    pub subtype: *mut c_char,
578
579    /// The OS-provided physical index number
580    ///
581    /// It is not guaranteed unique across the entire machine,
582    /// except for PUs and NUMA nodes.
583    ///
584    /// Set to [`HWLOC_UNKNOWN_INDEX`] if unknown or irrelevant for this object.
585    pub os_index: c_uint,
586
587    /// Object-specific name, if any
588    ///
589    /// Mostly used for identifying OS devices and Misc objects where a name
590    /// string is more useful than numerical indices.
591    pub name: *mut c_char,
592
593    /// Total memory (in bytes) in NUMA nodes below this object
594    ///
595    /// May not be accurate if
596    /// [`hwloc_topology_discovery_support::numa_memory`] is not set.
597    pub total_memory: u64,
598
599    /// Object type-specific attributes, if any
600    pub attr: *mut hwloc_obj_attr_u,
601
602    /// Vertical index in the hierarchy
603    ///
604    /// For normal objects, this is the depth of the horizontal level that
605    /// contains this object and its cousins of the same type. If the topology
606    /// is symmetric, this is equal to the parent depth plus one, and also equal
607    /// to the number of parent/child links from the root object to here.
608    ///
609    /// For special objects (NUMA nodes, I/O and Misc) that are not in the main
610    /// tree, this is a special value that is unique to their type.
611    pub depth: hwloc_get_type_depth_e,
612
613    /// Horizontal index in the whole list of similar objects, hence guaranteed
614    /// unique across the entire machine
615    ///
616    /// Could be a `cousin_rank` since it's the rank within the "cousin" list.
617    ///
618    /// Note that this index may change when restricting the topology
619    /// or when inserting a group.
620    pub logical_index: c_uint,
621
622    /// Next object of same type and depth
623    pub next_cousin: hwloc_obj_t,
624
625    /// Previous object of same type and depth
626    pub prev_cousin: hwloc_obj_t,
627
628    /// Parent object
629    ///
630    /// Only NULL for the root [`HWLOC_OBJ_MACHINE`] object.
631    pub parent: hwloc_obj_t,
632
633    /// Index in the parent's relevant child list for this object type
634    pub sibling_rank: c_uint,
635
636    /// Next object below the same parent, in the same child list
637    pub next_sibling: hwloc_obj_t,
638
639    /// Previous object below the same parent, in the same child list
640    pub prev_sibling: hwloc_obj_t,
641
642    /// Number of normal children (excluding Memory, Misc and I/O)
643    pub arity: c_uint,
644
645    /// Normal children of this object
646    pub children: *mut hwloc_obj_t,
647
648    /// First normal child of this object
649    pub first_child: hwloc_obj_t,
650
651    /// Last normal child of this object
652    pub last_child: hwloc_obj_t,
653
654    /// Truth that this object is symmetric, which means all normal children and
655    /// their children have identical subtrees
656    ///
657    /// Memory, I/O and Misc children are ignored.
658    ///
659    /// If this is true of the root object, then the topology may be exported
660    /// as a synthetic string.
661    pub symmetric_subtree: c_int,
662
663    /// Number of memory children
664    pub memory_arity: c_uint,
665
666    /// First memory child of this object
667    ///
668    /// NUMA nodes and Memory-side caches are listed here instead of in the
669    /// normal [`children`] list. See also [`hwloc_obj_type_is_memory()`].
670    ///
671    /// A memory hierarchy starts from a normal CPU-side object (e.g.
672    /// [`HWLOC_OBJ_PACKAGE`]) and ends with NUMA nodes as leaves. There might
673    /// exist some memory-side caches between them in the middle of the memory
674    /// subtree.
675    ///
676    /// [`children`]: Self::children
677    pub memory_first_child: hwloc_obj_t,
678
679    /// Number of I/O children
680    pub io_arity: c_uint,
681
682    /// First I/O child of this object
683    ///
684    /// Bridges, PCI and OS devices are listed here instead of in the normal
685    /// [`children`] list. See also [`hwloc_obj_type_is_io()`].
686    ///
687    /// [`children`]: Self::children
688    pub io_first_child: hwloc_obj_t,
689
690    /// Number of Misc children
691    pub misc_arity: c_uint,
692
693    /// First Misc child of this object
694    ///
695    /// Misc objects are listed here instead of in the normal [`children`] list.
696    ///
697    /// [`children`]: Self::children
698    pub misc_first_child: hwloc_obj_t,
699
700    /// CPUs covered by this object
701    ///
702    /// This is the set of CPUs for which there are PU objects in the
703    /// topology under this object, i.e. which are known to be physically
704    /// contained in this object and known how (the children path between this
705    /// object and the PU objects).
706    ///
707    /// If the [`HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED`] topology building
708    /// configuration flag is set, some of these CPUs may be online but not
709    /// allowed for binding, see [`hwloc_topology_get_allowed_cpuset()`].
710    ///
711    /// All objects have CPU and node sets except Misc and I/O objects, so if
712    /// you know this object to be a normal or Memory object, you can safely
713    /// assume this pointer to be non-NULL.
714    pub cpuset: hwloc_cpuset_t,
715
716    /// The complete CPU set of this object
717    ///
718    /// To the CPUs listed by [`cpuset`], this adds CPUs for which topology
719    /// information is unknown or incomplete, some offline CPUs, and CPUs that
720    /// are ignored when the [`HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED`] topology
721    /// building configuration flag is not set.
722    ///
723    /// Thus no corresponding PU object may be found in the topology, because
724    /// the precise position is undefined. It is however known that it would be
725    /// somewhere under this object.
726    ///
727    /// [`cpuset`]: Self::cpuset
728    pub complete_cpuset: hwloc_cpuset_t,
729
730    /// NUMA nodes covered by this object or containing this object.
731    ///
732    /// This is the set of NUMA nodes for which there are NUMA node objects in
733    /// the topology under or above this object, i.e. which are known to be
734    /// physically contained in this object or containing it and known how
735    /// (the children path between this object and the NUMA node objects). In
736    /// the end, these nodes are those that are close to the current object.
737    ///
738    #[cfg_attr(
739        feature = "hwloc-2_3_0",
740        doc = "With hwloc 2.3+, [`hwloc_get_local_numanode_objs()`] may be used to"
741    )]
742    #[cfg_attr(feature = "hwloc-2_3_0", doc = "list those NUMA nodes more precisely.")]
743    ///
744    /// If the [`HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED`] topology building
745    /// configuration flag is set, some of these nodes may not be allowed for
746    /// allocation, see [`hwloc_topology_get_allowed_nodeset()`].
747    ///
748    /// If there are no NUMA nodes in the machine, all the memory is close to
749    /// this object, so the nodeset is full.
750    ///
751    /// All objects have CPU and node sets except Misc and I/O objects, so if
752    /// you know this object to be a normal or Memory object, you can safely
753    /// assume this pointer to be non-NULL.
754    pub nodeset: hwloc_nodeset_t,
755
756    /// The complete NUMA node set of this object
757    ///
758    /// To the nodes listed by [`nodeset`], this adds nodes for which topology
759    /// information is unknown or incomplete, some offline nodes, and nodes
760    /// that are ignored when the
761    /// [`HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED`] topology building
762    /// configuration flag is not set.
763    ///
764    /// Thus no corresponding `NUMANode` object may be found in the topology,
765    /// because the precise position is undefined. It is however known that it
766    /// would be somewhere under this object.
767    ///
768    /// If there are no NUMA nodes in the machine, all the memory is close to
769    /// this object, so `complete_nodeset` is full.
770    ///
771    /// [`nodeset`]: Self::nodeset
772    pub complete_nodeset: hwloc_nodeset_t,
773
774    /// Complete list of (key, value) textual info pairs
775    ///
776    /// hwloc defines [a number of standard object info attribute names with
777    /// associated semantics](https://hwloc.readthedocs.io/en/v2.9/attributes.html#attributes_info).
778    ///
779    /// Beware that hwloc allows multiple informations with the same key to
780    /// exist, although no sane programs should leverage this possibility.
781    pub infos: *mut hwloc_info_s,
782
783    /// Number of (key, value) pairs in [`infos`]
784    ///
785    /// [`infos`]: Self::infos
786    pub infos_count: c_uint,
787
788    /// Application-given private data pointer, initialized to NULL, use it as
789    /// you wish
790    //
791    // --- Implementation details ---
792    //
793    // TODO: Add once support is ready: "See
794    // [`hwloc_topology_set_userdata_export_callback()`] if you wish to export
795    // this field to XML."
796    pub userdata: *mut c_void,
797
798    /// Global persistent index
799    ///
800    /// Generated by hwloc, unique across the topology (contrary to
801    /// [`os_index`]) and persistent across topology changes (contrary to
802    /// [`logical_index`]).
803    ///
804    /// All this means you can safely use this index as a cheap key representing
805    /// the object in a Set or a Map, as long as that Set or Map only refers to
806    /// [`hwloc_obj`]s originating from a single [`hwloc_topology`].
807    ///
808    /// [`logical_index`]: Self::logical_index
809    /// [`os_index`]: Self::os_index
810    pub gp_index: u64,
811}
812
813/// Value of [`hwloc_obj::os_index`] when unknown or irrelevant for this object
814pub const HWLOC_UNKNOWN_INDEX: c_uint = c_uint::MAX;
815
816/// Convenience typedef, a pointer to a struct [`hwloc_obj`]
817pub type hwloc_obj_t = *mut hwloc_obj;
818
819/// [`hwloc_obj_type_t`]-specific attributes
820#[derive(Copy, Clone)]
821#[repr(C)]
822pub union hwloc_obj_attr_u {
823    /// [`HWLOC_OBJ_NUMANODE`]-specific attributes
824    pub numa: hwloc_numanode_attr_s,
825
826    /// Cache-specific attributes
827    pub cache: hwloc_cache_attr_s,
828
829    /// [`HWLOC_OBJ_GROUP`]-specific attributes
830    pub group: hwloc_group_attr_s,
831
832    /// [`HWLOC_OBJ_PCI_DEVICE`]-specific attributes
833    pub pcidev: hwloc_pcidev_attr_s,
834
835    /// [`HWLOC_OBJ_BRIDGE`]-specific attributes
836    pub bridge: hwloc_bridge_attr_s,
837
838    /// [`HWLOC_OBJ_OS_DEVICE`]-specific attributes
839    pub osdev: hwloc_osdev_attr_s,
840}
841//
842impl Debug for hwloc_obj_attr_u {
843    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
844        f.debug_struct("hwloc_obj_attr_u").finish_non_exhaustive()
845    }
846}
847
848/// [`HWLOC_OBJ_NUMANODE`]-specific attributes
849#[derive(Copy, Clone, Debug)]
850#[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s")]
851#[repr(C)]
852pub struct hwloc_numanode_attr_s {
853    /// Local memory in bytes
854    ///
855    /// May not be accurate if
856    /// [`hwloc_topology_discovery_support::numa_memory`] is not set.
857    #[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s::local_memory")]
858    pub local_memory: u64,
859
860    /// Number of memory page types
861    #[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s::page_types_len")]
862    pub page_types_len: c_uint,
863
864    /// Memory page types, sorted by increasing page size
865    #[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s::page_types")]
866    pub page_types: *mut hwloc_memory_page_type_s,
867}
868//
869impl Default for hwloc_numanode_attr_s {
870    fn default() -> Self {
871        Self {
872            local_memory: 0,
873            page_types_len: 0,
874            page_types: std::ptr::null_mut(),
875        }
876    }
877}
878
879/// Local memory page type
880#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
881#[doc(alias = "hwloc_numanode_attr_s::hwloc_memory_page_type_s")]
882#[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s::hwloc_memory_page_type_s")]
883#[repr(C)]
884pub struct hwloc_memory_page_type_s {
885    /// Size of pages
886    #[doc(alias = "hwloc_numanode_attr_s::hwloc_memory_page_type_s::size")]
887    #[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s::hwloc_memory_page_type_s::size")]
888    pub size: u64,
889
890    /// Number of pages of this size
891    #[doc(alias = "hwloc_numanode_attr_s::hwloc_memory_page_type_s::count")]
892    #[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s::hwloc_memory_page_type_s::count")]
893    pub count: u64,
894}
895
896/// Cache-specific attributes
897#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
898#[doc(alias = "hwloc_obj_attr_u::hwloc_cache_attr_s")]
899#[repr(C)]
900pub struct hwloc_cache_attr_s {
901    /// Size of the cache in bytes
902    #[doc(alias = "hwloc_obj_attr_u::hwloc_cache_attr_s::size")]
903    pub size: u64,
904
905    /// Depth of the cache (e.g. L1, L2, ...)
906    #[doc(alias = "hwloc_obj_attr_u::hwloc_cache_attr_s::depth")]
907    pub depth: c_uint,
908
909    /// Cache line size in bytes
910    #[doc(alias = "hwloc_obj_attr_u::hwloc_cache_attr_s::linesize")]
911    pub linesize: c_uint,
912
913    /// Ways of associativity, -1 if fully associative, 0 if unknown
914    #[doc(alias = "hwloc_obj_attr_u::hwloc_cache_attr_s::associativity")]
915    pub associativity: c_int,
916
917    /// Cache type
918    #[doc(alias = "hwloc_cache_attr_s::type")]
919    #[doc(alias = "hwloc_obj_attr_u::hwloc_cache_attr_s::type")]
920    pub ty: hwloc_obj_cache_type_t,
921}
922
923/// [`HWLOC_OBJ_GROUP`]-specific attributes
924#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
925#[doc(alias = "hwloc_obj_attr_u::hwloc_group_attr_s")]
926#[repr(C)]
927pub struct hwloc_group_attr_s {
928    /// Depth of group object
929    ///
930    /// It may change if intermediate Group objects are added.
931    #[doc(alias = "hwloc_obj_attr_u::hwloc_group_attr_s::depth")]
932    pub depth: c_uint,
933
934    /// Internally-used kind of group
935    #[doc(alias = "hwloc_obj_attr_u::hwloc_group_attr_s::kind")]
936    pub kind: c_uint,
937
938    /// Internally-used subkind to distinguish different levels of groups with
939    /// the same kind
940    #[doc(alias = "hwloc_obj_attr_u::hwloc_group_attr_s::subkind")]
941    pub subkind: c_uint,
942
943    /// Flag preventing groups from being automatically merged with identical
944    /// parent or children
945    #[cfg(feature = "hwloc-2_0_4")]
946    #[doc(alias = "hwloc_obj_attr_u::hwloc_group_attr_s::dont_merge")]
947    pub dont_merge: c_uchar,
948}
949
950/// PCI domain width (depends on hwloc version)
951#[cfg(feature = "hwloc-3_0_0")]
952#[cfg_attr(docsrs, doc(cfg(all())))]
953pub type PCIDomain = u32;
954
955/// PCI domain width (depends on hwloc version)
956#[cfg(not(feature = "hwloc-3_0_0"))]
957#[cfg_attr(docsrs, doc(cfg(all())))]
958pub type PCIDomain = u16;
959
960/// [`HWLOC_OBJ_PCI_DEVICE`]-specific attributes
961#[derive(Copy, Clone, Debug, Default, PartialEq)]
962#[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s")]
963#[repr(C)]
964pub struct hwloc_pcidev_attr_s {
965    /// PCI domain
966    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::domain")]
967    pub domain: PCIDomain,
968
969    /// PCI bus id
970    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::bus")]
971    pub bus: c_uchar,
972
973    /// PCI bus device
974    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::dev")]
975    pub dev: c_uchar,
976
977    /// PCI function
978    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::func")]
979    pub func: c_uchar,
980
981    /// PCI class ID
982    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::class_id")]
983    pub class_id: c_ushort,
984
985    /// PCI vendor ID
986    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::vendor_id")]
987    pub vendor_id: c_ushort,
988
989    /// PCI device ID
990    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::device_id")]
991    pub device_id: c_ushort,
992
993    /// PCI sub-vendor ID
994    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::subvendor_id")]
995    pub subvendor_id: c_ushort,
996
997    /// PCI sub-device ID
998    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::subdevice_id")]
999    pub subdevice_id: c_ushort,
1000
1001    /// PCI revision
1002    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::revision")]
1003    pub revision: c_uchar,
1004
1005    /// Link speed in GB/s
1006    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::linkspeed")]
1007    pub linkspeed: c_float,
1008}
1009
1010/// [`HWLOC_OBJ_BRIDGE`]-specific attributes
1011#[derive(Copy, Clone, Debug)]
1012#[doc(alias = "hwloc_obj_attr_u::hwloc_bridge_attr_s")]
1013#[repr(C)]
1014pub struct hwloc_bridge_attr_s {
1015    /// Upstream attributes
1016    #[doc(alias = "hwloc_bridge_attr_s::upstream")]
1017    pub upstream: RawUpstreamAttributes,
1018
1019    /// Upstream type
1020    #[doc(alias = "hwloc_obj_attr_u::hwloc_bridge_attr_s::upstream_type")]
1021    pub upstream_type: hwloc_obj_bridge_type_t,
1022
1023    /// Downstream attributes
1024    #[doc(alias = "hwloc_obj_attr_u::hwloc_bridge_attr_s::downstream")]
1025    pub downstream: RawDownstreamAttributes,
1026
1027    /// Downstream type
1028    #[doc(alias = "hwloc_obj_attr_u::hwloc_bridge_attr_s::downstream_type")]
1029    pub downstream_type: hwloc_obj_bridge_type_t,
1030
1031    /// Bridge depth
1032    #[doc(alias = "hwloc_obj_attr_u::hwloc_bridge_attr_s::depth")]
1033    pub depth: c_uint,
1034}
1035
1036/// Upstream device attributes
1037#[derive(Copy, Clone)]
1038#[repr(C)]
1039pub union RawUpstreamAttributes {
1040    /// PCI-specific attributes
1041    pub pci: hwloc_pcidev_attr_s,
1042}
1043//
1044impl Debug for RawUpstreamAttributes {
1045    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1046        f.debug_struct("RawUpstreamAttributes")
1047            .finish_non_exhaustive()
1048    }
1049}
1050
1051/// Downstream PCI device attributes
1052#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
1053#[repr(C)]
1054pub struct RawDownstreamPCIAttributes {
1055    /// Downstram domain
1056    pub domain: PCIDomain,
1057
1058    /// Downstream secondary bus
1059    pub secondary_bus: c_uchar,
1060
1061    /// Downstream subordinate bus
1062    pub subordinate_bus: c_uchar,
1063}
1064
1065/// Downstream device attributes
1066#[derive(Copy, Clone)]
1067#[repr(C)]
1068pub union RawDownstreamAttributes {
1069    /// PCI-specific attributes
1070    pub pci: RawDownstreamPCIAttributes,
1071}
1072//
1073impl Debug for RawDownstreamAttributes {
1074    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1075        f.debug_struct("RawDownstreamAttributes")
1076            .finish_non_exhaustive()
1077    }
1078}
1079
1080/// [`HWLOC_OBJ_OS_DEVICE`]-specific attributes
1081#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
1082#[doc(alias = "hwloc_obj_attr_u::hwloc_osdev_attr_s")]
1083#[repr(C)]
1084pub struct hwloc_osdev_attr_s {
1085    /// OS device type
1086    #[doc(alias = "hwloc_osdev_attr_s::type")]
1087    #[doc(alias = "hwloc_obj_attr_u::hwloc_osdev_attr_s::type")]
1088    pub ty: hwloc_obj_osdev_type_t,
1089}
1090
1091/// Key-value string attributes
1092///
1093/// Used in multiple places of the hwloc API for extensible metadata.
1094///
1095/// See also [Consulting and Adding Info
1096/// Attributes](https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__info__attr.html).
1097///
1098/// This type does not implement [`Default`] because hwloc all but guarantees
1099/// that the inner pointers of this struct will not be null.
1100#[derive(Copy, Clone, Debug)]
1101#[repr(C)]
1102pub struct hwloc_info_s {
1103    /// Info name
1104    pub name: *mut c_char,
1105
1106    /// Info value
1107    pub value: *mut c_char,
1108}
1109
1110// === Topology Creation and Destruction: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__creation.html
1111
1112/// Opaque topology struct
1113///
1114/// Models the incomplete type that [`hwloc_topology_t`] API pointers map to.
1115///
1116/// This type purposely implements almost no traits, not even Debug, because you
1117/// should never, ever deal with it directly, only with raw pointers to it that
1118/// you blindly pass to the hwloc API.
1119///
1120/// The only exception to this rule is [`RefUnwindSafe`], which is special
1121/// because...
1122///
1123/// - You cannot implement [`UnwindSafe`] yourself for standard pointer types
1124///   due to orphan rules
1125/// - Rust implements it for pointers to [`RefUnwindSafe`], i.e. it assumes you
1126///   use pointers to such data responsibly.
1127/// - The ergonomic impact of everyday types not being [`UnwindSafe`] is
1128///   annoying (need [`AssertUnwindSafe`] in every [`catch_unwind()`]).
1129///
1130/// [`AssertUnwindSafe`]: std::panic::AssertUnwindSafe
1131/// [`catch_unwind()`]: std::panic::catch_unwind()
1132#[allow(missing_debug_implementations)]
1133#[repr(C)]
1134pub struct hwloc_topology(IncompleteType);
1135//
1136impl RefUnwindSafe for hwloc_topology {}
1137
1138/// Topology context
1139///
1140/// To be initialized with [`hwloc_topology_init()`] and built with [`hwloc_topology_load()`].
1141pub type hwloc_topology_t = *mut hwloc_topology;
1142
1143/// A non-modifiable [`hwloc_topology_t`]
1144pub type hwloc_const_topology_t = *const hwloc_topology;
1145
1146// === Object levels, depths and types: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__levels.html
1147
1148/// Depth of an object (or object type) in the topology
1149///
1150/// We can't use Rust enums to model C enums in FFI because that results in
1151/// undefined behavior if the C API gets new enum variants and sends them to us.
1152pub type hwloc_get_type_depth_e = c_int;
1153
1154/// No object of given type exists in the topology
1155pub const HWLOC_TYPE_DEPTH_UNKNOWN: hwloc_get_type_depth_e = -1;
1156
1157/// Objects of given type exist at different depth in the topology (only for Groups)
1158pub const HWLOC_TYPE_DEPTH_MULTIPLE: hwloc_get_type_depth_e = -2;
1159
1160/// Virtual depth for [`HWLOC_OBJ_NUMANODE`]
1161pub const HWLOC_TYPE_DEPTH_NUMANODE: hwloc_get_type_depth_e = -3;
1162
1163/// Virtual depth for [`HWLOC_OBJ_BRIDGE`]
1164pub const HWLOC_TYPE_DEPTH_BRIDGE: hwloc_get_type_depth_e = -4;
1165
1166/// Virtual depth for [`HWLOC_OBJ_PCI_DEVICE`]
1167pub const HWLOC_TYPE_DEPTH_PCI_DEVICE: hwloc_get_type_depth_e = -5;
1168
1169/// Virtual depth for [`HWLOC_OBJ_OS_DEVICE`]
1170pub const HWLOC_TYPE_DEPTH_OS_DEVICE: hwloc_get_type_depth_e = -6;
1171
1172/// Virtual depth for [`HWLOC_OBJ_MISC`]
1173pub const HWLOC_TYPE_DEPTH_MISC: hwloc_get_type_depth_e = -7;
1174
1175/// Virtual depth for [`HWLOC_OBJ_MEMCACHE`]
1176#[cfg(feature = "hwloc-2_1_0")]
1177pub const HWLOC_TYPE_DEPTH_MEMCACHE: hwloc_get_type_depth_e = -8;
1178
1179// === CPU binding: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__cpubinding.html
1180
1181/// Process/Thread binding flags
1182///
1183/// These bit flags can be used to refine the binding policy. All flags can be
1184/// OR'ed together with the exception of the binding targets flags
1185/// [`HWLOC_CPUBIND_THREAD`] and [`HWLOC_CPUBIND_PROCESS`], which are mutually
1186/// exclusive.
1187///
1188/// When using one of the functions that target the active process, you must use
1189/// at most one of these flags. The most portable binding targets are no flags,
1190/// which is interpreted as "assume a single-threaded process", followed by
1191/// [`HWLOC_CPUBIND_THREAD`] and [`HWLOC_CPUBIND_PROCESS`] in this order. These
1192/// flags must generally not be used with any other function, except on Linux
1193/// where flag [`HWLOC_CPUBIND_THREAD`] can also be used to turn
1194/// process-binding functions into thread-binding functions.
1195///
1196/// Individual CPU binding functions may not support all of these flags.
1197/// Please check the documentation of the function that you are
1198/// trying to call for more information.
1199pub type hwloc_cpubind_flags_t = c_int;
1200
1201/// Bind the current thread of the current process
1202///
1203/// This is the second most portable option when the process is multi-threaded,
1204/// and specifying no flags would thus be incorrect.
1205///
1206/// On Linux, this flag can also be used to turn process-binding
1207/// functions into thread-binding functions.
1208///
1209/// This is mutually exclusive with [`HWLOC_CPUBIND_PROCESS`].
1210pub const HWLOC_CPUBIND_THREAD: hwloc_cpubind_flags_t = 1 << 1;
1211
1212/// Bind all threads of the current process
1213///
1214/// This is mutually exclusive with [`HWLOC_CPUBIND_THREAD`].
1215pub const HWLOC_CPUBIND_PROCESS: hwloc_cpubind_flags_t = 1 << 0;
1216
1217/// Request for strict binding from the OS
1218///
1219/// By default, when the designated CPUs are all busy while other CPUs
1220/// are idle, operating systems may execute the thread/process on those
1221/// other CPUs instead of the designated CPUs, to let them progress
1222/// anyway. Strict binding means that the thread/process will _never_
1223/// execute on other CPUs than the designated CPUs, even when those are
1224/// busy with other tasks and other CPUs are idle.
1225///
1226/// Depending on the operating system, strict binding may not be
1227/// possible (e.g. the OS does not implement it) or not allowed (e.g.
1228/// for an administrative reasons), and the binding function will fail
1229/// in that case.
1230///
1231/// When retrieving the binding of a process, this flag checks whether
1232/// all its threads actually have the same binding. If the flag is not
1233/// given, the binding of each thread will be accumulated.
1234///
1235/// This flag should not be used when retrieving the binding of a
1236/// thread or the CPU location of a process.
1237pub const HWLOC_CPUBIND_STRICT: hwloc_cpubind_flags_t = 1 << 2;
1238
1239/// Avoid any effect on memory binding
1240///
1241/// On some operating systems, some CPU binding function would also bind
1242/// the memory on the corresponding NUMA node. It is often not a
1243/// problem for the application, but if it is, setting this flag will
1244/// make hwloc avoid using OS functions that would also bind memory.
1245/// This will however reduce the support of CPU bindings, i.e.
1246/// potentially result in the binding function erroring out.
1247///
1248/// This flag should only be used with functions that set the CPU
1249/// binding.
1250pub const HWLOC_CPUBIND_NOMEMBIND: hwloc_cpubind_flags_t = 1 << 3;
1251
1252// === Memory binding: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__membinding.html
1253
1254/// Memory binding flags.
1255///
1256/// These bit flags can be used to refine the binding policy. All flags can
1257/// be OR'ed together with the exception of the binding target flags
1258/// [`HWLOC_MEMBIND_THREAD`] and [`HWLOC_MEMBIND_PROCESS`], which are mutually
1259/// exclusive.
1260///
1261/// When using one of the methods that target a process, you must use
1262/// at most one of these flags. The most portable option is to specify no flags,
1263/// which means "assume the target process is single-threaded". These
1264/// flags must not be used with any other method.
1265///
1266/// Individual memory binding methods may not support all of these flags. Please
1267/// check the documentation of the function that you are trying to call for
1268/// more information.
1269pub type hwloc_membind_flags_t = c_int;
1270
1271/// Apply command to all threads of the specified process
1272///
1273/// This is mutually exclusive with [`HWLOC_MEMBIND_THREAD`]
1274pub const HWLOC_MEMBIND_PROCESS: hwloc_membind_flags_t = 1 << 0;
1275
1276/// Apply command to the current thread of the current process
1277///
1278/// This is mutually exclusive with [`HWLOC_MEMBIND_PROCESS`]
1279pub const HWLOC_MEMBIND_THREAD: hwloc_membind_flags_t = 1 << 1;
1280
1281/// Request strict binding from the OS
1282///
1283/// If this flag is set, a binding method will fail if the binding can
1284/// not be guaranteed or completely enforced. Otherwise, hwloc will
1285/// attempt to achieve an approximation of the requested binding (e.g.
1286/// targeting more or less threads and NUMA nodes).
1287///
1288/// This flag has slightly different meanings depending on which
1289/// method it is used with.
1290pub const HWLOC_MEMBIND_STRICT: hwloc_membind_flags_t = 1 << 2;
1291
1292/// Migrate existing allocated memory
1293///
1294/// If the memory cannot be migrated and the [`HWLOC_MEMBIND_STRICT`] flag is
1295/// set, an error will be returned.
1296///
1297/// This flag is only meaningful on operations that bind memory.
1298///
1299/// Only available if [`hwloc_topology_membind_support::migrate_membind`] is set.
1300pub const HWLOC_MEMBIND_MIGRATE: hwloc_membind_flags_t = 1 << 3;
1301
1302/// Avoid any effect on CPU binding
1303///
1304/// On some operating systems, some underlying memory binding
1305/// methods also bind the application to the corresponding CPU(s).
1306/// Using this flag will cause hwloc to avoid using OS functions that
1307/// could potentially affect CPU bindings.
1308///
1309/// Note, however, that using this flag may reduce hwloc's overall
1310/// memory binding support.
1311pub const HWLOC_MEMBIND_NOCPUBIND: hwloc_membind_flags_t = 1 << 4;
1312
1313/// Consider the bitmap argument as a nodeset.
1314///
1315/// The bitmap argument is considered a nodeset if this flag is given,
1316/// or a cpuset otherwise by default.
1317///
1318/// Memory binding by CPU set cannot work for CPU-less NUMA memory nodes.
1319/// Binding by nodeset should therefore be preferred whenever possible.
1320pub const HWLOC_MEMBIND_BYNODESET: hwloc_membind_flags_t = 1 << 5;
1321
1322/// Memory binding policy.
1323///
1324/// Not all systems support all kinds of binding.
1325/// [`hwloc_topology_get_support()`] may be used to query the
1326/// actual memory binding support in the currently used operating system.
1327pub type hwloc_membind_policy_t = c_int;
1328
1329/// Reset the memory allocation policy of the current process or thread to
1330/// the system default
1331///
1332/// Depending on the operating system, this may correspond to
1333/// [`HWLOC_MEMBIND_FIRSTTOUCH`] (Linux, FreeBSD) or [`HWLOC_MEMBIND_BIND`]
1334/// (AIX, HP-UX, Solaris, Windows).
1335///
1336/// This policy is never returned by get membind functions. The `nodeset`
1337/// argument is ignored.
1338pub const HWLOC_MEMBIND_DEFAULT: hwloc_membind_policy_t = 0;
1339
1340/// Allocate each memory page individually on the local NUMA
1341/// node of the thread that touches it
1342///
1343/// The given nodeset should usually be
1344/// [`hwloc_topology_get_topology_nodeset()`] so that the touching thread may
1345/// run and allocate on any node in the system.
1346///
1347/// On AIX, if the nodeset is smaller, pages are allocated locally (if the
1348/// local node is in the nodeset) or from a random non-local node (otherwise).
1349///
1350/// Only available if [`hwloc_topology_membind_support::firsttouch_membind`] is
1351/// set.
1352pub const HWLOC_MEMBIND_FIRSTTOUCH: hwloc_membind_policy_t = 1;
1353
1354/// Allocate memory on the specified nodes (most portable option)
1355///
1356/// The actual behavior may slightly vary between operating systems, especially
1357/// when (some of) the requested nodes are full. On Linux, by default, the
1358/// `MPOL_PREFERRED_MANY` (or `MPOL_PREFERRED`) policy is used. However, if
1359/// the [`HWLOC_MEMBIND_STRICT`] flag is also given, the Linux `MPOL_BIND`
1360/// policy is rather used.
1361///
1362/// Only available if [`hwloc_topology_membind_support::bind_membind`] is set.
1363pub const HWLOC_MEMBIND_BIND: hwloc_membind_policy_t = 2;
1364
1365/// Allocate memory on the given nodes in an interleaved round-robin manner
1366///
1367/// The precise layout of the memory across multiple NUMA nodes is OS/system
1368/// specific.
1369///
1370/// Interleaving can be useful when threads distributed across the specified
1371/// NUMA nodes will all be accessing the whole memory range concurrently,
1372/// since the interleave will then balance the memory references.
1373///
1374/// Only available if [`hwloc_topology_membind_support::interleave_membind`] is
1375/// set.
1376pub const HWLOC_MEMBIND_INTERLEAVE: hwloc_membind_policy_t = 3;
1377
1378/// Migrate pages on next touch
1379///
1380/// For each page bound with this policy, by next time it is touched (and
1381/// next time only), it is moved from its current location to the local NUMA
1382/// node of the thread where the memory reference occurred (if it needs to
1383/// be moved at all).
1384///
1385/// Only available if [`hwloc_topology_membind_support::nexttouch_membind`] is
1386/// set.
1387pub const HWLOC_MEMBIND_NEXTTOUCH: hwloc_membind_policy_t = 4;
1388
1389/// Mixture of memory binding policies
1390///
1391/// Returned by `get_membind()` functions when multiple threads or parts of a
1392/// memory area have differing memory binding policies. Also returned when
1393/// binding is unknown because binding hooks are empty when the topology is
1394/// loaded from XML without `HWLOC_THISSYSTEM=1`, etc.
1395pub const HWLOC_MEMBIND_MIXED: hwloc_membind_policy_t = -1;
1396
1397// === Changing the source of topology discovery: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__setsource.html
1398
1399/// Flags to be passed to [`hwloc_topology_set_components()`]
1400#[cfg(feature = "hwloc-2_1_0")]
1401pub type hwloc_topology_components_flag_e = c_ulong;
1402
1403/// Blacklist the target component from being used
1404#[cfg(feature = "hwloc-2_1_0")]
1405pub const HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST: hwloc_topology_components_flag_e = 1 << 0;
1406
1407// === Topology detection configuration and query: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__configuration.html
1408
1409/// Topology building configuration flags
1410pub type hwloc_topology_flags_e = c_ulong;
1411
1412/// Detect the whole system, ignore reservations, include disallowed objects
1413///
1414/// Gather all online resources, even if some were disabled by the
1415/// administrator. For instance, ignore Linux Cgroup/Cpusets and gather
1416/// all processors and memory nodes. However offline PUs and NUMA nodes
1417/// are still ignored.
1418///
1419/// When this flag is not set, PUs and NUMA nodes that are disallowed
1420/// are not added to the topology. Parent objects (package, core, cache,
1421/// etc.) are added only if some of their children are allowed. All
1422/// existing PUs and NUMA nodes in the topology are allowed.
1423/// [`hwloc_topology_get_allowed_cpuset()`] and
1424/// [`hwloc_topology_get_allowed_nodeset()`] are equal to the root object cpuset
1425/// and nodeset.
1426///
1427/// When this flag is set, the actual sets of allowed PUs and NUMA nodes
1428/// are given by [`hwloc_topology_get_allowed_cpuset()`] and
1429/// [`hwloc_topology_get_allowed_nodeset()`]. They may be smaller than the root
1430/// object cpuset and nodeset.
1431///
1432/// If the current topology is exported to XML and reimported later,
1433/// this flag should be set again in the reimported topology so that
1434/// disallowed resources are reimported as well.
1435///
1436#[cfg_attr(
1437    feature = "hwloc-2_1_0",
1438    doc = "What additional objects could be detected with this flag depends on"
1439)]
1440#[cfg_attr(
1441    feature = "hwloc-2_1_0",
1442    doc = "[`hwloc_topology_discovery_support::disallowed_pu`] and"
1443)]
1444#[cfg_attr(
1445    feature = "hwloc-2_1_0",
1446    doc = "[`hwloc_topology_discovery_support::disallowed_numa`], which can be checked"
1447)]
1448#[cfg_attr(feature = "hwloc-2_1_0", doc = "after building the topology.")]
1449#[doc(alias = "HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM")]
1450pub const HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED: hwloc_topology_flags_e = 1 << 0;
1451
1452/// Assume that the selected backend provides the topology for the
1453/// system on which we are running
1454///
1455/// This forces [`hwloc_topology_is_thissystem()`] to return true, i.e. makes
1456/// hwloc assume that the selected backend provides the topology for the system
1457/// on which we are running, even if it is not the OS-specific backend but the
1458/// XML backend for instance. This means making the binding functions actually
1459/// call the OS-specific system calls and really do binding, while the XML
1460/// backend would otherwise provide empty hooks just returning success.
1461///
1462/// Setting the environment variable `HWLOC_THISSYSTEM` may also result
1463/// in the same behavior.
1464///
1465/// This can be used for efficiency reasons to first detect the topology
1466/// once, save it to an XML file, and quickly reload it later through
1467/// the XML backend, but still having binding functions actually do bind.
1468pub const HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM: hwloc_topology_flags_e = 1 << 1;
1469
1470/// Get the set of allowed resources from the local operating system
1471/// even if the topology was loaded from XML or synthetic description
1472///
1473/// If the topology was loaded from XML or from a synthetic string,
1474/// restrict it by applying the current process restrictions such as
1475/// Linux Cgroup/Cpuset.
1476///
1477/// This is useful when the topology is not loaded directly from the
1478/// local machine (e.g. for performance reason) and it comes with all
1479/// resources, while the running process is restricted to only parts of
1480/// the machine.
1481///
1482/// If this flag is set, [`HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM`] must also be set,
1483/// since the loaded topology must match the underlying machine where
1484/// restrictions will be gathered from.
1485///
1486/// Setting the environment variable `HWLOC_THISSYSTEM_ALLOWED_RESOURCES`
1487/// would result in the same behavior.
1488pub const HWLOC_TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES: hwloc_topology_flags_e = 1 << 2;
1489
1490/// Import support from the imported topology
1491///
1492/// When importing a XML topology from a remote machine, binding is disabled by
1493/// default (see [`HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM`]). This disabling is also
1494/// marked by putting zeroes in the corresponding supported feature bits
1495/// reported by [`hwloc_topology_get_support()`].
1496///
1497/// This flag allows you to actually import support bits from the remote
1498/// machine. It also sets the
1499/// [`hwloc_topology_misc_support::imported_support`] support flag. If the
1500/// imported XML did not contain any support information(exporter hwloc is too
1501/// old), this flag is not set.
1502///
1503/// Note that these supported features are only relevant for the hwloc
1504/// installation that actually exported the XML topology (it may vary
1505/// with the operating system, or with how hwloc was compiled).
1506///
1507/// Note that setting this flag however does not enable binding for the
1508/// locally imported hwloc topology, it only reports what the remote
1509/// hwloc and machine support.
1510#[cfg(feature = "hwloc-2_3_0")]
1511pub const HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT: hwloc_topology_flags_e = 1 << 3;
1512
1513/// Do not consider resources outside of the process CPU binding
1514///
1515/// If the binding of the process is limited to a subset of cores,
1516/// ignore the other cores during discovery.
1517///
1518/// The resulting topology is identical to what a call to
1519/// [`hwloc_topology_restrict()`] would generate, but this flag also
1520/// prevents hwloc from ever touching other resources during the
1521/// discovery.
1522///
1523/// This flag especially tells the x86 backend to never temporarily
1524/// rebind a thread on any excluded core. This is useful on Windows
1525/// because such temporary rebinding can change the process binding.
1526/// Another use-case is to avoid cores that would not be able to perform
1527/// the hwloc discovery anytime soon because they are busy executing
1528/// some high-priority real-time tasks.
1529///
1530/// If process CPU binding is not supported, the thread CPU binding is
1531/// considered instead if supported, or the flag is ignored.
1532///
1533/// This flag requires [`HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM`] as well since
1534/// binding support is required.
1535#[cfg(feature = "hwloc-2_5_0")]
1536pub const HWLOC_TOPOLOGY_FLAG_RESTRICT_TO_CPUBINDING: hwloc_topology_flags_e = 1 << 4;
1537
1538/// Do not consider resources outside of the process memory binding
1539///
1540/// If the binding of the process is limited to a subset of NUMA nodes,
1541/// ignore the other NUMA nodes during discovery.
1542///
1543/// The resulting topology is identical to what a call to
1544/// [`hwloc_topology_restrict()`] would generate, but this flag also
1545/// prevents hwloc from ever touching other resources during the
1546/// discovery.
1547///
1548/// This flag is meant to be used together with
1549/// `RESTRICT_CPU_TO_THIS_PROCESS` when both cores and NUMA nodes should
1550/// be ignored outside of the process binding.
1551///
1552/// If process memory binding is not supported, the thread memory
1553/// binding is considered instead if supported, or the flag is ignored.
1554///
1555/// This flag requires [`HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM`] as well since
1556/// binding support is required.
1557#[cfg(feature = "hwloc-2_5_0")]
1558pub const HWLOC_TOPOLOGY_FLAG_RESTRICT_TO_MEMBINDING: hwloc_topology_flags_e = 1 << 5;
1559
1560/// Do not ever modify the process or thread binding during discovery
1561///
1562/// This flag disables all hwloc discovery steps that require a change
1563/// of the process or thread binding. This currently only affects the
1564/// x86 backend which gets entirely disabled.
1565///
1566/// This is useful when a topology is loaded while the application also creates
1567/// additional threads or modifies the binding.
1568///
1569/// This flag is also a strict way to make sure the process binding will
1570/// not change to due thread binding changes on Windows (see
1571/// `RESTRICT_CPU_TO_THIS_PROCESS`).
1572#[cfg(feature = "hwloc-2_5_0")]
1573pub const HWLOC_TOPOLOGY_FLAG_DONT_CHANGE_BINDING: hwloc_topology_flags_e = 1 << 6;
1574
1575/// Ignore distance information from the operating system (and from
1576/// XML)
1577///
1578/// Distances will not be used for grouping topology objects.
1579#[cfg(feature = "hwloc-2_8_0")]
1580pub const HWLOC_TOPOLOGY_FLAG_NO_DISTANCES: hwloc_topology_flags_e = 1 << 7;
1581
1582/// Ignore memory attribues from the operating system (and from XML)
1583#[cfg(feature = "hwloc-2_8_0")]
1584pub const HWLOC_TOPOLOGY_FLAG_NO_MEMATTRS: hwloc_topology_flags_e = 1 << 8;
1585
1586/// Ignore CPU kind information from the operating system (and from
1587/// XML)
1588#[cfg(feature = "hwloc-2_8_0")]
1589pub const HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS: hwloc_topology_flags_e = 1 << 9;
1590
1591/// Set of flags describing actual hwloc feature support for this topology
1592#[derive(Copy, Clone, Debug)]
1593#[repr(C)]
1594pub struct hwloc_topology_support {
1595    /// Support for discovering information about the topology
1596    pub discovery: *const hwloc_topology_discovery_support,
1597
1598    /// Support for getting and setting thread/process CPU bindings
1599    pub cpubind: *const hwloc_topology_cpubind_support,
1600
1601    /// Support for getting and setting thread/process NUMA node bindings
1602    pub membind: *const hwloc_topology_membind_support,
1603
1604    /// Miscellaneous support information
1605    #[cfg(feature = "hwloc-2_3_0")]
1606    pub misc: *const hwloc_topology_misc_support,
1607}
1608//
1609impl Default for hwloc_topology_support {
1610    fn default() -> Self {
1611        Self {
1612            discovery: ptr::null(),
1613            cpubind: ptr::null(),
1614            membind: ptr::null(),
1615            #[cfg(feature = "hwloc-2_3_0")]
1616            misc: ptr::null(),
1617        }
1618    }
1619}
1620
1621/// Support for discovering information about the topology
1622#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
1623#[repr(C)]
1624pub struct hwloc_topology_discovery_support {
1625    /// Detecting the number of PU objects is supported
1626    pub pu: c_uchar,
1627
1628    /// Detecting the number of NUMA nodes is supported
1629    pub numa: c_uchar,
1630
1631    /// Detecting the amount of memory in NUMA nodes is supported
1632    pub numa_memory: c_uchar,
1633
1634    /// Detecting and identifying PU objects that are not available to the
1635    /// current process is supported
1636    #[cfg(feature = "hwloc-2_1_0")]
1637    pub disallowed_pu: c_uchar,
1638
1639    /// Detecting and identifying NUMA nodes that are not available to the
1640    /// current process is supported
1641    #[cfg(feature = "hwloc-2_1_0")]
1642    pub disallowed_numa: c_uchar,
1643
1644    /// Detecting the efficiency of CPU kinds is supported
1645    ///
1646    /// See also [Kinds of CPU cores](https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__cpukinds.html).
1647    #[cfg(feature = "hwloc-2_4_0")]
1648    pub cpukind_efficiency: c_uchar,
1649}
1650
1651/// Support for getting and setting thread/process CPU bindings
1652///
1653/// A flag may be set even if the feature isn't supported in all cases
1654/// (e.g. binding to random sets of non-contiguous objects).
1655#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
1656#[repr(C)]
1657pub struct hwloc_topology_cpubind_support {
1658    /// Binding the whole current process is supported
1659    pub set_thisproc_cpubind: c_uchar,
1660
1661    /// Getting the binding of the whole current process is supported
1662    pub get_thisproc_cpubind: c_uchar,
1663
1664    /// Binding a whole given process is supported
1665    pub set_proc_cpubind: c_uchar,
1666
1667    /// Getting the binding of a whole given process is supported
1668    pub get_proc_cpubind: c_uchar,
1669
1670    /// Binding the current thread only is supported
1671    pub set_thisthread_cpubind: c_uchar,
1672
1673    /// Getting the binding of the current thread only is supported
1674    pub get_thisthread_cpubind: c_uchar,
1675
1676    /// Binding a given thread only is supported
1677    pub set_thread_cpubind: c_uchar,
1678
1679    /// Getting the binding of a given thread only is supported
1680    pub get_thread_cpubind: c_uchar,
1681
1682    /// Getting the last processors where the whole current process ran is supported
1683    pub get_thisproc_last_cpu_location: c_uchar,
1684
1685    /// Getting the last processors where a whole process ran is supported
1686    pub get_proc_last_cpu_location: c_uchar,
1687
1688    /// Getting the last processors where the current thread ran is supported
1689    pub get_thisthread_last_cpu_location: c_uchar,
1690}
1691
1692/// Support for getting and setting thread/process NUMA node bindings
1693///
1694/// A flag may be set even if the feature isn't supported in all cases
1695/// (e.g. binding to random sets of non-contiguous objects).
1696#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
1697#[repr(C)]
1698pub struct hwloc_topology_membind_support {
1699    /// Binding the whole current process is supported
1700    pub set_thisproc_membind: c_uchar,
1701
1702    /// Getting the binding of the whole current process is supported
1703    pub get_thisproc_membind: c_uchar,
1704
1705    /// Binding a whole given process is supported
1706    pub set_proc_membind: c_uchar,
1707
1708    /// Getting the binding of a whole given process is supported
1709    pub get_proc_membind: c_uchar,
1710
1711    /// Binding the current thread only is supported
1712    pub set_thisthread_membind: c_uchar,
1713
1714    /// Getting the binding of the current thread only is supported
1715    pub get_thisthread_membind: c_uchar,
1716
1717    /// Binding a given memory area is supported
1718    pub set_area_membind: c_uchar,
1719
1720    /// Getting the binding of a given memory area is supported
1721    pub get_area_membind: c_uchar,
1722
1723    /// Allocating a bound memory area is supported
1724    pub alloc_membind: c_uchar,
1725
1726    /// First-touch policy is supported
1727    pub firsttouch_membind: c_uchar,
1728
1729    /// Bind policy is supported
1730    pub bind_membind: c_uchar,
1731
1732    /// Interleave policy is supported
1733    pub interleave_membind: c_uchar,
1734
1735    /// Next-touch migration policy is supported
1736    pub nexttouch_membind: c_uchar,
1737
1738    /// Migration flag is supported
1739    pub migrate_membind: c_uchar,
1740
1741    /// Getting the last NUMA nodes where a memory area was allocated is supported
1742    pub get_area_memlocation: c_uchar,
1743}
1744
1745/// Miscellaneous support information
1746#[cfg(feature = "hwloc-2_3_0")]
1747#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
1748#[repr(C)]
1749pub struct hwloc_topology_misc_support {
1750    /// Support was imported when importing another topology
1751    ///
1752    /// See also [`HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT`].
1753    pub imported_support: c_uchar,
1754}
1755
1756/// Type filtering flags
1757///
1758/// By default...
1759///
1760/// - Most objects are kept ([`HWLOC_TYPE_FILTER_KEEP_ALL`])
1761/// - Instruction caches, I/O and Misc objects are ignored (
1762///   [`HWLOC_TYPE_FILTER_KEEP_NONE`]).
1763/// - Die and Group levels are ignored unless they bring structure (
1764///   [`HWLOC_TYPE_FILTER_KEEP_STRUCTURE`]).
1765///
1766/// Note that group objects are also ignored individually (without the entire
1767/// level) when they do not bring structure.
1768///
1769/// We can't use Rust enums to model C enums in FFI because that results in
1770/// undefined behavior if the C API gets new enum variants and sends them to us.
1771pub type hwloc_type_filter_e = c_int;
1772
1773/// Keep all objects of this type
1774///
1775/// Cannot be set for [`HWLOC_OBJ_GROUP`] (groups are designed only to add
1776/// more structure to the topology).
1777pub const HWLOC_TYPE_FILTER_KEEP_ALL: hwloc_type_filter_e = 0;
1778
1779/// Ignore all objects of this type
1780///
1781/// The bottom-level type [`HWLOC_OBJ_PU`], the [`HWLOC_OBJ_NUMANODE`] type
1782/// and the top-level type [`HWLOC_OBJ_MACHINE`] may not be ignored.
1783pub const HWLOC_TYPE_FILTER_KEEP_NONE: hwloc_type_filter_e = 1;
1784
1785/// Only ignore objects if their entire level does not bring any structure
1786///
1787/// Keep the entire level of objects if at least one of these objects adds
1788/// structure to the topology. An object brings structure when it has
1789/// multiple children and it is not the only child of its parent.
1790///
1791/// If all objects in the level are the only child of their parent, and if
1792/// none of them has multiple children, the entire level is removed.
1793///
1794/// Cannot be set for I/O and Misc objects since the topology structure does
1795/// not matter there.
1796pub const HWLOC_TYPE_FILTER_KEEP_STRUCTURE: hwloc_type_filter_e = 2;
1797
1798/// Only keep likely-important objects of the given type.
1799///
1800/// This is only useful for I/O object types.
1801///
1802/// For [`HWLOC_OBJ_PCI_DEVICE`] and [`HWLOC_OBJ_OS_DEVICE`], it means that
1803/// only objects of major/common kinds are kept (storage, network,
1804/// OpenFabrics, CUDA, OpenCL, RSMI, NVML, and displays).
1805/// Also, only OS devices directly attached on PCI (e.g. no USB) are reported.
1806///
1807/// For [`HWLOC_OBJ_BRIDGE`], it means that bridges are kept only if they
1808/// have children.
1809///
1810/// This flag is equivalent to [`HWLOC_TYPE_FILTER_KEEP_ALL`] for Normal, Memory
1811/// and Misc types since they are likely important.
1812pub const HWLOC_TYPE_FILTER_KEEP_IMPORTANT: hwloc_type_filter_e = 3;
1813
1814// === Modifying a loaded Topology: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__tinker.html
1815
1816/// Module existing solely to apply a common hwloc version gate
1817#[allow(clippy::wildcard_imports)]
1818#[cfg(feature = "hwloc-2_3_0")]
1819mod topology_editing {
1820    use super::*;
1821
1822    /// Flags to be given to [`hwloc_topology_restrict()`]
1823    pub type hwloc_restrict_flags_e = c_ulong;
1824
1825    /// Remove all objects that became CPU-less
1826    ///
1827    /// By default, only objects that contain no PU and no memory are removed. This
1828    /// flag allows you to remove all objects that do not have access to any CPU
1829    /// anymore when restricting by CPU set.
1830    pub const HWLOC_RESTRICT_FLAG_REMOVE_CPULESS: hwloc_restrict_flags_e = 1 << 0;
1831
1832    /// Restrict by NUMA node set insted of by CPU set
1833    pub const HWLOC_RESTRICT_FLAG_BYNODESET: hwloc_restrict_flags_e = 1 << 3;
1834
1835    /// Remove all objects that became memory-less
1836    ///
1837    /// By default, only objects that contain no PU and no memory are removed. This
1838    /// flag allows you to remove all objects that do not have access to any memory
1839    /// anymore when restricting by NUMA node set.
1840    pub const HWLOC_RESTRICT_FLAG_REMOVE_MEMLESS: hwloc_restrict_flags_e = 1 << 4;
1841
1842    /// Move Misc objects to ancestors if their parents are removed during
1843    /// restriction
1844    ///
1845    /// If this flag is not set, Misc objects are removed when their parents
1846    /// are removed.
1847    pub const HWLOC_RESTRICT_FLAG_ADAPT_MISC: hwloc_restrict_flags_e = 1 << 1;
1848
1849    /// Move I/O objects to ancestors if their parents are removed
1850    /// during restriction
1851    ///
1852    /// If this flag is not set, I/O devices and bridges are removed when
1853    /// their parents are removed.
1854    pub const HWLOC_RESTRICT_FLAG_ADAPT_IO: hwloc_restrict_flags_e = 1 << 2;
1855
1856    /// Flags to be given to [`hwloc_topology_allow()`]
1857    pub type hwloc_allow_flags_e = c_ulong;
1858
1859    /// Mark all objects as allowed in the topology
1860    ///
1861    /// `cpuset` and `nodeset` given to [`hwloc_topology_allow()`] must be NULL.
1862    pub const HWLOC_ALLOW_FLAG_ALL: hwloc_allow_flags_e = 1 << 0;
1863
1864    /// Only allow objects that are available to the current process
1865    ///
1866    /// Requires [`HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM`] so that the set of available
1867    /// resources can actually be retrieved from the operating system.
1868    ///
1869    /// `cpuset` and `nodeset` given to [`hwloc_topology_allow()`] must be NULL.
1870    pub const HWLOC_ALLOW_FLAG_LOCAL_RESTRICTIONS: hwloc_allow_flags_e = 1 << 1;
1871
1872    /// Allow a custom set of objects, given to [`hwloc_topology_allow()`] as
1873    /// `cpuset` and/or `nodeset` parameters.
1874    pub const HWLOC_ALLOW_FLAG_CUSTOM: hwloc_allow_flags_e = 1 << 2;
1875}
1876#[cfg(feature = "hwloc-2_3_0")]
1877pub use topology_editing::*;
1878
1879// === Distributing items over a topology:
1880// https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__helper__distribute.html
1881
1882/// Flags to be given to `hwloc_distrib()`
1883///
1884/// Note that the C version of `hwloc_distrib()` is not actually exposed in the
1885/// Rust binding as it is a static header function in the C library.
1886pub type hwloc_distrib_flags_e = c_ulong;
1887
1888/// Distrib in reverse order, starting from the last objects
1889pub const HWLOC_DISTRIB_FLAG_REVERSE: hwloc_distrib_flags_e = 1 << 0;
1890
1891// === The bitmap API: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__bitmap.html
1892
1893/// Opaque bitmap struct
1894///
1895/// Represents the private `hwloc_bitmap_s` type that `hwloc_bitmap_t` API
1896/// pointers map to.
1897///
1898/// This type purposely implements almost no traits, not even Debug, because you
1899/// should never, ever deal with it directly, only with raw pointers to it that
1900/// you blindly pass to the hwloc API.
1901///
1902/// The only exception to this rule is [`RefUnwindSafe`], which is special
1903/// because...
1904///
1905/// - You cannot implement [`UnwindSafe`] yourself for standard pointer types
1906///   due to orphan rules
1907/// - Rust implements it for pointers to [`RefUnwindSafe`], i.e. it assumes you
1908///   use pointers to such data responsibly.
1909/// - The ergonomic impact of everyday types not being [`UnwindSafe`] is
1910///   annoying (need [`AssertUnwindSafe`] in every [`catch_unwind()`]).
1911///
1912/// [`AssertUnwindSafe`]: std::panic::AssertUnwindSafe
1913/// [`catch_unwind()`]: std::panic::catch_unwind()
1914#[allow(missing_debug_implementations)]
1915#[repr(C)]
1916pub struct hwloc_bitmap_s(IncompleteType);
1917//
1918impl RefUnwindSafe for hwloc_bitmap_s {}
1919
1920/// Set of bits represented as an opaque pointer to an internal bitmap
1921pub type hwloc_bitmap_t = *mut hwloc_bitmap_s;
1922
1923/// A non-modifiable [`hwloc_bitmap_t`]
1924pub type hwloc_const_bitmap_t = *const hwloc_bitmap_s;
1925
1926// === Exporting Topologies to XML: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__xmlexport.html
1927
1928/// Flags to be given to [`hwloc_topology_export_xml()`]
1929pub type hwloc_topology_export_xml_flags_e = c_ulong;
1930
1931/// Export XML that is loadable by hwloc v1.x
1932///
1933/// The export may miss some details about the topology.
1934pub const HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1: hwloc_topology_export_xml_flags_e = 1 << 0;
1935
1936// === Exporting Topologies to Synthetic: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__syntheticexport.html
1937
1938/// Flags to be given to [`hwloc_topology_export_synthetic()`]
1939pub type hwloc_topology_export_synthetic_flags_e = c_ulong;
1940
1941/// Export extended types such as L2dcache as basic types such as Cache
1942///
1943/// This is required if loading the synthetic description with hwloc < 1.9.
1944pub const HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES:
1945    hwloc_topology_export_synthetic_flags_e = 1 << 0;
1946
1947/// Do not export level attributes
1948///
1949/// Ignore level attributes such as memory/cache sizes or PU indices.
1950///
1951/// This is required if loading the synthetic description with hwloc < 1.10.
1952pub const HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS: hwloc_topology_export_synthetic_flags_e =
1953    1 << 1;
1954
1955/// Export the memory hierarchy as expected in hwloc 1.x
1956///
1957/// Instead of attaching memory children to levels, export single NUMA
1958/// node children as normal intermediate levels, when possible.
1959///
1960/// This is required if loading the synthetic description with hwloc 1.x.
1961/// However this may fail if some objects have multiple local NUMA nodes.
1962pub const HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1: hwloc_topology_export_synthetic_flags_e = 1 << 2;
1963
1964/// Do not export memory information
1965///
1966/// Only export the actual hierarchy of normal CPU-side objects and
1967/// ignore where memory is attached.
1968///
1969/// This is useful for when the hierarchy of CPUs is what really matters,
1970/// but it behaves as if there was a single machine-wide NUMA node.
1971pub const HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_IGNORE_MEMORY:
1972    hwloc_topology_export_synthetic_flags_e = 1 << 3;
1973
1974// === Retrieve distances between objects: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__distances__get.html
1975
1976/// Kinds of distance matrices
1977///
1978/// A kind with a name starting with "FROM_" specifies where the distance
1979/// information comes from, if known.
1980///
1981/// A kind with a name starting with "MEANS_" specifies whether values are
1982/// latencies or bandwidths, if applicable.
1983///
1984/// Only one of the "FROM_" and "MEANS_" kinds should be present.
1985pub type hwloc_distances_kind_e = c_ulong;
1986
1987/// These distances were obtained from the operating system or hardware
1988pub const HWLOC_DISTANCES_KIND_FROM_OS: hwloc_distances_kind_e = 1 << 0;
1989
1990/// These distances were provided by the user
1991pub const HWLOC_DISTANCES_KIND_FROM_USER: hwloc_distances_kind_e = 1 << 1;
1992
1993/// Distance values are similar to latencies between objects
1994///
1995/// Values are smaller for closer objects, hence minimal on the diagonal
1996/// of the matrix (distance between an object and itself).
1997///
1998/// It could also be the number of network hops between objects, etc.
1999pub const HWLOC_DISTANCES_KIND_MEANS_LATENCY: hwloc_distances_kind_e = 1 << 2;
2000
2001/// Distance values are similar to bandwidths between objects
2002///
2003/// Values are higher for closer objects, hence maximal on the diagonal
2004/// of the matrix (distance between an object and itself).
2005///
2006/// Such values are currently ignored for distance-based grouping.
2007pub const HWLOC_DISTANCES_KIND_MEANS_BANDWIDTH: hwloc_distances_kind_e = 1 << 3;
2008
2009/// This distances structure covers objects of different types
2010///
2011/// This may apply to the "NVLinkBandwidth" structure in presence of a
2012/// NVSwitch or POWER processor NVLink port.
2013#[cfg(feature = "hwloc-2_1_0")]
2014pub const HWLOC_DISTANCES_KIND_HETEROGENEOUS_TYPES: hwloc_distances_kind_e = 1 << 4;
2015
2016/// Module existing solely to apply a common hwloc version gate
2017#[allow(clippy::wildcard_imports)]
2018#[cfg(feature = "hwloc-2_5_0")]
2019mod distances_transform {
2020    use super::*;
2021
2022    /// Transformations of distances structures
2023    ///
2024    /// We can't use Rust enums to model C enums in FFI because that results in
2025    /// undefined behavior if the C API gets new enum variants and sends them to us.
2026    pub type hwloc_distances_transform_e = c_uint;
2027
2028    /// Remove NULL objects from the distances structure.
2029    ///
2030    /// Every object that was replaced with NULL in [`hwloc_distances_s::objs`]
2031    /// is removed and the matrix is updated accordingly.
2032    ///
2033    /// At least 2 objects must remain, otherwise [`hwloc_distances_transform()`]
2034    /// will fail.
2035    ///
2036    /// [`hwloc_distances_s::kind`] will be updated with or without
2037    /// [`HWLOC_DISTANCES_KIND_HETEROGENEOUS_TYPES`] according to the remaining
2038    /// objects.
2039    pub const HWLOC_DISTANCES_TRANSFORM_REMOVE_NULL: hwloc_distances_transform_e = 0;
2040
2041    /// Replace bandwidth values with a number of links
2042    ///
2043    /// Usually all values will be either 0 (no link) or 1 (one link).
2044    /// However some matrices could get larger values if some pairs of
2045    /// peers are connected by different numbers of links.
2046    ///
2047    /// Values on the diagonal are set to 0.
2048    ///
2049    /// This transformation only applies to bandwidth matrices.
2050    pub const HWLOC_DISTANCES_TRANSFORM_LINKS: hwloc_distances_transform_e = 1;
2051
2052    /// Merge switches with multiple ports into a single object
2053    ///
2054    /// This currently only applies to NVSwitches where GPUs seem connected to
2055    /// different separate switch ports in the NVLinkBandwidth matrix.
2056    ///
2057    /// This transformation will replace all switch ports with the same port
2058    /// connected to all GPUs.
2059    ///
2060    /// Other ports are removed by applying the
2061    /// [`HWLOC_DISTANCES_TRANSFORM_REMOVE_NULL`] transformation internally.
2062    pub const HWLOC_DISTANCES_TRANSFORM_MERGE_SWITCH_PORTS: hwloc_distances_transform_e = 2;
2063
2064    /// Apply a transitive closure to the matrix to connect objects across
2065    /// switches.
2066    ///
2067    /// This currently only applies to GPUs and NVSwitches in the
2068    /// NVLinkBandwidth matrix.
2069    ///
2070    /// All pairs of GPUs will be reported as directly connected.
2071    pub const HWLOC_DISTANCES_TRANSFORM_TRANSITIVE_CLOSURE: hwloc_distances_transform_e = 3;
2072}
2073#[cfg(feature = "hwloc-2_5_0")]
2074pub use distances_transform::*;
2075
2076/// Matrix of distances between a set of objects
2077///
2078/// This matrix often contains latencies between NUMA nodes (as reported in the
2079/// System Locality Distance Information Table (SLIT) in the ACPI
2080/// specification), which may or may not be physically accurate. It corresponds
2081/// to the latency for accessing the memory of one node from a core in another
2082/// node. The corresponding kind is [`HWLOC_DISTANCES_KIND_FROM_OS`] |
2083/// [`HWLOC_DISTANCES_KIND_FROM_USER`]. The name of this distances structure is
2084/// "NUMALatency".
2085///
2086/// The names and semantics of other distances matrices currently created by
2087/// hwloc may be found
2088/// [in the hwloc documentation](https://hwloc.readthedocs.io/en/v2.9/topoattrs.html#topoattrs_distances).
2089///
2090/// The matrix may also contain bandwidths between random sets of objects,
2091/// possibly provided by the user, as specified in the `kind` attribute.
2092///
2093/// Pointers `objs` and `values` should not be replaced, reallocated, freed, etc.
2094/// However callers are allowed to modify `kind` as well as the contents of `objs`
2095/// and `values` arrays.
2096///
2097#[cfg_attr(
2098    feature = "hwloc-2_5_0",
2099    doc = "For instance, on hwloc 2.5+, if there is a single NUMA node per Package,"
2100)]
2101#[cfg_attr(
2102    feature = "hwloc-2_5_0",
2103    doc = "[`hwloc_get_obj_with_same_locality()`] may be used to convert"
2104)]
2105#[cfg_attr(
2106    feature = "hwloc-2_5_0",
2107    doc = "between them and replace NUMA nodes in the objs array with the corresponding"
2108)]
2109#[cfg_attr(feature = "hwloc-2_5_0", doc = "Packages.")]
2110#[cfg_attr(feature = "hwloc-2_5_0", doc = "")]
2111#[cfg_attr(
2112    feature = "hwloc-2_5_0",
2113    doc = "See also [`hwloc_distances_transform()`] for applying some"
2114)]
2115#[cfg_attr(feature = "hwloc-2_5_0", doc = "transformations to the structure.")]
2116#[derive(Copy, Clone, Debug)]
2117#[repr(C)]
2118pub struct hwloc_distances_s {
2119    /// Number of objects described by the distance matrix
2120    pub nbobj: c_uint,
2121
2122    /// Array of `nbobj` objects described by the distance matrix
2123    ///
2124    /// These objects are not in any particular order
2125    pub objs: *mut hwloc_obj_t,
2126
2127    /// OR'ed set of [`hwloc_distances_kind_e`].
2128    pub kind: c_ulong,
2129
2130    /// Matrix of distances between objects, stored as a
2131    /// one-dimension array of length `nbobj*nbobj`
2132    ///
2133    /// Distance from i-th to j-th object is stored in slot `i*nbobjs+j`. The
2134    /// meaning of the value depends on the `kind` attribute.
2135    pub values: *mut u64,
2136}
2137//
2138impl Default for hwloc_distances_s {
2139    fn default() -> Self {
2140        Self {
2141            nbobj: 0,
2142            objs: ptr::null_mut(),
2143            kind: 0,
2144            values: ptr::null_mut(),
2145        }
2146    }
2147}
2148
2149// === Add distances between objects: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__distances__add.html
2150
2151/// Handle to a new distances structure during its addition to the topology
2152#[cfg(feature = "hwloc-2_5_0")]
2153pub type hwloc_distances_add_handle_t = *mut c_void;
2154
2155/// Flags to be given to [`hwloc_distances_add_commit()`]
2156#[cfg(feature = "hwloc-2_5_0")]
2157pub type hwloc_distances_add_flag_e = c_ulong;
2158
2159/// Try to group objects based on the newly provided distance information
2160///
2161/// This is ignored for distances between objects of different types.
2162#[cfg(feature = "hwloc-2_5_0")]
2163pub const HWLOC_DISTANCES_ADD_FLAG_GROUP: hwloc_distances_add_flag_e = 1 << 0;
2164
2165/// Treat distances as inaccurate for grouping purposes
2166///
2167/// If grouping, consider the distance values as inaccurate and relax the
2168/// comparisons during the grouping algorithms. The actual accuracy may be
2169/// modified through the `HWLOC_GROUPING_ACCURACY` environment variable (see
2170/// [Environment Variables](https://hwloc.readthedocs.io/en/v2.9/envvar.html)).
2171#[cfg(feature = "hwloc-2_5_0")]
2172pub const HWLOC_DISTANCES_ADD_FLAG_GROUP_INACCURATE: hwloc_distances_add_flag_e = 1 << 1;
2173
2174// === Memory attributes
2175
2176/// Module existing solely to apply a common hwloc version gate
2177#[allow(clippy::wildcard_imports)]
2178#[cfg(feature = "hwloc-2_3_0")]
2179mod memory_attributes {
2180    use super::*;
2181
2182    // === Comparing memory node attributes for finding where to allocate on: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__memattrs.html
2183
2184    /// Memory attribute identifier
2185    ///
2186    /// May be one of the `HWLOC_MEMATTR_ID_` constants or a new id returned by
2187    /// [`hwloc_memattr_register()`].
2188    #[doc(alias = "hwloc_memattr_id_e")]
2189    pub type hwloc_memattr_id_t = c_uint;
2190
2191    /// Node capacity in bytes (see [`hwloc_obj::total_memory`])
2192    ///
2193    /// This attribute involves no initiator.
2194    ///
2195    /// Requires [`hwloc_topology_discovery_support::numa_memory`] to be set.
2196    pub const HWLOC_MEMATTR_ID_CAPACITY: hwloc_memattr_id_t = 0;
2197
2198    /// Number of PUs in that locality (i.e. cpuset weight)
2199    ///
2200    /// Smaller locality is better. This attribute involves no initiator.
2201    ///
2202    /// Requires [`hwloc_topology_discovery_support::pu`] to be set.
2203    pub const HWLOC_MEMATTR_ID_LOCALITY: hwloc_memattr_id_t = 1;
2204
2205    /// Average bandwidth in MiB/s, as seen from the given initiator location
2206    ///
2207    /// This is the average bandwidth for read and write accesses. If the
2208    /// platform provides individual read and write bandwidths but no
2209    /// explicit average value, hwloc computes and returns the average.
2210    pub const HWLOC_MEMATTR_ID_BANDWIDTH: hwloc_memattr_id_t = 2;
2211
2212    /// Read bandwidth in MiB/s, as seen from the given initiator location
2213    #[cfg(feature = "hwloc-2_8_0")]
2214    #[cfg_attr(docsrs, doc(cfg(feature = "hwloc-2_8_0")))]
2215    pub const HWLOC_MEMATTR_ID_READ_BANDWIDTH: hwloc_memattr_id_t = 4;
2216
2217    /// Write bandwidth in MiB/s, as seen from the given initiator location
2218    #[cfg(feature = "hwloc-2_8_0")]
2219    #[cfg_attr(docsrs, doc(cfg(feature = "hwloc-2_8_0")))]
2220    pub const HWLOC_MEMATTR_ID_WRITE_BANDWIDTH: hwloc_memattr_id_t = 5;
2221
2222    /// Latency in nanoseconds, as seen from the given initiator location
2223    ///
2224    /// This is the average latency for read and write accesses. If the
2225    /// platform value provides individual read and write latencies but no
2226    /// explicit average, hwloc computes and returns the average.
2227    pub const HWLOC_MEMATTR_ID_LATENCY: hwloc_memattr_id_t = 3;
2228
2229    /// Read latency in nanoseconds, as seen from the given initiator location
2230    #[cfg(feature = "hwloc-2_8_0")]
2231    #[cfg_attr(docsrs, doc(cfg(feature = "hwloc-2_8_0")))]
2232    pub const HWLOC_MEMATTR_ID_READ_LATENCY: hwloc_memattr_id_t = 6;
2233
2234    /// Write latency in nanoseconds, as seen from the given initiator location
2235    #[cfg(feature = "hwloc-2_8_0")]
2236    #[cfg_attr(docsrs, doc(cfg(feature = "hwloc-2_8_0")))]
2237    pub const HWLOC_MEMATTR_ID_WRITE_LATENCY: hwloc_memattr_id_t = 7;
2238    // NOTE: If you add new attributes, add support to hwlocality's
2239    //       hwloc_memattr_id_t, static_flags and MemoryAttribute constructors
2240
2241    /// Flags for selecting more target NUMA nodes
2242    ///
2243    /// By default only NUMA nodes whose locality is exactly the given location
2244    /// are selected.
2245    pub type hwloc_local_numanode_flag_e = c_ulong;
2246
2247    /// Select NUMA nodes whose locality is larger than the given cpuset
2248    ///
2249    /// For instance, if a single PU (or its cpuset) is given in `initiator`,
2250    /// select all nodes close to the package that contains this PU.
2251    pub const HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY: hwloc_local_numanode_flag_e = 1 << 0;
2252
2253    /// Select NUMA nodes whose locality is smaller than the given cpuset
2254    ///
2255    /// For instance, if a package (or its cpuset) is given in `initiator`,
2256    /// also select nodes that are attached to only a half of that package.
2257    pub const HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY: hwloc_local_numanode_flag_e = 1 << 1;
2258
2259    /// Select all NUMA nodes in the topology
2260    ///
2261    /// The initiator is ignored.
2262    pub const HWLOC_LOCAL_NUMANODE_FLAG_ALL: hwloc_local_numanode_flag_e = 1 << 2;
2263
2264    /// Where to measure attributes from
2265    #[derive(Copy, Clone, Debug)]
2266    #[repr(C)]
2267    pub struct hwloc_location {
2268        /// Type of location
2269        #[doc(alias = "hwloc_location::type")]
2270        pub ty: hwloc_location_type_e,
2271
2272        /// Actual location
2273        pub location: hwloc_location_u,
2274    }
2275
2276    /// Type of location
2277    ///
2278    /// C enums can't be modeled as Rust enums because new variants would be UB
2279    pub type hwloc_location_type_e = c_int;
2280
2281    /// Location is given as a cpuset, in the [`hwloc_location_u::cpuset`] union field
2282    pub const HWLOC_LOCATION_TYPE_CPUSET: hwloc_location_type_e = 1;
2283
2284    /// Location is given as an object, in the [`hwloc_location_u::object`] union field
2285    pub const HWLOC_LOCATION_TYPE_OBJECT: hwloc_location_type_e = 0;
2286
2287    /// Actual location
2288    #[derive(Copy, Clone)]
2289    #[doc(alias = "hwloc_location::hwloc_location_u")]
2290    #[repr(C)]
2291    pub union hwloc_location_u {
2292        /// Directly provide CPU set to find NUMA nodes with corresponding
2293        /// locality
2294        ///
2295        /// This is the only initiator type supported by most memory attribute
2296        /// queries on hwloc-defined memory attributes, though `object` remains
2297        /// an option for user-defined memory attributes.
2298        pub cpuset: hwloc_const_cpuset_t,
2299
2300        /// Use a topology object as an initiator
2301        ///
2302        /// Most memory attribute queries on hwloc-defined memory attributes do
2303        /// not support this initiator type, or translate it to a cpuset
2304        /// (going up the ancestor chain if necessary). But user-defined memory
2305        /// attributes may for instance use it to provide custom information
2306        /// about host memory accesses performed by GPUs.
2307        pub object: *const hwloc_obj,
2308    }
2309    //
2310    impl Debug for hwloc_location_u {
2311        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2312            f.debug_struct("hwloc_location_u").finish_non_exhaustive()
2313        }
2314    }
2315
2316    /// Memory attribute flags
2317    ///
2318    /// At least one of [`HWLOC_MEMATTR_FLAG_HIGHER_FIRST`] and
2319    /// [`HWLOC_MEMATTR_FLAG_LOWER_FIRST`] must be set.
2320    pub type hwloc_memattr_flag_e = c_ulong;
2321
2322    /// The best nodes for this memory attribute are those with the higher
2323    /// values
2324    ///
2325    /// For instance [`HWLOC_MEMATTR_ID_BANDWIDTH`].
2326    pub const HWLOC_MEMATTR_FLAG_HIGHER_FIRST: hwloc_memattr_flag_e = 1 << 0;
2327
2328    /// The best nodes for this memory attribute are those with the lower
2329    /// values
2330    ///
2331    /// For instance [`HWLOC_MEMATTR_ID_LATENCY`].
2332    pub const HWLOC_MEMATTR_FLAG_LOWER_FIRST: hwloc_memattr_flag_e = 1 << 1;
2333
2334    /// The value returned for this memory attribute depends on the given
2335    /// initiator
2336    ///
2337    /// For instance [`HWLOC_MEMATTR_ID_BANDWIDTH`] and
2338    /// [`HWLOC_MEMATTR_ID_LATENCY`], but not[`HWLOC_MEMATTR_ID_CAPACITY`].
2339    pub const HWLOC_MEMATTR_FLAG_NEED_INITIATOR: hwloc_memattr_flag_e = 1 << 2;
2340}
2341#[cfg(feature = "hwloc-2_3_0")]
2342pub use memory_attributes::*;
2343
2344// === Entry points
2345
2346/// Implement all the entry points with the right link name
2347macro_rules! extern_c_block {
2348    ($link_name:literal) => {
2349        #[link(name = $link_name)]
2350        extern "C" {
2351            // === API versioning: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__api__version.html
2352
2353            /// Indicate at runtime which hwloc API version was used at build time
2354            ///
2355            /// This number is updated to `(X<<16)+(Y<<8)+Z` when a new release X.Y.Z
2356            /// actually modifies the API.
2357            #[must_use]
2358            pub fn hwloc_get_api_version() -> c_uint;
2359
2360            // === Object types: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__object__types.html
2361
2362            /// Compare the depth of two object types.
2363            ///
2364            /// Types shouldn't be compared as they are, since newer ones may be
2365            /// added in the future.
2366            ///
2367            /// # Returns
2368            ///
2369            /// - A negative integer if `type1` objects usually include `type2`
2370            ///   objects.
2371            /// - A positive integer if `type1` objects are usually included in
2372            ///   `type2` objects.
2373            /// - 0 if `type1` and `type2` objects are the same.
2374            /// - [`HWLOC_TYPE_UNORDERED`] if objects cannot be compared
2375            ///   (because neither is usually contained in the other).
2376            ///
2377            /// # Note
2378            ///
2379            /// - Object types containing CPUs can always be compared (usually,
2380            ///   a machine contains packages, which contain caches, which
2381            ///   contain cores, which contain PUs).
2382            /// - [`HWLOC_OBJ_PU`] will always be the deepest, while
2383            ///   [`HWLOC_OBJ_MACHINE`] is always the highest.
2384            /// - This does not mean that the actual topology will respect that
2385            ///   order: e.g. as of today cores may also contain caches, and
2386            ///   packages may also contain nodes. This is thus just to be seen
2387            ///   as a fallback comparison method.
2388            #[must_use]
2389            pub fn hwloc_compare_types(type1: hwloc_obj_type_t, type2: hwloc_obj_type_t) -> c_int;
2390
2391            // === Topology creation and destruction: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__creation.html
2392
2393            /// Allocate a topology context
2394            ///
2395            /// # Parameters
2396            ///
2397            /// `[out] topologyp` is assigned a pointer to the new allocated
2398            /// context.
2399            ///
2400            /// # Returns
2401            ///
2402            /// 0 on success, -1 on error
2403            #[must_use]
2404            pub fn hwloc_topology_init(topology: *mut hwloc_topology_t) -> c_int;
2405
2406            /// Build the actual topology
2407            ///
2408            /// Build the actual topology once initialized with
2409            /// [`hwloc_topology_init()`] and tuned with[Topology Detection
2410            /// Configuration and
2411            /// Query](https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__configuration.html)
2412            /// and [Changing the Source of Topology
2413            /// Discovery](https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__setsource.html)
2414            /// routines. No other routine may be called earlier using this
2415            /// topology context.
2416            ///
2417            /// # Parameters
2418            ///
2419            /// `topology` is the topology to be loaded with objects.
2420            ///
2421            /// # Returns
2422            ///
2423            /// 0 on success, -1 on error
2424            ///
2425            /// # Note
2426            ///
2427            /// - On failure, the topology is reinitialized. It should be either
2428            ///   destroyed with [`hwloc_topology_destroy()`] or configured and
2429            ///   loaded again.
2430            /// - This function may be called only once per topology.
2431            /// - The binding of the current thread or process may temporarily
2432            ///   change during this call but it will be restored before it
2433            ///   returns.
2434            #[must_use]
2435            pub fn hwloc_topology_load(topology: hwloc_topology_t) -> c_int;
2436
2437            /// Terminate and free a topology context
2438            ///
2439            /// # Parameters
2440            ///
2441            /// `topology` is the topology to be freed
2442            pub fn hwloc_topology_destroy(topology: hwloc_topology_t);
2443
2444            /// Duplicate a topology
2445            ///
2446            /// The entire topology structure as well as its objects are
2447            /// duplicated into a new one.
2448            ///
2449            /// This is useful for keeping a backup while modifying a topology.
2450            ///
2451            /// # Returns
2452            ///
2453            /// 0 on success, -1 on error
2454            ///
2455            /// # Note
2456            ///
2457            /// Object userdata is not duplicated since hwloc does not know what
2458            /// it points to. The objects of both old and new topologies will
2459            /// point to the same userdata.
2460            #[must_use]
2461            pub fn hwloc_topology_dup(
2462                newtop: *mut hwloc_topology_t,
2463                oldtop: hwloc_const_topology_t,
2464            ) -> c_int;
2465
2466            /// Check that this topology is compatible with the current hwloc
2467            /// library
2468            ///
2469            /// This is useful when using the same topology structure (in
2470            /// memory) in different libraries that may use different hwloc
2471            /// installations (for instance if one library embeds a specific
2472            /// version of hwloc, while another library uses a default
2473            /// system-wide hwloc installation).
2474            ///
2475            /// If all libraries/programs use the same hwloc installation, this
2476            /// function always returns 0.
2477            ///
2478            /// # Returns
2479            ///
2480            /// - `0` on success
2481            /// - `-1` with errno set to `EINVAL` if incompatible
2482            //
2483            // --- Implementation details ---
2484            //
2485            // TODO: Propagate note about interprocess sharing from upstream docs
2486            //       once interprocess sharing is implemented.
2487            #[must_use]
2488            pub fn hwloc_topology_abi_check(topology: hwloc_const_topology_t) -> c_int;
2489
2490            /// Run internal checks on a topology structure
2491            ///
2492            /// The program aborts if an inconsistency is detected in the given
2493            /// topology.
2494            ///
2495            /// # Parameters
2496            ///
2497            /// `topology` is the topology to be checked
2498            ///
2499            /// # Note
2500            ///
2501            /// - This routine is only useful to developers.
2502            /// - The input topology should have been previously loaded with
2503            ///   [`hwloc_topology_load()`].
2504            pub fn hwloc_topology_check(topology: hwloc_const_topology_t);
2505
2506            // === Object levels, depths and types: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__levels.html
2507
2508            #[must_use]
2509            pub fn hwloc_topology_get_depth(
2510                topology: hwloc_const_topology_t,
2511            ) -> hwloc_get_type_depth_e;
2512            #[must_use]
2513            pub fn hwloc_get_type_depth(
2514                topology: hwloc_const_topology_t,
2515                object_type: hwloc_obj_type_t,
2516            ) -> hwloc_get_type_depth_e;
2517            #[must_use]
2518            pub fn hwloc_get_memory_parents_depth(
2519                topology: hwloc_const_topology_t,
2520            ) -> hwloc_get_type_depth_e;
2521            #[must_use]
2522            pub fn hwloc_get_depth_type(
2523                topology: hwloc_const_topology_t,
2524                depth: hwloc_get_type_depth_e,
2525            ) -> hwloc_obj_type_t;
2526            #[must_use]
2527            pub fn hwloc_get_nbobjs_by_depth(
2528                topology: hwloc_const_topology_t,
2529                depth: hwloc_get_type_depth_e,
2530            ) -> c_uint;
2531            #[must_use]
2532            pub fn hwloc_get_obj_by_depth(
2533                topology: hwloc_const_topology_t,
2534                depth: hwloc_get_type_depth_e,
2535                idx: c_uint,
2536            ) -> hwloc_obj_t;
2537
2538            // === Converting between object types, attributes and strings: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__object__strings.html
2539
2540            #[must_use]
2541            pub fn hwloc_obj_type_snprintf(
2542                into: *mut c_char,
2543                size: usize,
2544                object: *const hwloc_obj,
2545                verbose: c_int,
2546            ) -> c_int;
2547            #[must_use]
2548            pub fn hwloc_obj_attr_snprintf(
2549                into: *mut c_char,
2550                size: usize,
2551                object: *const hwloc_obj,
2552                separator: *const c_char,
2553                verbose: c_int,
2554            ) -> c_int;
2555            // NOTE: Not exposing type printf/scanf for now
2556
2557            // === Consulting and adding Key-Value info attributes: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__info__attr.html
2558
2559            #[must_use]
2560            pub fn hwloc_obj_add_info(
2561                obj: hwloc_obj_t,
2562                name: *const c_char,
2563                value: *const c_char,
2564            ) -> c_int;
2565
2566            // === CPU binding: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__cpubinding.html
2567
2568            #[must_use]
2569            pub fn hwloc_set_cpubind(
2570                topology: hwloc_const_topology_t,
2571                set: hwloc_const_cpuset_t,
2572                flags: hwloc_cpubind_flags_t,
2573            ) -> c_int;
2574            #[must_use]
2575            pub fn hwloc_get_cpubind(
2576                topology: hwloc_const_topology_t,
2577                set: hwloc_cpuset_t,
2578                flags: hwloc_cpubind_flags_t,
2579            ) -> c_int;
2580            #[must_use]
2581            pub fn hwloc_set_proc_cpubind(
2582                topology: hwloc_const_topology_t,
2583                pid: hwloc_pid_t,
2584                set: hwloc_const_cpuset_t,
2585                flags: hwloc_cpubind_flags_t,
2586            ) -> c_int;
2587            #[must_use]
2588            pub fn hwloc_get_proc_cpubind(
2589                topology: hwloc_const_topology_t,
2590                pid: hwloc_pid_t,
2591                set: hwloc_cpuset_t,
2592                flags: hwloc_cpubind_flags_t,
2593            ) -> c_int;
2594            #[must_use]
2595            pub fn hwloc_set_thread_cpubind(
2596                topology: hwloc_const_topology_t,
2597                thread: hwloc_thread_t,
2598                set: hwloc_const_cpuset_t,
2599                flags: hwloc_cpubind_flags_t,
2600            ) -> c_int;
2601            #[must_use]
2602            pub fn hwloc_get_thread_cpubind(
2603                topology: hwloc_const_topology_t,
2604                pid: hwloc_thread_t,
2605                set: hwloc_cpuset_t,
2606                flags: hwloc_cpubind_flags_t,
2607            ) -> c_int;
2608            #[must_use]
2609            pub fn hwloc_get_last_cpu_location(
2610                topology: hwloc_const_topology_t,
2611                set: hwloc_cpuset_t,
2612                flags: hwloc_cpubind_flags_t,
2613            ) -> c_int;
2614            #[must_use]
2615            pub fn hwloc_get_proc_last_cpu_location(
2616                topology: hwloc_const_topology_t,
2617                pid: hwloc_pid_t,
2618                set: hwloc_cpuset_t,
2619                flags: hwloc_cpubind_flags_t,
2620            ) -> c_int;
2621
2622            // === Memory binding: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__membinding.html
2623
2624            #[must_use]
2625            pub fn hwloc_set_membind(
2626                topology: hwloc_const_topology_t,
2627                set: hwloc_const_bitmap_t,
2628                policy: hwloc_membind_policy_t,
2629                flags: hwloc_membind_flags_t,
2630            ) -> c_int;
2631            #[must_use]
2632            pub fn hwloc_get_membind(
2633                topology: hwloc_const_topology_t,
2634                set: hwloc_bitmap_t,
2635                policy: *mut hwloc_membind_policy_t,
2636                flags: hwloc_membind_flags_t,
2637            ) -> c_int;
2638            #[must_use]
2639            pub fn hwloc_set_proc_membind(
2640                topology: hwloc_const_topology_t,
2641                pid: hwloc_pid_t,
2642                set: hwloc_const_bitmap_t,
2643                policy: hwloc_membind_policy_t,
2644                flags: hwloc_membind_flags_t,
2645            ) -> c_int;
2646            #[must_use]
2647            pub fn hwloc_get_proc_membind(
2648                topology: hwloc_const_topology_t,
2649                pid: hwloc_pid_t,
2650                set: hwloc_bitmap_t,
2651                policy: *mut hwloc_membind_policy_t,
2652                flags: hwloc_membind_flags_t,
2653            ) -> c_int;
2654            #[must_use]
2655            pub fn hwloc_set_area_membind(
2656                topology: hwloc_const_topology_t,
2657                addr: *const c_void,
2658                len: usize,
2659                set: hwloc_const_bitmap_t,
2660                policy: hwloc_membind_policy_t,
2661                flags: hwloc_membind_flags_t,
2662            ) -> c_int;
2663            #[must_use]
2664            pub fn hwloc_get_area_membind(
2665                topology: hwloc_const_topology_t,
2666                addr: *const c_void,
2667                len: usize,
2668                set: hwloc_bitmap_t,
2669                policy: *mut hwloc_membind_policy_t,
2670                flags: hwloc_membind_flags_t,
2671            ) -> c_int;
2672            #[must_use]
2673            pub fn hwloc_get_area_memlocation(
2674                topology: hwloc_const_topology_t,
2675                addr: *const c_void,
2676                len: usize,
2677                set: hwloc_bitmap_t,
2678                flags: hwloc_membind_flags_t,
2679            ) -> c_int;
2680            #[must_use]
2681            pub fn hwloc_alloc(topology: hwloc_const_topology_t, len: usize) -> *mut c_void;
2682            #[must_use]
2683            pub fn hwloc_alloc_membind(
2684                topology: hwloc_const_topology_t,
2685                len: usize,
2686                set: hwloc_const_bitmap_t,
2687                policy: hwloc_membind_policy_t,
2688                flags: hwloc_membind_flags_t,
2689            ) -> *mut c_void;
2690            #[must_use]
2691            pub fn hwloc_free(
2692                topology: hwloc_const_topology_t,
2693                addr: *mut c_void,
2694                len: usize,
2695            ) -> c_int;
2696
2697            // === Changing the source of topology discovery: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__setsource.html
2698
2699            #[must_use]
2700            pub fn hwloc_topology_set_pid(topology: hwloc_topology_t, pid: hwloc_pid_t) -> c_int;
2701            #[must_use]
2702            pub fn hwloc_topology_set_synthetic(
2703                topology: hwloc_topology_t,
2704                description: *const c_char,
2705            ) -> c_int;
2706            #[must_use]
2707            pub fn hwloc_topology_set_xml(
2708                topology: hwloc_topology_t,
2709                xmlpath: *const c_char,
2710            ) -> c_int;
2711            #[must_use]
2712            pub fn hwloc_topology_set_xmlbuffer(
2713                topology: hwloc_topology_t,
2714                buffer: *const c_char,
2715                size: c_int,
2716            ) -> c_int;
2717            #[cfg(feature = "hwloc-2_1_0")]
2718            #[must_use]
2719            pub fn hwloc_topology_set_components(
2720                topology: hwloc_topology_t,
2721                flags: hwloc_topology_components_flag_e,
2722                name: *const c_char,
2723            ) -> c_int;
2724
2725            // === Topology detection configuration and query: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__configuration.html
2726
2727            #[must_use]
2728            pub fn hwloc_topology_set_flags(
2729                topology: hwloc_topology_t,
2730                flags: hwloc_topology_flags_e,
2731            ) -> c_int;
2732            #[must_use]
2733            pub fn hwloc_topology_get_flags(
2734                topology: hwloc_const_topology_t,
2735            ) -> hwloc_topology_flags_e;
2736            #[must_use]
2737            pub fn hwloc_topology_is_thissystem(topology: hwloc_const_topology_t) -> c_int;
2738            #[must_use]
2739            pub fn hwloc_topology_get_support(
2740                topology: hwloc_const_topology_t,
2741            ) -> *const hwloc_topology_support;
2742            #[must_use]
2743            pub fn hwloc_topology_set_type_filter(
2744                topology: hwloc_topology_t,
2745                ty: hwloc_obj_type_t,
2746                filter: hwloc_type_filter_e,
2747            ) -> c_int;
2748            #[must_use]
2749            pub fn hwloc_topology_get_type_filter(
2750                topology: hwloc_const_topology_t,
2751                ty: hwloc_obj_type_t,
2752                filter: *mut hwloc_type_filter_e,
2753            ) -> c_int;
2754            #[must_use]
2755            pub fn hwloc_topology_set_all_types_filter(
2756                topology: hwloc_topology_t,
2757                filter: hwloc_type_filter_e,
2758            ) -> c_int;
2759            #[must_use]
2760            pub fn hwloc_topology_set_cache_types_filter(
2761                topology: hwloc_topology_t,
2762                filter: hwloc_type_filter_e,
2763            ) -> c_int;
2764            #[must_use]
2765            pub fn hwloc_topology_set_icache_types_filter(
2766                topology: hwloc_topology_t,
2767                filter: hwloc_type_filter_e,
2768            ) -> c_int;
2769            #[must_use]
2770            pub fn hwloc_topology_set_io_types_filter(
2771                topology: hwloc_topology_t,
2772                filter: hwloc_type_filter_e,
2773            ) -> c_int;
2774            // NOTE: set_userdata and get_userdata are NOT exposed because they
2775            //       are hard to make work with copying, persistence and thread
2776            //       safety and are not so useful as to justify the effort.
2777
2778            // === Modifying a loaded Topology: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__tinker.html
2779
2780            #[cfg(feature = "hwloc-2_3_0")]
2781            #[must_use]
2782            pub fn hwloc_topology_restrict(
2783                topology: hwloc_topology_t,
2784                set: hwloc_const_bitmap_t,
2785                flags: hwloc_restrict_flags_e,
2786            ) -> c_int;
2787            #[cfg(feature = "hwloc-2_3_0")]
2788            #[must_use]
2789            pub fn hwloc_topology_allow(
2790                topology: hwloc_topology_t,
2791                cpuset: hwloc_const_cpuset_t,
2792                nodeset: hwloc_const_nodeset_t,
2793                flags: hwloc_allow_flags_e,
2794            ) -> c_int;
2795            #[cfg(feature = "hwloc-2_3_0")]
2796            #[must_use]
2797            pub fn hwloc_topology_insert_misc_object(
2798                topology: hwloc_topology_t,
2799                parent: hwloc_obj_t,
2800                name: *const c_char,
2801            ) -> hwloc_obj_t;
2802            #[cfg(feature = "hwloc-2_3_0")]
2803            #[must_use]
2804            pub fn hwloc_topology_alloc_group_object(topology: hwloc_topology_t) -> hwloc_obj_t;
2805            #[cfg(feature = "hwloc-2_10_0")]
2806            #[must_use]
2807            pub fn hwloc_topology_free_group_object(
2808                topology: hwloc_topology_t,
2809                group: hwloc_obj_t,
2810            ) -> c_int;
2811            #[cfg(feature = "hwloc-2_3_0")]
2812            #[must_use]
2813            pub fn hwloc_topology_insert_group_object(
2814                topology: hwloc_topology_t,
2815                group: hwloc_obj_t,
2816            ) -> hwloc_obj_t;
2817            #[cfg(feature = "hwloc-2_3_0")]
2818            #[must_use]
2819            pub fn hwloc_obj_add_other_obj_sets(dst: hwloc_obj_t, src: *const hwloc_obj) -> c_int;
2820            #[cfg(feature = "hwloc-2_3_0")]
2821            #[must_use]
2822            pub fn hwloc_topology_refresh(topology: hwloc_topology_t) -> c_int;
2823
2824            // === Kinds of ObjectTypes: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__helper__types.html
2825
2826            #[must_use]
2827            pub fn hwloc_obj_type_is_normal(ty: hwloc_obj_type_t) -> c_int;
2828            #[must_use]
2829            pub fn hwloc_obj_type_is_io(ty: hwloc_obj_type_t) -> c_int;
2830            #[must_use]
2831            pub fn hwloc_obj_type_is_memory(ty: hwloc_obj_type_t) -> c_int;
2832            #[must_use]
2833            pub fn hwloc_obj_type_is_cache(ty: hwloc_obj_type_t) -> c_int;
2834            #[must_use]
2835            pub fn hwloc_obj_type_is_dcache(ty: hwloc_obj_type_t) -> c_int;
2836            #[must_use]
2837            pub fn hwloc_obj_type_is_icache(ty: hwloc_obj_type_t) -> c_int;
2838
2839            // === Finding objects, miscellaneous helpers: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__helper__find__misc.html
2840
2841            #[cfg(feature = "hwloc-2_2_0")]
2842            #[must_use]
2843            pub fn hwloc_bitmap_singlify_per_core(
2844                topology: hwloc_const_topology_t,
2845                cpuset: hwloc_cpuset_t,
2846                which: c_uint,
2847            ) -> c_int;
2848            #[cfg(feature = "hwloc-2_5_0")]
2849            #[must_use]
2850            pub fn hwloc_get_obj_with_same_locality(
2851                topology: hwloc_const_topology_t,
2852                src: *const hwloc_obj,
2853                ty: hwloc_obj_type_t,
2854                subtype: *const c_char,
2855                nameprefix: *const c_char,
2856                flags: c_ulong,
2857            ) -> *const hwloc_obj;
2858
2859            // === CPU and node sets of entire topologies: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__helper__topology__sets.html
2860
2861            #[must_use]
2862            pub fn hwloc_topology_get_complete_cpuset(
2863                topology: hwloc_const_topology_t,
2864            ) -> hwloc_const_cpuset_t;
2865            #[must_use]
2866            pub fn hwloc_topology_get_topology_cpuset(
2867                topology: hwloc_const_topology_t,
2868            ) -> hwloc_const_cpuset_t;
2869            #[must_use]
2870            pub fn hwloc_topology_get_allowed_cpuset(
2871                topology: hwloc_const_topology_t,
2872            ) -> hwloc_const_cpuset_t;
2873            #[must_use]
2874            pub fn hwloc_topology_get_complete_nodeset(
2875                topology: hwloc_const_topology_t,
2876            ) -> hwloc_const_nodeset_t;
2877            #[must_use]
2878            pub fn hwloc_topology_get_topology_nodeset(
2879                topology: hwloc_const_topology_t,
2880            ) -> hwloc_const_nodeset_t;
2881            #[must_use]
2882            pub fn hwloc_topology_get_allowed_nodeset(
2883                topology: hwloc_const_topology_t,
2884            ) -> hwloc_const_nodeset_t;
2885
2886            // === Bitmap API: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__bitmap.html
2887
2888            #[must_use]
2889            pub fn hwloc_bitmap_alloc() -> hwloc_bitmap_t;
2890            #[must_use]
2891            pub fn hwloc_bitmap_alloc_full() -> hwloc_bitmap_t;
2892            pub fn hwloc_bitmap_free(bitmap: hwloc_bitmap_t);
2893            #[must_use]
2894            pub fn hwloc_bitmap_dup(src: hwloc_const_bitmap_t) -> hwloc_bitmap_t;
2895            #[must_use]
2896            pub fn hwloc_bitmap_copy(dst: hwloc_bitmap_t, src: hwloc_const_bitmap_t) -> c_int;
2897
2898            #[must_use]
2899            pub fn hwloc_bitmap_list_snprintf(
2900                buf: *mut c_char,
2901                len: usize,
2902                bitmap: hwloc_const_bitmap_t,
2903            ) -> c_int;
2904            // NOTE: Not exposing other printfs and scanfs for now
2905
2906            pub fn hwloc_bitmap_zero(bitmap: hwloc_bitmap_t);
2907            pub fn hwloc_bitmap_fill(bitmap: hwloc_bitmap_t);
2908            #[must_use]
2909            pub fn hwloc_bitmap_only(bitmap: hwloc_bitmap_t, id: c_uint) -> c_int;
2910            #[must_use]
2911            pub fn hwloc_bitmap_allbut(bitmap: hwloc_bitmap_t, id: c_uint) -> c_int;
2912            // NOTE: Not exposing ulong-based APIs for now, so no from_ulong, from_ith_ulong, from_ulongs
2913            //       If I decide to add them, gate from_ulongs with #[cfg(feature = "hwloc-2_1_0")]
2914            #[must_use]
2915            pub fn hwloc_bitmap_set(bitmap: hwloc_bitmap_t, id: c_uint) -> c_int;
2916            #[must_use]
2917            pub fn hwloc_bitmap_set_range(
2918                bitmap: hwloc_bitmap_t,
2919                begin: c_uint,
2920                end: c_int,
2921            ) -> c_int;
2922            // NOTE: Not exposing ulong-based APIs for now, so no set_ith_ulong
2923            #[must_use]
2924            pub fn hwloc_bitmap_clr(bitmap: hwloc_bitmap_t, id: c_uint) -> c_int;
2925            #[must_use]
2926            pub fn hwloc_bitmap_clr_range(
2927                bitmap: hwloc_bitmap_t,
2928                begin: c_uint,
2929                end: c_int,
2930            ) -> c_int;
2931            pub fn hwloc_bitmap_singlify(bitmap: hwloc_bitmap_t) -> c_int;
2932            // NOTE: Not exposing ulong-based APIs for now, so no to_ulong, to_ith_ulong, to_ulongs and nr_ulongs
2933            //       If I decide to add them, gate nr_ulongs and to_ulongs with #[cfg(feature = "hwloc-2_1_0")]
2934
2935            #[must_use]
2936            pub fn hwloc_bitmap_isset(bitmap: hwloc_const_bitmap_t, id: c_uint) -> c_int;
2937            #[must_use]
2938            pub fn hwloc_bitmap_iszero(bitmap: hwloc_const_bitmap_t) -> c_int;
2939            #[must_use]
2940            pub fn hwloc_bitmap_isfull(bitmap: hwloc_const_bitmap_t) -> c_int;
2941
2942            #[must_use]
2943            pub fn hwloc_bitmap_first(bitmap: hwloc_const_bitmap_t) -> c_int;
2944            #[must_use]
2945            pub fn hwloc_bitmap_next(bitmap: hwloc_const_bitmap_t, prev: c_int) -> c_int;
2946            #[must_use]
2947            pub fn hwloc_bitmap_last(bitmap: hwloc_const_bitmap_t) -> c_int;
2948
2949            #[must_use]
2950            pub fn hwloc_bitmap_weight(bitmap: hwloc_const_bitmap_t) -> c_int;
2951
2952            #[must_use]
2953            pub fn hwloc_bitmap_first_unset(bitmap: hwloc_const_bitmap_t) -> c_int;
2954            #[must_use]
2955            pub fn hwloc_bitmap_next_unset(bitmap: hwloc_const_bitmap_t, prev: c_int) -> c_int;
2956            #[must_use]
2957            pub fn hwloc_bitmap_last_unset(bitmap: hwloc_const_bitmap_t) -> c_int;
2958
2959            #[must_use]
2960            pub fn hwloc_bitmap_or(
2961                result: hwloc_bitmap_t,
2962                bitmap1: hwloc_const_bitmap_t,
2963                bitmap2: hwloc_const_bitmap_t,
2964            ) -> c_int;
2965            #[must_use]
2966            pub fn hwloc_bitmap_and(
2967                result: hwloc_bitmap_t,
2968                bitmap1: hwloc_const_bitmap_t,
2969                bitmap2: hwloc_const_bitmap_t,
2970            ) -> c_int;
2971            #[must_use]
2972            pub fn hwloc_bitmap_andnot(
2973                result: hwloc_bitmap_t,
2974                bitmap1: hwloc_const_bitmap_t,
2975                bitmap2: hwloc_const_bitmap_t,
2976            ) -> c_int;
2977            #[must_use]
2978            pub fn hwloc_bitmap_xor(
2979                result: hwloc_bitmap_t,
2980                bitmap1: hwloc_const_bitmap_t,
2981                bitmap2: hwloc_const_bitmap_t,
2982            ) -> c_int;
2983            #[must_use]
2984            pub fn hwloc_bitmap_not(result: hwloc_bitmap_t, bitmap: hwloc_const_bitmap_t) -> c_int;
2985
2986            #[must_use]
2987            pub fn hwloc_bitmap_intersects(
2988                left: hwloc_const_bitmap_t,
2989                right: hwloc_const_bitmap_t,
2990            ) -> c_int;
2991            #[must_use]
2992            pub fn hwloc_bitmap_isincluded(
2993                left: hwloc_const_bitmap_t,
2994                right: hwloc_const_bitmap_t,
2995            ) -> c_int;
2996            #[must_use]
2997            pub fn hwloc_bitmap_isequal(
2998                left: hwloc_const_bitmap_t,
2999                right: hwloc_const_bitmap_t,
3000            ) -> c_int;
3001            // NOTE: Not providing compare_first since it trivially follows from
3002            //       first_set and seems obscure.
3003            #[must_use]
3004            pub fn hwloc_bitmap_compare(
3005                left: hwloc_const_bitmap_t,
3006                right: hwloc_const_bitmap_t,
3007            ) -> c_int;
3008
3009            // === Exporting Topologies to XML: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__xmlexport.html
3010
3011            #[must_use]
3012            pub fn hwloc_topology_export_xml(
3013                topology: hwloc_const_topology_t,
3014                xmlpath: *const c_char,
3015                flags: hwloc_topology_export_xml_flags_e,
3016            ) -> c_int;
3017            #[must_use]
3018            pub fn hwloc_topology_export_xmlbuffer(
3019                topology: hwloc_const_topology_t,
3020                xmlbuffer: *mut *mut c_char,
3021                buflen: *mut c_int,
3022                flags: hwloc_topology_export_xml_flags_e,
3023            ) -> c_int;
3024            pub fn hwloc_free_xmlbuffer(topology: hwloc_const_topology_t, xmlbuffer: *mut c_char);
3025            // NOTE: Not exposing userdata at the moment, so no need to bind
3026            //       associated API functions yet.
3027
3028            // === Exporting Topologies to Synthetic: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__syntheticexport.html
3029
3030            #[must_use]
3031            pub fn hwloc_topology_export_synthetic(
3032                topology: hwloc_const_topology_t,
3033                buffer: *mut c_char,
3034                buflen: usize,
3035                flags: hwloc_topology_export_synthetic_flags_e,
3036            ) -> c_int;
3037
3038            // === Retrieve distances between objects: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__distances__get.html
3039
3040            #[must_use]
3041            pub fn hwloc_distances_get(
3042                topology: hwloc_const_topology_t,
3043                nr: *mut c_uint,
3044                distances: *mut *mut hwloc_distances_s,
3045                kind: hwloc_distances_kind_e,
3046                flags: c_ulong,
3047            ) -> c_int;
3048            #[must_use]
3049            pub fn hwloc_distances_get_by_depth(
3050                topology: hwloc_const_topology_t,
3051                depth: c_int,
3052                nr: *mut c_uint,
3053                distances: *mut *mut hwloc_distances_s,
3054                kind: hwloc_distances_kind_e,
3055                flags: c_ulong,
3056            ) -> c_int;
3057            #[must_use]
3058            pub fn hwloc_distances_get_by_type(
3059                topology: hwloc_const_topology_t,
3060                ty: hwloc_obj_type_t,
3061                nr: *mut c_uint,
3062                distances: *mut *mut hwloc_distances_s,
3063                kind: hwloc_distances_kind_e,
3064                flags: c_ulong,
3065            ) -> c_int;
3066            #[cfg(feature = "hwloc-2_1_0")]
3067            #[must_use]
3068            pub fn hwloc_distances_get_by_name(
3069                topology: hwloc_const_topology_t,
3070                name: *const c_char,
3071                nr: *mut c_uint,
3072                distances: *mut *mut hwloc_distances_s,
3073                flags: c_ulong,
3074            ) -> c_int;
3075            #[cfg(feature = "hwloc-2_1_0")]
3076            #[must_use]
3077            pub fn hwloc_distances_get_name(
3078                topology: hwloc_const_topology_t,
3079                distances: *const hwloc_distances_s,
3080            ) -> *const c_char;
3081            pub fn hwloc_distances_release(
3082                topology: hwloc_const_topology_t,
3083                distances: *const hwloc_distances_s,
3084            );
3085            #[cfg(feature = "hwloc-2_5_0")]
3086            #[must_use]
3087            pub fn hwloc_distances_transform(
3088                topology: hwloc_const_topology_t,
3089                distances: *mut hwloc_distances_s,
3090                transform: hwloc_distances_transform_e,
3091                transform_attr: *mut c_void,
3092                flags: c_ulong,
3093            ) -> c_int;
3094
3095            // === Add distances between objects: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__distances__add.html
3096
3097            #[cfg(feature = "hwloc-2_5_0")]
3098            #[must_use]
3099            pub fn hwloc_distances_add_create(
3100                topology: hwloc_topology_t,
3101                name: *const c_char,
3102                kind: hwloc_distances_kind_e,
3103                flags: c_ulong,
3104            ) -> hwloc_distances_add_handle_t;
3105            #[cfg(feature = "hwloc-2_5_0")]
3106            #[must_use]
3107            pub fn hwloc_distances_add_values(
3108                topology: hwloc_topology_t,
3109                handle: hwloc_distances_add_handle_t,
3110                nbobjs: c_uint,
3111                objs: *const *const hwloc_obj,
3112                values: *const u64,
3113                flags: c_ulong,
3114            ) -> c_int;
3115            #[cfg(feature = "hwloc-2_5_0")]
3116            #[must_use]
3117            pub fn hwloc_distances_add_commit(
3118                topology: hwloc_topology_t,
3119                handle: hwloc_distances_add_handle_t,
3120                flags: hwloc_distances_add_flag_e,
3121            ) -> c_int;
3122
3123            // === Remove distances between objects: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__distances__remove.html
3124
3125            #[cfg(feature = "hwloc-2_3_0")]
3126            #[must_use]
3127            pub fn hwloc_distances_remove(topology: hwloc_topology_t) -> c_int;
3128            #[cfg(feature = "hwloc-2_3_0")]
3129            #[must_use]
3130            pub fn hwloc_distances_remove_by_depth(
3131                topology: hwloc_topology_t,
3132                depth: hwloc_get_type_depth_e,
3133            ) -> c_int;
3134            #[cfg(feature = "hwloc-2_3_0")]
3135            #[must_use]
3136            pub fn hwloc_distances_release_remove(
3137                topology: hwloc_topology_t,
3138                distances: *mut hwloc_distances_s,
3139            ) -> c_int;
3140
3141            // === Comparing memory node attributes for finding where to allocate on: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__memattrs.html
3142
3143            #[cfg(feature = "hwloc-2_3_0")]
3144            #[must_use]
3145            pub fn hwloc_memattr_get_by_name(
3146                topology: hwloc_const_topology_t,
3147                name: *const c_char,
3148                id: *mut hwloc_memattr_id_t,
3149            ) -> c_int;
3150            #[cfg(feature = "hwloc-2_3_0")]
3151            #[must_use]
3152            pub fn hwloc_get_local_numanode_objs(
3153                topology: hwloc_const_topology_t,
3154                location: *const hwloc_location,
3155                nr: *mut c_uint,
3156                nodes: *mut *const hwloc_obj,
3157                flags: hwloc_local_numanode_flag_e,
3158            ) -> c_int;
3159            #[cfg(feature = "hwloc-2_3_0")]
3160            #[must_use]
3161            pub fn hwloc_memattr_get_value(
3162                topology: hwloc_const_topology_t,
3163                attribute: hwloc_memattr_id_t,
3164                target_node: *const hwloc_obj,
3165                initiator: *const hwloc_location,
3166                flags: c_ulong,
3167                value: *mut u64,
3168            ) -> c_int;
3169            #[cfg(feature = "hwloc-2_3_0")]
3170            #[must_use]
3171            pub fn hwloc_memattr_get_best_target(
3172                topology: hwloc_const_topology_t,
3173                attribute: hwloc_memattr_id_t,
3174                initiator: *const hwloc_location,
3175                flags: c_ulong,
3176                best_target: *mut *const hwloc_obj,
3177                value: *mut u64,
3178            ) -> c_int;
3179            #[cfg(feature = "hwloc-2_3_0")]
3180            #[must_use]
3181            pub fn hwloc_memattr_get_best_initiator(
3182                topology: hwloc_const_topology_t,
3183                attribute: hwloc_memattr_id_t,
3184                target: *const hwloc_obj,
3185                flags: c_ulong,
3186                best_initiator: *mut hwloc_location,
3187                value: *mut u64,
3188            ) -> c_int;
3189
3190            // === Managing memory attributes: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__memattrs__manage.html
3191
3192            #[cfg(feature = "hwloc-2_3_0")]
3193            #[must_use]
3194            pub fn hwloc_memattr_get_name(
3195                topology: hwloc_const_topology_t,
3196                attribute: hwloc_memattr_id_t,
3197                name: *mut *const c_char,
3198            ) -> c_int;
3199            #[cfg(feature = "hwloc-2_3_0")]
3200            #[must_use]
3201            pub fn hwloc_memattr_get_flags(
3202                topology: hwloc_const_topology_t,
3203                attribute: hwloc_memattr_id_t,
3204                flags: *mut hwloc_memattr_flag_e,
3205            ) -> c_int;
3206            #[cfg(feature = "hwloc-2_3_0")]
3207            #[must_use]
3208            pub fn hwloc_memattr_register(
3209                topology: hwloc_const_topology_t,
3210                name: *const c_char,
3211                flags: hwloc_memattr_flag_e,
3212                id: *mut hwloc_memattr_id_t,
3213            ) -> c_int;
3214            #[cfg(feature = "hwloc-2_3_0")]
3215            #[must_use]
3216            pub fn hwloc_memattr_set_value(
3217                topology: hwloc_const_topology_t,
3218                attribute: hwloc_memattr_id_t,
3219                target_node: *const hwloc_obj,
3220                initiator: *const hwloc_location,
3221                flags: c_ulong,
3222                value: u64,
3223            ) -> c_int;
3224            #[cfg(feature = "hwloc-2_3_0")]
3225            #[must_use]
3226            pub fn hwloc_memattr_get_targets(
3227                topology: hwloc_const_topology_t,
3228                attribute: hwloc_memattr_id_t,
3229                initiator: *const hwloc_location,
3230                flags: c_ulong,
3231                nr: *mut c_uint,
3232                targets: *mut *const hwloc_obj,
3233                values: *mut u64,
3234            ) -> c_int;
3235            #[cfg(feature = "hwloc-2_3_0")]
3236            #[must_use]
3237            pub fn hwloc_memattr_get_initiators(
3238                topology: hwloc_const_topology_t,
3239                attribute: hwloc_memattr_id_t,
3240                target_node: *const hwloc_obj,
3241                flags: c_ulong,
3242                nr: *mut c_uint,
3243                initiators: *mut hwloc_location,
3244                values: *mut u64,
3245            ) -> c_int;
3246
3247            // === Kinds of CPU cores: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__cpukinds.html
3248
3249            #[cfg(feature = "hwloc-2_4_0")]
3250            #[must_use]
3251            pub fn hwloc_cpukinds_get_nr(topology: hwloc_const_topology_t, flags: c_ulong)
3252                -> c_int;
3253            #[cfg(feature = "hwloc-2_4_0")]
3254            #[must_use]
3255            pub fn hwloc_cpukinds_get_by_cpuset(
3256                topology: hwloc_const_topology_t,
3257                cpuset: hwloc_const_cpuset_t,
3258                flags: c_ulong,
3259            ) -> c_int;
3260            #[cfg(feature = "hwloc-2_4_0")]
3261            #[must_use]
3262            pub fn hwloc_cpukinds_get_info(
3263                topology: hwloc_const_topology_t,
3264                kind_index: c_uint,
3265                cpuset: hwloc_cpuset_t,
3266                efficiency: *mut c_int,
3267                nr_infos: *mut c_uint,
3268                infos: *mut *mut hwloc_info_s,
3269                flags: c_ulong,
3270            ) -> c_int;
3271            #[cfg(feature = "hwloc-2_4_0")]
3272            #[must_use]
3273            pub fn hwloc_cpukinds_register(
3274                topology: hwloc_topology_t,
3275                cpuset: hwloc_const_cpuset_t,
3276                forced_efficiency: c_int,
3277                nr_infos: c_uint,
3278                infos: *const hwloc_info_s,
3279                flags: c_ulong,
3280            ) -> c_int;
3281
3282            // === Linux-specific helpers: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__linux.html
3283
3284            #[cfg(any(doc, target_os = "linux"))]
3285            #[must_use]
3286            pub fn hwloc_linux_set_tid_cpubind(
3287                topology: hwloc_const_topology_t,
3288                tid: pid_t,
3289                set: hwloc_const_cpuset_t,
3290            ) -> c_int;
3291            #[cfg(any(doc, target_os = "linux"))]
3292            #[must_use]
3293            pub fn hwloc_linux_get_tid_cpubind(
3294                topology: hwloc_const_topology_t,
3295                tid: pid_t,
3296                set: hwloc_cpuset_t,
3297            ) -> c_int;
3298            #[cfg(any(doc, target_os = "linux"))]
3299            #[must_use]
3300            pub fn hwloc_linux_get_tid_last_cpu_location(
3301                topology: hwloc_const_topology_t,
3302                tid: pid_t,
3303                set: hwloc_cpuset_t,
3304            ) -> c_int;
3305            #[cfg(any(doc, target_os = "linux"))]
3306            #[must_use]
3307            pub fn hwloc_linux_read_path_as_cpumask(
3308                path: *const c_char,
3309                set: hwloc_cpuset_t,
3310            ) -> c_int;
3311
3312            // NOTE: libnuma interop is waiting for higher quality libnuma bindings
3313
3314            // === Windows-specific helpers: https://hwloc.readthedocs.io/en/v2.9/group__hwlocality__windows.html
3315
3316            #[cfg(any(doc, all(feature = "hwloc-2_5_0", target_os = "windows")))]
3317            #[must_use]
3318            pub fn hwloc_windows_get_nr_processor_groups(
3319                topology: hwloc_const_topology_t,
3320                flags: c_ulong,
3321            ) -> c_int;
3322            #[cfg(any(doc, all(feature = "hwloc-2_5_0", target_os = "windows")))]
3323            #[must_use]
3324            pub fn hwloc_windows_get_processor_group_cpuset(
3325                topology: hwloc_const_topology_t,
3326                pg_index: c_uint,
3327                cpuset: hwloc_cpuset_t,
3328                flags: c_ulong,
3329            ) -> c_int;
3330
3331            // NOTE: glibc interop is waiting for higher quality cpuset support
3332            //       in the libc crate: right now, it is not possible to safely
3333            //       crate a `cpu_set_t`, but functions that manipulate them
3334            //       expect `&mut cpu_set_t`...
3335
3336            // TODO: Cover more later: interop, differences, sharing, etc...
3337            //       Beware that primitives that modify the topology should be
3338            //       exposed in the TopologyEditor, not Topology, because per
3339            //       hwloc documentation hwloc_topology_refresh() must be called
3340            //       before multithreaded access is thread-safe again.
3341        }
3342    };
3343}
3344
3345#[cfg(all(not(feature = "vendored"), target_os = "windows"))]
3346extern_c_block!("libhwloc");
3347
3348#[cfg(all(feature = "vendored", target_os = "windows"))]
3349extern_c_block!("hwloc");
3350
3351#[cfg(not(target_os = "windows"))]
3352extern_c_block!("hwloc");
3353
3354#[cfg(test)]
3355mod tests {
3356    use super::*;
3357    use static_assertions::{assert_impl_all, assert_not_impl_any};
3358    use std::{
3359        fmt::{self, Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex},
3360        hash::Hash,
3361        io::{self, Read},
3362        ops::Deref,
3363        panic::UnwindSafe,
3364    };
3365
3366    // Opaque types implement almost no trait since the user shouldn't
3367    // manipulate them
3368    assert_impl_all!(IncompleteType: Sized);
3369    assert_not_impl_any!(IncompleteType:
3370        Binary, Clone, Debug, Default, Deref, Display, Drop, IntoIterator,
3371        LowerExp, LowerHex, Octal, PartialEq, Pointer, Read, Send, ToOwned,
3372        Unpin, RefUnwindSafe, UpperExp, UpperHex, fmt::Write, io::Write
3373    );
3374    assert_impl_all!(hwloc_bitmap_s: Sized, RefUnwindSafe);
3375    assert_not_impl_any!(hwloc_bitmap_s:
3376        Binary, Clone, Debug, Default, Deref, Display, Drop, IntoIterator,
3377        LowerExp, LowerHex, Octal, PartialEq, Pointer, Read, Send, ToOwned,
3378        Unpin, UnwindSafe, UpperExp, UpperHex, fmt::Write, io::Write
3379    );
3380    assert_impl_all!(hwloc_topology: Sized, RefUnwindSafe);
3381    assert_not_impl_any!(hwloc_topology:
3382        Binary, Clone, Debug, Default, Deref, Display, Drop, IntoIterator,
3383        LowerExp, LowerHex, Octal, PartialEq, Pointer, Read, Send, ToOwned,
3384        Unpin, UnwindSafe, UpperExp, UpperHex, fmt::Write, io::Write
3385    );
3386
3387    // Types with inner pointers that shouldn't be null and have unspecified
3388    // semantics implement a basic set of traits
3389    assert_impl_all!(hwloc_info_s:
3390        Copy, Debug, Sized, Unpin, UnwindSafe
3391    );
3392    assert_not_impl_any!(hwloc_info_s:
3393        Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex,
3394        Octal, PartialEq, Pointer, Read, Send, UpperExp, UpperHex, fmt::Write,
3395        io::Write
3396    );
3397    #[cfg(feature = "hwloc-2_3_0")]
3398    mod hwloc_location_impls {
3399        use super::*;
3400        assert_impl_all!(hwloc_location:
3401            Copy, Debug, Sized, Unpin, UnwindSafe
3402        );
3403        assert_not_impl_any!(hwloc_location:
3404            Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp,
3405            LowerHex, Octal, PartialEq, Pointer, Read, Send, UpperExp, UpperHex,
3406            fmt::Write, io::Write
3407        );
3408        assert_impl_all!(hwloc_location_u:
3409            Copy, Debug, Sized, Unpin, UnwindSafe
3410        );
3411        assert_not_impl_any!(hwloc_location_u:
3412            Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp,
3413            LowerHex, Octal, PartialEq, Pointer, Read, Send, UpperExp, UpperHex,
3414            fmt::Write, io::Write
3415        );
3416    }
3417    assert_impl_all!(hwloc_obj:
3418        Copy, Debug, Sized, Unpin, UnwindSafe
3419    );
3420    assert_not_impl_any!(hwloc_obj:
3421        Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex,
3422        Octal, PartialEq, Pointer, Read, Send, UpperExp, UpperHex, fmt::Write,
3423        io::Write
3424    );
3425
3426    // Types with pointers that can reasonably be null are like types with
3427    // non-nullable pointers, but also implement Default
3428    assert_impl_all!(hwloc_distances_s:
3429        Copy, Debug, Default, Sized, Unpin, UnwindSafe
3430    );
3431    assert_not_impl_any!(hwloc_distances_s:
3432        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3433        PartialEq, Pointer, Read, Send, UpperExp, UpperHex, fmt::Write,
3434        io::Write
3435    );
3436    assert_impl_all!(hwloc_numanode_attr_s:
3437        Copy, Debug, Default, Sized, Unpin, UnwindSafe
3438    );
3439    assert_not_impl_any!(hwloc_numanode_attr_s:
3440        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3441        PartialEq, Pointer, Read, Send, UpperExp, UpperHex, fmt::Write,
3442        io::Write
3443    );
3444    assert_impl_all!(hwloc_topology_support:
3445        Copy, Debug, Default, Sized, Unpin, UnwindSafe
3446    );
3447    assert_not_impl_any!(hwloc_topology_support:
3448        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3449        PartialEq, Pointer, Read, Send, UpperExp, UpperHex, fmt::Write,
3450        io::Write
3451    );
3452
3453    // As the union of all attribute structs, hwloc_obj_attr_u can only
3454    // implement the common subset of their inner traits. It also cannot
3455    // implement any trait that requires looking into the active variant since
3456    // it doesn't know what the active variant is, nor if there is even one.
3457    assert_impl_all!(hwloc_obj_attr_u:
3458        Copy, Debug, Sized, Unpin, UnwindSafe
3459    );
3460    assert_not_impl_any!(hwloc_obj_attr_u:
3461        Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex,
3462        Octal, PartialEq, Pointer, Read, Send, UpperExp, UpperHex, fmt::Write,
3463        io::Write
3464    );
3465
3466    // Unions that contain only Sync types can additionally impl Sync, and this
3467    // also applies to types that contain such unions
3468    assert_impl_all!(hwloc_bridge_attr_s:
3469        Copy, Debug, Sized, Sync, Unpin, UnwindSafe
3470    );
3471    assert_not_impl_any!(hwloc_bridge_attr_s:
3472        Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex,
3473        Octal, PartialEq, Pointer, Read, UpperExp, UpperHex, fmt::Write,
3474        io::Write
3475    );
3476    assert_impl_all!(RawDownstreamAttributes:
3477        Copy, Debug, Sized, Sync, Unpin, UnwindSafe
3478    );
3479    assert_not_impl_any!(RawDownstreamAttributes:
3480        Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex,
3481        Octal, PartialEq, Pointer, Read, UpperExp, UpperHex, fmt::Write,
3482        io::Write
3483    );
3484    assert_impl_all!(RawUpstreamAttributes:
3485        Copy, Debug, Sized, Sync, Unpin, UnwindSafe
3486    );
3487    assert_not_impl_any!(RawUpstreamAttributes:
3488        Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex,
3489        Octal, PartialEq, Pointer, Read, UpperExp, UpperHex, fmt::Write,
3490        io::Write
3491    );
3492
3493    // Most plain old data structs implement Default, Sync and comparisons
3494    //
3495    // Implemented comparisons are mostly equality+hashing and not order, since
3496    // ordering random structs with unrelated members doesn't make much sense.
3497    // We make an exception for hwloc_memory_page_type_s which has an officially
3498    // defined order.
3499    assert_impl_all!(hwloc_cache_attr_s:
3500        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3501    );
3502    assert_not_impl_any!(hwloc_cache_attr_s:
3503        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3504        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3505    );
3506    assert_impl_all!(hwloc_group_attr_s:
3507        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3508    );
3509    assert_not_impl_any!(hwloc_group_attr_s:
3510        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3511        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3512    );
3513    assert_impl_all!(hwloc_osdev_attr_s:
3514        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3515    );
3516    assert_not_impl_any!(hwloc_osdev_attr_s:
3517        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3518        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3519    );
3520    assert_impl_all!(hwloc_topology_cpubind_support:
3521        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3522    );
3523    assert_not_impl_any!(hwloc_topology_cpubind_support:
3524        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3525        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3526    );
3527    assert_impl_all!(hwloc_topology_discovery_support:
3528        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3529    );
3530    assert_not_impl_any!(hwloc_topology_discovery_support:
3531        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3532        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3533    );
3534    assert_impl_all!(hwloc_topology_membind_support:
3535        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3536    );
3537    assert_not_impl_any!(hwloc_topology_membind_support:
3538        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3539        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3540    );
3541    #[cfg(feature = "hwloc-2_3_0")]
3542    assert_impl_all!(hwloc_topology_misc_support:
3543        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3544    );
3545    #[cfg(feature = "hwloc-2_3_0")]
3546    assert_not_impl_any!(hwloc_topology_misc_support:
3547        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3548        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3549    );
3550    assert_impl_all!(RawDownstreamPCIAttributes:
3551        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3552    );
3553    assert_not_impl_any!(RawDownstreamPCIAttributes:
3554        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3555        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3556    );
3557
3558    // hwloc_memory_page_type_s has an officially defined order and has its
3559    // comparison abilities expanded accordingly
3560    assert_impl_all!(hwloc_memory_page_type_s:
3561        Copy, Debug, Default, Hash, Ord, Sized, Sync, Unpin, UnwindSafe
3562    );
3563    assert_not_impl_any!(hwloc_memory_page_type_s:
3564        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3565        Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3566    );
3567
3568    // PCIDevice attributes, contain a floating-point value and have their
3569    // comparison abilities restricted accordingly
3570    assert_impl_all!(hwloc_pcidev_attr_s:
3571        Copy, Debug, Default, PartialEq, Sized, Sync, Unpin,
3572        UnwindSafe
3573    );
3574    assert_not_impl_any!(hwloc_pcidev_attr_s:
3575        Binary, Deref, Display, Drop, Eq, IntoIterator, LowerExp, LowerHex,
3576        Octal, PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write,
3577        io::Write
3578    );
3579
3580    #[test]
3581    fn hwloc_obj_attr_u() {
3582        let attr = super::hwloc_obj_attr_u {
3583            cache: hwloc_cache_attr_s::default(),
3584        };
3585        assert_eq!(format!("{attr:?}"), "hwloc_obj_attr_u { .. }");
3586    }
3587
3588    #[test]
3589    fn hwloc_numanode_attr_s() {
3590        let hwloc_numanode_attr_s {
3591            local_memory,
3592            page_types_len,
3593            page_types,
3594        } = super::hwloc_numanode_attr_s::default();
3595        assert_eq!(local_memory, 0);
3596        assert_eq!(page_types_len, 0);
3597        assert!(page_types.is_null());
3598    }
3599
3600    #[test]
3601    fn hwloc_bridge_attr_s() {
3602        let attr = super::hwloc_bridge_attr_s {
3603            upstream: RawUpstreamAttributes {
3604                pci: hwloc_pcidev_attr_s::default(),
3605            },
3606            upstream_type: HWLOC_OBJ_BRIDGE_PCI,
3607            downstream: RawDownstreamAttributes {
3608                pci: RawDownstreamPCIAttributes::default(),
3609            },
3610            downstream_type: HWLOC_OBJ_BRIDGE_PCI,
3611            depth: 42,
3612        };
3613        assert_eq!(
3614            format!("{attr:?}"),
3615            "hwloc_bridge_attr_s { upstream: RawUpstreamAttributes { .. }, \
3616                                   upstream_type: 1, \
3617                                   downstream: RawDownstreamAttributes { .. }, \
3618                                   downstream_type: 1, \
3619                                   depth: 42 }"
3620        );
3621    }
3622
3623    #[test]
3624    fn hwloc_topology_support() {
3625        let default = super::hwloc_topology_support::default();
3626        #[cfg(not(feature = "hwloc-2_3_0"))]
3627        let hwloc_topology_support {
3628            discovery,
3629            cpubind,
3630            membind,
3631        } = default;
3632        #[cfg(feature = "hwloc-2_3_0")]
3633        let hwloc_topology_support {
3634            discovery,
3635            cpubind,
3636            membind,
3637            misc,
3638        } = default;
3639        assert!(discovery.is_null());
3640        assert!(cpubind.is_null());
3641        assert!(membind.is_null());
3642        #[cfg(feature = "hwloc-2_3_0")]
3643        assert!(misc.is_null());
3644    }
3645
3646    #[test]
3647    fn hwloc_distances_s() {
3648        let hwloc_distances_s {
3649            nbobj,
3650            objs,
3651            kind,
3652            values,
3653        } = super::hwloc_distances_s::default();
3654        assert_eq!(nbobj, 0);
3655        assert!(objs.is_null());
3656        assert_eq!(kind, 0);
3657        assert!(values.is_null());
3658    }
3659
3660    #[cfg(feature = "hwloc-2_3_0")]
3661    #[test]
3662    fn hwloc_location() {
3663        let location = super::hwloc_location {
3664            ty: HWLOC_LOCATION_TYPE_CPUSET,
3665            location: hwloc_location_u {
3666                cpuset: ptr::null(),
3667            },
3668        };
3669        assert_eq!(
3670            format!("{location:?}"),
3671            "hwloc_location { ty: 1, \
3672                              location: hwloc_location_u { .. } }"
3673        );
3674    }
3675}