dope_core/platform/
affinity.rs1use std::iter;
2
3use dope_sys::thread::{Thread as _, affinity};
4use o3::base::marker::ThreadBound;
5
6use crate::{Backend, Errno};
7
8#[repr(transparent)]
13pub struct Binding {
14 cpu: Cpu,
15 thread: ThreadBound,
16}
17
18impl Binding {
19 pub fn bind(cpu: Cpu) -> Result<Self, Error> {
20 Backend::bind(cpu.0).map_err(Error::from_native)?;
21 Ok(Self {
22 cpu,
23 thread: ThreadBound::NEW,
24 })
25 }
26
27 pub fn cpu(&self) -> Cpu {
28 self.cpu
29 }
30}
31
32const _: () = {
33 assert!(std::mem::size_of::<Binding>() == std::mem::size_of::<Cpu>());
34 assert!(std::mem::align_of::<Binding>() == std::mem::align_of::<Cpu>());
35};
36
37#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
39#[repr(transparent)]
40pub struct Cpu(affinity::raw::Cpu);
41
42impl Cpu {
43 pub fn current() -> Result<
44 impl DoubleEndedIterator<Item = Self> + ExactSizeIterator + iter::FusedIterator,
45 Error,
46 > {
47 Backend::current()
48 .map(|cpus| cpus.map(Self))
49 .map_err(Error::from_native)
50 }
51 pub const fn raw(self) -> u16 {
52 self.0.raw()
53 }
54 pub const fn matches(self, index: Index) -> bool {
55 self.raw() == index.0
56 }
57}
58
59impl From<Cpu> for u64 {
60 fn from(cpu: Cpu) -> Self {
61 u64::from(cpu.0)
62 }
63}
64
65#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
66#[repr(transparent)]
67pub struct Index(u16);
68
69impl From<u16> for Index {
70 fn from(index: u16) -> Self {
71 Self(index)
72 }
73}
74
75#[derive(Clone, Copy, Debug, PartialEq, Eq)]
76pub enum Error {
77 DiscoveryUnsupported,
78 BindingUnsupported { cpu: Cpu },
79 BindingRange { cpu: Cpu, maximum: u16 },
80 Current(Errno),
81 Bind { cpu: Cpu, fault: Errno },
82}
83
84impl Error {
85 fn from_native(error: affinity::Error) -> Self {
86 match error {
87 affinity::Error::DiscoveryUnsupported => Self::DiscoveryUnsupported,
88 affinity::Error::BindingUnsupported { cpu } => {
89 Self::BindingUnsupported { cpu: Cpu(cpu) }
90 }
91 affinity::Error::BindingRange { cpu, maximum } => Self::BindingRange {
92 cpu: Cpu(cpu),
93 maximum,
94 },
95 affinity::Error::Current(error) => Self::Current(error),
96 affinity::Error::Bind { cpu, fault } => Self::Bind {
97 cpu: Cpu(cpu),
98 fault,
99 },
100 }
101 }
102}