Add rustfmt from relibc and apply it with cargo fmt
This commit is contained in:
+48
-40
@@ -1,16 +1,20 @@
|
||||
use alloc::sync::Arc;
|
||||
use core::arch::asm;
|
||||
use core::mem;
|
||||
use core::ptr;
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
use core::mem::offset_of;
|
||||
use core::{
|
||||
arch::asm,
|
||||
mem,
|
||||
mem::offset_of,
|
||||
ptr,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
use spin::Once;
|
||||
|
||||
use crate::{push_scratch, pop_scratch};
|
||||
use crate::interrupt::handler::ScratchRegisters;
|
||||
use crate::device::cpu::registers::{control_regs, tlb};
|
||||
use crate::paging::{RmmA, RmmArch, TableKind};
|
||||
use crate::syscall::FloatRegisters;
|
||||
use crate::{
|
||||
device::cpu::registers::{control_regs, tlb},
|
||||
interrupt::handler::ScratchRegisters,
|
||||
paging::{RmmA, RmmArch, TableKind},
|
||||
pop_scratch, push_scratch,
|
||||
syscall::FloatRegisters,
|
||||
};
|
||||
|
||||
/// This must be used by the kernel to ensure that context switches are done atomically
|
||||
/// Compare and exchange this to true when beginning a context switch on any CPU
|
||||
@@ -25,24 +29,24 @@ pub const KFX_ALIGN: usize = 16;
|
||||
pub struct Context {
|
||||
elr_el1: usize,
|
||||
sp_el0: usize,
|
||||
pub(crate) tpidr_el0: usize, /* Pointer to TLS region for this Context */
|
||||
pub(crate) tpidr_el0: usize, /* Pointer to TLS region for this Context */
|
||||
pub(crate) tpidrro_el0: usize, /* Pointer to TLS (read-only) region for this Context */
|
||||
spsr_el1: usize,
|
||||
esr_el1: usize,
|
||||
fx_loadable: bool,
|
||||
sp: usize, /* Stack Pointer (x31) */
|
||||
lr: usize, /* Link Register (x30) */
|
||||
fp: usize, /* Frame pointer Register (x29) */
|
||||
x28: usize, /* Callee saved Register */
|
||||
x27: usize, /* Callee saved Register */
|
||||
x26: usize, /* Callee saved Register */
|
||||
x25: usize, /* Callee saved Register */
|
||||
x24: usize, /* Callee saved Register */
|
||||
x23: usize, /* Callee saved Register */
|
||||
x22: usize, /* Callee saved Register */
|
||||
x21: usize, /* Callee saved Register */
|
||||
x20: usize, /* Callee saved Register */
|
||||
x19: usize, /* Callee saved Register */
|
||||
sp: usize, /* Stack Pointer (x31) */
|
||||
lr: usize, /* Link Register (x30) */
|
||||
fp: usize, /* Frame pointer Register (x29) */
|
||||
x28: usize, /* Callee saved Register */
|
||||
x27: usize, /* Callee saved Register */
|
||||
x26: usize, /* Callee saved Register */
|
||||
x25: usize, /* Callee saved Register */
|
||||
x24: usize, /* Callee saved Register */
|
||||
x23: usize, /* Callee saved Register */
|
||||
x22: usize, /* Callee saved Register */
|
||||
x21: usize, /* Callee saved Register */
|
||||
x20: usize, /* Callee saved Register */
|
||||
x19: usize, /* Callee saved Register */
|
||||
}
|
||||
|
||||
impl Context {
|
||||
@@ -92,7 +96,7 @@ impl Context {
|
||||
self.tpidrro_el0
|
||||
}
|
||||
|
||||
pub unsafe fn signal_stack(&mut self, handler: extern fn(usize), sig: u8) {
|
||||
pub unsafe fn signal_stack(&mut self, handler: extern "C" fn(usize), sig: u8) {
|
||||
let lr = self.lr.clone();
|
||||
self.push_pair((sig as usize, lr));
|
||||
self.push_pair((0 as usize, handler as usize));
|
||||
@@ -148,9 +152,7 @@ impl super::Context {
|
||||
panic!("TODO: make get_fx_regs always work");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
ptr::read(self.kfx.as_ptr() as *const FloatRegisters)
|
||||
}
|
||||
unsafe { ptr::read(self.kfx.as_ptr() as *const FloatRegisters) }
|
||||
}
|
||||
|
||||
pub fn set_fx_regs(&mut self, mut new: FloatRegisters) {
|
||||
@@ -231,16 +233,22 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) {
|
||||
// Since Arc is essentially just wraps a pointer, in this case a regular pointer (as
|
||||
// opposed to dyn or slice fat pointers), and NonNull optimization exists, map_or will
|
||||
// hopefully be optimized down to checking prev and next pointers, as next cannot be null.
|
||||
Some(ref next_space) => if prev.addr_space.as_ref().map_or(true, |prev_space| !Arc::ptr_eq(&prev_space, &next_space)) {
|
||||
// Suppose we have two sibling threads A and B. A runs on CPU 0 and B on CPU 1. A
|
||||
// recently called yield and is now here about to switch back. Meanwhile, B is
|
||||
// currently creating a new mapping in their shared address space, for example a
|
||||
// message on a channel.
|
||||
//
|
||||
// Unless we acquire this lock, it may be possible that the TLB will not contain new
|
||||
// entries. While this can be caught and corrected in a page fault handler, this is not
|
||||
// true when entries are removed from a page table!
|
||||
next_space.read().table.utable.make_current();
|
||||
Some(ref next_space) => {
|
||||
if prev
|
||||
.addr_space
|
||||
.as_ref()
|
||||
.map_or(true, |prev_space| !Arc::ptr_eq(&prev_space, &next_space))
|
||||
{
|
||||
// Suppose we have two sibling threads A and B. A runs on CPU 0 and B on CPU 1. A
|
||||
// recently called yield and is now here about to switch back. Meanwhile, B is
|
||||
// currently creating a new mapping in their shared address space, for example a
|
||||
// message on a channel.
|
||||
//
|
||||
// Unless we acquire this lock, it may be possible that the TLB will not contain new
|
||||
// entries. While this can be caught and corrected in a page fault handler, this is not
|
||||
// true when entries are removed from a page table!
|
||||
next_space.read().table.utable.make_current();
|
||||
}
|
||||
}
|
||||
None => {
|
||||
RmmA::set_table(TableKind::User, empty_cr3());
|
||||
@@ -357,13 +365,13 @@ unsafe extern "C" fn switch_to_inner(_prev: &mut Context, _next: &mut Context) {
|
||||
pub struct SignalHandlerStack {
|
||||
scratch: ScratchRegisters,
|
||||
padding: usize,
|
||||
handler: extern fn(usize),
|
||||
handler: extern "C" fn(usize),
|
||||
sig: usize,
|
||||
lr: usize,
|
||||
}
|
||||
|
||||
#[naked]
|
||||
unsafe extern fn signal_handler_wrapper() {
|
||||
unsafe extern "C" fn signal_handler_wrapper() {
|
||||
#[inline(never)]
|
||||
unsafe extern "C" fn inner(stack: &SignalHandlerStack) {
|
||||
(stack.handler)(stack.sig);
|
||||
|
||||
+26
-19
@@ -1,13 +1,14 @@
|
||||
use core::mem;
|
||||
use core::sync::atomic::AtomicBool;
|
||||
use core::{mem, sync::atomic::AtomicBool};
|
||||
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use crate::{push_scratch, pop_scratch};
|
||||
use crate::gdt::{pcr, GDT_USER_FS, GDT_USER_GS};
|
||||
use crate::interrupt::handler::ScratchRegisters;
|
||||
use crate::paging::{RmmA, RmmArch, TableKind};
|
||||
use crate::syscall::FloatRegisters;
|
||||
use crate::{
|
||||
gdt::{pcr, GDT_USER_FS, GDT_USER_GS},
|
||||
interrupt::handler::ScratchRegisters,
|
||||
paging::{RmmA, RmmArch, TableKind},
|
||||
pop_scratch, push_scratch,
|
||||
syscall::FloatRegisters,
|
||||
};
|
||||
|
||||
use core::mem::offset_of;
|
||||
use spin::Once;
|
||||
@@ -67,7 +68,7 @@ impl Context {
|
||||
self.esp = address;
|
||||
}
|
||||
|
||||
pub unsafe fn signal_stack(&mut self, handler: extern fn(usize), sig: u8) {
|
||||
pub unsafe fn signal_stack(&mut self, handler: extern "C" fn(usize), sig: u8) {
|
||||
self.push_stack(sig as usize);
|
||||
self.push_stack(handler as usize);
|
||||
self.push_stack(signal_handler_wrapper as usize);
|
||||
@@ -148,16 +149,22 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) {
|
||||
// Since Arc is essentially just wraps a pointer, in this case a regular pointer (as
|
||||
// opposed to dyn or slice fat pointers), and NonNull optimization exists, map_or will
|
||||
// hopefully be optimized down to checking prev and next pointers, as next cannot be null.
|
||||
Some(ref next_space) => if prev.addr_space.as_ref().map_or(true, |prev_space| !Arc::ptr_eq(&prev_space, &next_space)) {
|
||||
// Suppose we have two sibling threads A and B. A runs on CPU 0 and B on CPU 1. A
|
||||
// recently called yield and is now here about to switch back. Meanwhile, B is
|
||||
// currently creating a new mapping in their shared address space, for example a
|
||||
// message on a channel.
|
||||
//
|
||||
// Unless we acquire this lock, it may be possible that the TLB will not contain new
|
||||
// entries. While this can be caught and corrected in a page fault handler, this is not
|
||||
// true when entries are removed from a page table!
|
||||
next_space.read().table.utable.make_current();
|
||||
Some(ref next_space) => {
|
||||
if prev
|
||||
.addr_space
|
||||
.as_ref()
|
||||
.map_or(true, |prev_space| !Arc::ptr_eq(&prev_space, &next_space))
|
||||
{
|
||||
// Suppose we have two sibling threads A and B. A runs on CPU 0 and B on CPU 1. A
|
||||
// recently called yield and is now here about to switch back. Meanwhile, B is
|
||||
// currently creating a new mapping in their shared address space, for example a
|
||||
// message on a channel.
|
||||
//
|
||||
// Unless we acquire this lock, it may be possible that the TLB will not contain new
|
||||
// entries. While this can be caught and corrected in a page fault handler, this is not
|
||||
// true when entries are removed from a page table!
|
||||
next_space.read().table.utable.make_current();
|
||||
}
|
||||
}
|
||||
None => {
|
||||
RmmA::set_table(TableKind::User, empty_cr3());
|
||||
@@ -238,7 +245,7 @@ unsafe extern "cdecl" fn switch_to_inner() {
|
||||
#[repr(packed)]
|
||||
pub struct SignalHandlerStack {
|
||||
scratch: ScratchRegisters,
|
||||
handler: extern fn(usize),
|
||||
handler: extern "C" fn(usize),
|
||||
sig: usize,
|
||||
eip: usize,
|
||||
}
|
||||
|
||||
+30
-20
@@ -1,13 +1,17 @@
|
||||
use core::mem;
|
||||
use core::ptr::{addr_of, addr_of_mut};
|
||||
use core::sync::atomic::AtomicBool;
|
||||
use core::{
|
||||
mem,
|
||||
ptr::{addr_of, addr_of_mut},
|
||||
sync::atomic::AtomicBool,
|
||||
};
|
||||
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use crate::{push_scratch, pop_scratch};
|
||||
use crate::interrupt::handler::ScratchRegisters;
|
||||
use crate::paging::{RmmA, RmmArch, TableKind};
|
||||
use crate::syscall::FloatRegisters;
|
||||
use crate::{
|
||||
interrupt::handler::ScratchRegisters,
|
||||
paging::{RmmA, RmmArch, TableKind},
|
||||
pop_scratch, push_scratch,
|
||||
syscall::FloatRegisters,
|
||||
};
|
||||
|
||||
use core::mem::offset_of;
|
||||
use spin::Once;
|
||||
@@ -78,7 +82,7 @@ impl Context {
|
||||
self.rsp = address;
|
||||
}
|
||||
|
||||
pub unsafe fn signal_stack(&mut self, handler: extern fn(usize), sig: u8) {
|
||||
pub unsafe fn signal_stack(&mut self, handler: extern "C" fn(usize), sig: u8) {
|
||||
self.push_stack(sig as usize);
|
||||
self.push_stack(handler as usize);
|
||||
self.push_stack(signal_handler_wrapper as usize);
|
||||
@@ -217,16 +221,22 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) {
|
||||
// Since Arc essentially just wraps a pointer, in this case a regular pointer (as opposed
|
||||
// to dyn or slice fat pointers), and NonNull optimization exists, map_or will hopefully be
|
||||
// optimized down to checking prev and next pointers, as next cannot be null.
|
||||
Some(ref next_space) => if prev.addr_space.as_ref().map_or(true, |prev_space| !Arc::ptr_eq(prev_space, next_space)) {
|
||||
// Suppose we have two sibling threads A and B. A runs on CPU 0 and B on CPU 1. A
|
||||
// recently called yield and is now here about to switch back. Meanwhile, B is
|
||||
// currently creating a new mapping in their shared address space, for example a
|
||||
// message on a channel.
|
||||
//
|
||||
// Unless we acquire this lock, it may be possible that the TLB will not contain new
|
||||
// entries. While this can be caught and corrected in a page fault handler, this is not
|
||||
// true when entries are removed from a page table!
|
||||
next_space.read().table.utable.make_current();
|
||||
Some(ref next_space) => {
|
||||
if prev
|
||||
.addr_space
|
||||
.as_ref()
|
||||
.map_or(true, |prev_space| !Arc::ptr_eq(prev_space, next_space))
|
||||
{
|
||||
// Suppose we have two sibling threads A and B. A runs on CPU 0 and B on CPU 1. A
|
||||
// recently called yield and is now here about to switch back. Meanwhile, B is
|
||||
// currently creating a new mapping in their shared address space, for example a
|
||||
// message on a channel.
|
||||
//
|
||||
// Unless we acquire this lock, it may be possible that the TLB will not contain new
|
||||
// entries. While this can be caught and corrected in a page fault handler, this is not
|
||||
// true when entries are removed from a page table!
|
||||
next_space.read().table.utable.make_current();
|
||||
}
|
||||
}
|
||||
None => {
|
||||
RmmA::set_table(TableKind::User, empty_cr3());
|
||||
@@ -308,13 +318,13 @@ unsafe extern "sysv64" fn switch_to_inner(_prev: &mut Context, _next: &mut Conte
|
||||
#[repr(packed)]
|
||||
pub struct SignalHandlerStack {
|
||||
scratch: ScratchRegisters,
|
||||
handler: extern fn(usize),
|
||||
handler: extern "C" fn(usize),
|
||||
sig: usize,
|
||||
rip: usize,
|
||||
}
|
||||
|
||||
#[naked]
|
||||
unsafe extern fn signal_handler_wrapper() {
|
||||
unsafe extern "C" fn signal_handler_wrapper() {
|
||||
#[inline(never)]
|
||||
unsafe extern "C" fn inner(stack: &SignalHandlerStack) {
|
||||
(stack.handler)(stack.sig);
|
||||
|
||||
+94
-48
@@ -1,31 +1,24 @@
|
||||
use core::{
|
||||
cmp::Ordering,
|
||||
mem,
|
||||
};
|
||||
use alloc::{
|
||||
boxed::Box,
|
||||
collections::VecDeque,
|
||||
sync::Arc,
|
||||
vec::Vec, borrow::Cow,
|
||||
};
|
||||
use alloc::{borrow::Cow, boxed::Box, collections::VecDeque, sync::Arc, vec::Vec};
|
||||
use core::{cmp::Ordering, mem};
|
||||
use spin::RwLock;
|
||||
|
||||
use crate::{LogicalCpuId, LogicalCpuSet};
|
||||
use crate::arch::{interrupt::InterruptStack, paging::PAGE_SIZE};
|
||||
use crate::common::aligned_box::AlignedBox;
|
||||
use crate::common::unique::Unique;
|
||||
use crate::context::{self, arch};
|
||||
use crate::context::file::FileDescriptor;
|
||||
use crate::context::memory::AddrSpace;
|
||||
use crate::ipi::{ipi, IpiKind, IpiTarget};
|
||||
use crate::paging::{RmmA, RmmArch};
|
||||
use crate::memory::{RaiiFrame, Frame};
|
||||
use crate::scheme::{SchemeNamespace, FileHandle, CallerCtx};
|
||||
use crate::sync::WaitMap;
|
||||
use crate::{
|
||||
arch::{interrupt::InterruptStack, paging::PAGE_SIZE},
|
||||
common::{aligned_box::AlignedBox, unique::Unique},
|
||||
context::{self, arch, file::FileDescriptor, memory::AddrSpace},
|
||||
ipi::{ipi, IpiKind, IpiTarget},
|
||||
memory::{Frame, RaiiFrame},
|
||||
paging::{RmmA, RmmArch},
|
||||
scheme::{CallerCtx, FileHandle, SchemeNamespace},
|
||||
sync::WaitMap,
|
||||
LogicalCpuId, LogicalCpuSet,
|
||||
};
|
||||
|
||||
use crate::syscall::data::SigAction;
|
||||
use crate::syscall::error::{Result, Error, EAGAIN, ESRCH};
|
||||
use crate::syscall::flag::{SIG_DFL, SigActionFlags};
|
||||
use crate::syscall::{
|
||||
data::SigAction,
|
||||
error::{Error, Result, EAGAIN, ESRCH},
|
||||
flag::{SigActionFlags, SIG_DFL},
|
||||
};
|
||||
|
||||
/// Unique identifier for a context (i.e. `pid`).
|
||||
use ::core::sync::atomic::AtomicUsize;
|
||||
@@ -40,14 +33,15 @@ pub enum Status {
|
||||
Runnable,
|
||||
|
||||
// TODO: Rename to SoftBlocked and move status_reason to this variant.
|
||||
|
||||
/// Not currently runnable, typically due to some blocking syscall, but it can be trivially
|
||||
/// unblocked by e.g. signals.
|
||||
Blocked,
|
||||
|
||||
/// Not currently runnable, and cannot be runnable until manually unblocked, depending on what
|
||||
/// reason.
|
||||
HardBlocked { reason: HardBlockedReason },
|
||||
HardBlocked {
|
||||
reason: HardBlockedReason,
|
||||
},
|
||||
|
||||
Stopped(usize),
|
||||
Exited(usize),
|
||||
@@ -188,11 +182,16 @@ pub struct Context {
|
||||
/// The architecture specific context
|
||||
pub arch: arch::Context,
|
||||
/// Kernel FX - used to store SIMD and FPU registers on context switch
|
||||
pub kfx: AlignedBox<[u8], {arch::KFX_ALIGN}>,
|
||||
pub kfx: AlignedBox<[u8], { arch::KFX_ALIGN }>,
|
||||
/// Kernel stack
|
||||
pub kstack: Option<Box<[u8]>>,
|
||||
/// Kernel signal backup: Registers, Kernel FX, Kernel Stack, Signal number
|
||||
pub ksig: Option<(arch::Context, AlignedBox<[u8], {arch::KFX_ALIGN}>, Option<Box<[u8]>>, u8)>,
|
||||
pub ksig: Option<(
|
||||
arch::Context,
|
||||
AlignedBox<[u8], { arch::KFX_ALIGN }>,
|
||||
Option<Box<[u8]>>,
|
||||
u8,
|
||||
)>,
|
||||
/// Restore ksig context on next switch
|
||||
pub ksig_restore: bool,
|
||||
/// Address space containing a page table lock, and grants. Normally this will have a value,
|
||||
@@ -257,7 +256,7 @@ impl Context {
|
||||
pending: VecDeque::new(),
|
||||
wake: None,
|
||||
arch: arch::Context::new(),
|
||||
kfx: AlignedBox::<[u8], {arch::KFX_ALIGN}>::try_zeroed_slice(crate::arch::kfx_size())?,
|
||||
kfx: AlignedBox::<[u8], { arch::KFX_ALIGN }>::try_zeroed_slice(crate::arch::kfx_size())?,
|
||||
kstack: None,
|
||||
ksig: None,
|
||||
ksig_restore: false,
|
||||
@@ -299,10 +298,10 @@ impl Context {
|
||||
pub fn unblock(&mut self) -> bool {
|
||||
if self.unblock_no_ipi() {
|
||||
if let Some(cpu_id) = self.cpu_id {
|
||||
if cpu_id != crate::cpu_id() {
|
||||
if cpu_id != crate::cpu_id() {
|
||||
// Send IPI if not on current CPU
|
||||
ipi(IpiKind::Wakeup, IpiTarget::Other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
@@ -396,25 +395,37 @@ impl Context {
|
||||
pub fn addr_space(&self) -> Result<&Arc<RwLock<AddrSpace>>> {
|
||||
self.addr_space.as_ref().ok_or(Error::new(ESRCH))
|
||||
}
|
||||
pub fn set_addr_space(&mut self, addr_space: Arc<RwLock<AddrSpace>>) -> Option<Arc<RwLock<AddrSpace>>> {
|
||||
pub fn set_addr_space(
|
||||
&mut self,
|
||||
addr_space: Arc<RwLock<AddrSpace>>,
|
||||
) -> Option<Arc<RwLock<AddrSpace>>> {
|
||||
if self.id == super::context_id() {
|
||||
unsafe { addr_space.read().table.utable.make_current(); }
|
||||
unsafe {
|
||||
addr_space.read().table.utable.make_current();
|
||||
}
|
||||
}
|
||||
|
||||
self.addr_space.replace(addr_space)
|
||||
}
|
||||
pub fn empty_actions() -> Arc<RwLock<Vec<(SigAction, usize)>>> {
|
||||
Arc::new(RwLock::new(vec![(
|
||||
SigAction {
|
||||
sa_handler: unsafe { mem::transmute(SIG_DFL) },
|
||||
sa_mask: [0; 2],
|
||||
sa_flags: SigActionFlags::empty(),
|
||||
},
|
||||
0
|
||||
); 128]))
|
||||
Arc::new(RwLock::new(vec![
|
||||
(
|
||||
SigAction {
|
||||
sa_handler: unsafe { mem::transmute(SIG_DFL) },
|
||||
sa_mask: [0; 2],
|
||||
sa_flags: SigActionFlags::empty(),
|
||||
},
|
||||
0
|
||||
);
|
||||
128
|
||||
]))
|
||||
}
|
||||
pub fn caller_ctx(&self) -> CallerCtx {
|
||||
CallerCtx { pid: self.id.into(), uid: self.euid, gid: self.egid }
|
||||
CallerCtx {
|
||||
pid: self.id.into(),
|
||||
uid: self.euid,
|
||||
gid: self.egid,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,21 +438,51 @@ pub struct BorrowedHtBuf {
|
||||
impl BorrowedHtBuf {
|
||||
pub fn head() -> Result<Self> {
|
||||
Ok(Self {
|
||||
inner: Some(context::current()?.write().syscall_head.take().ok_or(Error::new(EAGAIN))?),
|
||||
inner: Some(
|
||||
context::current()?
|
||||
.write()
|
||||
.syscall_head
|
||||
.take()
|
||||
.ok_or(Error::new(EAGAIN))?,
|
||||
),
|
||||
head_and_not_tail: true,
|
||||
})
|
||||
}
|
||||
pub fn tail() -> Result<Self> {
|
||||
Ok(Self {
|
||||
inner: Some(context::current()?.write().syscall_tail.take().ok_or(Error::new(EAGAIN))?),
|
||||
inner: Some(
|
||||
context::current()?
|
||||
.write()
|
||||
.syscall_tail
|
||||
.take()
|
||||
.ok_or(Error::new(EAGAIN))?,
|
||||
),
|
||||
head_and_not_tail: false,
|
||||
})
|
||||
}
|
||||
pub fn buf(&self) -> &[u8; PAGE_SIZE] {
|
||||
unsafe { &*(RmmA::phys_to_virt(self.inner.as_ref().expect("must succeed").get().start_address()).data() as *const [u8; PAGE_SIZE]) }
|
||||
unsafe {
|
||||
&*(RmmA::phys_to_virt(
|
||||
self.inner
|
||||
.as_ref()
|
||||
.expect("must succeed")
|
||||
.get()
|
||||
.start_address(),
|
||||
)
|
||||
.data() as *const [u8; PAGE_SIZE])
|
||||
}
|
||||
}
|
||||
pub fn buf_mut(&mut self) -> &mut [u8; PAGE_SIZE] {
|
||||
unsafe { &mut *(RmmA::phys_to_virt(self.inner.as_mut().expect("must succeed").get().start_address()).data() as *mut [u8; PAGE_SIZE]) }
|
||||
unsafe {
|
||||
&mut *(RmmA::phys_to_virt(
|
||||
self.inner
|
||||
.as_mut()
|
||||
.expect("must succeed")
|
||||
.get()
|
||||
.start_address(),
|
||||
)
|
||||
.data() as *mut [u8; PAGE_SIZE])
|
||||
}
|
||||
}
|
||||
pub fn frame(&self) -> Frame {
|
||||
self.inner.as_ref().expect("must succeed").get()
|
||||
@@ -477,7 +518,12 @@ impl Drop for BorrowedHtBuf {
|
||||
};
|
||||
match context.write() {
|
||||
mut context => {
|
||||
(if self.head_and_not_tail { &mut context.syscall_head } else { &mut context.syscall_tail }).get_or_insert(inner);
|
||||
(if self.head_and_not_tail {
|
||||
&mut context.syscall_head
|
||||
} else {
|
||||
&mut context.syscall_tail
|
||||
})
|
||||
.get_or_insert(inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-4
@@ -1,10 +1,12 @@
|
||||
//! File structs
|
||||
|
||||
use crate::{
|
||||
event,
|
||||
scheme::{self, SchemeId, SchemeNamespace},
|
||||
syscall::error::{Error, Result, EBADF},
|
||||
};
|
||||
use alloc::sync::Arc;
|
||||
use crate::event;
|
||||
use spin::RwLock;
|
||||
use crate::scheme::{self, SchemeNamespace, SchemeId};
|
||||
use crate::syscall::error::{Result, Error, EBADF};
|
||||
|
||||
/// A file description
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@@ -36,7 +38,8 @@ impl FileDescription {
|
||||
event::unregister_file(self.scheme, self.number);
|
||||
|
||||
let scheme = scheme::schemes()
|
||||
.get(self.scheme).ok_or(Error::new(EBADF))?
|
||||
.get(self.scheme)
|
||||
.ok_or(Error::new(EBADF))?
|
||||
.clone();
|
||||
|
||||
scheme.close(self.number)
|
||||
|
||||
+29
-15
@@ -1,17 +1,16 @@
|
||||
use alloc::sync::Arc;
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::{collections::BTreeMap, sync::Arc};
|
||||
use core::{iter, mem};
|
||||
|
||||
use spin::RwLock;
|
||||
|
||||
use crate::syscall::error::{Result, Error, EAGAIN};
|
||||
use super::context::{Context, ContextId};
|
||||
use crate::syscall::error::{Error, Result, EAGAIN};
|
||||
|
||||
/// Context list type
|
||||
pub struct ContextList {
|
||||
// Using a BTreeMap for it's range method
|
||||
map: BTreeMap<ContextId, Arc<RwLock<Context>>>,
|
||||
next_id: usize
|
||||
next_id: usize,
|
||||
}
|
||||
|
||||
impl ContextList {
|
||||
@@ -19,7 +18,7 @@ impl ContextList {
|
||||
pub const fn new() -> Self {
|
||||
ContextList {
|
||||
map: BTreeMap::new(),
|
||||
next_id: 1
|
||||
next_id: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,12 +28,18 @@ impl ContextList {
|
||||
}
|
||||
|
||||
/// Get an iterator of all parents
|
||||
pub fn ancestors(&'_ self, id: ContextId) -> impl Iterator<Item = (ContextId, &Arc<RwLock<Context>>)> + '_ {
|
||||
iter::successors(self.get(id).map(|context| (id, context)), move |(_id, context)| {
|
||||
let context = context.read();
|
||||
let id = context.ppid;
|
||||
self.get(id).map(|context| (id, context))
|
||||
})
|
||||
pub fn ancestors(
|
||||
&'_ self,
|
||||
id: ContextId,
|
||||
) -> impl Iterator<Item = (ContextId, &Arc<RwLock<Context>>)> + '_ {
|
||||
iter::successors(
|
||||
self.get(id).map(|context| (id, context)),
|
||||
move |(_id, context)| {
|
||||
let context = context.read();
|
||||
let id = context.ppid;
|
||||
self.get(id).map(|context| (id, context))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Get the current context.
|
||||
@@ -46,14 +51,23 @@ impl ContextList {
|
||||
self.map.iter()
|
||||
}
|
||||
|
||||
pub fn range(&self, range: impl core::ops::RangeBounds<ContextId>) -> ::alloc::collections::btree_map::Range<'_, ContextId, Arc<RwLock<Context>>> {
|
||||
pub fn range(
|
||||
&self,
|
||||
range: impl core::ops::RangeBounds<ContextId>,
|
||||
) -> ::alloc::collections::btree_map::Range<'_, ContextId, Arc<RwLock<Context>>> {
|
||||
self.map.range(range)
|
||||
}
|
||||
|
||||
pub(crate) fn insert_context_raw(&mut self, id: ContextId) -> Result<&Arc<RwLock<Context>>> {
|
||||
assert!(self.map.insert(id, Arc::new(RwLock::new(Context::new(id)?))).is_none());
|
||||
assert!(self
|
||||
.map
|
||||
.insert(id, Arc::new(RwLock::new(Context::new(id)?)))
|
||||
.is_none());
|
||||
|
||||
Ok(self.map.get(&id).expect("Failed to insert new context. ID is out of bounds."))
|
||||
Ok(self
|
||||
.map
|
||||
.get(&id)
|
||||
.expect("Failed to insert new context. ID is out of bounds."))
|
||||
}
|
||||
|
||||
/// Create a new context.
|
||||
@@ -84,7 +98,7 @@ impl ContextList {
|
||||
}
|
||||
|
||||
/// Spawn a context from a function.
|
||||
pub fn spawn(&mut self, func: extern fn()) -> Result<&Arc<RwLock<Context>>> {
|
||||
pub fn spawn(&mut self, func: extern "C" fn()) -> Result<&Arc<RwLock<Context>>> {
|
||||
let context_lock = self.new_context()?;
|
||||
{
|
||||
let mut context = context_lock.write();
|
||||
|
||||
+860
-253
File diff suppressed because it is too large
Load Diff
+22
-12
@@ -2,19 +2,22 @@
|
||||
//!
|
||||
//! For resources on contexts, please consult [wikipedia](https://en.wikipedia.org/wiki/Context_switch) and [osdev](https://wiki.osdev.org/Context_Switching)
|
||||
|
||||
use alloc::borrow::Cow;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::{borrow::Cow, sync::Arc};
|
||||
|
||||
use spin::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
use crate::LogicalCpuSet;
|
||||
use crate::paging::{RmmA, RmmArch, TableKind};
|
||||
use crate::percpu::PercpuBlock;
|
||||
use crate::syscall::error::{Error, ESRCH, Result};
|
||||
use crate::{
|
||||
paging::{RmmA, RmmArch, TableKind},
|
||||
percpu::PercpuBlock,
|
||||
syscall::error::{Error, Result, ESRCH},
|
||||
LogicalCpuSet,
|
||||
};
|
||||
|
||||
pub use self::context::{BorrowedHtBuf, Context, ContextId, Status, WaitpidKey};
|
||||
pub use self::list::ContextList;
|
||||
pub use self::switch::switch;
|
||||
pub use self::{
|
||||
context::{BorrowedHtBuf, Context, ContextId, Status, WaitpidKey},
|
||||
list::ContextList,
|
||||
switch::switch,
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[path = "arch/aarch64.rs"]
|
||||
@@ -65,7 +68,9 @@ pub use self::arch::empty_cr3;
|
||||
pub fn init() {
|
||||
let mut contexts = contexts_mut();
|
||||
let id = ContextId::from(crate::cpu_id().get() as usize + 1);
|
||||
let context_lock = contexts.insert_context_raw(id).expect("could not initialize first context");
|
||||
let context_lock = contexts
|
||||
.insert_context_raw(id)
|
||||
.expect("could not initialize first context");
|
||||
let mut context = context_lock.write();
|
||||
context.sched_affinity = LogicalCpuSet::single(crate::cpu_id());
|
||||
context.name = Cow::Borrowed("kmain");
|
||||
@@ -77,7 +82,9 @@ pub fn init() {
|
||||
context.cpu_id = Some(crate::cpu_id());
|
||||
|
||||
unsafe {
|
||||
PercpuBlock::current().switch_internals.set_context_id(context.id);
|
||||
PercpuBlock::current()
|
||||
.switch_internals
|
||||
.set_context_id(context.id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,5 +103,8 @@ pub fn context_id() -> ContextId {
|
||||
}
|
||||
|
||||
pub fn current() -> Result<Arc<RwLock<Context>>> {
|
||||
contexts().current().ok_or(Error::new(ESRCH)).map(Arc::clone)
|
||||
contexts()
|
||||
.current()
|
||||
.ok_or(Error::new(ESRCH))
|
||||
.map(Arc::clone)
|
||||
}
|
||||
|
||||
+53
-25
@@ -1,12 +1,19 @@
|
||||
use alloc::sync::Arc;
|
||||
use core::mem;
|
||||
use syscall::flag::{PTRACE_FLAG_IGNORE, PTRACE_STOP_SIGNAL, SIG_DFL, SIG_IGN, SIGCHLD, SIGCONT, SIGKILL, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU};
|
||||
use syscall::ptrace_event;
|
||||
use syscall::{
|
||||
flag::{
|
||||
PTRACE_FLAG_IGNORE, PTRACE_STOP_SIGNAL, SIGCHLD, SIGCONT, SIGKILL, SIGSTOP, SIGTSTP,
|
||||
SIGTTIN, SIGTTOU, SIG_DFL, SIG_IGN,
|
||||
},
|
||||
ptrace_event,
|
||||
};
|
||||
|
||||
use crate::context::{contexts, switch, Status, WaitpidKey};
|
||||
use crate::start::usermode;
|
||||
use crate::ptrace;
|
||||
use crate::syscall::usercopy::UserSlice;
|
||||
use crate::{
|
||||
context::{contexts, switch, Status, WaitpidKey},
|
||||
ptrace,
|
||||
start::usermode,
|
||||
syscall::usercopy::UserSlice,
|
||||
};
|
||||
|
||||
pub fn is_user_handled(handler: Option<extern "C" fn(usize)>) -> bool {
|
||||
let handler = handler.map(|ptr| ptr as usize).unwrap_or(0);
|
||||
@@ -16,7 +23,9 @@ pub fn is_user_handled(handler: Option<extern "C" fn(usize)>) -> bool {
|
||||
pub extern "C" fn signal_handler(sig: usize) {
|
||||
let ((action, restorer), sigstack) = {
|
||||
let contexts = contexts();
|
||||
let context_lock = contexts.current().expect("context::signal_handler not inside of context");
|
||||
let context_lock = contexts
|
||||
.current()
|
||||
.expect("context::signal_handler not inside of context");
|
||||
let context = context_lock.read();
|
||||
let actions = context.actions.read();
|
||||
(actions[sig], context.sigstack)
|
||||
@@ -24,8 +33,11 @@ pub extern "C" fn signal_handler(sig: usize) {
|
||||
|
||||
let handler = action.sa_handler.map(|ptr| ptr as usize).unwrap_or(0);
|
||||
|
||||
let thumbs_down = ptrace::breakpoint_callback(PTRACE_STOP_SIGNAL, Some(ptrace_event!(PTRACE_STOP_SIGNAL, sig, handler)))
|
||||
.and_then(|_| ptrace::next_breakpoint().map(|f| f.contains(PTRACE_FLAG_IGNORE)));
|
||||
let thumbs_down = ptrace::breakpoint_callback(
|
||||
PTRACE_STOP_SIGNAL,
|
||||
Some(ptrace_event!(PTRACE_STOP_SIGNAL, sig, handler)),
|
||||
)
|
||||
.and_then(|_| ptrace::next_breakpoint().map(|f| f.contains(PTRACE_FLAG_IGNORE)));
|
||||
|
||||
if sig != SIGKILL && thumbs_down.unwrap_or(false) {
|
||||
// If signal can be and was ignored
|
||||
@@ -37,7 +49,7 @@ pub extern "C" fn signal_handler(sig: usize) {
|
||||
match sig {
|
||||
SIGCHLD => {
|
||||
// println!("SIGCHLD");
|
||||
},
|
||||
}
|
||||
SIGCONT => {
|
||||
// println!("Continue");
|
||||
|
||||
@@ -45,7 +57,9 @@ pub extern "C" fn signal_handler(sig: usize) {
|
||||
let contexts = contexts();
|
||||
|
||||
let (pid, pgid, ppid) = {
|
||||
let context_lock = contexts.current().expect("context::signal_handler not inside of context");
|
||||
let context_lock = contexts
|
||||
.current()
|
||||
.expect("context::signal_handler not inside of context");
|
||||
let mut context = context_lock.write();
|
||||
context.status = Status::Runnable;
|
||||
(context.id, context.pgid, context.ppid)
|
||||
@@ -57,15 +71,18 @@ pub extern "C" fn signal_handler(sig: usize) {
|
||||
Arc::clone(&parent.waitpid)
|
||||
};
|
||||
|
||||
waitpid.send(WaitpidKey {
|
||||
pid: Some(pid),
|
||||
pgid: Some(pgid)
|
||||
}, (pid, 0xFFFF));
|
||||
waitpid.send(
|
||||
WaitpidKey {
|
||||
pid: Some(pid),
|
||||
pgid: Some(pgid),
|
||||
},
|
||||
(pid, 0xFFFF),
|
||||
);
|
||||
} else {
|
||||
println!("{}: {} not found for continue", pid.get(), ppid.get());
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
SIGSTOP | SIGTSTP | SIGTTIN | SIGTTOU => {
|
||||
// println!("Stop {}", sig);
|
||||
|
||||
@@ -73,7 +90,9 @@ pub extern "C" fn signal_handler(sig: usize) {
|
||||
let contexts = contexts();
|
||||
|
||||
let (pid, pgid, ppid) = {
|
||||
let context_lock = contexts.current().expect("context::signal_handler not inside of context");
|
||||
let context_lock = contexts
|
||||
.current()
|
||||
.expect("context::signal_handler not inside of context");
|
||||
let mut context = context_lock.write();
|
||||
context.status = Status::Stopped(sig);
|
||||
(context.id, context.pgid, context.ppid)
|
||||
@@ -85,17 +104,20 @@ pub extern "C" fn signal_handler(sig: usize) {
|
||||
Arc::clone(&parent.waitpid)
|
||||
};
|
||||
|
||||
waitpid.send(WaitpidKey {
|
||||
pid: Some(pid),
|
||||
pgid: Some(pgid)
|
||||
}, (pid, (sig << 8) | 0x7F));
|
||||
waitpid.send(
|
||||
WaitpidKey {
|
||||
pid: Some(pid),
|
||||
pgid: Some(pgid),
|
||||
},
|
||||
(pid, (sig << 8) | 0x7F),
|
||||
);
|
||||
} else {
|
||||
println!("{}: {} not found for stop", pid.get(), ppid.get());
|
||||
}
|
||||
}
|
||||
|
||||
unsafe { switch() };
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
// println!("Exit {}", sig);
|
||||
crate::syscall::exit(sig);
|
||||
@@ -108,10 +130,14 @@ pub extern "C" fn signal_handler(sig: usize) {
|
||||
|
||||
let singlestep = {
|
||||
let contexts = contexts();
|
||||
let context = contexts.current().expect("context::signal_handler userspace not inside of context");
|
||||
let context = contexts
|
||||
.current()
|
||||
.expect("context::signal_handler userspace not inside of context");
|
||||
let context = context.read();
|
||||
unsafe {
|
||||
ptrace::regs_for(&context).map(|s| s.is_singlestep()).unwrap_or(false)
|
||||
ptrace::regs_for(&context)
|
||||
.map(|s| s.is_singlestep())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -123,7 +149,9 @@ pub extern "C" fn signal_handler(sig: usize) {
|
||||
|
||||
sp -= mem::size_of::<usize>();
|
||||
|
||||
match UserSlice::wo(sp, core::mem::size_of::<usize>()).and_then(|buf| buf.write_usize(restorer)) {
|
||||
match UserSlice::wo(sp, core::mem::size_of::<usize>())
|
||||
.and_then(|buf| buf.write_usize(restorer))
|
||||
{
|
||||
Ok(()) => usermode(handler, sp, sig, usize::from(singlestep)),
|
||||
Err(error) => {
|
||||
log::error!("Failed to signal: {}", error);
|
||||
|
||||
+47
-28
@@ -1,17 +1,15 @@
|
||||
use core::cell::Cell;
|
||||
use core::ops::Bound;
|
||||
use core::sync::atomic::Ordering;
|
||||
use core::{cell::Cell, ops::Bound, sync::atomic::Ordering};
|
||||
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use spin::{RwLock, RwLockWriteGuard};
|
||||
|
||||
use crate::context::signal::signal_handler;
|
||||
use crate::context::{arch, contexts, Context};
|
||||
use crate::{interrupt, LogicalCpuId};
|
||||
use crate::percpu::PercpuBlock;
|
||||
use crate::ptrace;
|
||||
use crate::time;
|
||||
use crate::{
|
||||
context::{arch, contexts, signal::signal_handler, Context},
|
||||
interrupt,
|
||||
percpu::PercpuBlock,
|
||||
ptrace, time, LogicalCpuId,
|
||||
};
|
||||
|
||||
use super::ContextId;
|
||||
|
||||
@@ -33,15 +31,24 @@ unsafe fn update_runnable(context: &mut Context, cpu_id: LogicalCpuId) -> bool {
|
||||
|
||||
// Restore from signal, must only be done from another context to avoid overwriting the stack!
|
||||
if context.ksig_restore {
|
||||
let was_singlestep = ptrace::regs_for(context).map(|s| s.is_singlestep()).unwrap_or(false);
|
||||
let was_singlestep = ptrace::regs_for(context)
|
||||
.map(|s| s.is_singlestep())
|
||||
.unwrap_or(false);
|
||||
|
||||
let ksig = context.ksig.take().expect("context::switch: ksig not set with ksig_restore");
|
||||
let ksig = context
|
||||
.ksig
|
||||
.take()
|
||||
.expect("context::switch: ksig not set with ksig_restore");
|
||||
context.arch = ksig.0;
|
||||
|
||||
context.kfx.copy_from_slice(&*ksig.1);
|
||||
|
||||
if let Some(ref mut kstack) = context.kstack {
|
||||
kstack.copy_from_slice(&ksig.2.expect("context::switch: ksig kstack not set with ksig_restore"));
|
||||
kstack.copy_from_slice(
|
||||
&ksig
|
||||
.2
|
||||
.expect("context::switch: ksig kstack not set with ksig_restore"),
|
||||
);
|
||||
} else {
|
||||
panic!("context::switch: kstack not set with ksig_restore");
|
||||
}
|
||||
@@ -81,7 +88,6 @@ struct SwitchResult {
|
||||
next_lock: Arc<RwLock<Context>>,
|
||||
}
|
||||
|
||||
|
||||
pub fn tick() {
|
||||
let ticks_cell = &PercpuBlock::current().switch_internals.pit_ticks;
|
||||
|
||||
@@ -95,7 +101,11 @@ pub fn tick() {
|
||||
}
|
||||
|
||||
pub unsafe extern "C" fn switch_finish_hook() {
|
||||
if let Some(SwitchResult { prev_lock, next_lock }) = PercpuBlock::current().switch_internals.switch_result.take() {
|
||||
if let Some(SwitchResult {
|
||||
prev_lock,
|
||||
next_lock,
|
||||
}) = PercpuBlock::current().switch_internals.switch_result.take()
|
||||
{
|
||||
prev_lock.force_write_unlock();
|
||||
next_lock.force_write_unlock();
|
||||
} else {
|
||||
@@ -118,7 +128,10 @@ pub unsafe fn switch() -> bool {
|
||||
|
||||
// Set the global lock to avoid the unsafe operations below from causing issues
|
||||
// TODO: Better memory orderings?
|
||||
while arch::CONTEXT_SWITCH_LOCK.compare_exchange_weak(false, true, Ordering::SeqCst, Ordering::Relaxed).is_err() {
|
||||
while arch::CONTEXT_SWITCH_LOCK
|
||||
.compare_exchange_weak(false, true, Ordering::SeqCst, Ordering::Relaxed)
|
||||
.is_err()
|
||||
{
|
||||
interrupt::pause();
|
||||
}
|
||||
|
||||
@@ -130,20 +143,21 @@ pub unsafe fn switch() -> bool {
|
||||
let contexts = contexts();
|
||||
|
||||
// Lock previous context
|
||||
let prev_context_lock = contexts.current().expect("context::switch: not inside of context");
|
||||
let prev_context_lock = contexts
|
||||
.current()
|
||||
.expect("context::switch: not inside of context");
|
||||
let prev_context_guard = prev_context_lock.write();
|
||||
|
||||
// Locate next context
|
||||
for (_pid, next_context_lock) in contexts
|
||||
// Include all contexts with IDs greater than the current...
|
||||
.range(
|
||||
(Bound::Excluded(prev_context_guard.id), Bound::Unbounded)
|
||||
.range((Bound::Excluded(prev_context_guard.id), Bound::Unbounded))
|
||||
.chain(
|
||||
contexts
|
||||
// ... and all contexts with IDs less than the current...
|
||||
.range((Bound::Unbounded, Bound::Excluded(prev_context_guard.id))),
|
||||
)
|
||||
.chain(contexts
|
||||
// ... and all contexts with IDs less than the current...
|
||||
.range((Bound::Unbounded, Bound::Excluded(prev_context_guard.id)))
|
||||
)
|
||||
// ... but not the current context, which is already locked
|
||||
// ... but not the current context, which is already locked
|
||||
{
|
||||
// Lock next context
|
||||
let mut next_context_guard = next_context_lock.write();
|
||||
@@ -165,7 +179,9 @@ pub unsafe fn switch() -> bool {
|
||||
};
|
||||
|
||||
// Switch process states, TSS stack pointer, and store new context ID
|
||||
if let Some((prev_context_lock, prev_context_ptr, next_context_lock, next_context_ptr)) = switch_context_opt {
|
||||
if let Some((prev_context_lock, prev_context_ptr, next_context_lock, next_context_ptr)) =
|
||||
switch_context_opt
|
||||
{
|
||||
// Set old context as not running and update CPU time
|
||||
let prev_context = &mut *prev_context_ptr;
|
||||
prev_context.running = false;
|
||||
@@ -198,10 +214,13 @@ pub unsafe fn switch() -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
percpu.switch_internals.switch_result.set(Some(SwitchResult {
|
||||
prev_lock: prev_context_lock,
|
||||
next_lock: next_context_lock,
|
||||
}));
|
||||
percpu
|
||||
.switch_internals
|
||||
.switch_result
|
||||
.set(Some(SwitchResult {
|
||||
prev_lock: prev_context_lock,
|
||||
next_lock: next_context_lock,
|
||||
}));
|
||||
|
||||
arch::switch_to(prev_context, next_context);
|
||||
|
||||
|
||||
+13
-9
@@ -1,11 +1,15 @@
|
||||
use alloc::collections::VecDeque;
|
||||
use spin::{Once, Mutex, MutexGuard};
|
||||
use spin::{Mutex, MutexGuard, Once};
|
||||
|
||||
use crate::event;
|
||||
use crate::scheme::SchemeId;
|
||||
use crate::syscall::data::TimeSpec;
|
||||
use crate::syscall::flag::{CLOCK_MONOTONIC, CLOCK_REALTIME, EVENT_READ};
|
||||
use crate::time;
|
||||
use crate::{
|
||||
event,
|
||||
scheme::SchemeId,
|
||||
syscall::{
|
||||
data::TimeSpec,
|
||||
flag::{CLOCK_MONOTONIC, CLOCK_REALTIME, EVENT_READ},
|
||||
},
|
||||
time,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Timeout {
|
||||
@@ -35,7 +39,7 @@ pub fn register(scheme_id: SchemeId, event_id: usize, clock: usize, time: TimeSp
|
||||
scheme_id,
|
||||
event_id,
|
||||
clock,
|
||||
time: (time.tv_sec as u128 * time::NANOS_PER_SEC) + (time.tv_nsec as u128)
|
||||
time: (time.tv_sec as u128 * time::NANOS_PER_SEC) + (time.tv_nsec as u128),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -51,11 +55,11 @@ pub fn trigger() {
|
||||
CLOCK_MONOTONIC => {
|
||||
let time = registry[i].time;
|
||||
mono >= time
|
||||
},
|
||||
}
|
||||
CLOCK_REALTIME => {
|
||||
let time = registry[i].time;
|
||||
real >= time
|
||||
},
|
||||
}
|
||||
clock => {
|
||||
println!("timeout::trigger: unknown clock {}", clock);
|
||||
true
|
||||
|
||||
Reference in New Issue
Block a user