refactor: fix kernel warnings
This commit is contained in:
parent
74be46b29b
commit
49942563ef
@ -11,7 +11,7 @@ use async_trait::async_trait;
|
|||||||
use libk::{
|
use libk::{
|
||||||
block,
|
block,
|
||||||
error::Error,
|
error::Error,
|
||||||
task::runtime::{run_with_timeout, FutureTimeout},
|
task::runtime::with_timeout,
|
||||||
vfs::{ConnectionSocket, FileReadiness, ListenerSocket, Socket},
|
vfs::{ConnectionSocket, FileReadiness, ListenerSocket, Socket},
|
||||||
};
|
};
|
||||||
use libk_device::monotonic_timestamp;
|
use libk_device::monotonic_timestamp;
|
||||||
@ -64,7 +64,7 @@ impl TcpSocket {
|
|||||||
) -> Result<(SocketAddr, Arc<TcpSocket>), Error> {
|
) -> Result<(SocketAddr, Arc<TcpSocket>), Error> {
|
||||||
let future = Self::connect_async(remote);
|
let future = Self::connect_async(remote);
|
||||||
match timeout {
|
match timeout {
|
||||||
Some(timeout) => run_with_timeout(timeout, future).await.into(),
|
Some(timeout) => with_timeout(future, timeout).await?.into(),
|
||||||
None => future.await,
|
None => future.await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -290,10 +290,7 @@ impl TcpSocket {
|
|||||||
connection.poll_established(cx)
|
connection.poll_established(cx)
|
||||||
});
|
});
|
||||||
|
|
||||||
match run_with_timeout(timeout, fut).await {
|
with_timeout(fut, timeout).await?
|
||||||
FutureTimeout::Ok(value) => value,
|
|
||||||
FutureTimeout::Timeout => Err(Error::TimedOut),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ use alloc::{boxed::Box, collections::BTreeMap, sync::Arc, vec, vec::Vec};
|
|||||||
use atomic_enum::atomic_enum;
|
use atomic_enum::atomic_enum;
|
||||||
use device_api::{interrupt::InterruptHandler, Device};
|
use device_api::{interrupt::InterruptHandler, Device};
|
||||||
use futures_util::task::AtomicWaker;
|
use futures_util::task::AtomicWaker;
|
||||||
use libk::task::runtime::{self, FutureTimeout};
|
use libk::task::runtime;
|
||||||
use libk_mm::{
|
use libk_mm::{
|
||||||
address::{AsPhysicalAddress, PhysicalAddress},
|
address::{AsPhysicalAddress, PhysicalAddress},
|
||||||
PageBox,
|
PageBox,
|
||||||
@ -278,8 +278,7 @@ impl Xhci {
|
|||||||
|
|
||||||
// Wait for port reset
|
// Wait for port reset
|
||||||
// TODO handle disconnect during reset?
|
// TODO handle disconnect during reset?
|
||||||
let result = runtime::run_with_timeout(
|
let result = runtime::with_timeout(
|
||||||
Duration::from_secs(1),
|
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
let state = &self.port_states[port];
|
let state = &self.port_states[port];
|
||||||
|
|
||||||
@ -290,12 +289,13 @@ impl Xhci {
|
|||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
Duration::from_secs(1),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
FutureTimeout::Ok(()) => Ok(()),
|
Ok(()) => Ok(()),
|
||||||
FutureTimeout::Timeout => Err(UsbError::PortResetFailed),
|
Err(_) => Err(UsbError::PortResetFailed),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,8 +9,6 @@ use core::{
|
|||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use kernel_arch_interface::mem::KernelTableManager;
|
use kernel_arch_interface::mem::KernelTableManager;
|
||||||
|
|
||||||
use crate::table::EntryLevel;
|
|
||||||
|
|
||||||
/// Wrapper type to represent a physical memory address
|
/// Wrapper type to represent a physical memory address
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Pod, Zeroable)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Pod, Zeroable)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use core::ops::Range;
|
use core::ops::{Deref, Range};
|
||||||
|
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use kernel_arch::ProcessAddressSpaceImpl;
|
use kernel_arch::ProcessAddressSpaceImpl;
|
||||||
@ -7,7 +7,7 @@ use libk_mm_interface::{
|
|||||||
process::ProcessAddressSpaceManager,
|
process::ProcessAddressSpaceManager,
|
||||||
table::{MapAttributes, TableAllocator},
|
table::{MapAttributes, TableAllocator},
|
||||||
};
|
};
|
||||||
use libk_util::sync::IrqSafeSpinlock;
|
use libk_util::sync::{IrqSafeSpinlock, IrqSafeSpinlockGuard};
|
||||||
use vmalloc::{RangeData, VirtualMemoryAllocator};
|
use vmalloc::{RangeData, VirtualMemoryAllocator};
|
||||||
use yggdrasil_abi::error::Error;
|
use yggdrasil_abi::error::Error;
|
||||||
|
|
||||||
@ -26,6 +26,13 @@ pub enum VirtualRangeBacking {
|
|||||||
File(FileBacking),
|
File(FileBacking),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrapper type for ensuring the translation table cannot be modified while performing accesses
|
||||||
|
/// to the inner [PhysicalAddress].
|
||||||
|
pub struct TranslateGuard<'a, TA: TableAllocator> {
|
||||||
|
address: PhysicalAddress,
|
||||||
|
_guard: IrqSafeSpinlockGuard<'a, Inner<TA>>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Describes a file-backed memory range provider
|
/// Describes a file-backed memory range provider
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FileBacking {
|
pub struct FileBacking {
|
||||||
@ -415,6 +422,17 @@ impl<TA: TableAllocator> ProcessAddressSpace<TA> {
|
|||||||
self.inner.lock().table.translate(address).map(|e| e.0)
|
self.inner.lock().table.translate(address).map(|e| e.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Same as [ProcessAddressSpace::translate], except the lock on the address space is held
|
||||||
|
/// until the resulting [TranslateGuard] is dropped.
|
||||||
|
pub fn translate_lock(&self, address: usize) -> Result<TranslateGuard<TA>, Error> {
|
||||||
|
let guard = self.inner.lock();
|
||||||
|
let address = guard.table.translate(address).map(|e| e.0)?;
|
||||||
|
Ok(TranslateGuard {
|
||||||
|
address,
|
||||||
|
_guard: guard,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Removes a single PAGE_SIZE mapping from the address space.
|
/// Removes a single PAGE_SIZE mapping from the address space.
|
||||||
///
|
///
|
||||||
/// See [ProcessAddressSpaceManager::unmap].
|
/// See [ProcessAddressSpaceManager::unmap].
|
||||||
@ -449,3 +467,11 @@ impl<TA: TableAllocator> Drop for ProcessAddressSpace<TA> {
|
|||||||
self.clear().ok();
|
self.clear().ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<TA: TableAllocator> Deref for TranslateGuard<'_, TA> {
|
||||||
|
type Target = PhysicalAddress;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
trait_upcasting,
|
trait_upcasting,
|
||||||
arbitrary_self_types,
|
arbitrary_self_types,
|
||||||
slice_split_once,
|
slice_split_once,
|
||||||
arbitrary_self_types_pointers
|
arbitrary_self_types_pointers,
|
||||||
|
result_flattening
|
||||||
)]
|
)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
@ -5,7 +5,6 @@ use alloc::sync::Arc;
|
|||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use elf::{
|
use elf::{
|
||||||
endian::AnyEndian,
|
endian::AnyEndian,
|
||||||
io_traits::InputStream,
|
|
||||||
relocation::{Rel, Rela},
|
relocation::{Rel, Rela},
|
||||||
segment::ProgramHeader,
|
segment::ProgramHeader,
|
||||||
ElfStream, ParseError,
|
ElfStream, ParseError,
|
||||||
@ -14,14 +13,14 @@ use libk_mm::{
|
|||||||
pointer::PhysicalRefMut,
|
pointer::PhysicalRefMut,
|
||||||
process::{ProcessAddressSpace, VirtualRangeBacking},
|
process::{ProcessAddressSpace, VirtualRangeBacking},
|
||||||
table::MapAttributes,
|
table::MapAttributes,
|
||||||
PageBox, L3_PAGE_SIZE,
|
L3_PAGE_SIZE,
|
||||||
};
|
};
|
||||||
use libk_util::io::{Read, Seek};
|
use libk_util::io::{Read, Seek};
|
||||||
use yggdrasil_abi::{error::Error, io::SeekFrom, path::PathBuf};
|
use yggdrasil_abi::{error::Error, io::SeekFrom, path::PathBuf};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
random,
|
random,
|
||||||
task::{mem::ForeignPointer, process::ProcessImage, types::TlsImage},
|
task::{process::ProcessImage, types::TlsImage},
|
||||||
};
|
};
|
||||||
|
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use core::{alloc::Layout, ptr::NonNull};
|
|
||||||
|
|
||||||
use alloc::{
|
use alloc::{
|
||||||
borrow::ToOwned,
|
borrow::ToOwned,
|
||||||
string::String,
|
string::String,
|
||||||
@ -18,7 +16,6 @@ use libk_util::io::{Read, Seek};
|
|||||||
use yggdrasil_abi::{
|
use yggdrasil_abi::{
|
||||||
error::Error,
|
error::Error,
|
||||||
io::SeekFrom,
|
io::SeekFrom,
|
||||||
pass::{Place, Placer},
|
|
||||||
path::Path,
|
path::Path,
|
||||||
process::{auxv, AuxValue, ProcessGroupId},
|
process::{auxv, AuxValue, ProcessGroupId},
|
||||||
};
|
};
|
||||||
|
@ -1,27 +1,22 @@
|
|||||||
use core::{
|
use core::{
|
||||||
future::poll_fn,
|
future::poll_fn,
|
||||||
pin::Pin,
|
ptr,
|
||||||
sync::atomic::{AtomicU32, Ordering},
|
sync::atomic::{AtomicU32, Ordering},
|
||||||
task::{Context, Poll},
|
task::Poll,
|
||||||
};
|
};
|
||||||
|
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use futures_util::Future;
|
use libk_mm::process::ProcessAddressSpace;
|
||||||
use libk_mm::{
|
|
||||||
address::{AsPhysicalAddress, PhysicalAddress},
|
|
||||||
pointer::PhysicalRef,
|
|
||||||
process::ProcessAddressSpace,
|
|
||||||
};
|
|
||||||
use libk_util::waker::QueueWaker;
|
use libk_util::waker::QueueWaker;
|
||||||
use yggdrasil_abi::error::Error;
|
use yggdrasil_abi::error::Error;
|
||||||
|
|
||||||
use crate::task::thread::Thread;
|
use crate::task::mem::ForeignAtomic;
|
||||||
|
|
||||||
/// User-space mutex (like BSD/Linux's futex) data structure
|
/// User-space mutex (like BSD/Linux's futex) data structure
|
||||||
pub struct UserspaceMutex {
|
pub struct UserspaceMutex {
|
||||||
queue: QueueWaker,
|
queue: QueueWaker,
|
||||||
space: Arc<ProcessAddressSpace>,
|
space: Arc<ProcessAddressSpace>,
|
||||||
address: usize,
|
atomic: *const AtomicU32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserspaceMutex {
|
impl UserspaceMutex {
|
||||||
@ -30,35 +25,42 @@ impl UserspaceMutex {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
queue: QueueWaker::new(),
|
queue: QueueWaker::new(),
|
||||||
space: space.clone(),
|
space: space.clone(),
|
||||||
address,
|
atomic: ptr::with_exposed_provenance(address),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load(&self) -> u32 {
|
fn load(&self) -> Result<u32, Error> {
|
||||||
// TODO: this is slow, but this prevents the kernel from reading from unmapped memory
|
self.atomic
|
||||||
let phys = self.space.translate(self.address).unwrap();
|
.atomic_load_foreign(&self.space, Ordering::Acquire)
|
||||||
unsafe { PhysicalRef::<AtomicU32>::map(phys).load(Ordering::Acquire) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_predicate<P: Fn(u32) -> bool>(&self, predicate: P) {
|
async fn wait_predicate<P: Fn(u32) -> bool>(&self, predicate: P) -> Result<(), Error> {
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
if predicate(self.load()) {
|
let result = self.load();
|
||||||
self.queue.remove(cx.waker());
|
match result {
|
||||||
Poll::Ready(())
|
Err(err) => {
|
||||||
} else {
|
self.queue.remove(cx.waker());
|
||||||
self.queue.register(cx.waker());
|
Poll::Ready(Err(err))
|
||||||
Poll::Pending
|
}
|
||||||
|
Ok(val) if predicate(val) => {
|
||||||
|
self.queue.remove(cx.waker());
|
||||||
|
Poll::Ready(Ok(()))
|
||||||
|
}
|
||||||
|
Ok(_) => {
|
||||||
|
self.queue.register(cx.waker());
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn wait_until(self: Arc<Self>, compare_value: u32) {
|
pub async fn wait_until(self: Arc<Self>, compare_value: u32) -> Result<(), Error> {
|
||||||
self.wait_predicate(|value| value == compare_value).await
|
self.wait_predicate(|value| value == compare_value).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Blocks until the value at the mutex's address becomes different from `compare_value`
|
/// Blocks until the value at the mutex's address becomes different from `compare_value`
|
||||||
pub async fn wait(self: Arc<Self>, compare_value: u32) {
|
pub async fn wait(self: Arc<Self>, compare_value: u32) -> Result<(), Error> {
|
||||||
self.wait_predicate(|value| value != compare_value).await
|
self.wait_predicate(|value| value != compare_value).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
use core::{alloc::Layout, mem::size_of};
|
use core::{
|
||||||
|
alloc::Layout,
|
||||||
|
mem::size_of,
|
||||||
|
ptr,
|
||||||
|
sync::atomic::{AtomicU32, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
use libk_mm::{address::Virtualize, process::ProcessAddressSpace};
|
use libk_mm::{address::Virtualize, process::ProcessAddressSpace};
|
||||||
use yggdrasil_abi::error::Error;
|
use yggdrasil_abi::error::Error;
|
||||||
@ -96,6 +101,14 @@ pub trait ForeignPointer: Sized {
|
|||||||
) -> Result<&'a mut [Self], Error>;
|
) -> Result<&'a mut [Self], Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ForeignAtomic<T> {
|
||||||
|
fn atomic_load_foreign(
|
||||||
|
self: *const Self,
|
||||||
|
space: &ProcessAddressSpace,
|
||||||
|
ordering: Ordering,
|
||||||
|
) -> Result<T, Error>;
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> ForeignPointer for T {
|
impl<T> ForeignPointer for T {
|
||||||
unsafe fn write_foreign_volatile(self: *mut Self, space: &ProcessAddressSpace, value: T) {
|
unsafe fn write_foreign_volatile(self: *mut Self, space: &ProcessAddressSpace, value: T) {
|
||||||
self.try_write_foreign_volatile(space, value)
|
self.try_write_foreign_volatile(space, value)
|
||||||
@ -203,6 +216,23 @@ impl<T> ForeignPointer for T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ForeignAtomic<u32> for AtomicU32 {
|
||||||
|
fn atomic_load_foreign(
|
||||||
|
self: *const Self,
|
||||||
|
space: &ProcessAddressSpace,
|
||||||
|
ordering: Ordering,
|
||||||
|
) -> Result<u32, Error> {
|
||||||
|
let virt = self.addr();
|
||||||
|
if virt % size_of::<u32>() != 0 {
|
||||||
|
// Misaligned atomic
|
||||||
|
return Err(Error::InvalidMemoryOperation);
|
||||||
|
}
|
||||||
|
let phys = space.translate_lock(virt)?;
|
||||||
|
let phys_virt: *const Self = ptr::with_exposed_provenance(phys.virtualize());
|
||||||
|
Ok(unsafe { &*phys_virt }.load(ordering))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn validate_user_align_size(addr: usize, layout: &Layout) -> Result<(), Error> {
|
fn validate_user_align_size(addr: usize, layout: &Layout) -> Result<(), Error> {
|
||||||
// Explicitly disallow NULL
|
// Explicitly disallow NULL
|
||||||
if addr == 0 {
|
if addr == 0 {
|
||||||
|
@ -29,8 +29,7 @@ use yggdrasil_abi::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
task::{
|
task::{
|
||||||
binary, futex::UserspaceMutex, thread::Thread, types::AllocateProcessId, TaskContextImpl,
|
futex::UserspaceMutex, thread::Thread, types::AllocateProcessId, TaskContextImpl, ThreadId,
|
||||||
ThreadId,
|
|
||||||
},
|
},
|
||||||
vfs::{FileReadiness, FileSet, IoContext, NodeRef},
|
vfs::{FileReadiness, FileSet, IoContext, NodeRef},
|
||||||
};
|
};
|
||||||
|
@ -8,4 +8,4 @@ mod timer;
|
|||||||
|
|
||||||
pub use executor::{run_to_completion, spawn, spawn_async_worker};
|
pub use executor::{run_to_completion, spawn, spawn_async_worker};
|
||||||
pub use task_queue::init_task_queue;
|
pub use task_queue::init_task_queue;
|
||||||
pub use timer::{run_with_timeout, sleep, tick, FutureTimeout, SleepFuture};
|
pub use timer::{maybe_timeout, sleep, tick, with_timeout, SleepFuture};
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use core::{
|
use core::{
|
||||||
|
future::poll_fn,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
task::{Context, Poll, Waker},
|
task::{Context, Poll, Waker},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use futures_util::{future::BoxFuture, Future, FutureExt};
|
use futures_util::{Future, FutureExt};
|
||||||
use libk_util::sync::IrqSafeSpinlock;
|
use libk_util::sync::IrqSafeSpinlock;
|
||||||
use yggdrasil_abi::error::Error;
|
use yggdrasil_abi::error::Error;
|
||||||
|
|
||||||
@ -70,11 +71,6 @@ fn register_timeout(duration: Duration, waker: &Waker) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum FutureTimeout<T> {
|
|
||||||
Ok(T),
|
|
||||||
Timeout,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SleepFuture {
|
pub struct SleepFuture {
|
||||||
deadline: Duration,
|
deadline: Duration,
|
||||||
}
|
}
|
||||||
@ -113,42 +109,33 @@ pub fn sleep(duration: Duration) -> SleepFuture {
|
|||||||
SleepFuture { deadline }
|
SleepFuture { deadline }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_with_timeout<'a, T: 'a, F: Future<Output = T> + Send + 'a>(
|
pub fn with_timeout<'a, T: 'a, F: Future<Output = T> + Send + 'a>(
|
||||||
duration: Duration,
|
|
||||||
fut: F,
|
fut: F,
|
||||||
) -> impl Future<Output = FutureTimeout<T>> + 'a {
|
timeout: Duration,
|
||||||
struct TimeoutFuture<'f, T> {
|
) -> impl Future<Output = Result<T, Error>> + Send + 'a {
|
||||||
fut: BoxFuture<'f, T>,
|
let mut fut = fut.boxed();
|
||||||
sleep_fut: BoxFuture<'f, ()>,
|
let mut sleep_fut = sleep(timeout).boxed();
|
||||||
}
|
|
||||||
|
|
||||||
impl<'f, T> Future for TimeoutFuture<'f, T> {
|
poll_fn(move |cx| {
|
||||||
type Output = FutureTimeout<T>;
|
let (timeout, output) = (sleep_fut.poll_unpin(cx), fut.poll_unpin(cx));
|
||||||
|
if let Poll::Ready(output) = output {
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
Poll::Ready(Ok(output))
|
||||||
let (timeout, result) = (self.sleep_fut.as_mut().poll(cx), self.fut.as_mut().poll(cx));
|
} else if timeout.is_ready() {
|
||||||
|
Poll::Ready(Err(Error::TimedOut))
|
||||||
if let Poll::Ready(result) = result {
|
} else {
|
||||||
Poll::Ready(FutureTimeout::Ok(result))
|
Poll::Pending
|
||||||
} else if timeout.is_ready() {
|
|
||||||
Poll::Ready(FutureTimeout::Timeout)
|
|
||||||
} else {
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
TimeoutFuture {
|
|
||||||
fut: fut.boxed(),
|
|
||||||
sleep_fut: sleep(duration).boxed(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<FutureTimeout<Result<T, Error>>> for Result<T, Error> {
|
pub fn maybe_timeout<'a, T: 'a, F: Future<Output = T> + Send + 'a>(
|
||||||
fn from(value: FutureTimeout<Result<T, Error>>) -> Self {
|
fut: F,
|
||||||
match value {
|
timeout: Option<Duration>,
|
||||||
FutureTimeout::Ok(res) => res,
|
) -> impl Future<Output = Result<T, Error>> + Send + 'a {
|
||||||
FutureTimeout::Timeout => Err(Error::TimedOut),
|
async move {
|
||||||
|
match timeout {
|
||||||
|
Some(timeout) => with_timeout(fut, timeout).await,
|
||||||
|
None => Ok(fut.await),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,11 +59,6 @@ pub struct ThreadDebuggingInfo {
|
|||||||
pub breakpoints: BTreeMap<usize, BreakpointType>,
|
pub breakpoints: BTreeMap<usize, BreakpointType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SignalEntry {
|
|
||||||
entry: usize,
|
|
||||||
stack: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Describes a single thread within the system
|
/// Describes a single thread within the system
|
||||||
pub struct Thread {
|
pub struct Thread {
|
||||||
/// Unique thread ID
|
/// Unique thread ID
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
use alloc::sync::Arc;
|
|
||||||
use core::{
|
use core::{
|
||||||
fmt,
|
fmt,
|
||||||
sync::atomic::{AtomicU32, AtomicU64, Ordering},
|
sync::atomic::{AtomicU32, AtomicU64, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
use atomic_enum::atomic_enum;
|
use atomic_enum::atomic_enum;
|
||||||
use libk_mm::PageBox;
|
|
||||||
use yggdrasil_abi::process::ProcessId;
|
use yggdrasil_abi::process::ProcessId;
|
||||||
|
|
||||||
pub trait AllocateProcessId {
|
pub trait AllocateProcessId {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use core::{
|
use core::{
|
||||||
fmt,
|
fmt,
|
||||||
future::Future,
|
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
@ -13,10 +12,7 @@ use yggdrasil_abi::{
|
|||||||
net::{SocketAddr, SocketOption},
|
net::{SocketAddr, SocketOption},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{task::runtime::maybe_timeout, vfs::FileReadiness};
|
||||||
task::runtime::{run_with_timeout, FutureTimeout},
|
|
||||||
vfs::FileReadiness,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SocketInner {
|
enum SocketInner {
|
||||||
Connection(Arc<dyn ConnectionSocket + Send + 'static>),
|
Connection(Arc<dyn ConnectionSocket + Send + 'static>),
|
||||||
@ -130,7 +126,7 @@ impl SocketWrapper {
|
|||||||
let (remote, remote_socket) = match (options.non_blocking, options.recv_timeout) {
|
let (remote, remote_socket) = match (options.non_blocking, options.recv_timeout) {
|
||||||
(false, timeout) => {
|
(false, timeout) => {
|
||||||
let fut = socket.accept();
|
let fut = socket.accept();
|
||||||
block!(maybe_timeout(timeout, fut).await)??
|
block!(maybe_timeout(fut, timeout).await)???
|
||||||
}
|
}
|
||||||
(true, _) => socket.accept_nonblocking()?,
|
(true, _) => socket.accept_nonblocking()?,
|
||||||
};
|
};
|
||||||
@ -157,11 +153,11 @@ impl SocketWrapper {
|
|||||||
) -> Result<(usize, SocketAddr), Error> {
|
) -> Result<(usize, SocketAddr), Error> {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
SocketInner::Packet(socket) => {
|
SocketInner::Packet(socket) => {
|
||||||
maybe_timeout(timeout, socket.receive_from(buffer)).await
|
maybe_timeout(socket.receive_from(buffer), timeout).await?
|
||||||
}
|
}
|
||||||
SocketInner::Connection(socket) => {
|
SocketInner::Connection(socket) => {
|
||||||
let remote = socket.remote_address().ok_or(Error::NotConnected)?;
|
let remote = socket.remote_address().ok_or(Error::NotConnected)?;
|
||||||
let len = maybe_timeout(timeout, socket.receive(buffer)).await?;
|
let len = maybe_timeout(socket.receive(buffer), timeout).await??;
|
||||||
Ok((len, remote))
|
Ok((len, remote))
|
||||||
}
|
}
|
||||||
SocketInner::Listener(_) => Err(Error::InvalidOperation),
|
SocketInner::Listener(_) => Err(Error::InvalidOperation),
|
||||||
@ -184,9 +180,9 @@ impl SocketWrapper {
|
|||||||
) -> Result<usize, Error> {
|
) -> Result<usize, Error> {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
SocketInner::Packet(socket) => {
|
SocketInner::Packet(socket) => {
|
||||||
maybe_timeout(timeout, socket.send_to(remote, buffer)).await
|
maybe_timeout(socket.send_to(remote, buffer), timeout).await?
|
||||||
}
|
}
|
||||||
SocketInner::Connection(socket) => maybe_timeout(timeout, socket.send(buffer)).await,
|
SocketInner::Connection(socket) => maybe_timeout(socket.send(buffer), timeout).await?,
|
||||||
SocketInner::Listener(_) => Err(Error::InvalidOperation),
|
SocketInner::Listener(_) => Err(Error::InvalidOperation),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,20 +321,6 @@ impl Default for InnerOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn maybe_timeout<R, F: Future<Output = Result<R, Error>> + Send>(
|
|
||||||
timeout: Option<Duration>,
|
|
||||||
fut: F,
|
|
||||||
) -> Result<R, Error> {
|
|
||||||
if let Some(timeout) = timeout {
|
|
||||||
match run_with_timeout(timeout, fut).await {
|
|
||||||
FutureTimeout::Ok(value) => value,
|
|
||||||
FutureTimeout::Timeout => Err(Error::TimedOut),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fut.await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// impl From<Arc<dyn ConnectionSocket + 'static>> for SocketWrapper {
|
// impl From<Arc<dyn ConnectionSocket + 'static>> for SocketWrapper {
|
||||||
// fn from(value: Arc<dyn ConnectionSocket + 'static>) -> Self {
|
// fn from(value: Arc<dyn ConnectionSocket + 'static>) -> Self {
|
||||||
// Self::Connection(value)
|
// Self::Connection(value)
|
||||||
|
@ -6,7 +6,7 @@ pub(crate) use abi::{
|
|||||||
},
|
},
|
||||||
mem::{MappingFlags, MappingSource},
|
mem::{MappingFlags, MappingSource},
|
||||||
net::SocketType,
|
net::SocketType,
|
||||||
process::{Signal, SignalEntryData, SpawnOptions, ThreadOption},
|
process::{Signal, SignalEntryData, SpawnOptions},
|
||||||
system::SystemInfo,
|
system::SystemInfo,
|
||||||
};
|
};
|
||||||
use abi::{
|
use abi::{
|
||||||
|
@ -48,14 +48,12 @@ pub(crate) fn map_memory(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = space.allocate(
|
let mut attrs = MapAttributes::NON_GLOBAL | MapAttributes::USER_READ;
|
||||||
None,
|
if flags.contains(MappingFlags::WRITE) {
|
||||||
len,
|
attrs |= MapAttributes::USER_WRITE;
|
||||||
backing,
|
}
|
||||||
MapAttributes::USER_WRITE | MapAttributes::USER_READ | MapAttributes::NON_GLOBAL,
|
|
||||||
);
|
|
||||||
|
|
||||||
result
|
space.allocate(None, len, backing, attrs)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,6 +216,8 @@ pub(crate) fn send_signal(pid: ProcessId, signal: Signal) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO this would've been much simpler if physical pages behaved like Rc<...>'s and kernel could
|
||||||
|
// keep a copy of it, guaranteeing it cannot be freed and remapped into another process.
|
||||||
pub(crate) fn mutex(mutex: &AtomicU32, op: &MutexOperation) -> Result<(), Error> {
|
pub(crate) fn mutex(mutex: &AtomicU32, op: &MutexOperation) -> Result<(), Error> {
|
||||||
let thread = Thread::current();
|
let thread = Thread::current();
|
||||||
let process = thread.process();
|
let process = thread.process();
|
||||||
@ -225,8 +225,8 @@ pub(crate) fn mutex(mutex: &AtomicU32, op: &MutexOperation) -> Result<(), Error>
|
|||||||
let mutex = process.get_or_insert_mutex((mutex as *const AtomicU32).addr())?;
|
let mutex = process.get_or_insert_mutex((mutex as *const AtomicU32).addr())?;
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
&MutexOperation::Wait(value, _timeout) => block! { mutex.wait(value).await },
|
&MutexOperation::Wait(value, _timeout) => block! { mutex.wait(value).await }?,
|
||||||
&MutexOperation::WaitUntil(value, _timeout) => block! { mutex.wait_until(value).await },
|
&MutexOperation::WaitUntil(value, _timeout) => block! { mutex.wait_until(value).await }?,
|
||||||
MutexOperation::Wake => {
|
MutexOperation::Wake => {
|
||||||
mutex.wake();
|
mutex.wake();
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -291,7 +291,10 @@ pub(crate) fn wait_thread(id: u32) -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_thread_option(option: &mut ThreadOption) -> Result<(), Error> {
|
pub(crate) fn get_thread_option(option: &mut ThreadOption) -> Result<(), Error> {
|
||||||
todo!()
|
match option {
|
||||||
|
// There're better ways to do this, don't ask the kernel
|
||||||
|
ThreadOption::ThreadPointer(_) => Err(Error::InvalidOperation),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_thread_option(option: &ThreadOption) -> Result<(), Error> {
|
pub(crate) fn set_thread_option(option: &ThreadOption) -> Result<(), Error> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user