runtime: optimize for speed and fix deadlock

The previous method of taking the channel could cause deadlock, we now
use semaphore to signal if the channel is available instead of busy
polling the mutex.
This commit is contained in:
pca006132 2020-09-01 09:44:34 +08:00 committed by Gitea
parent fc285fcd13
commit ae07c05db4
5 changed files with 12 additions and 8 deletions

10
src/Cargo.lock generated
View File

@ -187,7 +187,7 @@ dependencies = [
[[package]] [[package]]
name = "libasync" name = "libasync"
version = "0.0.0" version = "0.0.0"
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#a73df780d0d0e757738f27feac162904f5bf93f9" source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#157439bc88cbb18bb40009428acf1fdee800e32e"
dependencies = [ dependencies = [
"embedded-hal", "embedded-hal",
"libcortex_a9", "libcortex_a9",
@ -199,7 +199,7 @@ dependencies = [
[[package]] [[package]]
name = "libboard_zynq" name = "libboard_zynq"
version = "0.0.0" version = "0.0.0"
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#a73df780d0d0e757738f27feac162904f5bf93f9" source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#157439bc88cbb18bb40009428acf1fdee800e32e"
dependencies = [ dependencies = [
"bit_field", "bit_field",
"embedded-hal", "embedded-hal",
@ -233,7 +233,7 @@ dependencies = [
[[package]] [[package]]
name = "libcortex_a9" name = "libcortex_a9"
version = "0.0.0" version = "0.0.0"
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#a73df780d0d0e757738f27feac162904f5bf93f9" source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#157439bc88cbb18bb40009428acf1fdee800e32e"
dependencies = [ dependencies = [
"bit_field", "bit_field",
"libregister", "libregister",
@ -249,7 +249,7 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
[[package]] [[package]]
name = "libregister" name = "libregister"
version = "0.0.0" version = "0.0.0"
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#a73df780d0d0e757738f27feac162904f5bf93f9" source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#157439bc88cbb18bb40009428acf1fdee800e32e"
dependencies = [ dependencies = [
"bit_field", "bit_field",
"vcell", "vcell",
@ -259,7 +259,7 @@ dependencies = [
[[package]] [[package]]
name = "libsupport_zynq" name = "libsupport_zynq"
version = "0.0.0" version = "0.0.0"
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#a73df780d0d0e757738f27feac162904f5bf93f9" source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#157439bc88cbb18bb40009428acf1fdee800e32e"
dependencies = [ dependencies = [
"compiler_builtins", "compiler_builtins",
"libboard_zynq", "libboard_zynq",

View File

@ -24,7 +24,7 @@ overflow-checks = false
panic = "abort" panic = "abort"
debug = true debug = true
codegen-units = 1 codegen-units = 1
opt-level = 's' opt-level = 2
lto = true lto = true
[patch.crates-io] [patch.crates-io]

View File

@ -1,7 +1,7 @@
use libcortex_a9::sync_channel::{Sender, Receiver}; use libcortex_a9::sync_channel::{Sender, Receiver};
use libsupport_zynq::boot::Core1; use libsupport_zynq::boot::Core1;
use super::{CHANNEL_0TO1, CHANNEL_1TO0, INIT_LOCK, Message}; use super::{CHANNEL_0TO1, CHANNEL_1TO0, CHANNEL_SEM, INIT_LOCK, Message};
use crate::irq::restart_core1; use crate::irq::restart_core1;
use core::mem::{forget, replace}; use core::mem::{forget, replace};
@ -12,6 +12,7 @@ pub struct Control {
} }
fn get_channels() -> (Sender<'static, Message>, Receiver<'static, Message>) { fn get_channels() -> (Sender<'static, Message>, Receiver<'static, Message>) {
CHANNEL_SEM.wait();
let mut core0_tx = None; let mut core0_tx = None;
while core0_tx.is_none() { while core0_tx.is_none() {
core0_tx = CHANNEL_0TO1.lock().take(); core0_tx = CHANNEL_0TO1.lock().take();

View File

@ -20,6 +20,7 @@ use super::{
rpc::rpc_send_async, rpc::rpc_send_async,
INIT_LOCK, INIT_LOCK,
CHANNEL_0TO1, CHANNEL_1TO0, CHANNEL_0TO1, CHANNEL_1TO0,
CHANNEL_SEM,
KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0,
KERNEL_IMAGE, KERNEL_IMAGE,
Message, Message,
@ -159,6 +160,7 @@ pub fn main_core1() {
} }
*CHANNEL_0TO1.lock() = Some(core0_tx); *CHANNEL_0TO1.lock() = Some(core0_tx);
*CHANNEL_1TO0.lock() = Some(core0_rx); *CHANNEL_1TO0.lock() = Some(core0_rx);
CHANNEL_SEM.signal();
// set on load, cleared on start // set on load, cleared on start
let mut loaded_kernel = None; let mut loaded_kernel = None;

View File

@ -1,7 +1,7 @@
use core::ptr; use core::ptr;
use alloc::{vec::Vec, string::String}; use alloc::{vec::Vec, string::String};
use libcortex_a9::{mutex::Mutex, sync_channel}; use libcortex_a9::{mutex::Mutex, sync_channel, semaphore::Semaphore};
use crate::eh_artiq; use crate::eh_artiq;
mod control; mod control;
@ -48,6 +48,7 @@ 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 CHANNEL_SEM: Semaphore = Semaphore::new(0, 1);
static mut KERNEL_CHANNEL_0TO1: Option<sync_channel::Receiver<'static, Message>> = None; static mut KERNEL_CHANNEL_0TO1: Option<sync_channel::Receiver<'static, Message>> = None;
static mut KERNEL_CHANNEL_1TO0: Option<sync_channel::Sender<'static, Message>> = None; static mut KERNEL_CHANNEL_1TO0: Option<sync_channel::Sender<'static, Message>> = None;