Base dummy waker on RawWaker to avoid allocations

The Wake trait is based on Arc, which leads to deallocation on wakes. Since interrupts should not (de)allocate, this can lead to a deadlock.
This commit is contained in:
Philipp Oppermann
2020-03-22 16:11:25 +01:00
parent 90abd5c8c5
commit 51f90236a5
2 changed files with 18 additions and 13 deletions

View File

@@ -13,7 +13,7 @@ name = "stack_overflow"
harness = false harness = false
[dependencies] [dependencies]
bootloader = { version = "0.8.0", features = ["map_physical_memory"]} bootloader = { version = "0.9.0", features = ["map_physical_memory"], path = "../../../bootloader/master"}
volatile = "0.2.6" volatile = "0.2.6"
spin = "0.5.2" spin = "0.5.2"
x86_64 = "0.9.6" x86_64 = "0.9.6"

View File

@@ -1,6 +1,9 @@
use super::Task; use super::Task;
use alloc::{collections::VecDeque, sync::Arc, task::Wake}; use alloc::collections::VecDeque;
use core::task::{Context, Poll, Waker}; use core::{
ptr,
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
};
pub struct SimpleExecutor { pub struct SimpleExecutor {
task_queue: VecDeque<Task>, task_queue: VecDeque<Task>,
@@ -19,7 +22,7 @@ impl SimpleExecutor {
pub fn run(&mut self) { pub fn run(&mut self) {
while let Some(mut task) = self.task_queue.pop_front() { while let Some(mut task) = self.task_queue.pop_front() {
let waker = DummyWaker.to_waker(); let waker = waker();
let mut context = Context::from_waker(&waker); let mut context = Context::from_waker(&waker);
match task.poll(&mut context) { match task.poll(&mut context) {
Poll::Ready(()) => {} // task done Poll::Ready(()) => {} // task done
@@ -29,16 +32,18 @@ impl SimpleExecutor {
} }
} }
struct DummyWaker; fn raw_waker() -> RawWaker {
fn no_op(_: *const ()) {}
impl Wake for DummyWaker { fn clone(_: *const ()) -> RawWaker {
fn wake(self: Arc<Self>) { raw_waker()
// do nothing
} }
RawWaker::new(
ptr::null(),
&RawWakerVTable::new(clone, no_op, no_op, no_op),
)
} }
impl DummyWaker { fn waker() -> Waker {
fn to_waker(self) -> Waker { unsafe { Waker::from_raw(raw_waker()) }
Waker::from(Arc::new(self))
}
} }