refactor: fix kernel warnings
This commit is contained in:
parent
74be46b29b
commit
49942563ef
@ -11,7 +11,7 @@ use async_trait::async_trait;
|
||||
use libk::{
|
||||
block,
|
||||
error::Error,
|
||||
task::runtime::{run_with_timeout, FutureTimeout},
|
||||
task::runtime::with_timeout,
|
||||
vfs::{ConnectionSocket, FileReadiness, ListenerSocket, Socket},
|
||||
};
|
||||
use libk_device::monotonic_timestamp;
|
||||
@ -64,7 +64,7 @@ impl TcpSocket {
|
||||
) -> Result<(SocketAddr, Arc<TcpSocket>), Error> {
|
||||
let future = Self::connect_async(remote);
|
||||
match timeout {
|
||||
Some(timeout) => run_with_timeout(timeout, future).await.into(),
|
||||
Some(timeout) => with_timeout(future, timeout).await?.into(),
|
||||
None => future.await,
|
||||
}
|
||||
}
|
||||
@ -290,10 +290,7 @@ impl TcpSocket {
|
||||
connection.poll_established(cx)
|
||||
});
|
||||
|
||||
match run_with_timeout(timeout, fut).await {
|
||||
FutureTimeout::Ok(value) => value,
|
||||
FutureTimeout::Timeout => Err(Error::TimedOut),
|
||||
}
|
||||
with_timeout(fut, timeout).await?
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ use alloc::{boxed::Box, collections::BTreeMap, sync::Arc, vec, vec::Vec};
|
||||
use atomic_enum::atomic_enum;
|
||||
use device_api::{interrupt::InterruptHandler, Device};
|
||||
use futures_util::task::AtomicWaker;
|
||||
use libk::task::runtime::{self, FutureTimeout};
|
||||
use libk::task::runtime;
|
||||
use libk_mm::{
|
||||
address::{AsPhysicalAddress, PhysicalAddress},
|
||||
PageBox,
|
||||
@ -278,8 +278,7 @@ impl Xhci {
|
||||
|
||||
// Wait for port reset
|
||||
// TODO handle disconnect during reset?
|
||||
let result = runtime::run_with_timeout(
|
||||
Duration::from_secs(1),
|
||||
let result = runtime::with_timeout(
|
||||
poll_fn(|cx| {
|
||||
let state = &self.port_states[port];
|
||||
|
||||
@ -290,12 +289,13 @@ impl Xhci {
|
||||
Poll::Pending
|
||||
}
|
||||
}),
|
||||
Duration::from_secs(1),
|
||||
)
|
||||
.await;
|
||||
|
||||
match result {
|
||||
FutureTimeout::Ok(()) => Ok(()),
|
||||
FutureTimeout::Timeout => Err(UsbError::PortResetFailed),
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => Err(UsbError::PortResetFailed),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,6 @@ use core::{
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use kernel_arch_interface::mem::KernelTableManager;
|
||||
|
||||
use crate::table::EntryLevel;
|
||||
|
||||
/// Wrapper type to represent a physical memory address
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Pod, Zeroable)]
|
||||
#[repr(transparent)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
use core::ops::Range;
|
||||
use core::ops::{Deref, Range};
|
||||
|
||||
use alloc::sync::Arc;
|
||||
use kernel_arch::ProcessAddressSpaceImpl;
|
||||
@ -7,7 +7,7 @@ use libk_mm_interface::{
|
||||
process::ProcessAddressSpaceManager,
|
||||
table::{MapAttributes, TableAllocator},
|
||||
};
|
||||
use libk_util::sync::IrqSafeSpinlock;
|
||||
use libk_util::sync::{IrqSafeSpinlock, IrqSafeSpinlockGuard};
|
||||
use vmalloc::{RangeData, VirtualMemoryAllocator};
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
@ -26,6 +26,13 @@ pub enum VirtualRangeBacking {
|
||||
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
|
||||
#[derive(Clone)]
|
||||
pub struct FileBacking {
|
||||
@ -415,6 +422,17 @@ impl<TA: TableAllocator> ProcessAddressSpace<TA> {
|
||||
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.
|
||||
///
|
||||
/// See [ProcessAddressSpaceManager::unmap].
|
||||
@ -449,3 +467,11 @@ impl<TA: TableAllocator> Drop for ProcessAddressSpace<TA> {
|
||||
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,
|
||||
arbitrary_self_types,
|
||||
slice_split_once,
|
||||
arbitrary_self_types_pointers
|
||||
arbitrary_self_types_pointers,
|
||||
result_flattening
|
||||
)]
|
||||
|
||||
extern crate alloc;
|
||||
|
@ -5,7 +5,6 @@ use alloc::sync::Arc;
|
||||
use cfg_if::cfg_if;
|
||||
use elf::{
|
||||
endian::AnyEndian,
|
||||
io_traits::InputStream,
|
||||
relocation::{Rel, Rela},
|
||||
segment::ProgramHeader,
|
||||
ElfStream, ParseError,
|
||||
@ -14,14 +13,14 @@ use libk_mm::{
|
||||
pointer::PhysicalRefMut,
|
||||
process::{ProcessAddressSpace, VirtualRangeBacking},
|
||||
table::MapAttributes,
|
||||
PageBox, L3_PAGE_SIZE,
|
||||
L3_PAGE_SIZE,
|
||||
};
|
||||
use libk_util::io::{Read, Seek};
|
||||
use yggdrasil_abi::{error::Error, io::SeekFrom, path::PathBuf};
|
||||
|
||||
use crate::{
|
||||
random,
|
||||
task::{mem::ForeignPointer, process::ProcessImage, types::TlsImage},
|
||||
task::{process::ProcessImage, types::TlsImage},
|
||||
};
|
||||
|
||||
cfg_if! {
|
||||
|
@ -1,5 +1,3 @@
|
||||
use core::{alloc::Layout, ptr::NonNull};
|
||||
|
||||
use alloc::{
|
||||
borrow::ToOwned,
|
||||
string::String,
|
||||
@ -18,7 +16,6 @@ use libk_util::io::{Read, Seek};
|
||||
use yggdrasil_abi::{
|
||||
error::Error,
|
||||
io::SeekFrom,
|
||||
pass::{Place, Placer},
|
||||
path::Path,
|
||||
process::{auxv, AuxValue, ProcessGroupId},
|
||||
};
|
||||
|
@ -1,27 +1,22 @@
|
||||
use core::{
|
||||
future::poll_fn,
|
||||
pin::Pin,
|
||||
ptr,
|
||||
sync::atomic::{AtomicU32, Ordering},
|
||||
task::{Context, Poll},
|
||||
task::Poll,
|
||||
};
|
||||
|
||||
use alloc::sync::Arc;
|
||||
use futures_util::Future;
|
||||
use libk_mm::{
|
||||
address::{AsPhysicalAddress, PhysicalAddress},
|
||||
pointer::PhysicalRef,
|
||||
process::ProcessAddressSpace,
|
||||
};
|
||||
use libk_mm::process::ProcessAddressSpace;
|
||||
use libk_util::waker::QueueWaker;
|
||||
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
|
||||
pub struct UserspaceMutex {
|
||||
queue: QueueWaker,
|
||||
space: Arc<ProcessAddressSpace>,
|
||||
address: usize,
|
||||
atomic: *const AtomicU32,
|
||||
}
|
||||
|
||||
impl UserspaceMutex {
|
||||
@ -30,35 +25,42 @@ impl UserspaceMutex {
|
||||
Ok(Self {
|
||||
queue: QueueWaker::new(),
|
||||
space: space.clone(),
|
||||
address,
|
||||
atomic: ptr::with_exposed_provenance(address),
|
||||
})
|
||||
}
|
||||
|
||||
fn load(&self) -> u32 {
|
||||
// TODO: this is slow, but this prevents the kernel from reading from unmapped memory
|
||||
let phys = self.space.translate(self.address).unwrap();
|
||||
unsafe { PhysicalRef::<AtomicU32>::map(phys).load(Ordering::Acquire) }
|
||||
fn load(&self) -> Result<u32, Error> {
|
||||
self.atomic
|
||||
.atomic_load_foreign(&self.space, 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| {
|
||||
if predicate(self.load()) {
|
||||
let result = self.load();
|
||||
match result {
|
||||
Err(err) => {
|
||||
self.queue.remove(cx.waker());
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
Poll::Ready(Err(err))
|
||||
}
|
||||
Ok(val) if predicate(val) => {
|
||||
self.queue.remove(cx.waker());
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
Ok(_) => {
|
||||
self.queue.register(cx.waker());
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
})
|
||||
.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
|
||||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
|
||||
|
@ -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 yggdrasil_abi::error::Error;
|
||||
@ -96,6 +101,14 @@ pub trait ForeignPointer: Sized {
|
||||
) -> 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 {
|
||||
unsafe fn write_foreign_volatile(self: *mut Self, space: &ProcessAddressSpace, value: T) {
|
||||
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> {
|
||||
// Explicitly disallow NULL
|
||||
if addr == 0 {
|
||||
|
@ -29,8 +29,7 @@ use yggdrasil_abi::{
|
||||
|
||||
use crate::{
|
||||
task::{
|
||||
binary, futex::UserspaceMutex, thread::Thread, types::AllocateProcessId, TaskContextImpl,
|
||||
ThreadId,
|
||||
futex::UserspaceMutex, thread::Thread, types::AllocateProcessId, TaskContextImpl, ThreadId,
|
||||
},
|
||||
vfs::{FileReadiness, FileSet, IoContext, NodeRef},
|
||||
};
|
||||
|
@ -8,4 +8,4 @@ mod timer;
|
||||
|
||||
pub use executor::{run_to_completion, spawn, spawn_async_worker};
|
||||
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::{
|
||||
future::poll_fn,
|
||||
pin::Pin,
|
||||
task::{Context, Poll, Waker},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use futures_util::{future::BoxFuture, Future, FutureExt};
|
||||
use futures_util::{Future, FutureExt};
|
||||
use libk_util::sync::IrqSafeSpinlock;
|
||||
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 {
|
||||
deadline: Duration,
|
||||
}
|
||||
@ -113,42 +109,33 @@ pub fn sleep(duration: Duration) -> SleepFuture {
|
||||
SleepFuture { deadline }
|
||||
}
|
||||
|
||||
pub fn run_with_timeout<'a, T: 'a, F: Future<Output = T> + Send + 'a>(
|
||||
duration: Duration,
|
||||
pub fn with_timeout<'a, T: 'a, F: Future<Output = T> + Send + 'a>(
|
||||
fut: F,
|
||||
) -> impl Future<Output = FutureTimeout<T>> + 'a {
|
||||
struct TimeoutFuture<'f, T> {
|
||||
fut: BoxFuture<'f, T>,
|
||||
sleep_fut: BoxFuture<'f, ()>,
|
||||
}
|
||||
timeout: Duration,
|
||||
) -> impl Future<Output = Result<T, Error>> + Send + 'a {
|
||||
let mut fut = fut.boxed();
|
||||
let mut sleep_fut = sleep(timeout).boxed();
|
||||
|
||||
impl<'f, T> Future for TimeoutFuture<'f, T> {
|
||||
type Output = FutureTimeout<T>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let (timeout, result) = (self.sleep_fut.as_mut().poll(cx), self.fut.as_mut().poll(cx));
|
||||
|
||||
if let Poll::Ready(result) = result {
|
||||
Poll::Ready(FutureTimeout::Ok(result))
|
||||
poll_fn(move |cx| {
|
||||
let (timeout, output) = (sleep_fut.poll_unpin(cx), fut.poll_unpin(cx));
|
||||
if let Poll::Ready(output) = output {
|
||||
Poll::Ready(Ok(output))
|
||||
} else if timeout.is_ready() {
|
||||
Poll::Ready(FutureTimeout::Timeout)
|
||||
Poll::Ready(Err(Error::TimedOut))
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
TimeoutFuture {
|
||||
fut: fut.boxed(),
|
||||
sleep_fut: sleep(duration).boxed(),
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<FutureTimeout<Result<T, Error>>> for Result<T, Error> {
|
||||
fn from(value: FutureTimeout<Result<T, Error>>) -> Self {
|
||||
match value {
|
||||
FutureTimeout::Ok(res) => res,
|
||||
FutureTimeout::Timeout => Err(Error::TimedOut),
|
||||
pub fn maybe_timeout<'a, T: 'a, F: Future<Output = T> + Send + 'a>(
|
||||
fut: F,
|
||||
timeout: Option<Duration>,
|
||||
) -> impl Future<Output = Result<T, Error>> + Send + 'a {
|
||||
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>,
|
||||
}
|
||||
|
||||
struct SignalEntry {
|
||||
entry: usize,
|
||||
stack: usize,
|
||||
}
|
||||
|
||||
/// Describes a single thread within the system
|
||||
pub struct Thread {
|
||||
/// Unique thread ID
|
||||
|
@ -1,11 +1,9 @@
|
||||
use alloc::sync::Arc;
|
||||
use core::{
|
||||
fmt,
|
||||
sync::atomic::{AtomicU32, AtomicU64, Ordering},
|
||||
};
|
||||
|
||||
use atomic_enum::atomic_enum;
|
||||
use libk_mm::PageBox;
|
||||
use yggdrasil_abi::process::ProcessId;
|
||||
|
||||
pub trait AllocateProcessId {
|
||||
|
@ -1,6 +1,5 @@
|
||||
use core::{
|
||||
fmt,
|
||||
future::Future,
|
||||
task::{Context, Poll},
|
||||
time::Duration,
|
||||
};
|
||||
@ -13,10 +12,7 @@ use yggdrasil_abi::{
|
||||
net::{SocketAddr, SocketOption},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
task::runtime::{run_with_timeout, FutureTimeout},
|
||||
vfs::FileReadiness,
|
||||
};
|
||||
use crate::{task::runtime::maybe_timeout, vfs::FileReadiness};
|
||||
|
||||
enum SocketInner {
|
||||
Connection(Arc<dyn ConnectionSocket + Send + 'static>),
|
||||
@ -130,7 +126,7 @@ impl SocketWrapper {
|
||||
let (remote, remote_socket) = match (options.non_blocking, options.recv_timeout) {
|
||||
(false, timeout) => {
|
||||
let fut = socket.accept();
|
||||
block!(maybe_timeout(timeout, fut).await)??
|
||||
block!(maybe_timeout(fut, timeout).await)???
|
||||
}
|
||||
(true, _) => socket.accept_nonblocking()?,
|
||||
};
|
||||
@ -157,11 +153,11 @@ impl SocketWrapper {
|
||||
) -> Result<(usize, SocketAddr), Error> {
|
||||
match &self.inner {
|
||||
SocketInner::Packet(socket) => {
|
||||
maybe_timeout(timeout, socket.receive_from(buffer)).await
|
||||
maybe_timeout(socket.receive_from(buffer), timeout).await?
|
||||
}
|
||||
SocketInner::Connection(socket) => {
|
||||
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))
|
||||
}
|
||||
SocketInner::Listener(_) => Err(Error::InvalidOperation),
|
||||
@ -184,9 +180,9 @@ impl SocketWrapper {
|
||||
) -> Result<usize, Error> {
|
||||
match &self.inner {
|
||||
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),
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
// fn from(value: Arc<dyn ConnectionSocket + 'static>) -> Self {
|
||||
// Self::Connection(value)
|
||||
|
@ -6,7 +6,7 @@ pub(crate) use abi::{
|
||||
},
|
||||
mem::{MappingFlags, MappingSource},
|
||||
net::SocketType,
|
||||
process::{Signal, SignalEntryData, SpawnOptions, ThreadOption},
|
||||
process::{Signal, SignalEntryData, SpawnOptions},
|
||||
system::SystemInfo,
|
||||
};
|
||||
use abi::{
|
||||
|
@ -48,14 +48,12 @@ pub(crate) fn map_memory(
|
||||
}
|
||||
};
|
||||
|
||||
let result = space.allocate(
|
||||
None,
|
||||
len,
|
||||
backing,
|
||||
MapAttributes::USER_WRITE | MapAttributes::USER_READ | MapAttributes::NON_GLOBAL,
|
||||
);
|
||||
let mut attrs = MapAttributes::NON_GLOBAL | MapAttributes::USER_READ;
|
||||
if flags.contains(MappingFlags::WRITE) {
|
||||
attrs |= MapAttributes::USER_WRITE;
|
||||
}
|
||||
|
||||
result
|
||||
space.allocate(None, len, backing, attrs)
|
||||
})
|
||||
}
|
||||
|
||||
@ -218,6 +216,8 @@ pub(crate) fn send_signal(pid: ProcessId, signal: Signal) -> Result<(), Error> {
|
||||
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> {
|
||||
let thread = Thread::current();
|
||||
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())?;
|
||||
|
||||
match op {
|
||||
&MutexOperation::Wait(value, _timeout) => block! { mutex.wait(value).await },
|
||||
&MutexOperation::WaitUntil(value, _timeout) => block! { mutex.wait_until(value).await },
|
||||
&MutexOperation::Wait(value, _timeout) => block! { mutex.wait(value).await }?,
|
||||
&MutexOperation::WaitUntil(value, _timeout) => block! { mutex.wait_until(value).await }?,
|
||||
MutexOperation::Wake => {
|
||||
mutex.wake();
|
||||
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> {
|
||||
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> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user