From 4fe6109e5b37b36283c6f4026212c764ec70fa98 Mon Sep 17 00:00:00 2001 From: Jacob Hinchliffe Date: Tue, 25 Feb 2025 03:18:12 +0000 Subject: [PATCH] Rename scheduling to 'async_io', general cleanup --- kernel/src/main.rs | 2 +- .../drivers/{scheduling => async_io}/mod.rs | 0 .../drivers/{scheduling => async_io}/task.rs | 5 + libk/src/drivers/mod.rs | 2 +- libk/src/lib.rs | 8 +- libk/src/std/application.rs | 5 +- libk/src/std/{io => }/io.rs | 0 libk/src/std/io/mod.rs | 2 - libk/src/threads.rs | 113 ++++++++++++++++++ libk/src/util/shell.rs | 2 +- 10 files changed, 127 insertions(+), 12 deletions(-) rename libk/src/drivers/{scheduling => async_io}/mod.rs (100%) rename libk/src/drivers/{scheduling => async_io}/task.rs (95%) rename libk/src/std/{io => }/io.rs (100%) delete mode 100644 libk/src/std/io/mod.rs create mode 100644 libk/src/threads.rs diff --git a/kernel/src/main.rs b/kernel/src/main.rs index d81265e..1eb77f5 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -5,8 +5,8 @@ extern crate alloc; use libk::{ drivers::{ + async_io::task::{Executor, Task}, io, - scheduling::task::{Executor, Task}, }, prelude::*, util::shell::shell, diff --git a/libk/src/drivers/scheduling/mod.rs b/libk/src/drivers/async_io/mod.rs similarity index 100% rename from libk/src/drivers/scheduling/mod.rs rename to libk/src/drivers/async_io/mod.rs diff --git a/libk/src/drivers/scheduling/task.rs b/libk/src/drivers/async_io/task.rs similarity index 95% rename from libk/src/drivers/scheduling/task.rs rename to libk/src/drivers/async_io/task.rs index 392638b..6076917 100644 --- a/libk/src/drivers/scheduling/task.rs +++ b/libk/src/drivers/async_io/task.rs @@ -1,3 +1,8 @@ +//! Allows creation of asynchronous IO bound tasks. +//! +//! Written by @zxq5 for the most part with code from +//! [here](https://github.com/phil-opp/blog_os/). +//! use crate::prelude::*; use alloc::collections::BTreeMap; use alloc::sync::Arc; diff --git a/libk/src/drivers/mod.rs b/libk/src/drivers/mod.rs index 61ec870..f60a9af 100644 --- a/libk/src/drivers/mod.rs +++ b/libk/src/drivers/mod.rs @@ -1,3 +1,3 @@ +pub mod async_io; pub mod io; pub mod kalloc; -pub mod scheduling; diff --git a/libk/src/lib.rs b/libk/src/lib.rs index 1846161..db0af38 100644 --- a/libk/src/lib.rs +++ b/libk/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] -#![allow(async_fn_in_trait)] +// #![allow(async_fn_in_trait)] #![warn(tail_expr_drop_order)] #![warn( clippy::correctness, @@ -12,15 +12,11 @@ rustdoc::missing_panics_doc )] -// alloc -// io : serial, framebuffer, ascii(?), keyboard -// ????? -// scheduling / tasks : async - extern crate alloc; pub mod drivers; pub mod resources; +pub mod threads; pub mod util; #[allow(unused)] // We aren't using much of this right now. diff --git a/libk/src/std/application.rs b/libk/src/std/application.rs index 44c2651..59ce535 100644 --- a/libk/src/std/application.rs +++ b/libk/src/std/application.rs @@ -7,7 +7,10 @@ mod window; pub trait Application { type Output; - async fn run(&mut self, args: Vec) -> Result; + fn run( + &mut self, + args: Vec, + ) -> impl core::future::Future> + Send; } #[derive(Debug)] diff --git a/libk/src/std/io/io.rs b/libk/src/std/io.rs similarity index 100% rename from libk/src/std/io/io.rs rename to libk/src/std/io.rs diff --git a/libk/src/std/io/mod.rs b/libk/src/std/io/mod.rs deleted file mode 100644 index 608d4e1..0000000 --- a/libk/src/std/io/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod io; -pub use io::*; diff --git a/libk/src/threads.rs b/libk/src/threads.rs new file mode 100644 index 0000000..76c2c13 --- /dev/null +++ b/libk/src/threads.rs @@ -0,0 +1,113 @@ +use core::arch::asm; + +#[repr(C)] +pub struct Thread { + id: usize, + /// This shall be default before the program is interrupted, otherwise it will store + /// CPU registers etc to be restored on context switch. + ctx: ThreadContext, +} + +/// CPU state to be saved on context switches. +#[repr(C)] +#[derive(Default)] +pub struct ThreadContext { + /// Accumulator register. + rax: u64, + /// Base register. + rbx: u64, + /// Counter register. + rcx: u64, + /// Data register. + rdx: u64, + /// Source index register. + rsi: u64, + /// Destination index register. + rdi: u64, + /// Base pointer register. + rbp: u64, + /// Stack pointer register. + rsp: u64, + /// An extended register. + r8: u64, + /// An extended register. + r9: u64, + /// An extended register. + r10: u64, + /// An extended register. + r11: u64, + /// An extended register. + r12: u64, + /// An extended register. + r13: u64, + /// An extended register. + r14: u64, + /// An extended register. + r15: u64, + /// The instruction pointer. + rip: u64, + /// RFLAGS register. + rflags: u64, +} + +impl ThreadContext { + /// Saves the current registers of the CPU before a context switch + /// to be restored later. + /// + /// # Notes + /// + /// This function should ONLY be called in interrupt handlers such + /// as that of the timer. This will then save registers as required + /// + /// + /// # Safety + /// + /// This function is unsafe because of the usage of inline ASM. + #[inline(always)] + pub unsafe fn save_registers() -> Self { + let mut context = Self::default(); + unsafe { + asm!( + "mov {0}, rax", + "mov {1}, rbx", + "mov {2}, rcx", + "mov {3}, rdx", + "mov {4}, rsi", + "mov {5}, rdi", + "mov {6}, rbp", + "mov {7}, rsp", + "mov {8}, r8", + "mov {9}, r9", + "mov {10}, r10", + "mov {11}, r11", + "mov {12}, r12", + "mov {13}, r13", + "mov {14}, r14", + "mov {15}, r15", + "lea {16}, [rip]", + "pushf", + "pop {17}", + out(reg) context.rax, + out(reg) context.rbx, + out(reg) context.rcx, + out(reg) context.rdx, + out(reg) context.rsi, + out(reg) context.rdi, + out(reg) context.rbp, + out(reg) context.rsp, + out(reg) context.r8, + out(reg) context.r9, + out(reg) context.r10, + out(reg) context.r11, + out(reg) context.r12, + out(reg) context.r13, + out(reg) context.r14, + out(reg) context.r15, + out(reg) context.rip, + out(reg) context.rflags, + ); + } + + context + } +} diff --git a/libk/src/util/shell.rs b/libk/src/util/shell.rs index fceb8ee..cf851de 100644 --- a/libk/src/util/shell.rs +++ b/libk/src/util/shell.rs @@ -1,4 +1,4 @@ -use x86_64::registers::rflags::read; +// use x86_64::registers::rflags::read; use crate::{drivers::io::ascii::clear_screen, prelude::stdin::read_line, print, println};