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}