1use std::collections::BTreeMap;
6
7use crate::bpf_skel::*;
8use anyhow::Result;
9use scx_utils::Cpumask;
10use scx_utils::Topology;
11use std::sync::Arc;
12use std::sync::Mutex;
13
14#[derive(Clone, Debug)]
15pub struct Domain {
16 id: usize,
17 mask: Cpumask,
18 pub ctx: Arc<Mutex<Option<*mut types::dom_ctx>>>,
19}
20
21impl Domain {
22 pub fn id(&self) -> usize {
24 self.id
25 }
26
27 pub fn mask(&self) -> Cpumask {
29 self.mask.clone()
30 }
31
32 pub fn mask_slice(&self) -> &[u64] {
35 self.mask.as_raw_slice()
36 }
37
38 pub fn weight(&self) -> usize {
40 self.mask.weight()
41 }
42
43 pub fn ctx(&self) -> Option<&mut types::dom_ctx> {
44 let domc = self.ctx.lock().unwrap();
45
46 match *domc {
50 Some(ptr) => Some(unsafe { &mut *(ptr) }),
51 None => None,
52 }
53 }
54}
55
56#[derive(Debug)]
57pub struct DomainGroup {
58 doms: BTreeMap<usize, Domain>,
59 dom_numa_map: BTreeMap<usize, usize>,
60 num_numa_nodes: usize,
61 span: Cpumask,
62}
63
64impl DomainGroup {
65 pub fn new(top: &Topology, cpumasks: &[String]) -> Result<Self> {
66 let mut span = Cpumask::new();
67 let mut dom_numa_map = BTreeMap::new();
68 let mut dom_id = 0;
73 let (doms, num_numa_nodes) = if !cpumasks.is_empty() {
74 let mut doms: BTreeMap<usize, Domain> = BTreeMap::new();
75 for mask_str in cpumasks.iter() {
76 let mask = Cpumask::from_str(mask_str)?;
77 span |= &mask;
78 doms.insert(
79 dom_id,
80 Domain {
81 id: dom_id,
82 mask,
83 ctx: Arc::new(Mutex::new(None)),
84 },
85 );
86 dom_numa_map.insert(dom_id, 0);
87 dom_id += 1;
88 }
89 (doms, 1)
90 } else {
91 let mut doms: BTreeMap<usize, Domain> = BTreeMap::new();
92 for (node_id, node) in &top.nodes {
93 for (_, llc) in node.llcs.iter() {
94 let mask = llc.span.clone();
95 span |= &mask;
96 doms.insert(
97 dom_id,
98 Domain {
99 id: dom_id,
100 mask,
101 ctx: Arc::new(Mutex::new(None)),
102 },
103 );
104 dom_numa_map.insert(dom_id, *node_id);
105 dom_id += 1;
106 }
107 }
108 (doms, top.nodes.len())
109 };
110
111 Ok(Self {
112 doms,
113 dom_numa_map,
114 num_numa_nodes,
115 span,
116 })
117 }
118
119 pub fn numa_doms(&self, numa_id: &usize) -> Vec<Domain> {
120 let mut numa_doms = Vec::new();
121 for (d_id, n_id) in self.dom_numa_map.iter() {
123 if n_id == numa_id {
124 let dom = self.doms.get(d_id).unwrap();
125 numa_doms.push(dom.clone());
126 }
127 }
128
129 numa_doms
130 }
131
132 pub fn doms(&self) -> &BTreeMap<usize, Domain> {
133 &self.doms
134 }
135
136 pub fn nr_doms(&self) -> usize {
137 self.doms.len()
138 }
139
140 pub fn nr_nodes(&self) -> usize {
141 self.num_numa_nodes
142 }
143
144 pub fn dom_numa_id(&self, dom_id: &usize) -> Option<usize> {
145 self.dom_numa_map.get(dom_id).copied()
146 }
147
148 pub fn weight(&self) -> usize {
149 self.span.weight()
150 }
151}