async tasks
This commit is contained in:
parent
ab874a2102
commit
cdad99a352
@ -15,6 +15,7 @@ pub mod interrupts;
|
|||||||
pub mod gdt;
|
pub mod gdt;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
pub mod allocator;
|
pub mod allocator;
|
||||||
|
pub mod task;
|
||||||
|
|
||||||
extern crate alloc;
|
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 alloc::{boxed::Box, vec, vec::Vec, rc::Rc};
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
use rust_os::println;
|
use rust_os::println;
|
||||||
|
use rust_os::task::{Task, simple_executor::SimpleExecutor};
|
||||||
use bootloader::{BootInfo, entry_point};
|
use bootloader::{BootInfo, entry_point};
|
||||||
use x86_64::VirtAddr;
|
use x86_64::VirtAddr;
|
||||||
|
|
||||||
@ -30,23 +31,9 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
|
|||||||
allocator::init_heap(&mut mapper, &mut frame_allocator)
|
allocator::init_heap(&mut mapper, &mut frame_allocator)
|
||||||
.expect("heap initialization failed");
|
.expect("heap initialization failed");
|
||||||
|
|
||||||
// allocate a number on the heap
|
let mut executor = SimpleExecutor::new();
|
||||||
let heap_value = Box::new(41);
|
executor.spawn(Task::new(example_task()));
|
||||||
println!("heap_value at {:p}", heap_value);
|
executor.run();
|
||||||
|
|
||||||
// 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));
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
test_main();
|
test_main();
|
||||||
@ -55,6 +42,15 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
|
|||||||
rust_os::hlt_loop();
|
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))]
|
#[cfg(not(test))]
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic(info: &PanicInfo) -> ! {
|
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