Skip to main content

wasmedge_sys/
statistics.rs

1//! Defines WasmEdge Statistics struct.
2
3use crate::{ffi, WasmEdgeResult};
4use std::sync::Arc;
5use wasmedge_types::error::WasmEdgeError;
6
7#[derive(Debug, Clone)]
8/// Struct of WasmEdge Statistics.
9pub struct Statistics {
10    pub(crate) inner: Arc<InnerStat>,
11}
12impl Statistics {
13    /// Creates a new [Statistics].
14    ///
15    /// # Error
16    ///
17    /// If fail to create a [Statistics], then an error is returned.
18    pub fn create() -> WasmEdgeResult<Self> {
19        let ctx = unsafe { ffi::WasmEdge_StatisticsCreate() };
20        match ctx.is_null() {
21            true => Err(Box::new(WasmEdgeError::StatisticsCreate)),
22            false => Ok(Statistics {
23                inner: Arc::new(InnerStat(ctx)),
24            }),
25        }
26    }
27
28    /// Returns the instruction count in execution.
29    pub fn instr_count(&self) -> u64 {
30        unsafe { ffi::WasmEdge_StatisticsGetInstrCount(self.inner.0) }
31    }
32
33    /// Returns the instruction count per second in execution.
34    ///
35    /// # Notice
36    ///
37    /// For the following cases,
38    /// * [Statistics] is not enabled, or
39    /// * the total execution time is 0
40    ///
41    /// The instructions per second could be `NaN`, which represents `divided-by-zero`.
42    /// Use the `is_nan` function of F64 to check the return value before use it,
43    /// for example,
44    ///
45    /// ```
46    /// use wasmedge_sys::Statistics;
47    ///
48    /// // create a Statistics instance
49    /// let stat = Statistics::create().expect("fail to create a Statistics");
50    ///
51    /// // check instruction count per second
52    /// assert!(stat.instr_per_sec().is_nan());
53    /// ```
54    pub fn instr_per_sec(&self) -> f64 {
55        unsafe { ffi::WasmEdge_StatisticsGetInstrPerSecond(self.inner.0) }
56    }
57
58    /// Returns the total cost in execution.
59    pub fn cost_in_total(&self) -> u64 {
60        unsafe { ffi::WasmEdge_StatisticsGetTotalCost(self.inner.0) }
61    }
62
63    /// Sets the cost of instructions.
64    ///
65    /// # Arguments
66    ///
67    /// * `cost_table` - The slice of cost table.
68    pub fn set_cost_table(&mut self, cost_table: impl AsRef<[u64]>) {
69        unsafe {
70            ffi::WasmEdge_StatisticsSetCostTable(
71                self.inner.0,
72                cost_table.as_ref().as_ptr() as *mut _,
73                cost_table.as_ref().len() as u32,
74            )
75        }
76    }
77
78    /// Sets the cost limit in execution.
79    ///
80    /// # Arguments
81    ///
82    /// * `limit` - The cost limit.
83    pub fn set_cost_limit(&mut self, limit: u64) {
84        unsafe { ffi::WasmEdge_StatisticsSetCostLimit(self.inner.0, limit) }
85    }
86
87    /// Clears the data in this statistics.
88    pub fn clear(&mut self) {
89        unsafe { ffi::WasmEdge_StatisticsClear(self.inner.0) }
90    }
91
92    /// Provides a raw pointer to the inner Statistics context.
93    #[cfg(feature = "ffi")]
94    #[cfg_attr(docsrs, doc(cfg(feature = "ffi")))]
95    pub fn as_ptr(&self) -> *const ffi::WasmEdge_StatisticsContext {
96        self.inner.0 as *const _
97    }
98}
99impl Drop for Statistics {
100    fn drop(&mut self) {
101        unsafe { ffi::WasmEdge_StatisticsDelete(self.inner.0) }
102    }
103}
104
105#[derive(Debug)]
106pub(crate) struct InnerStat(pub(crate) *mut ffi::WasmEdge_StatisticsContext);
107unsafe impl Send for InnerStat {}
108unsafe impl Sync for InnerStat {}