forked from M-Labs/artiq-zynq
implement core device cache
This commit is contained in:
parent
673ad3fd8e
commit
7f983a453d
@ -12,6 +12,11 @@ device_db = {
|
||||
"target": "cortexa9"
|
||||
}
|
||||
},
|
||||
"core_cache": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.cache",
|
||||
"class": "CoreCache"
|
||||
},
|
||||
"core_dma": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.dma",
|
||||
|
@ -4,6 +4,7 @@ use crate::eh_artiq;
|
||||
use crate::rtio;
|
||||
use super::rpc::{rpc_send, rpc_send_async, rpc_recv};
|
||||
use super::dma;
|
||||
use super::cache;
|
||||
|
||||
macro_rules! api {
|
||||
($i:ident) => ({
|
||||
@ -58,6 +59,10 @@ pub fn resolve(required: &[u8]) -> Option<u32> {
|
||||
api!(dma_retrieve = dma::dma_retrieve),
|
||||
api!(dma_playback = dma::dma_playback),
|
||||
|
||||
// cache
|
||||
api!(cache_get = cache::get),
|
||||
api!(cache_put = cache::put),
|
||||
|
||||
// Double-precision floating-point arithmetic helper functions
|
||||
// RTABI chapter 4.1.2, Table 2
|
||||
api!(__aeabi_dadd),
|
||||
|
79
src/runtime/src/kernel/cache.rs
Normal file
79
src/runtime/src/kernel/cache.rs
Normal file
@ -0,0 +1,79 @@
|
||||
use alloc::{string::String, vec::Vec, collections::BTreeMap};
|
||||
use libcortex_a9::mutex::Mutex;
|
||||
use cslice::{CSlice, AsCSlice};
|
||||
use core::mem::transmute;
|
||||
use core::str;
|
||||
use log::debug;
|
||||
|
||||
use crate::artiq_raise;
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Entry {
|
||||
data: Vec<i32>,
|
||||
borrowed: bool
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Cache {
|
||||
entries: BTreeMap<String, Entry>
|
||||
}
|
||||
|
||||
impl Cache {
|
||||
pub const fn new() -> Cache {
|
||||
Cache { entries: BTreeMap::new() }
|
||||
}
|
||||
|
||||
pub fn get(&mut self, key: &str) -> *const [i32] {
|
||||
match self.entries.get_mut(key) {
|
||||
None => &[],
|
||||
Some(ref mut entry) => {
|
||||
entry.borrowed = true;
|
||||
&entry.data[..]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn put(&mut self, key: &str, data: &[i32]) -> Result<(), ()> {
|
||||
match self.entries.get_mut(key) {
|
||||
None => (),
|
||||
Some(ref mut entry) => {
|
||||
if entry.borrowed { return Err(()) }
|
||||
entry.data = Vec::from(data);
|
||||
return Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
self.entries.insert(String::from(key), Entry {
|
||||
data: Vec::from(data),
|
||||
borrowed: false
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub unsafe fn unborrow(&mut self) {
|
||||
for (_key, entry) in self.entries.iter_mut() {
|
||||
entry.borrowed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static CACHE: Mutex<Cache> = Mutex::new(Cache::new());
|
||||
|
||||
pub extern fn get(key: CSlice<u8>) -> CSlice<'static, i32> {
|
||||
let value = CACHE.lock().get(str::from_utf8(key.as_ref()).unwrap());
|
||||
unsafe {
|
||||
transmute::<*const [i32], &'static [i32]>(value).as_c_slice()
|
||||
}
|
||||
}
|
||||
|
||||
pub extern fn put(key: CSlice<u8>, list: CSlice<i32>) {
|
||||
let result = CACHE.lock().put(str::from_utf8(key.as_ref()).unwrap(), list.as_ref());
|
||||
if result.is_err() {
|
||||
artiq_raise!("CacheError", "cannot put into a busy cache row");
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn unborrow() {
|
||||
CACHE.lock().unborrow();
|
||||
}
|
@ -19,6 +19,7 @@ use super::{
|
||||
KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0,
|
||||
KERNEL_IMAGE,
|
||||
Message,
|
||||
cache
|
||||
};
|
||||
|
||||
unsafe fn attribute_writeback(typeinfo: *const ()) {
|
||||
@ -170,6 +171,7 @@ pub fn main_core1() {
|
||||
core1_rx = core::mem::replace(&mut *KERNEL_CHANNEL_0TO1.lock(), None).unwrap();
|
||||
core1_tx = core::mem::replace(&mut *KERNEL_CHANNEL_1TO0.lock(), None).unwrap();
|
||||
}
|
||||
unsafe { cache::unborrow(); }
|
||||
info!("kernel finished");
|
||||
core1_tx.send(Message::KernelFinished);
|
||||
}
|
||||
@ -180,6 +182,8 @@ pub fn main_core1() {
|
||||
|
||||
/// Called by eh_artiq
|
||||
pub fn terminate(exception: &'static eh_artiq::Exception<'static>, backtrace: &'static mut [usize]) -> ! {
|
||||
unsafe { cache::unborrow(); }
|
||||
|
||||
let load_addr = unsafe {
|
||||
KERNEL_IMAGE.as_ref().unwrap().get_load_addr()
|
||||
};
|
||||
|
@ -10,6 +10,7 @@ pub mod core1;
|
||||
mod api;
|
||||
mod rpc;
|
||||
mod dma;
|
||||
mod cache;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RPCException {
|
||||
|
Loading…
Reference in New Issue
Block a user