Skip to content

Commit 0324aee

Browse files
committed
feat: use async-executor
1 parent fad68d8 commit 0324aee

File tree

6 files changed

+97
-33
lines changed

6 files changed

+97
-33
lines changed

Cargo.lock

Lines changed: 64 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ virtio = { package = "virtio-spec", version = "0.3", optional = true, features =
110110
ahash = { version = "0.8", default-features = false }
111111
align-address = "0.3"
112112
anstyle = { version = "1", default-features = false }
113+
async-executor = { git = "https://github.com/hermit-os/async-executor.git", branch = "no_std", default-features = false, features = ["static"] }
113114
async-lock = { version = "3.4.1", default-features = false }
114115
async-trait = "0.1.86"
115116
bit_field = "0.10"

src/arch/aarch64/kernel/core_local.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
use alloc::boxed::Box;
2-
use alloc::collections::vec_deque::VecDeque;
32
use core::arch::asm;
4-
use core::cell::{Cell, RefCell, RefMut};
3+
use core::cell::Cell;
54
use core::ptr;
65
use core::sync::atomic::Ordering;
76

7+
use async_executor::StaticExecutor;
88
#[cfg(feature = "smp")]
99
use hermit_sync::InterruptTicketMutex;
10+
use hermit_sync::{RawRwSpinLock, RawSpinMutex};
1011

1112
use super::CPU_ONLINE;
1213
use super::interrupts::{IRQ_COUNTERS, IrqStatistics};
13-
use crate::executor::task::AsyncTask;
1414
#[cfg(feature = "smp")]
1515
use crate::scheduler::SchedulerInput;
1616
use crate::scheduler::{CoreId, PerCoreScheduler};
@@ -23,8 +23,8 @@ pub(crate) struct CoreLocal {
2323
scheduler: Cell<*mut PerCoreScheduler>,
2424
/// Interface to the interrupt counters
2525
irq_statistics: &'static IrqStatistics,
26-
/// Queue of async tasks
27-
async_tasks: RefCell<VecDeque<AsyncTask>>,
26+
/// The core-local async executor.
27+
ex: StaticExecutor<RawSpinMutex, RawRwSpinLock>,
2828
/// Queues to handle incoming requests from the other cores
2929
#[cfg(feature = "smp")]
3030
pub scheduler_input: InterruptTicketMutex<SchedulerInput>,
@@ -46,7 +46,7 @@ impl CoreLocal {
4646
core_id,
4747
scheduler: Cell::new(ptr::null_mut()),
4848
irq_statistics,
49-
async_tasks: RefCell::new(VecDeque::new()),
49+
ex: StaticExecutor::new(),
5050
#[cfg(feature = "smp")]
5151
scheduler_input: InterruptTicketMutex::new(SchedulerInput::new()),
5252
};
@@ -96,8 +96,8 @@ pub(crate) fn core_scheduler() -> &'static mut PerCoreScheduler {
9696
unsafe { CoreLocal::get().scheduler.get().as_mut().unwrap() }
9797
}
9898

99-
pub(crate) fn async_tasks() -> RefMut<'static, VecDeque<AsyncTask>> {
100-
CoreLocal::get().async_tasks.borrow_mut()
99+
pub(crate) fn ex() -> &'static StaticExecutor<RawSpinMutex, RawRwSpinLock> {
100+
&CoreLocal::get().ex
101101
}
102102

103103
pub(crate) fn set_core_scheduler(scheduler: *mut PerCoreScheduler) {

src/arch/riscv64/kernel/core_local.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use alloc::boxed::Box;
2-
use alloc::collections::vec_deque::VecDeque;
32
use core::arch::asm;
4-
use core::cell::{Cell, RefCell, RefMut};
3+
use core::cell::Cell;
54
use core::ptr;
65
use core::sync::atomic::Ordering;
76

7+
use async_executor::StaticExecutor;
88
#[cfg(feature = "smp")]
99
use hermit_sync::InterruptTicketMutex;
10+
use hermit_sync::{RawRwSpinLock, RawSpinMutex};
1011

1112
use crate::arch::riscv64::kernel::CPU_ONLINE;
12-
use crate::executor::task::AsyncTask;
1313
#[cfg(feature = "smp")]
1414
use crate::scheduler::SchedulerInput;
1515
use crate::scheduler::{CoreId, PerCoreScheduler};
@@ -21,8 +21,8 @@ pub struct CoreLocal {
2121
scheduler: Cell<*mut PerCoreScheduler>,
2222
/// start address of the kernel stack
2323
pub kernel_stack: Cell<u64>,
24-
/// Queue of async tasks
25-
async_tasks: RefCell<VecDeque<AsyncTask>>,
24+
/// The core-local async executor.
25+
ex: StaticExecutor<RawSpinMutex, RawRwSpinLock>,
2626
/// Queues to handle incoming requests from the other cores
2727
#[cfg(feature = "smp")]
2828
pub scheduler_input: InterruptTicketMutex<SchedulerInput>,
@@ -41,7 +41,7 @@ impl CoreLocal {
4141
core_id,
4242
scheduler: Cell::new(ptr::null_mut()),
4343
kernel_stack: Cell::new(0),
44-
async_tasks: RefCell::new(VecDeque::new()),
44+
ex: StaticExecutor::new(),
4545
#[cfg(feature = "smp")]
4646
scheduler_input: InterruptTicketMutex::new(SchedulerInput::new()),
4747
};
@@ -84,6 +84,6 @@ pub fn set_core_scheduler(scheduler: *mut PerCoreScheduler) {
8484
CoreLocal::get().scheduler.set(scheduler);
8585
}
8686

87-
pub(crate) fn async_tasks() -> RefMut<'static, VecDeque<AsyncTask>> {
88-
CoreLocal::get().async_tasks.borrow_mut()
87+
pub(crate) fn ex() -> &'static StaticExecutor<RawSpinMutex, RawRwSpinLock> {
88+
&CoreLocal::get().ex
8989
}

src/arch/x86_64/kernel/core_local.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
use alloc::boxed::Box;
2-
use alloc::collections::vec_deque::VecDeque;
32
use core::arch::asm;
4-
use core::cell::{Cell, RefCell, RefMut};
3+
use core::cell::Cell;
54
#[cfg(feature = "smp")]
65
use core::sync::atomic::AtomicBool;
76
use core::sync::atomic::Ordering;
87
use core::{mem, ptr};
98

9+
use async_executor::StaticExecutor;
1010
#[cfg(feature = "smp")]
1111
use hermit_sync::InterruptTicketMutex;
12+
use hermit_sync::{RawRwSpinLock, RawSpinMutex};
1213
use x86_64::VirtAddr;
1314
use x86_64::registers::model_specific::GsBase;
1415
use x86_64::structures::tss::TaskStateSegment;
1516

1617
use super::CPU_ONLINE;
1718
use super::interrupts::{IRQ_COUNTERS, IrqStatistics};
18-
use crate::executor::task::AsyncTask;
1919
#[cfg(feature = "smp")]
2020
use crate::scheduler::SchedulerInput;
2121
use crate::scheduler::{CoreId, PerCoreScheduler};
@@ -32,8 +32,8 @@ pub(crate) struct CoreLocal {
3232
pub kernel_stack: Cell<*mut u8>,
3333
/// Interface to the interrupt counters
3434
irq_statistics: &'static IrqStatistics,
35-
/// Queue of async tasks
36-
async_tasks: RefCell<VecDeque<AsyncTask>>,
35+
/// The core-local async executor.
36+
ex: StaticExecutor<RawSpinMutex, RawRwSpinLock>,
3737
#[cfg(feature = "smp")]
3838
pub hlt: AtomicBool,
3939
/// Queues to handle incoming requests from the other cores
@@ -61,7 +61,7 @@ impl CoreLocal {
6161
tss: Cell::new(ptr::null_mut()),
6262
kernel_stack: Cell::new(ptr::null_mut()),
6363
irq_statistics,
64-
async_tasks: RefCell::new(VecDeque::new()),
64+
ex: StaticExecutor::new(),
6565
#[cfg(feature = "smp")]
6666
hlt: AtomicBool::new(false),
6767
#[cfg(feature = "smp")]
@@ -110,8 +110,8 @@ pub(crate) fn core_scheduler() -> &'static mut PerCoreScheduler {
110110
unsafe { CoreLocal::get().scheduler.get().as_mut().unwrap() }
111111
}
112112

113-
pub(crate) fn async_tasks() -> RefMut<'static, VecDeque<AsyncTask>> {
114-
CoreLocal::get().async_tasks.borrow_mut()
113+
pub(crate) fn ex() -> &'static StaticExecutor<RawSpinMutex, RawRwSpinLock> {
114+
&CoreLocal::get().ex
115115
}
116116

117117
pub(crate) fn set_core_scheduler(scheduler: *mut PerCoreScheduler) {

src/executor/mod.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub(crate) mod vsock;
99
use alloc::sync::Arc;
1010
use alloc::task::Wake;
1111
use core::future::Future;
12-
use core::pin::{Pin, pin};
12+
use core::pin::pin;
1313
use core::sync::atomic::AtomicU32;
1414
use core::task::{Context, Poll, Waker};
1515
use core::time::Duration;
@@ -94,14 +94,13 @@ impl Wake for TaskNotify {
9494
}
9595

9696
pub(crate) fn run() {
97-
let mut cx = Context::from_waker(Waker::noop());
98-
9997
without_interrupts(|| {
100-
// FIXME(mkroening): Not all tasks register wakers and never sleep
101-
for _ in 0..({ core_local::async_tasks().len() }) {
102-
let mut task = { core_local::async_tasks().pop_front().unwrap() };
103-
if Pin::new(&mut task).poll(&mut cx).is_pending() {
104-
core_local::async_tasks().push_back(task);
98+
// FIXME: We currently have no more than 3 tasks at a time, so this is fine.
99+
// Ideally, we would set this value to 200, but the network task currently immediately wakes up again.
100+
// This would lead to the network task being polled 200 times back to back, slowing things down considerably.
101+
for _ in 0..3 {
102+
if !core_local::ex().try_tick() {
103+
break;
105104
}
106105
}
107106
});
@@ -116,7 +115,7 @@ pub(crate) fn spawn<F>(future: F)
116115
where
117116
F: Future<Output = ()> + Send + 'static,
118117
{
119-
without_interrupts(|| core_local::async_tasks().push_back(AsyncTask::new(future)));
118+
core_local::ex().spawn(AsyncTask::new(future)).detach();
120119
}
121120

122121
pub fn init() {

0 commit comments

Comments
 (0)