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
[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"
spin = "0.5.2"
x86_64 = "0.9.6"

View File

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