rustmeter_beacon_core/
tracing.rs1use critical_section::Mutex;
2
3use crate::{
4 buffer::{BufferReader, BufferWriter},
5 protocol::EventPayload,
6 time_delta::TimeDelta,
7};
8
9unsafe extern "Rust" {
10 pub fn write_tracing_data(data: &[u8]);
12}
13
14static TRACE_WRITING: Mutex<()> = Mutex::new(());
15
16pub fn write_tracing_event(event: EventPayload) {
18 critical_section::with(|cs| {
20 let _lock = TRACE_WRITING.borrow(cs);
21
22 let timestamp = TimeDelta::from_now();
23
24 let mut buffer = BufferWriter::new();
26 event.write_bytes(&mut buffer);
27 timestamp.write_bytes(&mut buffer);
28
29 unsafe { write_tracing_data(buffer.as_slice()) };
31 });
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub enum ReadTracingError {
36 InvalidEventType,
37 InvalidTypedefID,
38 InvalidValueTypeID,
39 VarIntOverflow,
40 FloatConversionError,
41 StringConversionError(core::str::Utf8Error),
42 InsufficientData,
43}
44
45impl From<core::str::Utf8Error> for ReadTracingError {
46 fn from(err: core::str::Utf8Error) -> Self {
47 ReadTracingError::StringConversionError(err)
48 }
49}
50
51pub fn read_tracing_event(buffer: &mut BufferReader) -> Result<(TimeDelta, EventPayload), ReadTracingError> {
53 let event_type = buffer.read_byte()?;
54 let event = EventPayload::from_bytes(event_type, buffer)?;
55 let timestamp = TimeDelta::read_bytes(buffer)?;
56
57 Ok((timestamp, event))
58}
59
60#[cfg(test)]
61mod tests {
62 use arbitrary_int::u3;
63
64 use super::*;
65 use crate::{
66 mocks::test_mocks::{mock_time_provider, mock_trace_writer, with_mocks},
67 protocol::TypeDefinitionPayload,
68 };
69
70 #[test]
71 fn test_tracing_event_write_and_read() {
72 let events = vec![
73 EventPayload::EmbassyTaskReady {
74 task_id: 1234,
75 executor_id: u3::new(2),
76 },
77 EventPayload::EmbassyExecutorPollStart {
78 executor_id: u3::new(5),
79 },
80 EventPayload::TypeDefinition(TypeDefinitionPayload::FunctionMonitor {
81 monitor_id: 42,
82 fn_address: 0xDEADBEEF,
83 }),
84 EventPayload::TypeDefinition(TypeDefinitionPayload::ScopeMonitor {
85 monitor_id: 7,
86 name: "TestScope".to_string(),
87 }),
88 EventPayload::MonitorValue {
89 value_id: 1,
90 value: 456i16.into(),
91 },
92 ];
93
94 for event in events {
95 with_mocks(
96 mock_trace_writer(event.clone()),
97 mock_time_provider,
98 || 0,
99 || {
100 write_tracing_event(event);
101 },
102 );
103 }
104 }
105}