forked from rcore-os/zCore
Move ThreadSwitchFuture from kernel-hal to zircon-object
This commit is contained in:
parent
e71df32bca
commit
d791c52700
|
@ -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) {}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
|
@ -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>);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
});
|
||||
|
|
|
@ -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) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -70,7 +74,7 @@ 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);
|
||||
}
|
||||
|
||||
|
@ -78,11 +82,7 @@ async fn new_thread(thread: CurrentThread) {
|
|||
}
|
||||
}
|
||||
|
||||
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")]
|
||||
|
|
|
@ -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
|
||||
|
@ -216,10 +220,16 @@ 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);
|
||||
|
||||
if let Err(e) = handler_user_trap(&thread, trap_num).await {
|
||||
thread.handle_exception(e).await;
|
||||
}
|
||||
}
|
||||
thread.handle_exception(ExceptionType::ThreadExiting).await;
|
||||
}
|
||||
|
||||
async fn handler_user_trap(thread: &CurrentThread, trap_num: usize) -> Result<(), ExceptionType> {
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
match trap_num {
|
||||
0 => handle_syscall(&thread).await,
|
||||
|
@ -227,7 +237,7 @@ async fn new_thread(thread: CurrentThread) {
|
|||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
match trap_num {
|
||||
0x100 => handle_syscall(&thread).await,
|
||||
0x100 => handle_syscall(thread).await,
|
||||
0x20..=0xff => {
|
||||
kernel_hal::interrupt::handle_irq(trap_num);
|
||||
// TODO: configurable
|
||||
|
@ -238,6 +248,7 @@ async fn new_thread(thread: CurrentThread) {
|
|||
}
|
||||
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?} {:?}",
|
||||
|
@ -246,29 +257,23 @@ async fn new_thread(thread: CurrentThread) {
|
|||
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;
|
||||
return Err(ExceptionType::FatalPageFault);
|
||||
}
|
||||
}
|
||||
0x8 => thread.with_context(|cx| {
|
||||
panic!("Double fault from user mode! {:#x?}", cx);
|
||||
}),
|
||||
num => {
|
||||
let type_ = match num {
|
||||
return Err(match num {
|
||||
0x1 => ExceptionType::HardwareBreakpoint,
|
||||
0x3 => ExceptionType::SoftwareBreakpoint,
|
||||
0x6 => ExceptionType::UndefinedInstruction,
|
||||
0x17 => ExceptionType::UnalignedAccess,
|
||||
_ => ExceptionType::General,
|
||||
};
|
||||
thread.handle_exception(type_).await;
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
thread.handle_exception(ExceptionType::ThreadExiting).await;
|
||||
}
|
||||
|
||||
fn thread_fn(thread: CurrentThread) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
|
||||
Box::pin(new_thread(thread))
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_syscall(thread: &CurrentThread) {
|
||||
|
|
|
@ -299,7 +299,8 @@ pub struct JobInfo {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::task::{CurrentThread, Status, Thread, ThreadState, TASK_RETCODE_SYSCALL_KILL};
|
||||
use crate::task::{Status, Thread, ThreadState, TASK_RETCODE_SYSCALL_KILL};
|
||||
use core::time::Duration;
|
||||
|
||||
#[test]
|
||||
fn create() {
|
||||
|
@ -439,14 +440,28 @@ mod tests {
|
|||
assert!(!job.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn kill() {
|
||||
#[async_std::test]
|
||||
async fn kill() {
|
||||
let root_job = Job::root();
|
||||
let job = Job::create_child(&root_job).expect("failed to create job");
|
||||
let proc = Process::create(&root_job, "proc").expect("failed to create process");
|
||||
let thread = Thread::create(&proc, "thread").expect("failed to create thread");
|
||||
let current_thread = CurrentThread(thread.clone());
|
||||
thread
|
||||
.start(0, 0, 0, 0, |thread| {
|
||||
std::boxed::Box::pin(async {
|
||||
println!("should not be killed");
|
||||
async_std::task::sleep(Duration::from_millis(1000)).await;
|
||||
{
|
||||
// FIXME
|
||||
drop(thread);
|
||||
async_std::task::sleep(Duration::from_millis(1000)).await;
|
||||
}
|
||||
unreachable!("should be killed");
|
||||
})
|
||||
})
|
||||
.expect("failed to start thread");
|
||||
|
||||
async_std::task::sleep(Duration::from_millis(500)).await;
|
||||
root_job.kill();
|
||||
assert!(root_job.inner.lock().killed);
|
||||
assert!(job.inner.lock().killed);
|
||||
|
@ -458,7 +473,8 @@ mod tests {
|
|||
assert!(!proc.signal().contains(Signal::PROCESS_TERMINATED));
|
||||
assert!(!thread.signal().contains(Signal::THREAD_TERMINATED));
|
||||
|
||||
std::mem::drop(current_thread);
|
||||
// wait for killing...
|
||||
async_std::task::sleep(Duration::from_millis(1000)).await;
|
||||
assert!(root_job.inner.lock().killed);
|
||||
assert!(job.inner.lock().killed);
|
||||
assert_eq!(proc.status(), Status::Exited(TASK_RETCODE_SYSCALL_KILL));
|
||||
|
|
|
@ -178,8 +178,11 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
type ThreadFuture = dyn Future<Output = ()> + Send;
|
||||
type ThreadFuturePinned = Pin<Box<ThreadFuture>>;
|
||||
|
||||
/// The type of a new thread function.
|
||||
pub type ThreadFn = fn(thread: CurrentThread) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>>;
|
||||
pub type ThreadFn = fn(thread: CurrentThread) -> ThreadFuturePinned;
|
||||
|
||||
impl Thread {
|
||||
/// Create a new thread.
|
||||
|
@ -270,8 +273,7 @@ impl Thread {
|
|||
}
|
||||
inner.change_state(ThreadState::Running, &self.base);
|
||||
}
|
||||
let vmtoken = self.proc().vmar().table_phys();
|
||||
kernel_hal::thread::spawn(thread_fn(CurrentThread(self.clone())), vmtoken);
|
||||
self.spawn(thread_fn);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -288,8 +290,7 @@ impl Thread {
|
|||
}
|
||||
inner.change_state(ThreadState::Running, &self.base);
|
||||
}
|
||||
let vmtoken = self.proc().vmar().table_phys();
|
||||
kernel_hal::thread::spawn(thread_fn(CurrentThread(self.clone())), vmtoken);
|
||||
self.spawn(thread_fn);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -309,8 +310,7 @@ impl Thread {
|
|||
}
|
||||
inner.change_state(ThreadState::Running, &self.base);
|
||||
}
|
||||
let vmtoken = self.proc().vmar().table_phys();
|
||||
kernel_hal::thread::spawn(thread_fn(CurrentThread(self.clone())), vmtoken);
|
||||
self.spawn(thread_fn);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -337,7 +337,7 @@ impl Thread {
|
|||
}
|
||||
inner.change_state(ThreadState::Dying, &self.base);
|
||||
if let Some(waker) = inner.waker.take() {
|
||||
waker.wake();
|
||||
waker.wake_by_ref();
|
||||
}
|
||||
// For blocking thread, use the killer
|
||||
if let Some(killer) = inner.killer.take() {
|
||||
|
@ -449,6 +449,21 @@ impl Thread {
|
|||
context.general.gsbase = gsbase;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Spawn the future returned by `thread_fn` in this thread.
|
||||
fn spawn(self: &Arc<Self>, thread_fn: ThreadFn) {
|
||||
let current = CurrentThread(self.clone());
|
||||
let future = thread_fn(current);
|
||||
kernel_hal::thread::spawn(ThreadSwitchFuture::new(self.clone(), future));
|
||||
}
|
||||
|
||||
/// Terminate the current running thread.
|
||||
fn terminate(&self) {
|
||||
let mut inner = self.inner.lock();
|
||||
self.exceptionate.shutdown();
|
||||
inner.change_state(ThreadState::Dead, &self.base);
|
||||
self.proc().remove_thread(self.base.id);
|
||||
}
|
||||
}
|
||||
|
||||
impl Task for Thread {
|
||||
|
@ -471,7 +486,7 @@ impl Task for Thread {
|
|||
let state = inner.state;
|
||||
inner.change_state(state, &self.base);
|
||||
if let Some(waker) = inner.waker.take() {
|
||||
waker.wake();
|
||||
waker.wake_by_ref();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -494,27 +509,14 @@ impl Task for Thread {
|
|||
///
|
||||
/// [`Thread`]: crate::task::Thread
|
||||
/// [`Thread::start`]: crate::task::Thread::start
|
||||
pub struct CurrentThread(pub(super) Arc<Thread>);
|
||||
|
||||
impl Deref for CurrentThread {
|
||||
type Target = Arc<Thread>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for CurrentThread {
|
||||
/// Terminate the current running thread.
|
||||
fn drop(&mut self) {
|
||||
let mut inner = self.inner.lock();
|
||||
self.exceptionate.shutdown();
|
||||
inner.change_state(ThreadState::Dead, &self.base);
|
||||
self.proc().remove_thread(self.base.id);
|
||||
}
|
||||
}
|
||||
pub struct CurrentThread(Arc<Thread>);
|
||||
|
||||
impl CurrentThread {
|
||||
/// Returns the inner structure `Arc<Thread>`.
|
||||
pub fn inner(&self) -> Arc<Thread> {
|
||||
self.0.clone()
|
||||
}
|
||||
|
||||
/// Exit the current thread.
|
||||
///
|
||||
/// The thread do not terminate immediately when exited. It is just made dying.
|
||||
|
@ -687,6 +689,20 @@ impl CurrentThread {
|
|||
}
|
||||
}
|
||||
|
||||
impl Deref for CurrentThread {
|
||||
type Target = Arc<Thread>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for CurrentThread {
|
||||
fn drop(&mut self) {
|
||||
self.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
/// `into_result` returns `Self` if the type parameter is already a `ZxResult`,
|
||||
/// otherwise wraps the value in an `Ok`.
|
||||
///
|
||||
|
@ -758,6 +774,28 @@ pub struct ThreadInfo {
|
|||
cpu_affinity_mask: [u64; 8],
|
||||
}
|
||||
|
||||
struct ThreadSwitchFuture {
|
||||
thread: Arc<Thread>,
|
||||
future: Mutex<ThreadFuturePinned>,
|
||||
}
|
||||
|
||||
impl ThreadSwitchFuture {
|
||||
pub fn new(thread: Arc<Thread>, future: ThreadFuturePinned) -> Self {
|
||||
Self {
|
||||
future: Mutex::new(future),
|
||||
thread,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Future for ThreadSwitchFuture {
|
||||
type Output = ();
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
kernel_hal::vm::activate_paging(self.thread.proc().vmar().table_phys());
|
||||
self.future.lock().as_mut().poll(cx)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::job::Job;
|
||||
|
|
|
@ -30,7 +30,7 @@ impl Syscall<'_> {
|
|||
} else {
|
||||
Some(proc.get_object::<Thread>(new_futex_owner)?)
|
||||
};
|
||||
let future = futex.wait_with_owner(current_value, Some((*self.thread).clone()), new_owner);
|
||||
let future = futex.wait_with_owner(current_value, Some(self.thread.inner()), new_owner);
|
||||
self.thread
|
||||
.blocking_run(future, ThreadState::BlockedFutex, deadline.into(), None)
|
||||
.await?;
|
||||
|
|
Loading…
Reference in New Issue