async tasks
This commit is contained in:
parent
ab874a2102
commit
cdad99a352
@ -15,6 +15,7 @@ pub mod interrupts;
|
||||
pub mod gdt;
|
||||
pub mod memory;
|
||||
pub mod allocator;
|
||||
pub mod task;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
|
||||
30
src/main.rs
30
src/main.rs
@ -9,6 +9,7 @@ extern crate alloc;
|
||||
use alloc::{boxed::Box, vec, vec::Vec, rc::Rc};
|
||||
use core::panic::PanicInfo;
|
||||
use rust_os::println;
|
||||
use rust_os::task::{Task, simple_executor::SimpleExecutor};
|
||||
use bootloader::{BootInfo, entry_point};
|
||||
use x86_64::VirtAddr;
|
||||
|
||||
@ -30,23 +31,9 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
|
||||
allocator::init_heap(&mut mapper, &mut frame_allocator)
|
||||
.expect("heap initialization failed");
|
||||
|
||||
// allocate a number on the heap
|
||||
let heap_value = Box::new(41);
|
||||
println!("heap_value at {:p}", heap_value);
|
||||
|
||||
// create a dynamically sized vector
|
||||
let mut vec = Vec::new();
|
||||
for i in 0..500 {
|
||||
vec.push(i);
|
||||
}
|
||||
println!("vec at {:p}", vec.as_slice());
|
||||
|
||||
// create a reference counted vector -> will be freed when count reaches 0
|
||||
let reference_counted = Rc::new(vec![1, 2, 3]);
|
||||
let cloned_reference = reference_counted.clone();
|
||||
println!("current reference count is {}", Rc::strong_count(&cloned_reference));
|
||||
core::mem::drop(reference_counted);
|
||||
println!("reference count is {} now", Rc::strong_count(&cloned_reference));
|
||||
let mut executor = SimpleExecutor::new();
|
||||
executor.spawn(Task::new(example_task()));
|
||||
executor.run();
|
||||
|
||||
#[cfg(test)]
|
||||
test_main();
|
||||
@ -55,6 +42,15 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
|
||||
rust_os::hlt_loop();
|
||||
}
|
||||
|
||||
async fn async_number() -> u32 {
|
||||
42
|
||||
}
|
||||
|
||||
async fn example_task() {
|
||||
let number = async_number().await;
|
||||
println!("async number: {}", number);
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[panic_handler]
|
||||
fn panic(info: &PanicInfo) -> ! {
|
||||
|
||||
21
src/task/mod.rs
Normal file
21
src/task/mod.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use core::{future::Future, pin::Pin};
|
||||
use alloc::boxed::Box;
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
pub mod simple_executor;
|
||||
|
||||
pub struct Task {
|
||||
future: Pin<Box<dyn Future<Output = ()>>>,
|
||||
}
|
||||
|
||||
impl Task {
|
||||
pub fn new(future: impl Future<Output = ()> + 'static) -> Task {
|
||||
Task {
|
||||
future: Box::pin(future),
|
||||
}
|
||||
}
|
||||
|
||||
fn poll(&mut self, context: &mut Context) -> Poll<()> {
|
||||
self.future.as_mut().poll(context)
|
||||
}
|
||||
}
|
||||
44
src/task/simple_executor.rs
Normal file
44
src/task/simple_executor.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use super::Task;
|
||||
use alloc::collections::VecDeque;
|
||||
use core::task::{Waker, RawWaker, RawWakerVTable, Context, Poll};
|
||||
|
||||
pub struct SimpleExecutor {
|
||||
task_queue: VecDeque<Task>,
|
||||
}
|
||||
|
||||
impl SimpleExecutor {
|
||||
pub fn new() -> SimpleExecutor {
|
||||
SimpleExecutor {
|
||||
task_queue: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn(&mut self, task: Task) {
|
||||
self.task_queue.push_back(task)
|
||||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
while let Some(mut task) = self.task_queue.pop_front() {
|
||||
let waker = dummy_waker();
|
||||
let mut context = Context::from_waker(&waker);
|
||||
match task.poll(&mut context) {
|
||||
Poll::Ready(()) => {} // task done
|
||||
Poll::Pending => self.task_queue.push_back(task),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn dummy_raw_waker() -> RawWaker {
|
||||
fn no_op(_: *const ()) {}
|
||||
fn clone(_: *const ()) -> RawWaker {
|
||||
dummy_raw_waker()
|
||||
}
|
||||
|
||||
let vtable = &RawWakerVTable::new(clone, no_op, no_op, no_op);
|
||||
RawWaker::new(0 as *const (), vtable)
|
||||
}
|
||||
|
||||
fn dummy_waker() -> Waker {
|
||||
unsafe { Waker::from_raw(dummy_raw_waker()) }
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user