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) -> Result<Self> {
66 let mut span = Cpumask::new();
67 let mut dom_numa_map = BTreeMap::new();
68 let mut dom_id = 0;
73 let mut doms: BTreeMap<usize, Domain> = BTreeMap::new();
74 for (node_id, node) in &top.nodes {
75 for (_, llc) in node.llcs.iter() {
76 let mask = llc.span.clone();
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, *node_id);
87 dom_id += 1;
88 }
89 }
90
91 Ok(Self {
92 doms,
93 dom_numa_map,
94 num_numa_nodes: top.nodes.len(),
95 span,
96 })
97 }
98
99 pub fn numa_doms(&self, numa_id: &usize) -> Vec<Domain> {
100 let mut numa_doms = Vec::new();
101 for (d_id, n_id) in self.dom_numa_map.iter() {
103 if n_id == numa_id {
104 let dom = self.doms.get(d_id).unwrap();
105 numa_doms.push(dom.clone());
106 }
107 }
108
109 numa_doms
110 }
111
112 pub fn doms(&self) -> &BTreeMap<usize, Domain> {
113 &self.doms
114 }
115
116 pub fn nr_doms(&self) -> usize {
117 self.doms.len()
118 }
119
120 pub fn nr_nodes(&self) -> usize {
121 self.num_numa_nodes
122 }
123
124 pub fn dom_numa_id(&self, dom_id: &usize) -> Option<usize> {
125 self.dom_numa_map.get(dom_id).copied()
126 }
127
128 pub fn weight(&self) -> usize {
129 self.span.weight()
130 }
131}