synchronization primitives #82
@ -14,7 +14,7 @@ let
|
|||||||
version = "0.1.0";
|
version = "0.1.0";
|
||||||
|
|
||||||
src = ./src;
|
src = ./src;
|
||||||
cargoSha256 = "0d9wbki0cnpv7b62hf0pgcqhqwc8iixzl48my0rc0l0djrnmqnw0";
|
cargoSha256 = "0da6smxhlq1z739g8pdhmkfiq7b8vjqapvskz58rzklh9scf2i99";
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
pkgs.gnumake
|
pkgs.gnumake
|
||||||
|
10
src/Cargo.lock
generated
10
src/Cargo.lock
generated
@ -201,7 +201,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/zc706.git#b65606f2d02fab273645835a102048b23c3394f7"
|
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#25c6d5eeaa6243724700e975e3935a5965c09a27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
"libcortex_a9",
|
"libcortex_a9",
|
||||||
@ -213,7 +213,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/zc706.git#b65606f2d02fab273645835a102048b23c3394f7"
|
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#25c6d5eeaa6243724700e975e3935a5965c09a27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
@ -237,7 +237,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/zc706.git#b65606f2d02fab273645835a102048b23c3394f7"
|
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#25c6d5eeaa6243724700e975e3935a5965c09a27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"libregister",
|
"libregister",
|
||||||
@ -252,7 +252,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/zc706.git#b65606f2d02fab273645835a102048b23c3394f7"
|
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#25c6d5eeaa6243724700e975e3935a5965c09a27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"vcell",
|
"vcell",
|
||||||
@ -262,7 +262,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/zc706.git#b65606f2d02fab273645835a102048b23c3394f7"
|
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#25c6d5eeaa6243724700e975e3935a5965c09a27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"libboard_zynq",
|
"libboard_zynq",
|
||||||
|
@ -18,7 +18,7 @@ use libboard_zynq::{
|
|||||||
},
|
},
|
||||||
timer::GlobalTimer,
|
timer::GlobalTimer,
|
||||||
};
|
};
|
||||||
use libcortex_a9::sync_channel;
|
use libcortex_a9::semaphore::Semaphore;
|
||||||
use futures::{select_biased, future::FutureExt};
|
use futures::{select_biased, future::FutureExt};
|
||||||
use libasync::{smoltcp::{Sockets, TcpStream}, task};
|
use libasync::{smoltcp::{Sockets, TcpStream}, task};
|
||||||
|
|
||||||
@ -353,30 +353,25 @@ pub fn main(timer: GlobalTimer, cfg: &config::Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
task::spawn(async move {
|
task::spawn(async move {
|
||||||
let (tx, rx) = sync_channel!(u32, 1);
|
let connection = Rc::new(Semaphore::new(1, 1));
|
||||||
let tx = RefCell::new(tx);
|
let terminate = Rc::new(Semaphore::new(0, 1));
|
||||||
let rx = Rc::new(RefCell::new(rx));
|
|
||||||
let has_connection = Rc::new(RefCell::new(false));
|
|
||||||
loop {
|
loop {
|
||||||
let stream = TcpStream::accept(1381, 2048, 2048).await.unwrap();
|
let stream = TcpStream::accept(1381, 2048, 2048).await.unwrap();
|
||||||
let has_connection = has_connection.clone();
|
|
||||||
|
|
||||||
if *has_connection.borrow() {
|
if connection.try_wait().is_none() {
|
||||||
let mut tx = tx.borrow_mut();
|
// there is an existing connection
|
||||||
tx.async_send(42).await;
|
terminate.signal();
|
||||||
// the second send is used to block until another connection received the abort
|
connection.async_wait().await;
|
||||||
// request.
|
|
||||||
tx.async_send(42).await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*has_connection.borrow_mut() = true;
|
|
||||||
let control = control.clone();
|
let control = control.clone();
|
||||||
let idle_kernel = idle_kernel.clone();
|
let idle_kernel = idle_kernel.clone();
|
||||||
let _ = rx.borrow_mut().try_recv();
|
let connection = connection.clone();
|
||||||
|
let terminate = terminate.clone();
|
||||||
|
|
||||||
let new_rx = rx.clone();
|
// we make sure the value of terminate is 0 before we start
|
||||||
|
let _ = terminate.try_wait();
|
||||||
task::spawn(async move {
|
task::spawn(async move {
|
||||||
let mut new_rx = new_rx.borrow_mut();
|
|
||||||
select_biased! {
|
select_biased! {
|
||||||
_ = (async {
|
_ = (async {
|
||||||
let _ = handle_connection(&stream, control.clone())
|
let _ = handle_connection(&stream, control.clone())
|
||||||
@ -392,14 +387,9 @@ pub fn main(timer: GlobalTimer, cfg: &config::Config) {
|
|||||||
info!("Idle kernel terminated");
|
info!("Idle kernel terminated");
|
||||||
}
|
}
|
||||||
}).fuse() => (),
|
}).fuse() => (),
|
||||||
_ = new_rx.async_recv().fuse() => ()
|
_ = terminate.async_wait().fuse() => ()
|
||||||
}
|
}
|
||||||
*has_connection.borrow_mut() = false;
|
connection.signal();
|
||||||
// it is possible that when `handle_connection` is terminating,
|
|
||||||
// another connection sent an abort request and get blocked,
|
|
||||||
// so we try_recv here to unblock in that case.
|
|
||||||
let _ = new_rx.try_recv();
|
|
||||||
core::mem::drop(new_rx);
|
|
||||||
let _ = stream.flush().await;
|
let _ = stream.flush().await;
|
||||||
let _ = stream.abort().await;
|
let _ = stream.abort().await;
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,7 @@ use libboard_zynq::{gic, mpcore, println, stdio};
|
|||||||
use libcortex_a9::{
|
use libcortex_a9::{
|
||||||
asm,
|
asm,
|
||||||
regs::{MPIDR, SP},
|
regs::{MPIDR, SP},
|
||||||
|
spin_lock_yield, notify_spin_lock
|
||||||
};
|
};
|
||||||
use libregister::{RegisterR, RegisterW};
|
use libregister::{RegisterR, RegisterW};
|
||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
@ -27,7 +28,7 @@ pub unsafe extern "C" fn IRQ() {
|
|||||||
SP.write(&mut __stack1_start as *mut _ as u32);
|
SP.write(&mut __stack1_start as *mut _ as u32);
|
||||||
asm::enable_irq();
|
asm::enable_irq();
|
||||||
CORE1_RESTART.store(false, Ordering::Relaxed);
|
CORE1_RESTART.store(false, Ordering::Relaxed);
|
||||||
asm::sev();
|
notify_spin_lock();
|
||||||
main_core1();
|
main_core1();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,6 +42,6 @@ pub fn restart_core1() {
|
|||||||
CORE1_RESTART.store(true, Ordering::Relaxed);
|
CORE1_RESTART.store(true, Ordering::Relaxed);
|
||||||
interrupt_controller.send_sgi(gic::InterruptId(0), gic::CPUCore::Core1.into());
|
interrupt_controller.send_sgi(gic::InterruptId(0), gic::CPUCore::Core1.into());
|
||||||
while CORE1_RESTART.load(Ordering::Relaxed) {
|
while CORE1_RESTART.load(Ordering::Relaxed) {
|
||||||
asm::wfe();
|
spin_lock_yield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user