Skip to main content

rvm_types/
coherence.rs

1//! Coherence metric types for the RVM microhypervisor.
2//!
3//! Coherence is the first-class scheduling and resource-allocation signal
4//! in RVM. Partitions with higher coherence scores receive preferential
5//! scheduling and memory placement. Cut pressure drives migration and
6//! split/merge decisions.
7//!
8//! See ADR-132 (DC-1, DC-2, DC-4, DC-9) for design constraints.
9
10use crate::PartitionId;
11
12/// A coherence score in the range `[0.0, 1.0]`.
13///
14/// Stored internally as a `u16` fixed-point value (0..=10000) to avoid
15/// floating-point dependencies in `no_std` contexts. 1 basis point = 0.0001.
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
17#[repr(transparent)]
18pub struct CoherenceScore(u16);
19
20impl CoherenceScore {
21    /// Maximum representable score (1.0).
22    pub const MAX: Self = Self(10_000);
23
24    /// Minimum representable score (0.0).
25    pub const MIN: Self = Self(0);
26
27    /// Default coherence threshold below which partitions are deprioritized.
28    pub const DEFAULT_THRESHOLD: Self = Self(3_000); // 0.30
29
30    /// Default merge threshold. Partitions must exceed this to merge (DC-11).
31    pub const DEFAULT_MERGE_THRESHOLD: Self = Self(7_000); // 0.70
32
33    /// Create a coherence score from a fixed-point value (0..=10000).
34    ///
35    /// Values above 10000 are clamped to 10000.
36    #[must_use]
37    pub const fn from_basis_points(bp: u16) -> Self {
38        if bp > 10_000 {
39            Self(10_000)
40        } else {
41            Self(bp)
42        }
43    }
44
45    /// Return the raw basis-point value.
46    #[must_use]
47    pub const fn as_basis_points(self) -> u16 {
48        self.0
49    }
50
51    /// Check whether this score meets the given threshold.
52    #[must_use]
53    pub const fn meets_threshold(self, threshold: Self) -> bool {
54        self.0 >= threshold.0
55    }
56
57    /// Check whether this score is above the default coherence threshold.
58    #[must_use]
59    pub const fn is_coherent(self) -> bool {
60        self.0 >= Self::DEFAULT_THRESHOLD.0
61    }
62}
63
64/// An integrated-information (Phi) value used as a coherence input signal.
65///
66/// Stored as fixed-point with 4 decimal digits of precision.
67#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
68#[repr(transparent)]
69pub struct PhiValue(u32);
70
71impl PhiValue {
72    /// Zero Phi -- no integrated information.
73    pub const ZERO: Self = Self(0);
74
75    /// Create a Phi value from a fixed-point representation.
76    #[must_use]
77    pub const fn from_fixed(val: u32) -> Self {
78        Self(val)
79    }
80
81    /// Return the raw fixed-point value.
82    #[must_use]
83    pub const fn as_fixed(self) -> u32 {
84        self.0
85    }
86}
87
88/// Cut pressure: graph-derived isolation signal (ADR-132, DC-2).
89///
90/// High pressure triggers migration or split. Computed by the mincut crate
91/// within the DC-2 time budget (50 microseconds per epoch).
92#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
93#[repr(transparent)]
94pub struct CutPressure(u32);
95
96impl CutPressure {
97    /// Zero pressure -- no migration or split needed.
98    pub const ZERO: Self = Self(0);
99
100    /// Default split threshold. Partitions exceeding this are candidates for split.
101    pub const DEFAULT_SPLIT_THRESHOLD: Self = Self(8_000);
102
103    /// Create a cut pressure value from a fixed-point representation.
104    #[must_use]
105    pub const fn from_fixed(val: u32) -> Self {
106        Self(val)
107    }
108
109    /// Return the raw fixed-point value.
110    #[must_use]
111    pub const fn as_fixed(self) -> u32 {
112        self.0
113    }
114
115    /// Check whether this pressure exceeds the given threshold.
116    #[must_use]
117    pub const fn exceeds_threshold(self, threshold: Self) -> bool {
118        self.0 > threshold.0
119    }
120}
121
122/// Unique identifier for a communication edge in the coherence graph.
123#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
124#[repr(transparent)]
125pub struct CommEdgeId(u64);
126
127impl CommEdgeId {
128    /// Create a new communication edge identifier.
129    #[must_use]
130    pub const fn new(id: u64) -> Self {
131        Self(id)
132    }
133
134    /// Return the raw identifier value.
135    #[must_use]
136    pub const fn as_u64(self) -> u64 {
137        self.0
138    }
139}
140
141/// A weighted communication edge between two partitions.
142///
143/// Edges are the weighted links in the coherence graph. Weight represents
144/// accumulated message bytes, decayed per epoch. The mincut algorithm
145/// identifies the cheapest set of edges to sever for partition splitting.
146#[derive(Debug, Clone, Copy)]
147pub struct CommEdge {
148    /// Unique identifier for this edge.
149    pub id: CommEdgeId,
150    /// Source partition.
151    pub source: PartitionId,
152    /// Destination partition.
153    pub dest: PartitionId,
154    /// Edge weight (accumulated message bytes, decayed per epoch).
155    pub weight: u64,
156    /// Epoch in which this edge was last updated.
157    pub last_epoch: u32,
158}