refactor: fix warnings
This commit is contained in:
parent
15d3e38a2d
commit
b6946443b8
@ -7,6 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
kernel-util = { path = "../kernel-util" }
|
||||
vfs = { path = "../vfs" }
|
||||
|
||||
static_assertions = "1.1.0"
|
||||
|
@ -19,7 +19,7 @@ pub const ENTRY_COUNT: usize = SIZE / size_of::<usize>();
|
||||
///
|
||||
/// This trait is unsafe to implement because it has to provide and accept raw data pointers of
|
||||
/// exactly [SIZE].
|
||||
pub unsafe trait BlockAllocator: 'static {
|
||||
pub unsafe trait BlockAllocator: Send + Sync + 'static {
|
||||
/// Allocates a contiguous block of size [SIZE]
|
||||
fn alloc() -> Result<NonNull<u8>, Error>;
|
||||
|
||||
|
@ -1,21 +1,20 @@
|
||||
use core::{any::Any, cell::RefCell};
|
||||
use core::any::Any;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use vfs::{CommonImpl, Node, NodeFlags, NodeRef, RegularImpl};
|
||||
use kernel_util::sync::IrqSafeSpinlock;
|
||||
use vfs::{CommonImpl, InstanceData, Node, NodeFlags, NodeRef, RegularImpl};
|
||||
use yggdrasil_abi::{error::Error, io::OpenOptions};
|
||||
|
||||
use crate::{block::BlockAllocator, bvec::BVec};
|
||||
|
||||
pub(crate) struct FileNode<A: BlockAllocator> {
|
||||
// TODO IrqSafeSpinlock
|
||||
pub(crate) data: RefCell<BVec<'static, A>>,
|
||||
pub(crate) data: IrqSafeSpinlock<BVec<'static, A>>,
|
||||
}
|
||||
|
||||
impl<A: BlockAllocator> FileNode<A> {
|
||||
pub fn new() -> NodeRef {
|
||||
Node::regular(
|
||||
Self {
|
||||
data: RefCell::new(BVec::new()),
|
||||
data: IrqSafeSpinlock::new(BVec::new()),
|
||||
},
|
||||
NodeFlags::IN_MEMORY_PROPS,
|
||||
)
|
||||
@ -28,7 +27,7 @@ impl<A: BlockAllocator> CommonImpl for FileNode<A> {
|
||||
}
|
||||
|
||||
fn size(&self, _node: &NodeRef) -> Result<u64, Error> {
|
||||
Ok(self.data.borrow().size() as u64)
|
||||
Ok(self.data.lock().size() as u64)
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,10 +36,10 @@ impl<A: BlockAllocator> RegularImpl for FileNode<A> {
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
opts: OpenOptions,
|
||||
) -> Result<(u64, Option<Box<dyn Any>>), Error> {
|
||||
) -> Result<(u64, Option<InstanceData>), Error> {
|
||||
// TODO provide APPEND by vfs driver instead
|
||||
if opts.contains(OpenOptions::APPEND) {
|
||||
Ok((self.data.borrow().size() as u64, None))
|
||||
Ok((self.data.lock().size() as u64, None))
|
||||
} else {
|
||||
Ok((0, None))
|
||||
}
|
||||
@ -49,24 +48,24 @@ impl<A: BlockAllocator> RegularImpl for FileNode<A> {
|
||||
fn read(
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
_instance: Option<&Box<dyn Any>>,
|
||||
_instance: Option<&InstanceData>,
|
||||
pos: u64,
|
||||
buf: &mut [u8],
|
||||
) -> Result<usize, Error> {
|
||||
self.data.borrow().read(pos, buf)
|
||||
self.data.lock().read(pos, buf)
|
||||
}
|
||||
|
||||
fn write(
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
_instance: Option<&Box<dyn Any>>,
|
||||
_instance: Option<&InstanceData>,
|
||||
pos: u64,
|
||||
buf: &[u8],
|
||||
) -> Result<usize, Error> {
|
||||
self.data.borrow_mut().write(pos, buf)
|
||||
self.data.lock().write(pos, buf)
|
||||
}
|
||||
|
||||
fn close(&self, _node: &NodeRef, _instance: Option<&Box<dyn Any>>) -> Result<(), Error> {
|
||||
fn close(&self, _node: &NodeRef, _instance: Option<&InstanceData>) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! In-memory filesystem driver
|
||||
#![no_std]
|
||||
#![deny(missing_docs)]
|
||||
#![allow(clippy::new_without_default)]
|
||||
#![allow(clippy::new_without_default, clippy::new_ret_no_self)]
|
||||
#![feature(
|
||||
const_mut_refs,
|
||||
maybe_uninit_uninit_array,
|
||||
@ -158,7 +158,7 @@ impl<A: BlockAllocator> MemoryFilesystem<A> {
|
||||
if hdr.node_kind() == FileType::File {
|
||||
let data = data.unwrap();
|
||||
let node_data = node.data_as_ref::<FileNode<A>>();
|
||||
let mut bvec = node_data.data.borrow_mut();
|
||||
let mut bvec = node_data.data.lock();
|
||||
|
||||
bvec.init_with_cow(data)?;
|
||||
assert_eq!(bvec.size(), data.len());
|
||||
|
@ -4,7 +4,7 @@ use crate::node::{CommonImpl, NodeRef};
|
||||
|
||||
/// Block device interface
|
||||
#[allow(unused)]
|
||||
pub trait BlockDevice {
|
||||
pub trait BlockDevice: Sync {
|
||||
/// Reads data frmo the given offset of the device
|
||||
fn read(&'static self, pos: u64, buf: &mut [u8]) -> Result<usize, Error> {
|
||||
Err(Error::NotImplemented)
|
||||
@ -36,7 +36,7 @@ pub trait BlockDevice {
|
||||
|
||||
/// Character device interface
|
||||
#[allow(unused)]
|
||||
pub trait CharDevice {
|
||||
pub trait CharDevice: Sync {
|
||||
/// Reads data from the device
|
||||
fn read(&'static self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||
Err(Error::NotImplemented)
|
||||
|
@ -1,5 +1,4 @@
|
||||
use core::cell::Cell;
|
||||
|
||||
use kernel_util::sync::IrqSafeSpinlock;
|
||||
use yggdrasil_abi::{error::Error, io::SeekFrom};
|
||||
|
||||
use crate::{
|
||||
@ -10,7 +9,7 @@ use crate::{
|
||||
pub struct BlockFile {
|
||||
pub(super) device: BlockDeviceWrapper,
|
||||
pub(super) node: NodeRef,
|
||||
pub(super) position: Cell<u64>,
|
||||
pub(super) position: IrqSafeSpinlock<u64>,
|
||||
pub(super) read: bool,
|
||||
pub(super) write: bool,
|
||||
}
|
||||
@ -24,24 +23,25 @@ pub struct CharFile {
|
||||
|
||||
impl BlockFile {
|
||||
pub fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||
let pos = self.position.get();
|
||||
let count = self.device.0.read(pos, buf)?;
|
||||
self.position.set(pos + count as u64);
|
||||
let mut position = self.position.lock();
|
||||
let count = self.device.0.read(*position, buf)?;
|
||||
*position += count as u64;
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> Result<usize, Error> {
|
||||
let pos = self.position.get();
|
||||
let count = self.device.0.write(pos, buf)?;
|
||||
self.position.set(pos + count as u64);
|
||||
let mut position = self.position.lock();
|
||||
let count = self.device.0.write(*position, buf)?;
|
||||
*position += count as u64;
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
pub fn seek(&self, from: SeekFrom) -> Result<u64, Error> {
|
||||
let pos = self.position.get();
|
||||
let mut position = self.position.lock();
|
||||
|
||||
let newpos = match from {
|
||||
SeekFrom::Current(off) => {
|
||||
let newpos = i64::try_from(pos).unwrap() + off;
|
||||
let newpos = i64::try_from(*position).unwrap() + off;
|
||||
if newpos < 0 {
|
||||
return Err(Error::InvalidArgument);
|
||||
}
|
||||
@ -60,7 +60,7 @@ impl BlockFile {
|
||||
}
|
||||
};
|
||||
|
||||
self.position.set(newpos);
|
||||
*position = newpos;
|
||||
Ok(newpos)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use core::{cell::Cell, mem::MaybeUninit, str::FromStr};
|
||||
use core::{mem::MaybeUninit, str::FromStr};
|
||||
|
||||
use kernel_util::sync::IrqSafeSpinlock;
|
||||
use yggdrasil_abi::{error::Error, io::DirectoryEntry, util::FixedString};
|
||||
|
||||
use crate::node::NodeRef;
|
||||
@ -21,7 +22,7 @@ pub(super) enum DirectoryPosition {
|
||||
|
||||
pub struct DirectoryFile {
|
||||
pub(super) node: NodeRef,
|
||||
pub(super) position: Cell<DirectoryPosition>,
|
||||
pub(super) position: IrqSafeSpinlock<DirectoryPosition>,
|
||||
}
|
||||
|
||||
impl DirectoryFile {
|
||||
@ -79,8 +80,9 @@ impl DirectoryFile {
|
||||
&self,
|
||||
entries: &mut [MaybeUninit<DirectoryEntry>],
|
||||
) -> Result<usize, Error> {
|
||||
let pos = self.position.get();
|
||||
let (count, pos) = match pos {
|
||||
let mut position = self.position.lock();
|
||||
|
||||
let (count, pos) = match *position {
|
||||
DirectoryPosition::Cache(pos) => {
|
||||
let (count, pos) = DirectoryFile::read_cached(&self.node, pos, entries)?;
|
||||
(count, DirectoryPosition::Cache(pos))
|
||||
@ -90,7 +92,7 @@ impl DirectoryFile {
|
||||
(count, DirectoryPosition::Physical(pos))
|
||||
}
|
||||
};
|
||||
self.position.set(pos);
|
||||
*position = pos;
|
||||
|
||||
Ok(count)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
use core::{any::Any, cell::Cell, fmt, mem::MaybeUninit};
|
||||
use core::{any::Any, fmt, mem::MaybeUninit};
|
||||
|
||||
use alloc::{boxed::Box, sync::Arc};
|
||||
use kernel_util::sync::IrqSafeSpinlock;
|
||||
use yggdrasil_abi::{
|
||||
error::Error,
|
||||
io::{DirectoryEntry, OpenOptions, SeekFrom},
|
||||
@ -22,6 +23,9 @@ mod device;
|
||||
mod directory;
|
||||
mod regular;
|
||||
|
||||
/// Per-file optional instance data created when a regular file is opened
|
||||
pub type InstanceData = Box<dyn Any + Send + Sync>;
|
||||
|
||||
/// Describes the starting position of the directory
|
||||
pub enum DirectoryOpenPosition {
|
||||
/// Contents should be fetched from the directory impl with given offset
|
||||
@ -45,14 +49,14 @@ pub enum File {
|
||||
|
||||
impl File {
|
||||
pub(crate) fn directory(node: NodeRef, position: DirectoryOpenPosition) -> Arc<Self> {
|
||||
let position = Cell::new(position.into());
|
||||
let position = IrqSafeSpinlock::new(position.into());
|
||||
Arc::new(Self::Directory(DirectoryFile { node, position }))
|
||||
}
|
||||
|
||||
pub(crate) fn regular(
|
||||
node: NodeRef,
|
||||
position: u64,
|
||||
instance_data: Option<Box<dyn Any>>,
|
||||
instance_data: Option<InstanceData>,
|
||||
opts: OpenOptions,
|
||||
) -> Arc<Self> {
|
||||
let read = opts.contains(OpenOptions::READ);
|
||||
@ -63,7 +67,7 @@ impl File {
|
||||
read,
|
||||
write,
|
||||
instance_data,
|
||||
position: Cell::new(position),
|
||||
position: IrqSafeSpinlock::new(position),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -85,7 +89,7 @@ impl File {
|
||||
Ok(Arc::new(Self::Block(BlockFile {
|
||||
device,
|
||||
node,
|
||||
position: Cell::new(0),
|
||||
position: IrqSafeSpinlock::new(0),
|
||||
read,
|
||||
write,
|
||||
})))
|
||||
@ -158,8 +162,8 @@ impl Write for File {
|
||||
impl Seek for File {
|
||||
fn tell(&self) -> Result<u64, Error> {
|
||||
match self {
|
||||
Self::Regular(file) => Ok(file.position.get()),
|
||||
Self::Block(file) => Ok(file.position.get()),
|
||||
Self::Regular(file) => Ok(*file.position.lock()),
|
||||
Self::Block(file) => Ok(*file.position.lock()),
|
||||
Self::Char(_) => Err(Error::InvalidOperation),
|
||||
Self::Directory(_) => Err(Error::IsADirectory),
|
||||
}
|
||||
@ -180,13 +184,13 @@ impl fmt::Debug for File {
|
||||
match self {
|
||||
Self::Regular(file) => f
|
||||
.debug_struct("RegularFile")
|
||||
.field("position", &file.position.get())
|
||||
.field("position", &*file.position.lock())
|
||||
.field("read", &file.read)
|
||||
.field("write", &file.write)
|
||||
.finish_non_exhaustive(),
|
||||
Self::Block(file) => f
|
||||
.debug_struct("BlockFile")
|
||||
.field("position", &file.position.get())
|
||||
.field("position", &*file.position.lock())
|
||||
.field("read", &file.read)
|
||||
.field("write", &file.write)
|
||||
.finish_non_exhaustive(),
|
||||
@ -202,8 +206,8 @@ impl fmt::Debug for File {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::{any::Any, cell::RefCell, mem::MaybeUninit, str::FromStr};
|
||||
use std::sync::Arc;
|
||||
use core::{mem::MaybeUninit, str::FromStr};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use kernel_util::sync::IrqSafeSpinlock;
|
||||
use yggdrasil_abi::{
|
||||
@ -215,10 +219,26 @@ mod tests {
|
||||
use crate::{
|
||||
device::{BlockDevice, CharDevice},
|
||||
file::DirectoryOpenPosition,
|
||||
impls::const_value_node,
|
||||
node::{AccessToken, CommonImpl, DirectoryImpl, Node, NodeFlags, NodeRef, RegularImpl},
|
||||
traits::{Read, Seek, Write},
|
||||
InstanceData,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn file_send_sync() {
|
||||
fn file_send<T: Send>(_f: &T) {}
|
||||
fn file_sync<T: Sync>(_f: &T) {}
|
||||
|
||||
let node = const_value_node("1234");
|
||||
let file = node
|
||||
.open(OpenOptions::READ, AccessToken::test_authorized())
|
||||
.unwrap();
|
||||
|
||||
file_send(&file);
|
||||
file_sync(&file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn physical_dir_read() {
|
||||
struct D {
|
||||
@ -350,12 +370,12 @@ mod tests {
|
||||
#[test]
|
||||
fn file_read_write() {
|
||||
struct F {
|
||||
data: Arc<RefCell<Vec<u8>>>,
|
||||
data: Arc<Mutex<Vec<u8>>>,
|
||||
}
|
||||
|
||||
impl CommonImpl for F {
|
||||
fn size(&self, _node: &NodeRef) -> Result<u64, Error> {
|
||||
Ok(self.data.borrow().len() as _)
|
||||
Ok(self.data.lock().unwrap().len() as _)
|
||||
}
|
||||
}
|
||||
impl RegularImpl for F {
|
||||
@ -363,19 +383,19 @@ mod tests {
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
_opts: OpenOptions,
|
||||
) -> Result<(u64, Option<Box<dyn Any>>), Error> {
|
||||
) -> Result<(u64, Option<InstanceData>), Error> {
|
||||
Ok((0, None))
|
||||
}
|
||||
|
||||
fn read(
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
_instance: Option<&Box<dyn Any>>,
|
||||
_instance: Option<&InstanceData>,
|
||||
pos: u64,
|
||||
buf: &mut [u8],
|
||||
) -> Result<usize, Error> {
|
||||
let pos = pos as usize;
|
||||
let data = self.data.borrow();
|
||||
let data = self.data.lock().unwrap();
|
||||
if pos >= data.len() {
|
||||
return Ok(0);
|
||||
}
|
||||
@ -387,19 +407,19 @@ mod tests {
|
||||
fn write(
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
_instance: Option<&Box<dyn Any>>,
|
||||
_instance: Option<&InstanceData>,
|
||||
pos: u64,
|
||||
buf: &[u8],
|
||||
) -> Result<usize, Error> {
|
||||
let pos = pos as usize;
|
||||
let mut data = self.data.borrow_mut();
|
||||
let mut data = self.data.lock().unwrap();
|
||||
data.resize(pos + buf.len(), 0);
|
||||
data[pos..pos + buf.len()].copy_from_slice(buf);
|
||||
Ok(buf.len())
|
||||
}
|
||||
}
|
||||
|
||||
let data = Arc::new(RefCell::new(vec![]));
|
||||
let data = Arc::new(Mutex::new(vec![]));
|
||||
let node = Node::regular(F { data: data.clone() }, NodeFlags::empty());
|
||||
let file = node
|
||||
.open(
|
||||
@ -409,19 +429,19 @@ mod tests {
|
||||
.unwrap();
|
||||
let mut buf = [0; 512];
|
||||
|
||||
assert_eq!(&*data.borrow(), &[]);
|
||||
assert_eq!(&*data.lock().unwrap(), &[]);
|
||||
assert_eq!(file.tell().unwrap(), 0);
|
||||
|
||||
assert_eq!(file.write(b"Hello").unwrap(), 5);
|
||||
assert_eq!(file.tell().unwrap(), 5);
|
||||
assert_eq!(&*data.borrow(), b"Hello");
|
||||
assert_eq!(&*data.lock().unwrap(), b"Hello");
|
||||
|
||||
assert_eq!(file.seek(SeekFrom::End(-2)).unwrap(), 3);
|
||||
assert_eq!(file.tell().unwrap(), 3);
|
||||
|
||||
assert_eq!(file.write(b"123456").unwrap(), 6);
|
||||
assert_eq!(file.tell().unwrap(), 9);
|
||||
assert_eq!(&*data.borrow(), b"Hel123456");
|
||||
assert_eq!(&*data.lock().unwrap(), b"Hel123456");
|
||||
|
||||
assert_eq!(file.seek(SeekFrom::Start(2)).unwrap(), 2);
|
||||
assert_eq!(file.read(&mut buf).unwrap(), 7);
|
||||
|
@ -1,15 +1,15 @@
|
||||
use alloc::boxed::Box;
|
||||
use core::{any::Any, cell::Cell};
|
||||
use kernel_util::sync::IrqSafeSpinlock;
|
||||
use yggdrasil_abi::{error::Error, io::SeekFrom};
|
||||
|
||||
use super::InstanceData;
|
||||
use crate::node::NodeRef;
|
||||
|
||||
pub struct RegularFile {
|
||||
pub(super) node: NodeRef,
|
||||
pub(super) read: bool,
|
||||
pub(super) write: bool,
|
||||
pub(super) instance_data: Option<Box<dyn Any>>,
|
||||
pub(super) position: Cell<u64>,
|
||||
pub(super) instance_data: Option<InstanceData>,
|
||||
pub(super) position: IrqSafeSpinlock<u64>,
|
||||
}
|
||||
|
||||
impl RegularFile {
|
||||
@ -17,10 +17,10 @@ impl RegularFile {
|
||||
if !self.read {
|
||||
return Err(Error::InvalidFile);
|
||||
}
|
||||
let mut position = self.position.lock();
|
||||
let reg = self.node.as_regular()?;
|
||||
let pos = self.position.get();
|
||||
let count = reg.read(&self.node, self.instance_data.as_ref(), pos, buf)?;
|
||||
self.position.set(pos + count as u64);
|
||||
let count = reg.read(&self.node, self.instance_data.as_ref(), *position, buf)?;
|
||||
*position += count as u64;
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
@ -28,19 +28,20 @@ impl RegularFile {
|
||||
if !self.write {
|
||||
return Err(Error::InvalidFile);
|
||||
}
|
||||
let mut position = self.position.lock();
|
||||
let reg = self.node.as_regular()?;
|
||||
let pos = self.position.get();
|
||||
let count = reg.write(&self.node, self.instance_data.as_ref(), pos, buf)?;
|
||||
self.position.set(pos + count as u64);
|
||||
let count = reg.write(&self.node, self.instance_data.as_ref(), *position, buf)?;
|
||||
*position += count as u64;
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
// TODO should seek beyond the end of a read-only file be allowed?
|
||||
pub fn seek(&self, from: SeekFrom) -> Result<u64, Error> {
|
||||
let pos = self.position.get();
|
||||
let mut position = self.position.lock();
|
||||
|
||||
let newpos = match from {
|
||||
SeekFrom::Current(off) => {
|
||||
let newpos = i64::try_from(pos).unwrap() + off;
|
||||
let newpos = i64::try_from(*position).unwrap() + off;
|
||||
if newpos < 0 {
|
||||
return Err(Error::InvalidArgument);
|
||||
}
|
||||
@ -60,7 +61,7 @@ impl RegularFile {
|
||||
}
|
||||
};
|
||||
|
||||
self.position.set(newpos);
|
||||
*position = newpos;
|
||||
Ok(newpos)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! Virtual filesystem interfaces and driver implementation
|
||||
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
#![allow(clippy::new_ret_no_self)]
|
||||
#![deny(missing_docs)]
|
||||
#![feature(
|
||||
trait_upcasting,
|
||||
@ -23,7 +24,7 @@ pub(crate) mod path;
|
||||
pub(crate) mod traits;
|
||||
|
||||
pub use device::{BlockDevice, CharDevice};
|
||||
pub use file::{DirectoryOpenPosition, File, FileRef};
|
||||
pub use file::{DirectoryOpenPosition, File, FileRef, InstanceData};
|
||||
pub use ioctx::{Action, IoContext};
|
||||
pub use node::{
|
||||
impls, AccessToken, CommonImpl, CreateInfo, DirectoryImpl, Metadata, Node, NodeFlags, NodeRef,
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! Various helper node implementations for convenience
|
||||
use core::{any::Any, cell::RefCell, marker::PhantomData, str::FromStr};
|
||||
use core::{marker::PhantomData, str::FromStr};
|
||||
|
||||
use alloc::{
|
||||
boxed::Box,
|
||||
@ -8,9 +8,10 @@ use alloc::{
|
||||
vec::Vec,
|
||||
};
|
||||
|
||||
use kernel_util::sync::IrqSafeSpinlock;
|
||||
use yggdrasil_abi::{error::Error, io::OpenOptions};
|
||||
|
||||
use crate::DirectoryOpenPosition;
|
||||
use crate::{DirectoryOpenPosition, InstanceData};
|
||||
|
||||
use super::{CommonImpl, DirectoryImpl, Node, NodeFlags, NodeRef, RegularImpl, SymlinkImpl};
|
||||
|
||||
@ -22,18 +23,18 @@ trait SliceWrite {
|
||||
fn write_slice(&mut self, offset: usize, buf: &[u8]) -> usize;
|
||||
}
|
||||
|
||||
trait IntoInstanceData {
|
||||
fn into_instance_data(&self) -> Vec<u8>;
|
||||
trait AsInstanceData {
|
||||
fn as_instance_data(&self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
/// Closure interface for reading a single value
|
||||
pub trait ValueReadFn<T> = Fn() -> Result<T, Error>;
|
||||
pub trait ValueReadFn<T> = Fn() -> Result<T, Error> + Send + Sync;
|
||||
/// Closure interface for writing a single value
|
||||
pub trait ValueWriteFn<T> = Fn(T) -> Result<(), Error>;
|
||||
pub trait ValueWriteFn<T> = Fn(T) -> Result<(), Error> + Send + Sync;
|
||||
/// Closure interface for reading bytes
|
||||
pub trait ReadFn = Fn(u64, &mut [u8]) -> Result<usize, Error>;
|
||||
pub trait ReadFn = Fn(u64, &mut [u8]) -> Result<usize, Error> + Send + Sync;
|
||||
/// Closure interface for writing bytes
|
||||
pub trait WriteFn = Fn(u64, &[u8]) -> Result<usize, Error>;
|
||||
pub trait WriteFn = Fn(u64, &[u8]) -> Result<usize, Error> + Send + Sync;
|
||||
|
||||
impl<T: AsRef<[u8]>> SliceRead for T {
|
||||
fn read_slice(&self, pos: usize, buf: &mut [u8]) -> usize {
|
||||
@ -57,15 +58,15 @@ impl SliceWrite for Vec<u8> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToString> IntoInstanceData for T {
|
||||
fn into_instance_data(&self) -> Vec<u8> {
|
||||
impl<T: ToString> AsInstanceData for T {
|
||||
fn as_instance_data(&self) -> Vec<u8> {
|
||||
self.to_string().as_bytes().to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
enum FnNodeData {
|
||||
Read(Vec<u8>),
|
||||
Write(RefCell<Vec<u8>>),
|
||||
Write(IrqSafeSpinlock<Vec<u8>>),
|
||||
}
|
||||
|
||||
/// Allows read-only access to a value. The value is converted to a string representation when it's
|
||||
@ -95,7 +96,11 @@ pub struct FixedSymlink {
|
||||
target: NodeRef,
|
||||
}
|
||||
|
||||
impl<T: ToString + 'static, R: ValueReadFn<T> + 'static> ReadOnlyFnValueNode<T, R> {
|
||||
impl<T, R> ReadOnlyFnValueNode<T, R>
|
||||
where
|
||||
T: ToString + Send + Sync + 'static,
|
||||
R: ValueReadFn<T> + 'static,
|
||||
{
|
||||
/// Creates a new [ReadOnlyFnValueNode] with given read function
|
||||
pub fn new(read: R) -> NodeRef {
|
||||
Node::regular(
|
||||
@ -112,29 +117,37 @@ impl<T: ToString + 'static, R: ValueReadFn<T> + 'static> ReadOnlyFnValueNode<T,
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToString, R: ValueReadFn<T>> CommonImpl for ReadOnlyFnValueNode<T, R> {
|
||||
impl<T, R> CommonImpl for ReadOnlyFnValueNode<T, R>
|
||||
where
|
||||
T: ToString + Send + Sync,
|
||||
R: ValueReadFn<T>,
|
||||
{
|
||||
fn size(&self, _node: &NodeRef) -> Result<u64, Error> {
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToString + 'static, R: ValueReadFn<T>> RegularImpl for ReadOnlyFnValueNode<T, R> {
|
||||
impl<T, R> RegularImpl for ReadOnlyFnValueNode<T, R>
|
||||
where
|
||||
T: ToString + Send + Sync,
|
||||
R: ValueReadFn<T>,
|
||||
{
|
||||
fn open(
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
opts: OpenOptions,
|
||||
) -> Result<(u64, Option<Box<dyn Any>>), Error> {
|
||||
) -> Result<(u64, Option<InstanceData>), Error> {
|
||||
if opts.contains(OpenOptions::WRITE) {
|
||||
return Err(Error::ReadOnly);
|
||||
}
|
||||
let t = (self.read)()?;
|
||||
Ok((0, Some(Box::new(t.into_instance_data()))))
|
||||
Ok((0, Some(Box::new(t.as_instance_data()))))
|
||||
}
|
||||
|
||||
fn read(
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
instance: Option<&Box<dyn Any>>,
|
||||
instance: Option<&InstanceData>,
|
||||
pos: u64,
|
||||
buf: &mut [u8],
|
||||
) -> Result<usize, Error> {
|
||||
@ -145,7 +158,7 @@ impl<T: ToString + 'static, R: ValueReadFn<T>> RegularImpl for ReadOnlyFnValueNo
|
||||
fn write(
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
_instance: Option<&Box<dyn Any>>,
|
||||
_instance: Option<&InstanceData>,
|
||||
_pos: u64,
|
||||
_buf: &[u8],
|
||||
) -> Result<usize, Error> {
|
||||
@ -157,11 +170,11 @@ impl<T: ToString + 'static, R: ValueReadFn<T>> RegularImpl for ReadOnlyFnValueNo
|
||||
|
||||
impl FnNodeData {
|
||||
fn write() -> Self {
|
||||
Self::Write(RefCell::new(Vec::new()))
|
||||
Self::Write(IrqSafeSpinlock::new(Vec::new()))
|
||||
}
|
||||
|
||||
fn read<T: IntoInstanceData>(value: T) -> Self {
|
||||
Self::Read(value.into_instance_data())
|
||||
fn read<T: AsInstanceData>(value: T) -> Self {
|
||||
Self::Read(value.as_instance_data())
|
||||
}
|
||||
|
||||
fn as_read(&self) -> Result<&Vec<u8>, Error> {
|
||||
@ -171,7 +184,7 @@ impl FnNodeData {
|
||||
}
|
||||
}
|
||||
|
||||
fn as_write(&self) -> Result<&RefCell<Vec<u8>>, Error> {
|
||||
fn as_write(&self) -> Result<&IrqSafeSpinlock<Vec<u8>>, Error> {
|
||||
match self {
|
||||
Self::Write(w) => Ok(w),
|
||||
Self::Read(_) => Err(Error::InvalidOperation),
|
||||
@ -181,7 +194,7 @@ impl FnNodeData {
|
||||
|
||||
impl<T, R, W> FnValueNode<T, R, W>
|
||||
where
|
||||
T: ToString + FromStr + 'static,
|
||||
T: ToString + FromStr + Send + Sync + 'static,
|
||||
R: ValueReadFn<T> + 'static,
|
||||
W: ValueWriteFn<T> + 'static,
|
||||
{
|
||||
@ -202,22 +215,28 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToString + FromStr, R: ValueReadFn<T>, W: ValueWriteFn<T>> CommonImpl
|
||||
for FnValueNode<T, R, W>
|
||||
impl<T, R, W> CommonImpl for FnValueNode<T, R, W>
|
||||
where
|
||||
T: ToString + FromStr + Send + Sync,
|
||||
R: ValueReadFn<T>,
|
||||
W: ValueWriteFn<T>,
|
||||
{
|
||||
fn size(&self, _node: &NodeRef) -> Result<u64, Error> {
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToString + FromStr, R: ValueReadFn<T>, W: ValueWriteFn<T>> RegularImpl
|
||||
for FnValueNode<T, R, W>
|
||||
impl<T, R, W> RegularImpl for FnValueNode<T, R, W>
|
||||
where
|
||||
T: ToString + FromStr + Send + Sync,
|
||||
R: ValueReadFn<T>,
|
||||
W: ValueWriteFn<T>,
|
||||
{
|
||||
fn open(
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
opts: OpenOptions,
|
||||
) -> Result<(u64, Option<Box<dyn Any>>), Error> {
|
||||
) -> Result<(u64, Option<InstanceData>), Error> {
|
||||
if opts.contains(OpenOptions::READ | OpenOptions::WRITE) {
|
||||
Err(Error::InvalidOperation)
|
||||
} else if opts.contains(OpenOptions::WRITE) {
|
||||
@ -230,14 +249,14 @@ impl<T: ToString + FromStr, R: ValueReadFn<T>, W: ValueWriteFn<T>> RegularImpl
|
||||
}
|
||||
}
|
||||
|
||||
fn close(&self, _node: &NodeRef, instance: Option<&Box<dyn Any>>) -> Result<(), Error> {
|
||||
fn close(&self, _node: &NodeRef, instance: Option<&InstanceData>) -> Result<(), Error> {
|
||||
if let Ok(write) = instance
|
||||
.unwrap()
|
||||
.downcast_ref::<FnNodeData>()
|
||||
.unwrap()
|
||||
.as_write()
|
||||
{
|
||||
let write = write.borrow();
|
||||
let write = write.lock();
|
||||
// Flush write
|
||||
let str = core::str::from_utf8(write.as_ref())
|
||||
.map_err(|_| Error::InvalidArgument)?
|
||||
@ -252,7 +271,7 @@ impl<T: ToString + FromStr, R: ValueReadFn<T>, W: ValueWriteFn<T>> RegularImpl
|
||||
fn read(
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
instance: Option<&Box<dyn Any>>,
|
||||
instance: Option<&InstanceData>,
|
||||
pos: u64,
|
||||
buf: &mut [u8],
|
||||
) -> Result<usize, Error> {
|
||||
@ -263,12 +282,12 @@ impl<T: ToString + FromStr, R: ValueReadFn<T>, W: ValueWriteFn<T>> RegularImpl
|
||||
fn write(
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
instance: Option<&Box<dyn Any>>,
|
||||
instance: Option<&InstanceData>,
|
||||
pos: u64,
|
||||
buf: &[u8],
|
||||
) -> Result<usize, Error> {
|
||||
let instance = instance.unwrap().downcast_ref::<FnNodeData>().unwrap();
|
||||
Ok(instance.as_write()?.borrow_mut().write_slice(pos as _, buf))
|
||||
Ok(instance.as_write()?.lock().write_slice(pos as _, buf))
|
||||
}
|
||||
}
|
||||
|
||||
@ -301,7 +320,7 @@ where
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
opts: OpenOptions,
|
||||
) -> Result<(u64, Option<Box<dyn Any>>), Error> {
|
||||
) -> Result<(u64, Option<InstanceData>), Error> {
|
||||
if opts.contains(OpenOptions::WRITE) {
|
||||
return Err(Error::ReadOnly);
|
||||
}
|
||||
@ -311,7 +330,7 @@ where
|
||||
fn read(
|
||||
&self,
|
||||
_node: &NodeRef,
|
||||
_instance: Option<&Box<dyn Any>>,
|
||||
_instance: Option<&InstanceData>,
|
||||
pos: u64,
|
||||
buf: &mut [u8],
|
||||
) -> Result<usize, Error> {
|
||||
@ -348,19 +367,25 @@ impl SymlinkImpl for FixedSymlink {
|
||||
}
|
||||
|
||||
/// Creates a read-only value node with given `value`
|
||||
pub fn const_value_node<T: ToString + Clone + 'static>(value: T) -> NodeRef {
|
||||
pub fn const_value_node<T>(value: T) -> NodeRef
|
||||
where
|
||||
T: ToString + Clone + Send + Sync + 'static,
|
||||
{
|
||||
ReadOnlyFnValueNode::new(move || Ok(value.clone()))
|
||||
}
|
||||
|
||||
/// Creates a read-write value node with given `value`
|
||||
pub fn value_node<T: ToString + FromStr + Clone + 'static>(value: T) -> NodeRef {
|
||||
let rd_state = Arc::new(RefCell::new(value));
|
||||
pub fn value_node<T>(value: T) -> NodeRef
|
||||
where
|
||||
T: ToString + FromStr + Clone + Send + Sync + 'static,
|
||||
{
|
||||
let rd_state = Arc::new(IrqSafeSpinlock::new(value));
|
||||
let wr_state = rd_state.clone();
|
||||
|
||||
FnValueNode::new(
|
||||
move || Ok(rd_state.borrow().clone()),
|
||||
move || Ok(rd_state.lock().clone()),
|
||||
move |t| {
|
||||
*wr_state.borrow_mut() = t;
|
||||
*wr_state.lock() = t;
|
||||
Ok(())
|
||||
},
|
||||
)
|
||||
|
@ -295,7 +295,7 @@ mod tests {
|
||||
use core::any::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::node::NodeFlags;
|
||||
use crate::{node::NodeFlags, NodeRef};
|
||||
|
||||
use super::{CommonImpl, DirectoryImpl, Node, RegularImpl};
|
||||
|
||||
@ -308,6 +308,15 @@ mod tests {
|
||||
impl CommonImpl for DummyFile {}
|
||||
impl RegularImpl for DummyFile {}
|
||||
|
||||
#[test]
|
||||
fn node_sync_send() {
|
||||
fn node_send<T: Send>(_n: &T) {}
|
||||
|
||||
let node = Node::regular(DummyFile, NodeFlags::empty());
|
||||
|
||||
node_send(&node);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dir_cache_add() {
|
||||
let d1 = Node::directory(DummyDirectory, NodeFlags::empty());
|
||||
|
@ -6,13 +6,13 @@ use yggdrasil_abi::{
|
||||
io::{DirectoryEntry, FileType, OpenOptions},
|
||||
};
|
||||
|
||||
use crate::file::DirectoryOpenPosition;
|
||||
use crate::file::{DirectoryOpenPosition, InstanceData};
|
||||
|
||||
use super::{Metadata, NodeRef};
|
||||
|
||||
/// Common interface shared by all filesystem nodes
|
||||
#[allow(unused)]
|
||||
pub trait CommonImpl {
|
||||
pub trait CommonImpl: Send + Sync {
|
||||
/// Returns `&self` as a reference to `dyn Any`
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
unimplemented!();
|
||||
@ -37,12 +37,12 @@ pub trait RegularImpl: CommonImpl {
|
||||
&self,
|
||||
node: &NodeRef,
|
||||
opts: OpenOptions,
|
||||
) -> Result<(u64, Option<Box<dyn Any>>), Error> {
|
||||
) -> Result<(u64, Option<InstanceData>), Error> {
|
||||
Err(Error::NotImplemented)
|
||||
}
|
||||
|
||||
/// Closes a file
|
||||
fn close(&self, node: &NodeRef, instance: Option<&Box<dyn Any>>) -> Result<(), Error> {
|
||||
fn close(&self, node: &NodeRef, instance: Option<&InstanceData>) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ pub trait RegularImpl: CommonImpl {
|
||||
fn read(
|
||||
&self,
|
||||
node: &NodeRef,
|
||||
instance: Option<&Box<dyn Any>>,
|
||||
instance: Option<&InstanceData>,
|
||||
pos: u64,
|
||||
buf: &mut [u8],
|
||||
) -> Result<usize, Error> {
|
||||
@ -60,7 +60,7 @@ pub trait RegularImpl: CommonImpl {
|
||||
fn write(
|
||||
&self,
|
||||
node: &NodeRef,
|
||||
instance: Option<&Box<dyn Any>>,
|
||||
instance: Option<&InstanceData>,
|
||||
pos: u64,
|
||||
buf: &[u8],
|
||||
) -> Result<usize, Error> {
|
||||
|
@ -16,7 +16,7 @@ use abi::{
|
||||
use tock_registers::interfaces::{Readable, Writeable};
|
||||
|
||||
use crate::{
|
||||
arch::{aarch64::cpu::Cpu, Architecture, ArchitectureImpl},
|
||||
arch::{Architecture, ArchitectureImpl},
|
||||
debug::LogLevel,
|
||||
syscall::raw_syscall_handler,
|
||||
task::{context::TaskFrame, thread::Thread},
|
||||
@ -117,7 +117,7 @@ pub fn init_exceptions() {
|
||||
}
|
||||
|
||||
fn dump_irrecoverable_exception(frame: &ExceptionFrame, ec: u64, iss: u64) {
|
||||
let cpu = Cpu::get_local();
|
||||
// let cpu = Cpu::get_local();
|
||||
|
||||
log_print_raw!(LogLevel::Fatal, "SYNC exception:\n");
|
||||
log_print_raw!(LogLevel::Fatal, "FAR: {:#x}\n", FAR_EL1.get());
|
||||
|
20
src/debug.rs
20
src/debug.rs
@ -2,17 +2,9 @@
|
||||
use core::fmt::{self, Arguments};
|
||||
|
||||
use abi::error::Error;
|
||||
use alloc::sync::Arc;
|
||||
use futures_util::Future;
|
||||
use kernel_util::{
|
||||
sync::IrqSafeSpinlock,
|
||||
util::{OneTimeInit, StaticVector},
|
||||
};
|
||||
use kernel_util::{sync::IrqSafeSpinlock, util::StaticVector};
|
||||
|
||||
use crate::{
|
||||
task::{process::Process, runtime::QueueWaker},
|
||||
util::ring::RingBuffer,
|
||||
};
|
||||
use crate::{task::process::Process, util::ring::RingBuffer};
|
||||
|
||||
const MAX_DEBUG_SINKS: usize = 4;
|
||||
const RING_LOGGER_CAPACITY: usize = 65536;
|
||||
@ -25,7 +17,6 @@ struct RingLoggerInner {
|
||||
|
||||
pub struct RingLoggerSink {
|
||||
inner: IrqSafeSpinlock<RingLoggerInner>,
|
||||
waker: QueueWaker,
|
||||
}
|
||||
|
||||
/// Defines the severity of the message
|
||||
@ -175,12 +166,11 @@ impl RingLoggerSink {
|
||||
inner: IrqSafeSpinlock::new(RingLoggerInner {
|
||||
data: RingBuffer::new(0),
|
||||
}),
|
||||
waker: QueueWaker::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(&self, pos: usize, buffer: &mut [u8]) -> usize {
|
||||
unsafe { self.inner.lock().data.read_all_static(pos, buffer) }
|
||||
self.inner.lock().data.read_all_static(pos, buffer)
|
||||
}
|
||||
|
||||
fn write_fmt(&self, args: fmt::Arguments<'_>) -> fmt::Result {
|
||||
@ -192,9 +182,7 @@ impl RingLoggerSink {
|
||||
impl fmt::Write for RingLoggerInner {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
for ch in s.bytes() {
|
||||
unsafe {
|
||||
self.data.write_unchecked(ch);
|
||||
}
|
||||
self.data.write(ch);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ impl TtyContext {
|
||||
}
|
||||
|
||||
pub fn set_config(&self, config: &TerminalOptions) -> Result<(), Error> {
|
||||
self.inner.lock().config = config.clone();
|
||||
self.inner.lock().config = *config;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,15 @@
|
||||
//! Device virtual file system
|
||||
use core::sync::atomic::{AtomicU32, AtomicU8, AtomicUsize, Ordering};
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use abi::error::Error;
|
||||
use alloc::{format, string::String, sync::Arc};
|
||||
use kernel_util::{sync::IrqSafeSpinlock, util::OneTimeInit};
|
||||
use alloc::{format, string::String};
|
||||
use kernel_util::util::OneTimeInit;
|
||||
use vfs::{
|
||||
impls::{mdir, read_fn_node, MemoryDirectory},
|
||||
impls::{read_fn_node, MemoryDirectory},
|
||||
CharDevice, Node, NodeFlags, NodeRef,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
arch::{Architecture, ARCHITECTURE},
|
||||
proc::random,
|
||||
};
|
||||
use crate::proc::random;
|
||||
|
||||
/// Describes the kind of a character device
|
||||
#[derive(Debug)]
|
||||
|
@ -1,13 +1,4 @@
|
||||
use core::{any::Any, marker::PhantomData};
|
||||
|
||||
use abi::{
|
||||
error::Error,
|
||||
io::{FileAttr, FileMode, FileType, OpenOptions},
|
||||
};
|
||||
use alloc::{
|
||||
boxed::Box,
|
||||
string::{String, ToString},
|
||||
};
|
||||
use abi::error::Error;
|
||||
use git_version::git_version;
|
||||
use kernel_util::util::OneTimeInit;
|
||||
use vfs::{
|
||||
|
110
src/panic.rs
110
src/panic.rs
@ -8,7 +8,7 @@ use crate::{
|
||||
arch::{Architecture, ArchitectureImpl, CpuMessage, ARCHITECTURE},
|
||||
debug::{debug_internal, LogLevel},
|
||||
device::display::console::flush_consoles,
|
||||
task::{sched::CpuQueue, Cpu},
|
||||
task::Cpu,
|
||||
};
|
||||
|
||||
static PANIC_HANDLED_FENCE: SpinFence = SpinFence::new();
|
||||
@ -49,80 +49,66 @@ fn panic_handler(pi: &core::panic::PanicInfo) -> ! {
|
||||
|
||||
static PANIC_HAPPENED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
infoln!("{:?}", pi);
|
||||
fatalln!("{:?}", pi);
|
||||
|
||||
// if PANIC_HAPPENED
|
||||
// .compare_exchange(false, true, Ordering::Release, Ordering::Acquire)
|
||||
// .is_ok()
|
||||
// {
|
||||
// let id = Cpu::local_id();
|
||||
// // Let other CPUs know we're screwed
|
||||
// unsafe {
|
||||
// ARCHITECTURE
|
||||
// .send_ipi(IpiDeliveryTarget::OtherCpus, CpuMessage::Panic)
|
||||
// .ok();
|
||||
// }
|
||||
if PANIC_HAPPENED
|
||||
.compare_exchange(false, true, Ordering::Release, Ordering::Acquire)
|
||||
.is_ok()
|
||||
{
|
||||
let id = Cpu::local_id();
|
||||
// Let other CPUs know we're screwed
|
||||
unsafe {
|
||||
ARCHITECTURE
|
||||
.send_ipi(IpiDeliveryTarget::OtherCpus, CpuMessage::Panic)
|
||||
.ok();
|
||||
}
|
||||
|
||||
// let ap_count = ArchitectureImpl::cpu_count() - 1;
|
||||
// PANIC_HANDLED_FENCE.wait_all(ap_count);
|
||||
let ap_count = ArchitectureImpl::cpu_count() - 1;
|
||||
PANIC_HANDLED_FENCE.wait_all(ap_count);
|
||||
|
||||
// unsafe {
|
||||
// hack_locks();
|
||||
// }
|
||||
unsafe {
|
||||
hack_locks();
|
||||
}
|
||||
|
||||
// log_print_raw!(LogLevel::Fatal, "--- BEGIN PANIC ---\n");
|
||||
// log_print_raw!(LogLevel::Fatal, "In CPU {}\n", Cpu::local_id());
|
||||
// log_print_raw!(LogLevel::Fatal, "Kernel panic ");
|
||||
log_print_raw!(LogLevel::Fatal, "--- BEGIN PANIC ---\n");
|
||||
log_print_raw!(LogLevel::Fatal, "In CPU {}\n", Cpu::local_id());
|
||||
log_print_raw!(LogLevel::Fatal, "Kernel panic ");
|
||||
|
||||
// if let Some(location) = pi.location() {
|
||||
// log_print_raw!(
|
||||
// LogLevel::Fatal,
|
||||
// "at {}:{}:",
|
||||
// location.file(),
|
||||
// location.line()
|
||||
// );
|
||||
// } else {
|
||||
// log_print_raw!(LogLevel::Fatal, ":");
|
||||
// }
|
||||
if let Some(location) = pi.location() {
|
||||
log_print_raw!(
|
||||
LogLevel::Fatal,
|
||||
"at {}:{}:",
|
||||
location.file(),
|
||||
location.line()
|
||||
);
|
||||
} else {
|
||||
log_print_raw!(LogLevel::Fatal, ":");
|
||||
}
|
||||
|
||||
// log_print_raw!(LogLevel::Fatal, "\n");
|
||||
log_print_raw!(LogLevel::Fatal, "\n");
|
||||
|
||||
// if let Some(msg) = pi.message() {
|
||||
// debug_internal(*msg, LogLevel::Fatal);
|
||||
// log_print_raw!(LogLevel::Fatal, "\n");
|
||||
// }
|
||||
if let Some(msg) = pi.message() {
|
||||
debug_internal(*msg, LogLevel::Fatal);
|
||||
log_print_raw!(LogLevel::Fatal, "\n");
|
||||
}
|
||||
|
||||
// for (i, queue) in CpuQueue::all().enumerate() {
|
||||
// log_print_raw!(LogLevel::Fatal, "queue{}:\n", i);
|
||||
// let lock = unsafe { queue.grab() };
|
||||
// for item in lock.iter() {
|
||||
// log_print_raw!(
|
||||
// LogLevel::Fatal,
|
||||
// "* {} {:?} {:?}\n",
|
||||
// item.id(),
|
||||
// item.name(),
|
||||
// item.state()
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
log_print_raw!(LogLevel::Fatal, "--- END PANIC ---\n");
|
||||
|
||||
// log_print_raw!(LogLevel::Fatal, "--- END PANIC ---\n");
|
||||
PANIC_FINISHED_FENCE.signal();
|
||||
while PANIC_SEQUENCE.load(Ordering::Acquire) != id {
|
||||
core::hint::spin_loop();
|
||||
}
|
||||
|
||||
// PANIC_FINISHED_FENCE.signal();
|
||||
// while PANIC_SEQUENCE.load(Ordering::Acquire) != id {
|
||||
// core::hint::spin_loop();
|
||||
// }
|
||||
log_print_raw!(LogLevel::Fatal, "X");
|
||||
|
||||
// log_print_raw!(LogLevel::Fatal, "X");
|
||||
flush_consoles();
|
||||
|
||||
// flush_consoles();
|
||||
PANIC_SEQUENCE.fetch_add(1, Ordering::Release);
|
||||
|
||||
// PANIC_SEQUENCE.fetch_add(1, Ordering::Release);
|
||||
|
||||
// unsafe {
|
||||
// ARCHITECTURE.reset();
|
||||
// }
|
||||
// }
|
||||
unsafe {
|
||||
ARCHITECTURE.reset();
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
ArchitectureImpl::wait_for_interrupt();
|
||||
|
@ -255,7 +255,7 @@ fn tls_segment(
|
||||
load_bytes(
|
||||
space,
|
||||
base_address + data_offset + data_size,
|
||||
|off, mut dst| {
|
||||
|_, mut dst| {
|
||||
dst.fill(0);
|
||||
Ok(())
|
||||
},
|
||||
@ -274,12 +274,6 @@ pub fn load_elf_from_file(
|
||||
let file = FileReader { file: &file };
|
||||
let elf = ElfStream::<AnyEndian, _>::open_stream(file).map_err(from_parse_error)?;
|
||||
|
||||
struct TlsInfo {
|
||||
master_address: usize,
|
||||
offset: usize,
|
||||
size: usize,
|
||||
}
|
||||
|
||||
let mut tls = None;
|
||||
|
||||
for phdr in elf.segments() {
|
||||
|
@ -11,10 +11,7 @@ use vfs::FileRef;
|
||||
|
||||
use crate::{
|
||||
mem::{
|
||||
phys,
|
||||
pointer::{PhysicalRef, PhysicalRefMut},
|
||||
process::ProcessAddressSpace,
|
||||
table::MapAttributes,
|
||||
phys, pointer::PhysicalRefMut, process::ProcessAddressSpace, table::MapAttributes,
|
||||
ForeignPointer,
|
||||
},
|
||||
proc,
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
use abi::{error::Error, io::RawFd};
|
||||
use alloc::collections::{btree_map::Entry, BTreeMap};
|
||||
use kernel_util::sync::IrqSafeSpinlock;
|
||||
use vfs::{FileRef, IoContext};
|
||||
|
||||
/// I/O context of a process, contains information like root, current directory and file
|
||||
|
@ -4,18 +4,13 @@ use core::{mem::MaybeUninit, time::Duration};
|
||||
use abi::{
|
||||
error::Error,
|
||||
io::{DeviceRequest, DirectoryEntry, FileAttr, FileMode, OpenOptions, RawFd, SeekFrom},
|
||||
path::Path,
|
||||
process::{ExitCode, MutexOperation, Signal, SpawnOption, SpawnOptions, ThreadSpawnOptions},
|
||||
syscall::SyscallFunction,
|
||||
};
|
||||
use alloc::{rc::Rc, sync::Arc};
|
||||
use alloc::sync::Arc;
|
||||
use kernel_util::sync::IrqSafeSpinlockGuard;
|
||||
use vfs::{CreateInfo, IoContext, NodeRef, Read, Seek, Write};
|
||||
// use vfs::{IoContext, Read, ReadDirectory, Seek, VnodeKind, VnodeRef, Write};
|
||||
use yggdrasil_abi::{
|
||||
error::SyscallResult,
|
||||
io::{MountOptions, UnmountOptions},
|
||||
};
|
||||
use vfs::{IoContext, NodeRef, Read, Seek, Write};
|
||||
use yggdrasil_abi::{error::SyscallResult, io::MountOptions};
|
||||
|
||||
use crate::{
|
||||
block,
|
||||
@ -135,7 +130,7 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
let opts = OpenOptions::from(args[3] as u32);
|
||||
let mode = FileMode::from(args[4] as u32);
|
||||
|
||||
run_with_io_at(&process, at, |at, mut io| {
|
||||
run_with_io_at(process, at, |at, mut io| {
|
||||
let file = io.ioctx().open(at, path, opts, mode)?;
|
||||
|
||||
// TODO NO_CTTY?
|
||||
@ -153,7 +148,7 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
let at = arg_option_fd(args[0] as u32);
|
||||
let path = arg_user_str(args[1] as usize, args[2] as usize)?;
|
||||
|
||||
run_with_io_at(&process, at, |at, mut io| {
|
||||
run_with_io_at(process, at, |at, mut io| {
|
||||
let node = io.ioctx().find(at, path, true, true)?;
|
||||
let access = io.ioctx().check_access(vfs::Action::Read, &node)?;
|
||||
let file = node.open_directory(access)?;
|
||||
@ -166,19 +161,19 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
let fd = RawFd(args[0] as u32);
|
||||
let data = arg_buffer_mut(args[1] as _, args[2] as _)?;
|
||||
|
||||
run_with_io(&process, |io| io.file(fd)?.read(data))
|
||||
run_with_io(process, |io| io.file(fd)?.read(data))
|
||||
}
|
||||
SyscallFunction::Write => {
|
||||
let fd = RawFd(args[0] as u32);
|
||||
let data = arg_buffer_ref(args[1] as _, args[2] as _)?;
|
||||
|
||||
run_with_io(&process, |io| io.file(fd)?.write(data))
|
||||
run_with_io(process, |io| io.file(fd)?.write(data))
|
||||
}
|
||||
SyscallFunction::Seek => {
|
||||
let fd = RawFd(args[0] as u32);
|
||||
let pos = SeekFrom::from(args[1]);
|
||||
|
||||
run_with_io(&process, |io| io.file(fd)?.seek(pos).map(|v| v as usize))
|
||||
run_with_io(process, |io| io.file(fd)?.seek(pos).map(|v| v as usize))
|
||||
}
|
||||
SyscallFunction::ReadDirectory => {
|
||||
let fd = RawFd(args[0] as u32);
|
||||
@ -187,12 +182,12 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
args[2] as usize,
|
||||
)?;
|
||||
|
||||
run_with_io(&process, |io| io.file(fd)?.read_dir(buffer))
|
||||
run_with_io(process, |io| io.file(fd)?.read_dir(buffer))
|
||||
}
|
||||
SyscallFunction::Close => {
|
||||
let fd = RawFd(args[0] as u32);
|
||||
|
||||
run_with_io(&process, |mut io| {
|
||||
run_with_io(process, |mut io| {
|
||||
io.close_file(fd)?;
|
||||
Ok(0)
|
||||
})
|
||||
@ -200,7 +195,7 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
SyscallFunction::Mount => {
|
||||
let options = arg_user_ref::<MountOptions>(args[0] as usize)?;
|
||||
|
||||
run_with_io(&process, |mut io| {
|
||||
run_with_io(process, |mut io| {
|
||||
let fs_root = fs::create_filesystem(options)?;
|
||||
io.ioctx().mount(options.target, fs_root)?;
|
||||
Ok(0)
|
||||
@ -213,7 +208,7 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
let fd = RawFd(args[0] as u32);
|
||||
let req = arg_user_mut::<DeviceRequest>(args[1] as usize)?;
|
||||
|
||||
run_with_io(&process, |io| {
|
||||
run_with_io(process, |io| {
|
||||
let file = io.file(fd)?;
|
||||
let node = file.node().ok_or(Error::InvalidFile)?;
|
||||
node.device_request(req)?;
|
||||
@ -226,7 +221,7 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
let buffer = arg_user_mut::<MaybeUninit<FileAttr>>(args[3] as usize)?;
|
||||
let follow = args[4] != 0;
|
||||
|
||||
run_with_io_at(&process, at, |at, mut io| {
|
||||
run_with_io_at(process, at, |at, mut io| {
|
||||
let node = if path.is_empty() {
|
||||
at.ok_or(Error::InvalidArgument)?
|
||||
} else {
|
||||
@ -250,7 +245,7 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
let path = arg_user_str(args[1] as usize, args[2] as usize)?;
|
||||
let mode = FileMode::from(args[3] as u32);
|
||||
|
||||
run_with_io_at(&process, at, |at, mut io| {
|
||||
run_with_io_at(process, at, |at, mut io| {
|
||||
io.ioctx().create_directory(at, path, mode)?;
|
||||
Ok(0)
|
||||
})
|
||||
@ -258,9 +253,8 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
SyscallFunction::Remove => {
|
||||
let at = arg_option_fd(args[0] as u32);
|
||||
let path = arg_user_str(args[1] as usize, args[2] as usize)?;
|
||||
let recurse = args[3] != 0;
|
||||
|
||||
run_with_io_at(&process, at, |at, mut io| {
|
||||
run_with_io_at(process, at, |at, mut io| {
|
||||
io.ioctx().remove_file(at, path)?;
|
||||
Ok(0)
|
||||
})
|
||||
@ -272,7 +266,7 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
SyscallFunction::SpawnProcess => {
|
||||
let options = arg_user_ref::<SpawnOptions>(args[0] as usize)?;
|
||||
|
||||
run_with_io(&process, |mut io| {
|
||||
run_with_io(process, |mut io| {
|
||||
// let node = io.ioctx().find(None, options.program, true, true)?;
|
||||
|
||||
// Setup a new process from the file
|
||||
@ -287,7 +281,7 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
let pid: u32 = child_process.id().into();
|
||||
|
||||
// Inherit group and session from the creator
|
||||
child_process.inherit(&process)?;
|
||||
child_process.inherit(process)?;
|
||||
|
||||
// Inherit root from the creator
|
||||
// let child_ioctx = IoContext::new(io.ioctx().root().clone());
|
||||
@ -395,10 +389,10 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
|
||||
if let Some(ctty) = session_terminal {
|
||||
// Drop all FDs referring to the old session terminal
|
||||
run_with_io(&process, |mut io| {
|
||||
run_with_io(process, |mut io| {
|
||||
io.retain(|_, f| {
|
||||
f.node()
|
||||
.map(|node| !Arc::ptr_eq(&node, &ctty))
|
||||
.map(|node| !Arc::ptr_eq(node, &ctty))
|
||||
.unwrap_or(true)
|
||||
});
|
||||
});
|
||||
|
@ -3,18 +3,15 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use abi::error::Error;
|
||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||
use kernel_util::sync::{IrqSafeSpinlock, SpinFence};
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use kernel_util::sync::SpinFence;
|
||||
|
||||
use crate::{
|
||||
arch::{Architecture, ArchitectureImpl},
|
||||
task::{sched::CpuQueue, thread::Thread},
|
||||
};
|
||||
|
||||
use self::{
|
||||
context::{TaskContextImpl, Termination},
|
||||
process::Process,
|
||||
};
|
||||
use self::context::{TaskContextImpl, Termination};
|
||||
|
||||
pub mod context;
|
||||
pub mod process;
|
||||
@ -25,48 +22,6 @@ pub mod thread;
|
||||
|
||||
pub use context::{Cpu, TaskContext};
|
||||
|
||||
// /// Process identifier alias for clarity
|
||||
// pub type ProcessId = usize;
|
||||
|
||||
// /// Wrapper structure to hold all the system's processes
|
||||
// pub struct ProcessList {
|
||||
// data: Vec<(ProcessId, Arc<Process>)>,
|
||||
// last_process_id: ProcessId,
|
||||
// }
|
||||
//
|
||||
// impl ProcessList {
|
||||
// /// Constructs an empty process list
|
||||
// pub const fn new() -> Self {
|
||||
// Self {
|
||||
// last_process_id: 0,
|
||||
// data: Vec::new(),
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /// Inserts a new process into the list.
|
||||
// ///
|
||||
// /// # Safety
|
||||
// ///
|
||||
// /// Only meant to be called from inside the Process impl, as this function does not perform any
|
||||
// /// accounting information updates.
|
||||
// pub unsafe fn push(&mut self, process: Arc<Process>) -> ProcessId {
|
||||
// self.last_process_id += 1;
|
||||
// debugln!("Insert process with ID {}", self.last_process_id);
|
||||
// self.data.push((self.last_process_id, process));
|
||||
// self.last_process_id
|
||||
// }
|
||||
//
|
||||
// /// Looks up a process by its ID
|
||||
// pub fn get(&self, id: ProcessId) -> Option<&Arc<Process>> {
|
||||
// self.data
|
||||
// .iter()
|
||||
// .find_map(|(i, p)| if *i == id { Some(p) } else { None })
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /// Global shared process list
|
||||
// pub static PROCESSES: IrqSafeSpinlock<ProcessList> = IrqSafeSpinlock::new(ProcessList::new());
|
||||
|
||||
/// Creates a new kernel-space process to execute a closure and queues it to some CPU
|
||||
pub fn spawn_kernel_closure<S: Into<String>, T: Termination, F: Fn() -> T + Send + 'static>(
|
||||
name: S,
|
||||
|
@ -4,7 +4,7 @@ use core::{
|
||||
fmt,
|
||||
mem::size_of,
|
||||
pin::Pin,
|
||||
sync::atomic::{AtomicBool, AtomicU32, AtomicU64, Ordering},
|
||||
sync::atomic::{AtomicU64, Ordering},
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
@ -12,23 +12,13 @@ use abi::{
|
||||
error::Error,
|
||||
process::{ExitCode, Signal, ThreadSpawnOptions},
|
||||
};
|
||||
use alloc::{
|
||||
collections::{BTreeMap, VecDeque},
|
||||
string::String,
|
||||
sync::Arc,
|
||||
vec::Vec,
|
||||
};
|
||||
use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec};
|
||||
use futures_util::Future;
|
||||
use kernel_util::{sync::IrqSafeSpinlock, util::OneTimeInit};
|
||||
use kernel_util::sync::IrqSafeSpinlock;
|
||||
use vfs::NodeRef;
|
||||
|
||||
use crate::{
|
||||
mem::{
|
||||
phys,
|
||||
pointer::{PhysicalRef, PhysicalRefMut},
|
||||
process::ProcessAddressSpace,
|
||||
table::MapAttributes,
|
||||
},
|
||||
mem::process::ProcessAddressSpace,
|
||||
proc::{self, io::ProcessIo},
|
||||
task::context::TaskContextImpl,
|
||||
};
|
||||
@ -36,7 +26,7 @@ use crate::{
|
||||
use super::{
|
||||
runtime::QueueWaker,
|
||||
sync::UserspaceMutex,
|
||||
thread::{Thread, ThreadId, ThreadState},
|
||||
thread::{Thread, ThreadId},
|
||||
TaskContext,
|
||||
};
|
||||
|
||||
@ -197,8 +187,7 @@ impl Process {
|
||||
);
|
||||
|
||||
let tls_address = if let Some(image) = self.image.as_ref() {
|
||||
todo!()
|
||||
// proc::elf::clone_tls(&self.space, image)?
|
||||
proc::elf::clone_tls(&self.space, image)?
|
||||
} else {
|
||||
0
|
||||
};
|
||||
@ -378,8 +367,6 @@ impl Process {
|
||||
|
||||
impl fmt::Display for ProcessId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use fmt::Write;
|
||||
|
||||
write!(f, "<Process {}>", self.0)
|
||||
}
|
||||
}
|
||||
|
@ -2,20 +2,11 @@
|
||||
|
||||
use core::sync::atomic::Ordering;
|
||||
|
||||
// use aarch64_cpu::registers::CNTPCT_EL0;
|
||||
use alloc::{
|
||||
collections::{BTreeMap, VecDeque},
|
||||
sync::Arc,
|
||||
vec::Vec,
|
||||
};
|
||||
use alloc::{collections::VecDeque, sync::Arc, vec::Vec};
|
||||
use cfg_if::cfg_if;
|
||||
use kernel_util::{
|
||||
sync::{IrqGuard, IrqSafeSpinlock, IrqSafeSpinlockGuard},
|
||||
util::OneTimeInit,
|
||||
};
|
||||
use kernel_util::{sync::IrqSafeSpinlock, util::OneTimeInit};
|
||||
|
||||
use crate::{
|
||||
// arch::aarch64::{context::TaskContext, cpu::Cpu},
|
||||
arch::{Architecture, ArchitectureImpl},
|
||||
task::thread::ThreadState,
|
||||
};
|
||||
@ -169,11 +160,7 @@ impl CpuQueue {
|
||||
|
||||
let mut inner = self.inner.lock();
|
||||
|
||||
// let t = CNTPCT_EL0.get();
|
||||
// let delta = t - inner.stats.measure_time;
|
||||
// inner.stats.measure_time = t;
|
||||
|
||||
let current = inner.current.clone();
|
||||
let current = inner.current;
|
||||
let current_t = current.and_then(Thread::get);
|
||||
|
||||
if let Some(current_t) = current_t.as_ref() {
|
||||
@ -192,14 +179,10 @@ impl CpuQueue {
|
||||
.is_ok()
|
||||
{
|
||||
inner.queue.push_back(current_t.id());
|
||||
// inner.stats.cpu_time += delta;
|
||||
}
|
||||
}
|
||||
// else
|
||||
// inner.stats.idle_time += delta;
|
||||
|
||||
let next_t = inner.next_ready_task();
|
||||
// let next_t = next.and_then(Thread::get);
|
||||
|
||||
inner.current = next_t.as_deref().map(Thread::id);
|
||||
|
||||
@ -221,23 +204,6 @@ impl CpuQueue {
|
||||
|
||||
assert!(ArchitectureImpl::interrupt_mask());
|
||||
to.switch(from)
|
||||
|
||||
// // log_print_raw!(crate::debug::LogLevel::Info, "{}: ", Cpu::local_id());
|
||||
// // if let Some(from) = current.as_ref() {
|
||||
// // log_print_raw!(crate::debug::LogLevel::Info, "{}", from.id(),);
|
||||
// // } else {
|
||||
// // log_print_raw!(crate::debug::LogLevel::Info, "{{idle}}");
|
||||
// // }
|
||||
|
||||
// // log_print_raw!(crate::debug::LogLevel::Info, " -> ");
|
||||
|
||||
// // if let Some(to) = next.as_ref() {
|
||||
// // log_print_raw!(crate::debug::LogLevel::Info, "{}", to.id(),);
|
||||
// // } else {
|
||||
// // log_print_raw!(crate::debug::LogLevel::Info, "{{idle}}");
|
||||
// // }
|
||||
|
||||
// // log_print_raw!(crate::debug::LogLevel::Info, "\n");
|
||||
}
|
||||
|
||||
/// Pushes the process to the back of the execution queue.
|
||||
|
@ -18,10 +18,7 @@ use alloc::{
|
||||
};
|
||||
use atomic_enum::atomic_enum;
|
||||
use futures_util::{task::ArcWake, Future};
|
||||
use kernel_util::{
|
||||
sync::{IrqGuard, IrqSafeSpinlock},
|
||||
util::OneTimeInit,
|
||||
};
|
||||
use kernel_util::sync::{IrqGuard, IrqSafeSpinlock};
|
||||
|
||||
use crate::{
|
||||
block,
|
||||
@ -179,17 +176,17 @@ impl Thread {
|
||||
.queue()
|
||||
.current_id()
|
||||
.and_then(Self::get)
|
||||
.map(|t| unsafe { CurrentThread(t, guard) })
|
||||
.map(|t| CurrentThread(t, guard))
|
||||
}
|
||||
|
||||
pub fn enqueue_somewhere(&self) {
|
||||
pub fn enqueue_somewhere(&self) -> usize {
|
||||
// Doesn't have to be precise, so even if something changes, we can still be rebalanced
|
||||
// to another CPU
|
||||
let (index, queue) = CpuQueue::least_loaded().unwrap();
|
||||
|
||||
self.enqueue_to(queue);
|
||||
|
||||
// index
|
||||
index
|
||||
}
|
||||
|
||||
pub fn enqueue_to(&self, queue: &'static CpuQueue) {
|
||||
@ -264,6 +261,11 @@ impl Thread {
|
||||
}
|
||||
}
|
||||
|
||||
/// Marks the process as running and sets its "current" CPU index.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Only meant to be called from within the scheduler.
|
||||
pub unsafe fn set_running(&self, cpu: u32) {
|
||||
self.cpu_id.store(cpu, Ordering::Release);
|
||||
self.state.store(ThreadState::Running, Ordering::Release);
|
||||
@ -400,9 +402,9 @@ impl CurrentThread {
|
||||
/// This function is only meant to be called right before returning from an userspace
|
||||
/// exception handler.
|
||||
pub unsafe fn handle_pending_signals<F: TaskFrame>(&self, frame: &mut F) {
|
||||
let ThreadId::User(id) = self.id else {
|
||||
if !self.id.is_user() {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
let mut inner = self.inner.lock();
|
||||
|
||||
@ -443,19 +445,6 @@ impl CurrentThread {
|
||||
// Pass the frame pointer as an argument to signal handler entry
|
||||
frame.set_argument(usp as _);
|
||||
}
|
||||
|
||||
// let process = self.process();
|
||||
|
||||
// if let Some((entry, signal)) = process.pop_signal() {
|
||||
// debugln!(
|
||||
// "{} of {}, enter signal handler from pc={:#x}, sp={:#x}",
|
||||
// self.id,
|
||||
// process.id(),
|
||||
// frame.user_ip(),
|
||||
// frame.user_sp()
|
||||
// );
|
||||
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -486,12 +475,14 @@ impl ThreadId {
|
||||
&Self::User(id) => id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_user(&self) -> bool {
|
||||
matches!(self, ThreadId::User(_))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ThreadId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use fmt::Write;
|
||||
|
||||
match self {
|
||||
Self::Kernel(id) => write!(f, "#[{id}]"),
|
||||
Self::User(id) => write!(f, "#{id}"),
|
||||
|
@ -44,13 +44,13 @@ impl<T: Copy, const N: usize> RingBuffer<T, N> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn read_unchecked(&mut self) -> T {
|
||||
fn read_single(&mut self) -> T {
|
||||
let res = self.data[self.rd];
|
||||
self.rd = (self.rd + 1) % N;
|
||||
res
|
||||
}
|
||||
|
||||
pub unsafe fn read_all_static(&mut self, pos: usize, buffer: &mut [T]) -> usize {
|
||||
pub fn read_all_static(&mut self, pos: usize, buffer: &mut [T]) -> usize {
|
||||
let mut pos = (self.rd + pos) % N;
|
||||
let mut off = 0;
|
||||
while off < buffer.len() && self.is_readable_at(pos) {
|
||||
@ -62,7 +62,7 @@ impl<T: Copy, const N: usize> RingBuffer<T, N> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn write_unchecked(&mut self, ch: T) {
|
||||
pub fn write(&mut self, ch: T) {
|
||||
self.data[self.wr] = ch;
|
||||
self.wr = (self.wr + 1) % N;
|
||||
}
|
||||
@ -77,11 +77,10 @@ impl<T: Copy, const N: usize> AsyncRing<T, N> {
|
||||
}
|
||||
|
||||
pub fn try_write(&self, item: T) -> Result<(), Error> {
|
||||
let mut lock = self.inner.lock();
|
||||
unsafe {
|
||||
lock.write_unchecked(item);
|
||||
{
|
||||
let mut lock = self.inner.lock();
|
||||
lock.write(item);
|
||||
}
|
||||
drop(lock);
|
||||
self.read_waker.wake_one();
|
||||
|
||||
Ok(())
|
||||
@ -102,7 +101,7 @@ impl<T: Copy, const N: usize> AsyncRing<T, N> {
|
||||
let mut inner = self.inner.lock();
|
||||
if inner.is_readable() {
|
||||
self.read_waker.remove(cx.waker());
|
||||
Poll::Ready(unsafe { inner.read_unchecked() })
|
||||
Poll::Ready(inner.read_single())
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user