Skip to content

Commit

Permalink
Move ThreadSwitchFuture from kernel-hal to zircon-object
Browse files Browse the repository at this point in the history
  • Loading branch information
equation314 committed Oct 30, 2021
1 parent e71df32 commit d791c52
Show file tree
Hide file tree
Showing 15 changed files with 186 additions and 136 deletions.
25 changes: 3 additions & 22 deletions kernel-hal/src/bare/thread.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,11 @@
//! Thread spawning.
use alloc::boxed::Box;
use core::task::{Context, Poll};
use core::{future::Future, pin::Pin};

use spin::Mutex;
use core::future::Future;

hal_fn_impl! {
impl mod crate::hal_fn::thread {
fn spawn(future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>, vmtoken: usize) {
struct PageTableSwitchWrapper {
inner: Mutex<Pin<Box<dyn Future<Output = ()> + Send>>>,
vmtoken: usize,
}
impl Future for PageTableSwitchWrapper {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
crate::vm::activate_paging(self.vmtoken);
self.inner.lock().as_mut().poll(cx)
}
}

executor::spawn(PageTableSwitchWrapper {
inner: Mutex::new(future),
vmtoken,
});
fn spawn(future: impl Future<Output = ()> + Send + 'static) {
executor::spawn(future);
}

fn set_tid(_tid: u64, _pid: u64) {}
Expand Down
6 changes: 3 additions & 3 deletions kernel-hal/src/common/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl Future for YieldFuture {
Poll::Ready(())
} else {
self.flag = true;
cx.waker().clone().wake();
cx.waker().wake_by_ref();
Poll::Pending
}
}
Expand All @@ -46,7 +46,7 @@ impl Future for SleepFuture {
}
if self.deadline.as_nanos() < i64::max_value() as u128 {
let waker = cx.waker().clone();
timer::timer_set(self.deadline, Box::new(move |_| waker.wake()));
timer::timer_set(self.deadline, Box::new(move |_| waker.wake_by_ref()));
}
Poll::Pending
}
Expand Down Expand Up @@ -118,7 +118,7 @@ impl Future for DisplayFlushFuture {
let frame_time = self.frame_time;
self.next_flush_time += frame_time;
let waker = cx.waker().clone();
timer::timer_set(self.next_flush_time, Box::new(move |_| waker.wake()));
timer::timer_set(self.next_flush_time, Box::new(move |_| waker.wake_by_ref()));
}
Poll::Pending
}
Expand Down
14 changes: 8 additions & 6 deletions kernel-hal/src/hal_fn.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use alloc::{boxed::Box, string::String, vec::Vec};
use core::{future::Future, ops::Range, pin::Pin, time::Duration};
use core::{future::Future, ops::Range, time::Duration};

use crate::drivers::prelude::{IrqHandler, IrqPolarity, IrqTriggerMode};
use crate::{common, HalResult, KernelConfig, KernelHandler, MMUFlags, PhysAddr, VirtAddr};
Expand Down Expand Up @@ -63,11 +63,13 @@ hal_fn_def! {

/// Virutal memory operations.
pub mod vm: common::vm {
/// Read current VM token. (e.g. CR3, SATP, ...)
/// Read the current VM token, which is the page table root address on
/// various architectures. (e.g. CR3, SATP, ...)
pub fn current_vmtoken() -> PhysAddr;

/// Activate this page table by given `vmtoken`.
pub(crate) fn activate_paging(vmtoken: PhysAddr);
/// Activate the page table associated with the `vmtoken` by writing the
/// page table root address.
pub fn activate_paging(vmtoken: PhysAddr);

/// Flush TLB by the associated `vaddr`, or flush the entire TLB. (`vaddr` is `None`).
pub(crate) fn flush_tlb(vaddr: Option<VirtAddr>);
Expand Down Expand Up @@ -124,7 +126,7 @@ hal_fn_def! {
pub(crate) fn console_write_early(_s: &str) {}
}

/// Context switch.
/// User context.
pub mod context: common::context {
/// Enter user mode.
pub fn context_run(context: &mut UserContext) {
Expand All @@ -148,7 +150,7 @@ hal_fn_def! {
/// Thread spawning.
pub mod thread: common::thread {
/// Spawn a new thread.
pub fn spawn(future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>, vmtoken: usize);
pub fn spawn(future: impl Future<Output = ()> + Send + 'static);

/// Set tid and pid of current task.
pub fn set_tid(tid: u64, pid: u64);
Expand Down
1 change: 1 addition & 0 deletions kernel-hal/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Hardware Abstraction Layer
#![cfg_attr(not(feature = "libos"), no_std)]
#![cfg_attr(feature = "libos", feature(thread_id_value))]
#![feature(asm)]
#![feature(doc_cfg)]
#![deny(warnings)]
Expand Down
7 changes: 7 additions & 0 deletions kernel-hal/src/libos/cpu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
hal_fn_impl! {
impl mod crate::hal_fn::cpu {
fn cpu_id() -> u8 {
std::thread::current().id().as_u64().get() as u8
}
}
}
5 changes: 3 additions & 2 deletions kernel-hal/src/libos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod mock_mem;

pub mod boot;
pub mod config;
pub mod cpu;
pub mod mem;
pub mod thread;
pub mod timer;
Expand All @@ -14,9 +15,9 @@ pub mod vm;
#[doc(cfg(feature = "libos"))]
pub mod libos;

pub use super::hal_fn::{context, cpu, interrupt, rand};
pub use super::hal_fn::{context, interrupt, rand};

hal_fn_impl_default!(context, cpu, interrupt, rand, super::hal_fn::console);
hal_fn_impl_default!(context, interrupt, rand, super::hal_fn::console);

#[cfg(target_os = "macos")]
mod macos;
Expand Down
4 changes: 2 additions & 2 deletions kernel-hal/src/libos/thread.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Thread spawning.
use async_std::task_local;
use core::{cell::Cell, future::Future, pin::Pin};
use core::{cell::Cell, future::Future};

task_local! {
static TID: Cell<u64> = Cell::new(0);
Expand All @@ -10,7 +10,7 @@ task_local! {

hal_fn_impl! {
impl mod crate::hal_fn::thread {
fn spawn(future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>, _vmtoken: usize) {
fn spawn(future: impl Future<Output = ()> + Send + 'static) {
async_std::task::spawn(future);
}

Expand Down
2 changes: 1 addition & 1 deletion kernel-hal/src/libos/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ hal_fn_impl! {
}

fn timer_set(deadline: Duration, callback: Box<dyn FnOnce(Duration) + Send + Sync>) {
let dur = deadline - timer_now();
task::spawn(async move {
let dur = deadline - timer_now();
task::sleep(dur).await;
callback(timer_now());
});
Expand Down
5 changes: 2 additions & 3 deletions kernel-hal/src/libos/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ use crate::{addr::is_aligned, MMUFlags, PhysAddr, VirtAddr, PAGE_SIZE};

hal_fn_impl! {
impl mod crate::hal_fn::vm {
fn current_vmtoken() -> PhysAddr {
0
}
fn current_vmtoken() -> PhysAddr { 0 }
fn activate_paging(_vmtoken: PhysAddr) {}
}
}

Expand Down
4 changes: 2 additions & 2 deletions linux-syscall/src/file/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ impl Syscall<'_> {
let waker = cx.waker().clone();
timer::timer_set(
Duration::from_millis(deadline as u64),
Box::new(move |_| waker.wake()),
Box::new(move |_| waker.wake_by_ref()),
);
}
}
Expand Down Expand Up @@ -237,7 +237,7 @@ impl Syscall<'_> {
let waker = cx.waker().clone();
timer::timer_set(
Duration::from_millis(deadline as u64),
Box::new(move |_| waker.wake()),
Box::new(move |_| waker.wake_by_ref()),
);
}
}
Expand Down
14 changes: 7 additions & 7 deletions loader/src/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ pub fn run(args: Vec<String>, envs: Vec<String>, rootfs: Arc<dyn FileSystem>) ->
proc
}

fn thread_fn(thread: CurrentThread) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
Box::pin(run_user(thread))
}

/// The function of a new thread.
///
/// loop:
Expand All @@ -55,7 +59,7 @@ pub fn run(args: Vec<String>, envs: Vec<String>, rootfs: Arc<dyn FileSystem>) ->
/// - enter user mode
/// - handle trap/interrupt/syscall according to the return value
/// - return the context to the user thread
async fn new_thread(thread: CurrentThread) {
async fn run_user(thread: CurrentThread) {
kernel_hal::thread::set_tid(thread.id(), thread.proc().id());
loop {
// wait
Expand All @@ -70,19 +74,15 @@ async fn new_thread(thread: CurrentThread) {
trace!("back from user: {:#x?}", cx);
// handle trap/interrupt/syscall

if let Err(err) = handler_user_trap(&thread, &mut cx).await {
if let Err(err) = handle_user_trap(&thread, &mut cx).await {
thread.exit_linux(err as i32);
}

thread.end_running(cx);
}
}

fn thread_fn(thread: CurrentThread) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
Box::pin(new_thread(thread))
}

async fn handler_user_trap(thread: &CurrentThread, cx: &mut UserContext) -> ZxResult {
async fn handle_user_trap(thread: &CurrentThread, cx: &mut UserContext) -> ZxResult {
let pid = thread.proc().id();

#[cfg(target_arch = "x86_64")]
Expand Down
99 changes: 52 additions & 47 deletions loader/src/zircon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,11 @@ kcounter!(EXCEPTIONS_USER, "exceptions.user");
kcounter!(EXCEPTIONS_TIMER, "exceptions.timer");
kcounter!(EXCEPTIONS_PGFAULT, "exceptions.pgfault");

async fn new_thread(thread: CurrentThread) {
fn thread_fn(thread: CurrentThread) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
Box::pin(run_user(thread))
}

async fn run_user(thread: CurrentThread) {
kernel_hal::thread::set_tid(thread.id(), thread.proc().id());
if thread.is_first_thread() {
thread
Expand Down Expand Up @@ -216,59 +220,60 @@ async fn new_thread(thread: CurrentThread) {
EXCEPTIONS_USER.add(1);

let trap_num = cx.trap_num;
#[cfg(target_arch = "x86_64")]
let error_code = cx.error_code;
thread.end_running(cx);

#[cfg(target_arch = "aarch64")]
match trap_num {
0 => handle_syscall(&thread).await,
_ => unimplemented!(),
}
#[cfg(target_arch = "x86_64")]
match trap_num {
0x100 => handle_syscall(&thread).await,
0x20..=0xff => {
kernel_hal::interrupt::handle_irq(trap_num);
// TODO: configurable
if trap_num == 0xf1 {
EXCEPTIONS_TIMER.add(1);
kernel_hal::thread::yield_now().await;
}
}
0xe => {
EXCEPTIONS_PGFAULT.add(1);
let (vaddr, flags) = kernel_hal::context::fetch_page_fault_info(error_code);
info!(
"page fault from user mode {:#x} {:#x?} {:?}",
vaddr, error_code, flags
);
let vmar = thread.proc().vmar();
if let Err(err) = vmar.handle_page_fault(vaddr, flags) {
error!("handle_page_fault error: {:?}", err);
thread.handle_exception(ExceptionType::FatalPageFault).await;
}
}
0x8 => thread.with_context(|cx| {
panic!("Double fault from user mode! {:#x?}", cx);
}),
num => {
let type_ = match num {
0x1 => ExceptionType::HardwareBreakpoint,
0x3 => ExceptionType::SoftwareBreakpoint,
0x6 => ExceptionType::UndefinedInstruction,
0x17 => ExceptionType::UnalignedAccess,
_ => ExceptionType::General,
};
thread.handle_exception(type_).await;
}
if let Err(e) = handler_user_trap(&thread, trap_num).await {
thread.handle_exception(e).await;
}
}
thread.handle_exception(ExceptionType::ThreadExiting).await;
}

fn thread_fn(thread: CurrentThread) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
Box::pin(new_thread(thread))
async fn handler_user_trap(thread: &CurrentThread, trap_num: usize) -> Result<(), ExceptionType> {
#[cfg(target_arch = "aarch64")]
match trap_num {
0 => handle_syscall(&thread).await,
_ => unimplemented!(),
}
#[cfg(target_arch = "x86_64")]
match trap_num {
0x100 => handle_syscall(thread).await,
0x20..=0xff => {
kernel_hal::interrupt::handle_irq(trap_num);
// TODO: configurable
if trap_num == 0xf1 {
EXCEPTIONS_TIMER.add(1);
kernel_hal::thread::yield_now().await;
}
}
0xe => {
EXCEPTIONS_PGFAULT.add(1);
let error_code = thread.with_context(|cx| cx.error_code);
let (vaddr, flags) = kernel_hal::context::fetch_page_fault_info(error_code);
info!(
"page fault from user mode {:#x} {:#x?} {:?}",
vaddr, error_code, flags
);
let vmar = thread.proc().vmar();
if let Err(err) = vmar.handle_page_fault(vaddr, flags) {
error!("handle_page_fault error: {:?}", err);
return Err(ExceptionType::FatalPageFault);
}
}
0x8 => thread.with_context(|cx| {
panic!("Double fault from user mode! {:#x?}", cx);
}),
num => {
return Err(match num {
0x1 => ExceptionType::HardwareBreakpoint,
0x3 => ExceptionType::SoftwareBreakpoint,
0x6 => ExceptionType::UndefinedInstruction,
0x17 => ExceptionType::UnalignedAccess,
_ => ExceptionType::General,
})
}
}
Ok(())
}

async fn handle_syscall(thread: &CurrentThread) {
Expand Down
Loading

0 comments on commit d791c52

Please sign in to comment.