vyre_runtime/megakernel/
protocol_api.rs1mod publish;
4
5use crate::PipelineError;
6
7use super::protocol::{self, DebugRecord};
8use super::Megakernel;
9
10impl Megakernel {
11 pub fn encode_control(
18 shutdown: bool,
19 tenant_count: u32,
20 observable_slots: u32,
21 ) -> Result<Vec<u8>, PipelineError> {
22 protocol::encode_control(shutdown, tenant_count, observable_slots).map_err(protocol_error)
23 }
24
25 pub fn try_encode_control(
32 shutdown: bool,
33 tenant_count: u32,
34 observable_slots: u32,
35 ) -> Result<Vec<u8>, PipelineError> {
36 Self::encode_control(shutdown, tenant_count, observable_slots)
37 }
38
39 pub fn try_encode_control_into(
46 shutdown: bool,
47 tenant_count: u32,
48 observable_slots: u32,
49 dst: &mut Vec<u8>,
50 ) -> Result<(), PipelineError> {
51 protocol::try_encode_control_into(shutdown, tenant_count, observable_slots, dst)
52 .map_err(protocol_error)
53 }
54
55 pub fn encode_empty_ring(slot_count: u32) -> Result<Vec<u8>, PipelineError> {
62 protocol::encode_empty_ring(slot_count).map_err(protocol_error)
63 }
64
65 pub fn try_encode_empty_ring(slot_count: u32) -> Result<Vec<u8>, PipelineError> {
72 Self::encode_empty_ring(slot_count)
73 }
74
75 pub fn try_encode_empty_ring_into(
82 slot_count: u32,
83 dst: &mut Vec<u8>,
84 ) -> Result<(), PipelineError> {
85 protocol::try_encode_empty_ring_into(slot_count, dst).map_err(protocol_error)
86 }
87
88 pub fn encode_empty_debug_log(record_capacity: u32) -> Result<Vec<u8>, PipelineError> {
94 protocol::encode_empty_debug_log(record_capacity).map_err(protocol_error)
95 }
96
97 pub fn try_encode_empty_debug_log(record_capacity: u32) -> Result<Vec<u8>, PipelineError> {
103 Self::encode_empty_debug_log(record_capacity)
104 }
105
106 pub fn try_encode_empty_debug_log_into(
112 record_capacity: u32,
113 dst: &mut Vec<u8>,
114 ) -> Result<(), PipelineError> {
115 protocol::try_encode_empty_debug_log_into(record_capacity, dst).map_err(protocol_error)
116 }
117
118 #[must_use]
120 pub fn read_done_count(control_bytes: &[u8]) -> u32 {
121 protocol::read_done_count(control_bytes)
122 }
123
124 pub fn try_read_done_count(control_bytes: &[u8]) -> Result<u32, PipelineError> {
131 protocol::try_read_done_count(control_bytes).map_err(protocol_error)
132 }
133
134 pub fn try_count_done_ring_slots(
141 ring_bytes: &[u8],
142 item_count: usize,
143 ) -> Result<u64, PipelineError> {
144 protocol::try_count_done_ring_slots(ring_bytes, item_count).map_err(protocol_error)
145 }
146
147 #[must_use]
149 pub fn read_debug_log(debug_bytes: &[u8]) -> Vec<DebugRecord> {
150 protocol::read_debug_log(debug_bytes)
151 }
152
153 pub fn read_debug_log_into(debug_bytes: &[u8], out: &mut Vec<DebugRecord>) {
155 protocol::read_debug_log_into(debug_bytes, out);
156 }
157
158 pub fn try_read_debug_log(debug_bytes: &[u8]) -> Result<Vec<DebugRecord>, PipelineError> {
165 protocol::try_read_debug_log(debug_bytes).map_err(protocol_error)
166 }
167
168 pub fn try_read_debug_log_into(
175 debug_bytes: &[u8],
176 out: &mut Vec<DebugRecord>,
177 ) -> Result<(), PipelineError> {
178 protocol::try_read_debug_log_into(debug_bytes, out).map_err(protocol_error)
179 }
180
181 #[must_use]
185 pub fn read_epoch(control_bytes: &[u8]) -> u32 {
186 protocol::read_epoch(control_bytes)
187 }
188
189 pub fn try_read_epoch(control_bytes: &[u8]) -> Result<u32, PipelineError> {
196 protocol::try_read_epoch(control_bytes).map_err(protocol_error)
197 }
198
199 #[must_use]
203 pub fn read_observable(control_bytes: &[u8], index: u32) -> u32 {
204 protocol::read_observable(control_bytes, index)
205 }
206
207 pub fn try_read_observable(control_bytes: &[u8], index: u32) -> Result<u32, PipelineError> {
214 protocol::try_read_observable(control_bytes, index).map_err(protocol_error)
215 }
216
217 #[must_use]
221 pub fn read_metrics(control_bytes: &[u8]) -> Vec<(u32, u32)> {
222 protocol::read_metrics(control_bytes)
223 }
224
225 pub fn read_metrics_into(control_bytes: &[u8], out: &mut Vec<(u32, u32)>) {
227 protocol::read_metrics_into(control_bytes, out);
228 }
229
230 pub fn try_read_metrics(control_bytes: &[u8]) -> Result<Vec<(u32, u32)>, PipelineError> {
237 protocol::try_read_metrics(control_bytes).map_err(protocol_error)
238 }
239
240 pub fn try_read_metrics_into(
247 control_bytes: &[u8],
248 out: &mut Vec<(u32, u32)>,
249 ) -> Result<(), PipelineError> {
250 protocol::try_read_metrics_into(control_bytes, out).map_err(protocol_error)
251 }
252}
253
254fn protocol_error(error: protocol::ProtocolError) -> PipelineError {
255 match error {
256 protocol::ProtocolError::ByteLengthOverflow { fix, .. } => PipelineError::QueueFull {
257 queue: "submission",
258 fix,
259 },
260 other => PipelineError::Backend(other.to_string()),
261 }
262}
263
264pub(super) fn validate_control_bytes(control_bytes: &[u8]) -> Result<(), PipelineError> {
265 let min = protocol::control_byte_len(0).ok_or_else(|| {
266 PipelineError::Backend(
267 "megakernel minimum control-buffer length overflowed usize. Fix: keep CONTROL_MIN_WORDS within host address limits."
268 .to_string(),
269 )
270 })?;
271 if control_bytes.len() < min || control_bytes.len() % 4 != 0 {
272 return Err(PipelineError::Backend(format!(
273 "megakernel control buffer has {} bytes, expected at least {min} bytes and 4-byte alignment. Fix: build it with Megakernel::encode_control.",
274 control_bytes.len()
275 )));
276 }
277 Ok(())
278}
279
280pub(super) fn validate_debug_log_bytes(debug_log_bytes: &[u8]) -> Result<(), PipelineError> {
281 let expected = protocol::debug_log_byte_len(protocol::debug::RECORD_CAPACITY)
282 .ok_or(PipelineError::QueueFull {
283 queue: "submission",
284 fix: "debug-log minimum length overflowed usize; keep debug ABI constants within host limits",
285 })?;
286 if debug_log_bytes.len() != expected {
287 return Err(PipelineError::Backend(format!(
288 "megakernel debug-log buffer has {} bytes, expected exactly {expected} bytes for {} PRINTF records. Fix: build it with Megakernel::encode_empty_debug_log(protocol::debug::RECORD_CAPACITY).",
289 debug_log_bytes.len(),
290 protocol::debug::RECORD_CAPACITY
291 )));
292 }
293 Ok(())
294}
295
296#[cfg(test)]
297mod tests;