forked from M-Labs/artiq-zynq
runtime/kernel: use mutable static for shared channel
Mutex would prevent restart if we failed while waiting for RPC.
This commit is contained in:
parent
e592efb2b8
commit
fa187fb37a
|
@ -5,10 +5,11 @@ use super::{KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, Message};
|
||||||
|
|
||||||
pub extern fn get(key: CSlice<u8>) -> CSlice<'static, i32> {
|
pub extern fn get(key: CSlice<u8>) -> CSlice<'static, i32> {
|
||||||
let key = String::from_utf8(key.as_ref().to_vec()).unwrap();
|
let key = String::from_utf8(key.as_ref().to_vec()).unwrap();
|
||||||
KERNEL_CHANNEL_1TO0.lock().as_mut().unwrap().send(Message::CacheGetRequest(key));
|
unsafe {
|
||||||
let msg = KERNEL_CHANNEL_0TO1.lock().as_mut().unwrap().recv();
|
KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::CacheGetRequest(key));
|
||||||
|
let msg = KERNEL_CHANNEL_0TO1.as_mut().unwrap().recv();
|
||||||
if let Message::CacheGetReply(v) = msg {
|
if let Message::CacheGetReply(v) = msg {
|
||||||
let slice = unsafe { transmute(v.as_c_slice()) };
|
let slice = transmute(v.as_c_slice());
|
||||||
// we intentionally leak the memory here,
|
// we intentionally leak the memory here,
|
||||||
// which does not matter as core1 would restart
|
// which does not matter as core1 would restart
|
||||||
forget(v);
|
forget(v);
|
||||||
|
@ -17,10 +18,13 @@ pub extern fn get(key: CSlice<u8>) -> CSlice<'static, i32> {
|
||||||
panic!("Expected CacheGetReply for CacheGetRequest");
|
panic!("Expected CacheGetReply for CacheGetRequest");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub extern fn put(key: CSlice<u8>, list: CSlice<i32>) {
|
pub extern fn put(key: CSlice<u8>, list: CSlice<i32>) {
|
||||||
let key = String::from_utf8(key.as_ref().to_vec()).unwrap();
|
let key = String::from_utf8(key.as_ref().to_vec()).unwrap();
|
||||||
let value = list.as_ref().to_vec();
|
let value = list.as_ref().to_vec();
|
||||||
KERNEL_CHANNEL_1TO0.lock().as_mut().unwrap().send(Message::CachePutRequest(key, value));
|
unsafe {
|
||||||
|
KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::CachePutRequest(key, value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,15 +179,15 @@ pub fn main_core1() {
|
||||||
Message::StartRequest => {
|
Message::StartRequest => {
|
||||||
info!("kernel starting");
|
info!("kernel starting");
|
||||||
if let Some(kernel) = loaded_kernel.take() {
|
if let Some(kernel) = loaded_kernel.take() {
|
||||||
*KERNEL_CHANNEL_0TO1.lock() = Some(core1_rx);
|
|
||||||
*KERNEL_CHANNEL_1TO0.lock() = Some(core1_tx);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
KERNEL_CHANNEL_0TO1 = Some(core1_rx);
|
||||||
|
KERNEL_CHANNEL_1TO0 = Some(core1_tx);
|
||||||
KERNEL_IMAGE = &kernel as *const KernelImage;
|
KERNEL_IMAGE = &kernel as *const KernelImage;
|
||||||
kernel.exec();
|
kernel.exec();
|
||||||
KERNEL_IMAGE = ptr::null();
|
KERNEL_IMAGE = ptr::null();
|
||||||
|
core1_rx = KERNEL_CHANNEL_0TO1.take().unwrap();
|
||||||
|
core1_tx = KERNEL_CHANNEL_1TO0.take().unwrap();
|
||||||
}
|
}
|
||||||
core1_rx = core::mem::replace(&mut *KERNEL_CHANNEL_0TO1.lock(), None).unwrap();
|
|
||||||
core1_tx = core::mem::replace(&mut *KERNEL_CHANNEL_1TO0.lock(), None).unwrap();
|
|
||||||
}
|
}
|
||||||
info!("kernel finished");
|
info!("kernel finished");
|
||||||
core1_tx.send(Message::KernelFinished);
|
core1_tx.send(Message::KernelFinished);
|
||||||
|
@ -213,8 +213,8 @@ pub fn terminate(exception: &'static eh_artiq::Exception<'static>, backtrace: &'
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut core1_tx = KERNEL_CHANNEL_1TO0.lock();
|
let core1_tx = unsafe { KERNEL_CHANNEL_1TO0.as_mut().unwrap() };
|
||||||
core1_tx.as_mut().unwrap().send(Message::KernelException(exception, &backtrace[..cursor]));
|
core1_tx.send(Message::KernelException(exception, &backtrace[..cursor]));
|
||||||
}
|
}
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,9 @@ pub unsafe fn init_dma_recorder() {
|
||||||
|
|
||||||
pub extern fn dma_record_start(name: CSlice<u8>) {
|
pub extern fn dma_record_start(name: CSlice<u8>) {
|
||||||
let name = String::from_utf8(name.as_ref().to_vec()).unwrap();
|
let name = String::from_utf8(name.as_ref().to_vec()).unwrap();
|
||||||
KERNEL_CHANNEL_1TO0.lock().as_mut().unwrap().send(Message::DmaEraseRequest(name.clone()));
|
unsafe {
|
||||||
|
KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::DmaEraseRequest(name.clone()));
|
||||||
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
if RECORDER.is_some() {
|
if RECORDER.is_some() {
|
||||||
artiq_raise!("DMAError", "DMA is already recording")
|
artiq_raise!("DMAError", "DMA is already recording")
|
||||||
|
@ -70,7 +72,7 @@ pub extern fn dma_record_stop(duration: i64) {
|
||||||
|
|
||||||
let mut recorder = RECORDER.take().unwrap();
|
let mut recorder = RECORDER.take().unwrap();
|
||||||
recorder.duration = duration;
|
recorder.duration = duration;
|
||||||
KERNEL_CHANNEL_1TO0.lock().as_mut().unwrap().send(
|
KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(
|
||||||
Message::DmaPutRequest(recorder)
|
Message::DmaPutRequest(recorder)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -135,13 +137,17 @@ pub extern fn dma_record_output_wide(target: i32, words: CSlice<i32>) {
|
||||||
|
|
||||||
pub extern fn dma_erase(name: CSlice<u8>) {
|
pub extern fn dma_erase(name: CSlice<u8>) {
|
||||||
let name = String::from_utf8(name.as_ref().to_vec()).unwrap();
|
let name = String::from_utf8(name.as_ref().to_vec()).unwrap();
|
||||||
KERNEL_CHANNEL_1TO0.lock().as_mut().unwrap().send(Message::DmaEraseRequest(name));
|
unsafe {
|
||||||
|
KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::DmaEraseRequest(name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn dma_retrieve(name: CSlice<u8>) -> DmaTrace {
|
pub extern fn dma_retrieve(name: CSlice<u8>) -> DmaTrace {
|
||||||
let name = String::from_utf8(name.as_ref().to_vec()).unwrap();
|
let name = String::from_utf8(name.as_ref().to_vec()).unwrap();
|
||||||
KERNEL_CHANNEL_1TO0.lock().as_mut().unwrap().send(Message::DmaGetRequest(name));
|
unsafe {
|
||||||
match KERNEL_CHANNEL_0TO1.lock().as_mut().unwrap().recv() {
|
KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::DmaGetRequest(name));
|
||||||
|
}
|
||||||
|
match unsafe {KERNEL_CHANNEL_0TO1.as_mut().unwrap()}.recv() {
|
||||||
Message::DmaGetReply(None) => (),
|
Message::DmaGetReply(None) => (),
|
||||||
Message::DmaGetReply(Some((mut v, duration))) => {
|
Message::DmaGetReply(Some((mut v, duration))) => {
|
||||||
v.reserve(ALIGNMENT - 1);
|
v.reserve(ALIGNMENT - 1);
|
||||||
|
|
|
@ -49,8 +49,8 @@ pub enum Message {
|
||||||
static CHANNEL_0TO1: Mutex<Option<sync_channel::Sender<'static, Message>>> = Mutex::new(None);
|
static CHANNEL_0TO1: Mutex<Option<sync_channel::Sender<'static, Message>>> = Mutex::new(None);
|
||||||
static CHANNEL_1TO0: Mutex<Option<sync_channel::Receiver<'static, Message>>> = Mutex::new(None);
|
static CHANNEL_1TO0: Mutex<Option<sync_channel::Receiver<'static, Message>>> = Mutex::new(None);
|
||||||
|
|
||||||
static KERNEL_CHANNEL_0TO1: Mutex<Option<sync_channel::Receiver<'static, Message>>> = Mutex::new(None);
|
static mut KERNEL_CHANNEL_0TO1: Option<sync_channel::Receiver<'static, Message>> = None;
|
||||||
static KERNEL_CHANNEL_1TO0: Mutex<Option<sync_channel::Sender<'static, Message>>> = Mutex::new(None);
|
static mut KERNEL_CHANNEL_1TO0: Option<sync_channel::Sender<'static, Message>> = None;
|
||||||
|
|
||||||
static mut KERNEL_IMAGE: *const core1::KernelImage = ptr::null();
|
static mut KERNEL_IMAGE: *const core1::KernelImage = ptr::null();
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,10 @@ use super::{
|
||||||
};
|
};
|
||||||
|
|
||||||
fn rpc_send_common(is_async: bool, service: u32, tag: &CSlice<u8>, data: *const *const ()) {
|
fn rpc_send_common(is_async: bool, service: u32, tag: &CSlice<u8>, data: *const *const ()) {
|
||||||
let mut core1_tx = KERNEL_CHANNEL_1TO0.lock();
|
let core1_tx = unsafe { KERNEL_CHANNEL_1TO0.as_mut().unwrap() };
|
||||||
let mut buffer = Vec::<u8>::new();
|
let mut buffer = Vec::<u8>::new();
|
||||||
send_args(&mut buffer, service, tag.as_ref(), data).expect("RPC encoding failed");
|
send_args(&mut buffer, service, tag.as_ref(), data).expect("RPC encoding failed");
|
||||||
core1_tx.as_mut().unwrap().send(Message::RpcSend { is_async, data: buffer });
|
core1_tx.send(Message::RpcSend { is_async, data: buffer });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn rpc_send(service: u32, tag: &CSlice<u8>, data: *const *const ()) {
|
pub extern fn rpc_send(service: u32, tag: &CSlice<u8>, data: *const *const ()) {
|
||||||
|
@ -26,11 +26,11 @@ pub extern fn rpc_send_async(service: u32, tag: &CSlice<u8>, data: *const *const
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn rpc_recv(slot: *mut ()) -> usize {
|
pub extern fn rpc_recv(slot: *mut ()) -> usize {
|
||||||
let reply = {
|
let reply = unsafe {
|
||||||
let mut core1_rx = KERNEL_CHANNEL_0TO1.lock();
|
let core1_rx = KERNEL_CHANNEL_0TO1.as_mut().unwrap();
|
||||||
let mut core1_tx = KERNEL_CHANNEL_1TO0.lock();
|
let core1_tx = KERNEL_CHANNEL_1TO0.as_mut().unwrap();
|
||||||
core1_tx.as_mut().unwrap().send(Message::RpcRecvRequest(slot));
|
core1_tx.send(Message::RpcRecvRequest(slot));
|
||||||
core1_rx.as_mut().unwrap().recv()
|
core1_rx.recv()
|
||||||
};
|
};
|
||||||
match reply {
|
match reply {
|
||||||
Message::RpcRecvReply(Ok(alloc_size)) => alloc_size,
|
Message::RpcRecvReply(Ok(alloc_size)) => alloc_size,
|
||||||
|
|
Loading…
Reference in New Issue