78 lines
2.4 KiB
Rust
Raw Normal View History

2023-06-08 16:26:47 +01:00
//! Memory manager routines
2023-06-17 12:00:33 -05:00
use core::future::poll_fn;
2023-06-17 15:37:34 -05:00
use core::marker::PhantomData;
2023-06-17 12:00:33 -05:00
use core::task::Poll;
use cortex_m::interrupt;
use embassy_stm32::ipcc::Ipcc;
2023-06-17 12:00:33 -05:00
use embassy_sync::waitqueue::AtomicWaker;
use crate::evt::EvtPacket;
use crate::tables::MemManagerTable;
use crate::unsafe_linked_list::LinkedListNode;
use crate::{
channels, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUF_QUEUE, LOCAL_FREE_BUF_QUEUE, POOL_SIZE, SYS_SPARE_EVT_BUF,
TL_MEM_MANAGER_TABLE,
};
2023-06-17 12:00:33 -05:00
static MM_WAKER: AtomicWaker = AtomicWaker::new();
2023-06-17 15:37:34 -05:00
pub struct MemoryManager {
phantom: PhantomData<MemoryManager>,
}
impl MemoryManager {
2023-06-17 15:37:34 -05:00
pub(crate) fn new() -> Self {
unsafe {
2023-06-08 16:26:47 +01:00
LinkedListNode::init_head(FREE_BUF_QUEUE.as_mut_ptr());
2023-05-20 10:11:29 -05:00
LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr());
2023-06-13 17:12:34 -05:00
TL_MEM_MANAGER_TABLE.as_mut_ptr().write_volatile(MemManagerTable {
spare_ble_buffer: BLE_SPARE_EVT_BUF.as_ptr().cast(),
spare_sys_buffer: SYS_SPARE_EVT_BUF.as_ptr().cast(),
2023-06-08 16:26:47 +01:00
blepool: EVT_POOL.as_ptr().cast(),
blepoolsize: POOL_SIZE as u32,
pevt_free_buffer_queue: FREE_BUF_QUEUE.as_mut_ptr(),
traces_evt_pool: core::ptr::null(),
2023-06-08 16:26:47 +01:00
tracespoolsize: 0,
});
}
2023-06-17 15:37:34 -05:00
Self { phantom: PhantomData }
2023-05-15 10:25:02 +01:00
}
2023-06-17 12:00:33 -05:00
/// SAFETY: passing a pointer to something other than an event packet is UB
2023-06-17 15:37:34 -05:00
pub(crate) unsafe fn drop_event_packet(evt: *mut EvtPacket) {
2023-06-17 12:00:33 -05:00
interrupt::free(|_| unsafe {
LinkedListNode::insert_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), evt as *mut _);
});
2023-05-15 10:25:02 +01:00
2023-06-17 12:00:33 -05:00
MM_WAKER.wake();
2023-05-15 10:25:02 +01:00
}
2023-06-08 16:26:47 +01:00
2023-06-17 15:37:34 -05:00
pub async fn run_queue(&self) {
2023-06-17 12:00:33 -05:00
loop {
poll_fn(|cx| unsafe {
MM_WAKER.register(cx.waker());
if LinkedListNode::is_empty(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) {
Poll::Pending
} else {
Poll::Ready(())
}
})
.await;
Ipcc::send(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, || {
interrupt::free(|_| unsafe {
// CS required while moving nodes
while let Some(node_ptr) = LinkedListNode::remove_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) {
LinkedListNode::insert_head(FREE_BUF_QUEUE.as_mut_ptr(), node_ptr);
}
})
})
.await;
}
2023-06-08 16:26:47 +01:00
}
}