#[cfg(target_has_atomic = "64")]
use core::sync::atomic::{AtomicU32, AtomicU64, Ordering};
#[cfg(not(target_has_atomic = "64"))]
use portable_atomic::{AtomicU32, AtomicU64, Ordering};
use telepath_wire::MetricsSnapshot;
pub(crate) static ENCODE_CYCLES: AtomicU64 = AtomicU64::new(0);
pub(crate) static DECODE_CYCLES: AtomicU64 = AtomicU64::new(0);
pub(crate) static ENCODED_BYTES: AtomicU32 = AtomicU32::new(0);
pub(crate) static DECODED_BYTES: AtomicU32 = AtomicU32::new(0);
pub(crate) static SAMPLE_COUNT: AtomicU32 = AtomicU32::new(0);
pub fn init_dwt() {
#[cfg(target_arch = "arm")]
unsafe {
let mut cp = cortex_m::peripheral::Peripherals::steal();
cp.DCB.enable_trace();
cortex_m::peripheral::DWT::unlock();
cp.DWT.enable_cycle_counter();
cp.DWT.cyccnt.write(0);
}
}
#[inline(always)]
pub fn cycles_now() -> u32 {
#[cfg(target_arch = "arm")]
{
cortex_m::peripheral::DWT::cycle_count()
}
#[cfg(not(target_arch = "arm"))]
{
0
}
}
pub fn snapshot_and_reset() -> MetricsSnapshot {
MetricsSnapshot {
encode_cycles: ENCODE_CYCLES.swap(0, Ordering::Relaxed),
decode_cycles: DECODE_CYCLES.swap(0, Ordering::Relaxed),
encoded_bytes: ENCODED_BYTES.swap(0, Ordering::Relaxed),
decoded_bytes: DECODED_BYTES.swap(0, Ordering::Relaxed),
sample_count: SAMPLE_COUNT.swap(0, Ordering::Relaxed),
}
}
fn get_metrics_shim(
input: &[u8],
output: &mut [u8],
_resources: &crate::ResourceRegistry,
) -> Result<usize, crate::DispatchError> {
if !input.is_empty() {
return Err(crate::DispatchError::DeserializeError);
}
let snap = snapshot_and_reset();
postcard::to_slice(&snap, output)
.map(|s| s.len())
.map_err(|_| crate::DispatchError::SerializeError)
}
fn get_metrics_args_schema(out: &mut [u8]) -> Result<usize, ()> {
postcard::to_slice(<() as crate::__postcard_schema::Schema>::SCHEMA, out)
.map(|s| s.len())
.map_err(|_| ())
}
fn get_metrics_ret_schema(out: &mut [u8]) -> Result<usize, ()> {
postcard::to_slice(
<MetricsSnapshot as crate::__postcard_schema::Schema>::SCHEMA,
out,
)
.map(|s| s.len())
.map_err(|_| ())
}
pub const GET_METRICS_CMD: crate::CommandMetadata = crate::CommandMetadata {
name: "get_metrics",
id: telepath_wire::CMD_ID_METRICS,
invoke: get_metrics_shim,
args_schema: get_metrics_args_schema,
ret_schema: get_metrics_ret_schema,
arg_names: "",
};
#[allow(non_upper_case_globals, non_snake_case)]
#[crate::__linkme::distributed_slice(crate::TELEPATH_COMMANDS)]
#[linkme(crate = crate::__linkme)]
static __TELEPATH_REG_GET_METRICS: crate::CommandMetadata = GET_METRICS_CMD;