embedded_shadow/shadow/
host.rs

1#![allow(unsafe_code)]
2
3use crate::{
4    AccessPolicy, HostView, PersistTrigger,
5    policy::PersistPolicy,
6    storage::{NoStage, ShadowStorageBase, WithStage},
7    types::StagingBuffer,
8    view::HostViewStaged,
9};
10
11pub struct HostShadow<'a, const TS: usize, const BS: usize, const BC: usize, AP, PP, PT, PK, SS>
12where
13    AP: AccessPolicy,
14    PP: PersistPolicy<PK>,
15    PT: PersistTrigger<PK>,
16    bitmaps::BitsImpl<BC>: bitmaps::Bits,
17{
18    storage: &'a ShadowStorageBase<TS, BS, BC, AP, PP, PT, PK, SS>,
19}
20
21impl<'a, const TS: usize, const BS: usize, const BC: usize, AP, PP, PT, PK, SS>
22    HostShadow<'a, TS, BS, BC, AP, PP, PT, PK, SS>
23where
24    AP: AccessPolicy,
25    PP: PersistPolicy<PK>,
26    PT: PersistTrigger<PK>,
27    bitmaps::BitsImpl<BC>: bitmaps::Bits,
28{
29    pub(crate) fn new(storage: &'a ShadowStorageBase<TS, BS, BC, AP, PP, PT, PK, SS>) -> Self {
30        Self { storage }
31    }
32}
33
34impl<'a, const TS: usize, const BS: usize, const BC: usize, AP, PP, PT, PK>
35    HostShadow<'a, TS, BS, BC, AP, PP, PT, PK, NoStage>
36where
37    AP: AccessPolicy,
38    PP: PersistPolicy<PK>,
39    PT: PersistTrigger<PK>,
40    bitmaps::BitsImpl<BC>: bitmaps::Bits,
41{
42    pub fn with_view<R>(
43        &self,
44        f: impl FnOnce(&mut HostView<TS, BS, BC, AP, PP, PT, PK>) -> R,
45    ) -> R {
46        critical_section::with(|_| unsafe { self.with_view_unchecked(f) })
47    }
48
49    /// # Safety
50    /// This function is unsafe because it requires exclusive access to the shadow's storage.
51    /// However, if you can guarantee that the shadow's storage is not being accessed by any
52    /// other domains such as ISR or other threads you can safely call this function.
53    pub unsafe fn with_view_unchecked<R>(
54        &self,
55        f: impl FnOnce(&mut HostView<TS, BS, BC, AP, PP, PT, PK>) -> R,
56    ) -> R {
57        let table = unsafe { &mut *self.storage.table.get() };
58        let persist_trigger = unsafe { &mut *self.storage.persist_trigger.get() };
59        let access_policy = &self.storage.access_policy;
60        let persist_policy = &self.storage.persist_policy;
61        let mut view = HostView::new(table, access_policy, persist_policy, persist_trigger);
62        f(&mut view)
63    }
64}
65
66impl<'a, const TS: usize, const BS: usize, const BC: usize, AP, PP, PT, PK, SB>
67    HostShadow<'a, TS, BS, BC, AP, PP, PT, PK, WithStage<SB>>
68where
69    AP: AccessPolicy,
70    PP: PersistPolicy<PK>,
71    PT: PersistTrigger<PK>,
72    bitmaps::BitsImpl<BC>: bitmaps::Bits,
73    SB: StagingBuffer,
74{
75    pub fn with_view<R>(
76        &self,
77        f: impl FnOnce(&mut HostViewStaged<TS, BS, BC, AP, PP, PT, PK, SB>) -> R,
78    ) -> R {
79        critical_section::with(|_| unsafe { self.with_view_unchecked(f) })
80    }
81
82    /// # Safety
83    /// This function is unsafe because it requires exclusive access to the shadow's storage.
84    /// However, if you can guarantee that the shadow's storage is not being accessed by any
85    /// other domains such as ISR or other threads you can safely call this function.
86    pub unsafe fn with_view_unchecked<R>(
87        &self,
88        f: impl FnOnce(&mut HostViewStaged<TS, BS, BC, AP, PP, PT, PK, SB>) -> R,
89    ) -> R {
90        let table = unsafe { &mut *self.storage.table.get() };
91        let stage = unsafe { &mut *self.storage.stage_state.get() };
92        let persist_trigger = unsafe { &mut *self.storage.persist_trigger.get() };
93        let access_policy = &self.storage.access_policy;
94        let persist_policy = &self.storage.persist_policy;
95        let base = HostView::new(table, access_policy, persist_policy, persist_trigger);
96        let mut view = HostViewStaged::new(base, &mut stage.sb);
97        f(&mut view)
98    }
99}