Fix multiple issues pointed out by the new compiler
This commit is contained in:
parent
5f2bd9d0ac
commit
9e4257b655
|
@ -655,9 +655,9 @@ checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
|
|||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.30.0"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2e1d97fbe9722ba9bbd0c97051c2956e726562b61f86a25a4360398a40edfc9"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "hash32"
|
||||
|
@ -1668,11 +1668,11 @@ checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a"
|
|||
|
||||
[[package]]
|
||||
name = "unwinding"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc55842d0db6329a669d55a623c674b02d677b16bfb2d24857d4089d41eba882"
|
||||
checksum = "637d511437df708cee34bdec7ba2f1548d256b7acf3ff20e0a1c559f9bf3a987"
|
||||
dependencies = [
|
||||
"gimli 0.30.0",
|
||||
"gimli 0.31.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -48,7 +48,7 @@ impl device::RxToken for RxToken {
|
|||
|
||||
pub struct TxToken<'a>(&'a mut dyn AnyNetworkDevice);
|
||||
|
||||
impl<'a> device::TxToken for TxToken<'a> {
|
||||
impl device::TxToken for TxToken<'_> {
|
||||
fn consume<R, F>(self, len: usize, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut [u8]) -> R,
|
||||
|
|
|
@ -166,9 +166,12 @@ impl ClockSource {
|
|||
}
|
||||
}
|
||||
|
||||
/// `Instant` captures a specific moment, storing the duration of time
|
||||
/// A specific moment.
|
||||
///
|
||||
/// [`Instant`] captures a specific moment, storing the duration of time
|
||||
/// elapsed since a reference point (typically the system boot time).
|
||||
/// The `Instant` is expressed in seconds and the fractional part is expressed in nanoseconds.
|
||||
/// The [`Instant`] is expressed in seconds and the fractional part is
|
||||
/// expressed in nanoseconds.
|
||||
#[derive(Debug, Default, Copy, Clone)]
|
||||
pub struct Instant {
|
||||
secs: u64,
|
||||
|
|
|
@ -162,9 +162,9 @@ impl<D, E> EtherIface<D, E> {
|
|||
}
|
||||
|
||||
// Ignore the ARP packet if we do not own the target address.
|
||||
if !iface_cx
|
||||
if iface_cx
|
||||
.ipv4_addr()
|
||||
.is_some_and(|addr| addr == *target_protocol_addr)
|
||||
.is_none_or(|addr| addr != *target_protocol_addr)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ impl<'a, E> PollContext<'a, E> {
|
|||
pub(super) trait FnHelper<A, B, C, O>: FnMut(A, B, C) -> O {}
|
||||
impl<A, B, C, O, F> FnHelper<A, B, C, O> for F where F: FnMut(A, B, C) -> O {}
|
||||
|
||||
impl<'a, E> PollContext<'a, E> {
|
||||
impl<E> PollContext<'_, E> {
|
||||
pub(super) fn poll_ingress<D, P, Q>(
|
||||
&mut self,
|
||||
device: &mut D,
|
||||
|
@ -280,7 +280,7 @@ impl<'a, E> PollContext<'a, E> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, E> PollContext<'a, E> {
|
||||
impl<E> PollContext<'_, E> {
|
||||
pub(super) fn poll_egress<D, Q>(&mut self, device: &mut D, mut dispatch_phy: Q)
|
||||
where
|
||||
D: Device + ?Sized,
|
||||
|
|
|
@ -368,7 +368,7 @@ impl<T, R> SafePtr<T, DmaStream, R> {
|
|||
}
|
||||
|
||||
#[inherit_methods(from = "(*self)")]
|
||||
impl<'a, T, R> SafePtr<T, &'a DmaStream, R> {
|
||||
impl<T, R> SafePtr<T, &DmaStream, R> {
|
||||
pub fn sync(&self) -> Result<()>;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use crate::{Cons, Nil};
|
||||
|
||||
/// This trait will extend a set with another item.
|
||||
///
|
||||
/// If the set already contains the item, it will return the original set.
|
||||
/// Otherwise, it will return the new set with the new item.
|
||||
/// The implementation should care about the item orders when extending set.
|
||||
|
|
|
@ -159,15 +159,19 @@ impl<'a> CurrentUserSpace<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A trait providing the ability to read a C string from the user space
|
||||
/// of the current process specifically for [`VmReader<'_, UserSpace>`], which
|
||||
/// should reading the bytes iteratively in the reader until encountering
|
||||
/// the end of the reader or reading a `\0` (is also included into the final C String).
|
||||
/// A trait providing the ability to read a C string from the user space.
|
||||
///
|
||||
/// The user space should be of the current process. The implemented method
|
||||
/// should read the bytes iteratively in the reader ([`VmReader`]) until
|
||||
/// encountering the end of the reader or reading a `\0` (which is also
|
||||
/// included in the final C String).
|
||||
pub trait ReadCString {
|
||||
fn read_cstring(&mut self) -> Result<CString>;
|
||||
}
|
||||
|
||||
impl<'a> ReadCString for VmReader<'a, Fallible> {
|
||||
impl ReadCString for VmReader<'_, Fallible> {
|
||||
/// Reads a C string from the user space.
|
||||
///
|
||||
/// This implementation is inspired by
|
||||
/// the `do_strncpy_from_user` function in Linux kernel.
|
||||
/// The original Linux implementation can be found at:
|
||||
|
|
|
@ -240,7 +240,7 @@ impl LineDiscipline {
|
|||
b'\r' => echo_callback("\r\n"),
|
||||
ch if ch == *termios.get_special_char(CC_C_CHAR::VERASE) => {
|
||||
// write a space to overwrite current character
|
||||
let backspace: &str = core::str::from_utf8(&[b'\x08', b' ', b'\x08']).unwrap();
|
||||
let backspace: &str = core::str::from_utf8(b"\x08 \x08").unwrap();
|
||||
echo_callback(backspace);
|
||||
}
|
||||
ch if is_printable_char(ch) => print!("{}", char::from(ch)),
|
||||
|
|
|
@ -403,8 +403,8 @@ impl ExfatDentrySet {
|
|||
}
|
||||
Ok(name)
|
||||
}
|
||||
/// Name dentries are not permitted to modify. We should create a new dentry set for renaming.
|
||||
|
||||
/// Name dentries are not permitted to modify. We should create a new dentry set for renaming.
|
||||
fn calculate_checksum(&self) -> u16 {
|
||||
const CHECKSUM_BYTES_RANGE: Range<usize> = 2..4;
|
||||
const EMPTY_RANGE: Range<usize> = 0..0;
|
||||
|
@ -502,7 +502,6 @@ impl Iterator for ExfatDentryIterator {
|
|||
}
|
||||
|
||||
/// On-disk dentry formats
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(Clone, Debug, Default, Copy, Pod)]
|
||||
// For files & directories
|
||||
|
|
|
@ -891,7 +891,7 @@ impl ExfatInode {
|
|||
// TODO: remove trailing periods of pathname.
|
||||
// Do not allow creation of files with names ending with period(s).
|
||||
|
||||
let name_dentries = (name.len() + EXFAT_FILE_NAME_LEN - 1) / EXFAT_FILE_NAME_LEN;
|
||||
let name_dentries = name.len().div_ceil(EXFAT_FILE_NAME_LEN);
|
||||
let num_dentries = name_dentries + 2; // FILE Entry + Stream Entry + Name Entry
|
||||
|
||||
// We update the size of inode before writing page_cache, but it is fine since we've cleaned the page_cache.
|
||||
|
@ -1139,7 +1139,7 @@ impl Inode for ExfatInode {
|
|||
ino: inner.ino,
|
||||
size: inner.size,
|
||||
blk_size,
|
||||
blocks: (inner.size + blk_size - 1) / blk_size,
|
||||
blocks: inner.size.div_ceil(blk_size),
|
||||
atime: inner.atime.as_duration().unwrap_or_default(),
|
||||
mtime: inner.mtime.as_duration().unwrap_or_default(),
|
||||
ctime: inner.ctime.as_duration().unwrap_or_default(),
|
||||
|
|
|
@ -698,7 +698,7 @@ mod test {
|
|||
}
|
||||
|
||||
let steps = 7;
|
||||
let write_len = (BUF_SIZE + steps - 1) / steps;
|
||||
let write_len = BUF_SIZE.div_ceil(steps);
|
||||
for i in 0..steps {
|
||||
let start = i * write_len;
|
||||
let end = BUF_SIZE.min(start + write_len);
|
||||
|
|
|
@ -14,7 +14,7 @@ pub fn make_hash_index(cluster: ClusterID, offset: u32) -> usize {
|
|||
pub fn calc_checksum_32(data: &[u8]) -> u32 {
|
||||
let mut checksum: u32 = 0;
|
||||
for &value in data {
|
||||
checksum = ((checksum << 31) | (checksum >> 1)).wrapping_add(value as u32);
|
||||
checksum = checksum.rotate_right(1).wrapping_add(value as u32);
|
||||
}
|
||||
checksum
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ pub fn calc_checksum_16(data: &[u8], ignore: core::ops::Range<usize>, prev_check
|
|||
if ignore.contains(&pos) {
|
||||
continue;
|
||||
}
|
||||
result = ((result << 15) | (result >> 1)).wrapping_add(value as u16);
|
||||
result = result.rotate_right(1).wrapping_add(value as u16);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
|
|
@ -192,7 +192,7 @@ impl<'a> DirEntryReader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for DirEntryReader<'a> {
|
||||
impl Iterator for DirEntryReader<'_> {
|
||||
type Item = (usize, DirEntry);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
|
|
@ -1761,7 +1761,7 @@ impl<'a> DeviceRangeReader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for DeviceRangeReader<'a> {
|
||||
impl Iterator for DeviceRangeReader<'_> {
|
||||
type Item = Range<Ext2Bid>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
|
|
@ -491,7 +491,7 @@ impl<'a> FsPath<'a> {
|
|||
impl<'a> TryFrom<&'a str> for FsPath<'a> {
|
||||
type Error = crate::error::Error;
|
||||
|
||||
fn try_from(path: &'a str) -> Result<FsPath> {
|
||||
fn try_from(path: &'a str) -> Result<FsPath<'a>> {
|
||||
if path.is_empty() {
|
||||
return_errno_with_message!(Errno::ENOENT, "path is an empty string");
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ use crate::{
|
|||
mod cap_last_cap;
|
||||
|
||||
/// Represents the inode at `/proc/sys/kernel`.
|
||||
|
||||
pub struct KernelDirOps;
|
||||
|
||||
impl KernelDirOps {
|
||||
|
|
|
@ -502,7 +502,7 @@ pub struct InodeWriter<'a> {
|
|||
offset: usize,
|
||||
}
|
||||
|
||||
impl<'a> Write for InodeWriter<'a> {
|
||||
impl Write for InodeWriter<'_> {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
|
||||
let mut reader = VmReader::from(buf).to_fallible();
|
||||
|
|
|
@ -6,6 +6,7 @@ use super::*;
|
|||
pub const OFFSET_MAX: usize = i64::MAX as usize;
|
||||
|
||||
/// A range in a file.
|
||||
///
|
||||
/// The range is [start, end).
|
||||
/// The range is valid if start < end.
|
||||
/// The range is empty if start == end.
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#![feature(fn_traits)]
|
||||
#![feature(format_args_nl)]
|
||||
#![feature(int_roundings)]
|
||||
#![feature(iter_repeat_n)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(linkage)]
|
||||
#![feature(linked_list_remove)]
|
||||
|
|
|
@ -74,9 +74,8 @@ impl BoundDatagram {
|
|||
// But current smoltcp API seems not to support this behavior.
|
||||
reader
|
||||
.read(&mut VmWriter::from(socket_buffer))
|
||||
.map_err(|e| {
|
||||
warn!("unexpected UDP packet will be sent");
|
||||
e
|
||||
.inspect_err(|e| {
|
||||
warn!("unexpected UDP packet {e:#?} will be sent");
|
||||
})
|
||||
});
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@ pub(super) struct Credentials_ {
|
|||
supplementary_gids: RwLock<BTreeSet<Gid>>,
|
||||
|
||||
/// The Linux capabilities.
|
||||
///
|
||||
/// This is not the capability (in static_cap.rs) enforced on rust objects.
|
||||
|
||||
/// Capability that child processes can inherit
|
||||
inheritable_capset: AtomicCapSet,
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ impl<'a> FutexIter<'a> {
|
|||
|
||||
const ROBUST_LIST_LIMIT: isize = 2048;
|
||||
|
||||
impl<'a> Iterator for FutexIter<'a> {
|
||||
impl Iterator for FutexIter<'_> {
|
||||
type Item = Vaddr;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
|
|
@ -108,7 +108,7 @@ pub struct ProcessGroupGuard<'a> {
|
|||
inner: MutexGuard<'a, Inner>,
|
||||
}
|
||||
|
||||
impl<'a> ProcessGroupGuard<'a> {
|
||||
impl ProcessGroupGuard<'_> {
|
||||
/// Returns an iterator over the processes in the group.
|
||||
pub fn iter(&self) -> ProcessGroupIter {
|
||||
ProcessGroupIter {
|
||||
|
|
|
@ -44,7 +44,7 @@ pub struct ProcessTable<'a> {
|
|||
inner: MutexGuard<'a, BTreeMap<Pid, Arc<Process>>>,
|
||||
}
|
||||
|
||||
impl<'a> ProcessTable<'a> {
|
||||
impl ProcessTable<'_> {
|
||||
/// Returns an iterator over the processes in the table.
|
||||
pub fn iter(&self) -> ProcessTableIter {
|
||||
ProcessTableIter {
|
||||
|
|
|
@ -14,7 +14,6 @@ use crate::prelude::*;
|
|||
/// > about the environment in which it is operating. The form of this information
|
||||
/// > is a table of key-value pairs, where the keys are from the set of ‘AT_’
|
||||
/// > values in elf.h.
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
#[repr(u8)]
|
||||
|
|
|
@ -338,11 +338,7 @@ fn map_segment_vmo(
|
|||
vm_map_options = vm_map_options.offset(offset).handle_page_faults_around();
|
||||
let map_addr = vm_map_options.build()?;
|
||||
|
||||
let anonymous_map_size: usize = if total_map_size > segment_size {
|
||||
total_map_size - segment_size
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let anonymous_map_size: usize = total_map_size.saturating_sub(segment_size);
|
||||
|
||||
if anonymous_map_size > 0 {
|
||||
let mut anonymous_map_options = root_vmar
|
||||
|
|
|
@ -104,7 +104,7 @@ impl<'a, T: DirentSerializer> DirentBufferReader<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: DirentSerializer> DirentVisitor for DirentBufferReader<'a, T> {
|
||||
impl<T: DirentSerializer> DirentVisitor for DirentBufferReader<'_, T> {
|
||||
fn visit(&mut self, name: &str, ino: u64, type_: InodeType, offset: usize) -> Result<()> {
|
||||
let dirent_serializer = T::new(ino, offset as u64, type_, CString::new(name)?);
|
||||
if self.read_len >= self.buffer.len() {
|
||||
|
|
|
@ -218,6 +218,7 @@ impl MMapOptions {
|
|||
self.typ
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn flags(&self) -> MMapFlags {
|
||||
self.flags
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ impl From<c_pollfd> for PollFd {
|
|||
|
||||
impl From<PollFd> for c_pollfd {
|
||||
fn from(raw: PollFd) -> Self {
|
||||
let fd = if let Some(fd) = raw.fd() { fd } else { -1 };
|
||||
let fd = raw.fd().unwrap_or(-1);
|
||||
let events = raw.events().bits() as i16;
|
||||
let revents = raw.revents().get().bits() as i16;
|
||||
Self {
|
||||
|
|
|
@ -61,6 +61,7 @@ pub struct Taskless {
|
|||
/// The function that will be called when executing this taskless job.
|
||||
callback: Box<RefCell<dyn FnMut() + Send + Sync + 'static>>,
|
||||
/// Whether this `Taskless` is disabled.
|
||||
#[allow(unused)]
|
||||
is_disabled: AtomicBool,
|
||||
link: LinkedListAtomicLink,
|
||||
}
|
||||
|
@ -74,6 +75,7 @@ cpu_local! {
|
|||
|
||||
impl Taskless {
|
||||
/// Creates a new `Taskless` instance with its callback function.
|
||||
#[allow(unused)]
|
||||
pub fn new<F>(callback: F) -> Arc<Self>
|
||||
where
|
||||
F: FnMut() + Send + Sync + 'static,
|
||||
|
@ -94,6 +96,7 @@ impl Taskless {
|
|||
/// Schedules this taskless job and it will be executed in later time.
|
||||
///
|
||||
/// If the taskless job has been scheduled, this function will do nothing.
|
||||
#[allow(unused)]
|
||||
pub fn schedule(self: &Arc<Self>) {
|
||||
do_schedule(self, &TASKLESS_LIST);
|
||||
SoftIrqLine::get(TASKLESS_SOFTIRQ_ID).raise();
|
||||
|
@ -103,6 +106,7 @@ impl Taskless {
|
|||
/// in softirq context.
|
||||
///
|
||||
/// If the taskless job has been scheduled, this function will do nothing.
|
||||
#[allow(unused)]
|
||||
pub fn schedule_urgent(self: &Arc<Self>) {
|
||||
do_schedule(self, &TASKLESS_URGENT_LIST);
|
||||
SoftIrqLine::get(TASKLESS_URGENT_SOFTIRQ_ID).raise();
|
||||
|
@ -111,17 +115,20 @@ impl Taskless {
|
|||
/// Enables this `Taskless` so that it can be executed once it has been scheduled.
|
||||
///
|
||||
/// A new `Taskless` is enabled by default.
|
||||
#[allow(unused)]
|
||||
pub fn enable(&self) {
|
||||
self.is_disabled.store(false, Ordering::Release);
|
||||
}
|
||||
|
||||
/// Disables this `Taskless` so that it can not be scheduled. Note that if the `Taskless`
|
||||
/// has been scheduled, it can still continue to complete this job.
|
||||
#[allow(unused)]
|
||||
pub fn disable(&self) {
|
||||
self.is_disabled.store(true, Ordering::Release);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn do_schedule(
|
||||
taskless: &Arc<Taskless>,
|
||||
taskless_list: &'static CpuLocal<RefCell<LinkedList<TasklessAdapter>>>,
|
||||
|
|
|
@ -2,6 +2,68 @@
|
|||
|
||||
#![allow(dead_code)]
|
||||
|
||||
//! Work queue mechanism.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! A `workqueue` is a kernel-level mechanism used to schedule and execute deferred work.
|
||||
//! Deferred work refers to tasks that need to be executed at some point in the future,
|
||||
//! but not necessarily immediately.
|
||||
//!
|
||||
//! The workqueue mechanism is implemented using a combination of kernel threads and data
|
||||
//! structures such as `WorkItem`, `WorkQueue`, `Worker` and `WorkerPool`. The `WorkItem`
|
||||
//! represents a task to be processed, while the `WorkQueue` maintains the queue of submitted
|
||||
//! `WorkItems`. The `Worker` is responsible for processing these submitted tasks,
|
||||
//! and the `WorkerPool` manages and schedules these workers.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! The system has a default work queue and worker pool,
|
||||
//! and it also provides high-level APIs for users to use.
|
||||
//! Here is a basic example to how to use those APIs.
|
||||
//!
|
||||
//! ```rust
|
||||
//! use crate::thread::work_queue::{submit_work_func, submit_work_item, WorkItem};
|
||||
//!
|
||||
//! // Submit to high priority queue.
|
||||
//! submit_work_func(||{ }, true);
|
||||
//!
|
||||
//! // Submit to low priority queue.
|
||||
//! submit_work_func(||{ }, false);
|
||||
//!
|
||||
//! fn deferred_task(){
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! // Create a work item.
|
||||
//! let work_item = Arc::new(WorkItem::new(Box::new(deferred_task)));
|
||||
//!
|
||||
//! // Submit to high priority queue.
|
||||
//! submit_work_item(work_item, true);
|
||||
//!
|
||||
//! // Submit to low priority queue.
|
||||
//! submit_work_item(work_item, false);
|
||||
//! ```
|
||||
//!
|
||||
//! Certainly, users can also create a dedicated WorkQueue and WorkerPool.
|
||||
//!
|
||||
//! ```rust
|
||||
//! use ostd::cpu::CpuSet;
|
||||
//! use crate::thread::work_queue::{WorkQueue, WorkerPool, WorkItem};
|
||||
//!
|
||||
//! fn deferred_task(){
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! let cpu_set = CpuSet::new_full();
|
||||
//! let high_pri_pool = WorkerPool::new(true, cpu_set);
|
||||
//! let my_queue = WorkQueue::new(Arc::downgrade(high_pri_pool.get().unwrap()));
|
||||
//!
|
||||
//! let work_item = Arc::new(WorkItem::new(Box::new(deferred_task)));
|
||||
//! my_queue.enqueue(work_item);
|
||||
//!
|
||||
//! ```
|
||||
|
||||
use ostd::cpu::CpuSet;
|
||||
use spin::Once;
|
||||
use work_item::WorkItem;
|
||||
|
@ -19,68 +81,6 @@ static WORKERPOOL_HIGH_PRI: Once<Arc<WorkerPool>> = Once::new();
|
|||
static WORKQUEUE_GLOBAL_NORMAL: Once<Arc<WorkQueue>> = Once::new();
|
||||
static WORKQUEUE_GLOBAL_HIGH_PRI: Once<Arc<WorkQueue>> = Once::new();
|
||||
|
||||
/// Work queue mechanism.
|
||||
///
|
||||
/// # Overview
|
||||
///
|
||||
/// A `workqueue` is a kernel-level mechanism used to schedule and execute deferred work.
|
||||
/// Deferred work refers to tasks that need to be executed at some point in the future,
|
||||
/// but not necessarily immediately.
|
||||
///
|
||||
/// The workqueue mechanism is implemented using a combination of kernel threads and data
|
||||
/// structures such as `WorkItem`, `WorkQueue`, `Worker` and `WorkerPool`. The `WorkItem`
|
||||
/// represents a task to be processed, while the `WorkQueue` maintains the queue of submitted
|
||||
/// `WorkItems`. The `Worker` is responsible for processing these submitted tasks,
|
||||
/// and the `WorkerPool` manages and schedules these workers.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// The system has a default work queue and worker pool,
|
||||
/// and it also provides high-level APIs for users to use.
|
||||
/// Here is a basic example to how to use those APIs.
|
||||
///
|
||||
/// ```rust
|
||||
/// use crate::thread::work_queue::{submit_work_func, submit_work_item, WorkItem};
|
||||
///
|
||||
/// // Submit to high priority queue.
|
||||
/// submit_work_func(||{ }, true);
|
||||
///
|
||||
/// // Submit to low priority queue.
|
||||
/// submit_work_func(||{ }, false);
|
||||
///
|
||||
/// fn deferred_task(){
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// // Create a work item.
|
||||
/// let work_item = Arc::new(WorkItem::new(Box::new(deferred_task)));
|
||||
///
|
||||
/// // Submit to high priority queue.
|
||||
/// submit_work_item(work_item, true);
|
||||
///
|
||||
/// // Submit to low priority queue.
|
||||
/// submit_work_item(work_item, false);
|
||||
/// ```
|
||||
///
|
||||
/// Certainly, users can also create a dedicated WorkQueue and WorkerPool.
|
||||
///
|
||||
/// ```rust
|
||||
/// use ostd::cpu::CpuSet;
|
||||
/// use crate::thread::work_queue::{WorkQueue, WorkerPool, WorkItem};
|
||||
///
|
||||
/// fn deferred_task(){
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let cpu_set = CpuSet::new_full();
|
||||
/// let high_pri_pool = WorkerPool::new(true, cpu_set);
|
||||
/// let my_queue = WorkQueue::new(Arc::downgrade(high_pri_pool.get().unwrap()));
|
||||
///
|
||||
/// let work_item = Arc::new(WorkItem::new(Box::new(deferred_task)));
|
||||
/// my_queue.enqueue(work_item);
|
||||
///
|
||||
/// ```
|
||||
|
||||
/// Submit a function to a global work queue.
|
||||
pub fn submit_work_func<F>(work_func: F, work_priority: WorkPriority)
|
||||
where
|
||||
|
|
|
@ -57,6 +57,7 @@ pub trait WorkerScheduler: Sync + Send {
|
|||
}
|
||||
|
||||
/// The `Monitor` is responsible for monitoring the `WorkerPool` for scheduling needs.
|
||||
///
|
||||
/// Currently, it only performs a liveness check, and attempts to schedule when no workers
|
||||
/// are found processing in the pool.
|
||||
pub struct Monitor {
|
||||
|
|
|
@ -13,6 +13,7 @@ pub struct CpuClock {
|
|||
}
|
||||
|
||||
/// A profiling clock that contains a user CPU clock and a kernel CPU clock.
|
||||
///
|
||||
/// These two clocks record the CPU time in user mode and kernel mode respectively.
|
||||
/// Reading this clock directly returns the sum of both times.
|
||||
pub struct ProfClock {
|
||||
|
|
|
@ -173,7 +173,7 @@ pub trait MultiWrite {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> MultiRead for VmReaderArray<'a> {
|
||||
impl MultiRead for VmReaderArray<'_> {
|
||||
fn read(&mut self, writer: &mut VmWriter<'_, Infallible>) -> Result<usize> {
|
||||
let mut total_len = 0;
|
||||
|
||||
|
@ -192,7 +192,7 @@ impl<'a> MultiRead for VmReaderArray<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> MultiRead for VmReader<'a> {
|
||||
impl MultiRead for VmReader<'_> {
|
||||
fn read(&mut self, writer: &mut VmWriter<'_, Infallible>) -> Result<usize> {
|
||||
Ok(self.read_fallible(writer)?)
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ impl<'a> MultiRead for VmReader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> MultiWrite for VmWriterArray<'a> {
|
||||
impl MultiWrite for VmWriterArray<'_> {
|
||||
fn write(&mut self, reader: &mut VmReader<'_, Infallible>) -> Result<usize> {
|
||||
let mut total_len = 0;
|
||||
|
||||
|
@ -221,7 +221,7 @@ impl<'a> MultiWrite for VmWriterArray<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> MultiWrite for VmWriter<'a> {
|
||||
impl MultiWrite for VmWriter<'_> {
|
||||
fn write(&mut self, reader: &mut VmReader<'_, Infallible>) -> Result<usize> {
|
||||
Ok(self.write_fallible(reader)?)
|
||||
}
|
||||
|
|
|
@ -47,7 +47,9 @@ where
|
|||
|
||||
bytes[..2].copy_from_slice(&(CSocketAddrFamily::AF_UNIX as u16).to_ne_bytes());
|
||||
#[allow(clippy::assertions_on_constants)]
|
||||
const { assert!(CSocketAddrUnix::PATH_OFFSET == 2) };
|
||||
const {
|
||||
assert!(CSocketAddrUnix::PATH_OFFSET == 2)
|
||||
};
|
||||
|
||||
let sun_path = &mut bytes[CSocketAddrUnix::PATH_OFFSET..];
|
||||
|
||||
|
|
|
@ -224,6 +224,7 @@ impl RingBuffer<u8> {
|
|||
/// Writes data from the `reader` to the `RingBuffer`.
|
||||
///
|
||||
/// Returns the number of bytes written.
|
||||
#[allow(unused)]
|
||||
pub fn write_fallible(&mut self, reader: &mut dyn MultiRead) -> Result<usize> {
|
||||
let mut producer = Producer {
|
||||
rb: self,
|
||||
|
|
|
@ -11,4 +11,4 @@ repository ="https://github.com/asterinas/asterinas"
|
|||
[dependencies]
|
||||
ostd = { version = "0.9.2", path = "../../ostd" }
|
||||
owo-colors = "4.0.0"
|
||||
unwinding = { version = "0.2.2", default-features = false, features = ["fde-gnu-eh-frame-hdr", "hide-trace", "panic", "personality", "unwinder"] }
|
||||
unwinding = { version = "0.2.3", default-features = false, features = ["fde-gnu-eh-frame-hdr", "hide-trace", "panic", "personality", "unwinder"] }
|
||||
|
|
|
@ -46,6 +46,7 @@ impl KtestPath {
|
|||
self.path.pop_back()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn push_front(&mut self, s: &str) {
|
||||
self.path.push_front(PathElement::from(s))
|
||||
}
|
||||
|
@ -54,6 +55,7 @@ impl KtestPath {
|
|||
self.path.pop_front()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn len(&self) -> usize {
|
||||
self.path.len()
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ pub struct KtestModule {
|
|||
}
|
||||
|
||||
impl KtestModule {
|
||||
#[allow(dead_code)]
|
||||
pub fn nr_this_tests(&self) -> usize {
|
||||
self.tests.len()
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ owo-colors = { version = "3", optional = true }
|
|||
ostd-pod = { git = "https://github.com/asterinas/ostd-pod", rev = "c4644be", version = "0.1.1" }
|
||||
spin = "0.9.4"
|
||||
static_assertions = "1.1.0"
|
||||
unwinding = { version = "0.2.2", default-features = false, features = ["fde-gnu-eh-frame-hdr", "hide-trace", "panic", "personality", "unwinder"] }
|
||||
unwinding = { version = "0.2.3", default-features = false, features = ["fde-gnu-eh-frame-hdr", "hide-trace", "panic", "personality", "unwinder"] }
|
||||
volatile = { version = "0.4.5", features = ["unstable"] }
|
||||
xarray = { git = "https://github.com/asterinas/xarray", version = "0.1.0" }
|
||||
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
/// `u64`, and `usize`, to provide methods to make integers aligned to a
|
||||
/// power of two.
|
||||
pub trait AlignExt {
|
||||
/// Returns whether the number is a power of two
|
||||
fn is_power_of_two(&self) -> bool;
|
||||
|
||||
/// Returns to the smallest number that is greater than or equal to
|
||||
/// `self` and is a multiple of the given power of two.
|
||||
///
|
||||
|
@ -50,11 +47,6 @@ macro_rules! impl_align_ext {
|
|||
($( $uint_type:ty ),+,) => {
|
||||
$(
|
||||
impl AlignExt for $uint_type {
|
||||
#[inline]
|
||||
fn is_power_of_two(&self) -> bool {
|
||||
(*self != 0) && ((*self & (*self - 1)) == 0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn align_up(self, align: Self) -> Self {
|
||||
assert!(align.is_power_of_two() && align >= 2);
|
||||
|
|
|
@ -33,20 +33,37 @@ impl Write for Stdout {
|
|||
}
|
||||
}
|
||||
|
||||
/// Print a string to the console.
|
||||
///
|
||||
/// This is used when dyn Trait is not supported or fmt::Arguments is fragile to use in PIE.
|
||||
///
|
||||
/// SAFETY: init() must be called before print_str() and there should be no race conditions.
|
||||
/// # Safety
|
||||
///
|
||||
/// [`init()`] must be called before it and there should be no race conditions.
|
||||
pub unsafe fn print_str(s: &str) {
|
||||
#[allow(static_mut_refs)]
|
||||
STDOUT.write_str(s).unwrap();
|
||||
}
|
||||
|
||||
/// Print a single character to the console.
|
||||
///
|
||||
/// This is used when dyn Trait is not supported or fmt::Arguments is fragile to use in PIE.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// [`init()`] must be called before it and there should be no race conditions.
|
||||
unsafe fn print_char(c: char) {
|
||||
#[allow(static_mut_refs)]
|
||||
STDOUT.serial_port.send(c as u8);
|
||||
}
|
||||
|
||||
/// Print a hexadecimal number to the console.
|
||||
///
|
||||
/// This is used when dyn Trait is not supported or fmt::Arguments is fragile to use in PIE.
|
||||
///
|
||||
/// SAFETY: init() must be called before print_hex() and there should be no race conditions.
|
||||
/// # Safety
|
||||
///
|
||||
/// [`init()`] must be called before it and there should be no race conditions.
|
||||
pub unsafe fn print_hex(n: u64) {
|
||||
print_str("0x");
|
||||
for i in (0..16).rev() {
|
||||
|
|
|
@ -65,7 +65,6 @@
|
|||
//!
|
||||
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
#![feature(panic_info_message)]
|
||||
|
||||
extern crate alloc;
|
||||
use alloc::{boxed::Box, string::String};
|
||||
|
|
|
@ -30,6 +30,7 @@ use crate::{
|
|||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[allow(dead_code)]
|
||||
pub struct IommuVersion {
|
||||
major: u8,
|
||||
minor: u8,
|
||||
|
@ -37,11 +38,13 @@ pub struct IommuVersion {
|
|||
|
||||
impl IommuVersion {
|
||||
/// Major version number
|
||||
#[allow(dead_code)]
|
||||
pub fn major(&self) -> u8 {
|
||||
self.major
|
||||
}
|
||||
|
||||
/// Minor version number
|
||||
#[allow(dead_code)]
|
||||
pub fn minor(&self) -> u8 {
|
||||
self.minor
|
||||
}
|
||||
|
@ -50,6 +53,7 @@ impl IommuVersion {
|
|||
/// Important registers used by IOMMU.
|
||||
#[derive(Debug)]
|
||||
pub struct IommuRegisters {
|
||||
#[allow(dead_code)]
|
||||
version: Volatile<&'static u32, ReadOnly>,
|
||||
capability: Volatile<&'static u64, ReadOnly>,
|
||||
extended_capability: Volatile<&'static u64, ReadOnly>,
|
||||
|
@ -62,6 +66,7 @@ pub struct IommuRegisters {
|
|||
|
||||
impl IommuRegisters {
|
||||
/// Version of IOMMU
|
||||
#[allow(dead_code)]
|
||||
pub fn version(&self) -> IommuVersion {
|
||||
let version = self.version.read();
|
||||
IommuVersion {
|
||||
|
|
|
@ -195,6 +195,7 @@ impl ApicId {
|
|||
/// In x2APIC mode, the 32-bit logical x2APIC ID, which can be read from
|
||||
/// LDR, is derived from the 32-bit local x2APIC ID:
|
||||
/// Logical x2APIC ID = [(x2APIC ID[19:4] << 16) | (1 << x2APIC ID[3:0])]
|
||||
#[allow(unused)]
|
||||
pub fn x2apic_logical_id(&self) -> u32 {
|
||||
self.x2apic_logical_cluster_id() << 16 | 1 << self.x2apic_logical_field_id()
|
||||
}
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
|
||||
//! Provides the ability to exit QEMU and return a value as debug result.
|
||||
|
||||
/// The exit code of x86 QEMU isa debug device. In `qemu-system-x86_64` the
|
||||
/// exit code will be `(code << 1) | 1`. So you could never let QEMU invoke
|
||||
/// `exit(0)`. We also need to check if the exit code is returned by the
|
||||
/// kernel, so we couldn't use 0 as exit_success because this may conflict
|
||||
/// with QEMU return value 1, which indicates that QEMU itself fails.
|
||||
/// The exit code of x86 QEMU isa debug device.
|
||||
///
|
||||
/// In `qemu-system-x86_64` the exit code will be `(code << 1) | 1`. So you
|
||||
/// could never let QEMU invoke `exit(0)`. We also need to check if the exit
|
||||
/// code is returned by the kernel, so we couldn't use 0 as exit_success
|
||||
/// because this may conflict with QEMU return value 1, which indicates that
|
||||
/// QEMU itself fails.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u32)]
|
||||
pub enum QemuExitCode {
|
||||
|
|
|
@ -17,15 +17,18 @@ use crate::{
|
|||
trap::{self, IrqLine, TrapFrame},
|
||||
};
|
||||
|
||||
/// The timer frequency (Hz). Here we choose 1000Hz since 1000Hz is easier for unit conversion and
|
||||
/// convenient for timer. What's more, the frequency cannot be set too high or too low, 1000Hz is
|
||||
/// a modest choice.
|
||||
/// The timer frequency (Hz).
|
||||
///
|
||||
/// For system performance reasons, this rate cannot be set too high, otherwise most of the time
|
||||
/// is spent executing timer code.
|
||||
/// Here we choose 1000Hz since 1000Hz is easier for unit conversion and
|
||||
/// convenient for timer. What's more, the frequency cannot be set too high or
|
||||
/// too low, 1000Hz is a modest choice.
|
||||
///
|
||||
/// Due to hardware limitations, this value cannot be set too low; for example, PIT cannot accept
|
||||
/// frequencies lower than 19Hz = 1193182 / 65536 (Timer rate / Divider)
|
||||
/// For system performance reasons, this rate cannot be set too high, otherwise
|
||||
/// most of the time is spent executing timer code.
|
||||
///
|
||||
/// Due to hardware limitations, this value cannot be set too low; for example,
|
||||
/// PIT cannot accept frequencies lower than 19Hz = 1193182 / 65536 (Timer rate
|
||||
/// / Divider)
|
||||
pub const TIMER_FREQ: u64 = 1000;
|
||||
|
||||
static TIMER_IRQ: Once<IrqLine> = Once::new();
|
||||
|
|
|
@ -208,6 +208,7 @@ impl<T: 'static + SingleInstructionBitXorAssign<T>> CpuLocalCell<T> {
|
|||
///
|
||||
/// Note that this memory operation will not be elided or reordered by the
|
||||
/// compiler since it is a black-box.
|
||||
#[allow(unused)]
|
||||
pub fn bitxor_assign(&'static self, rhs: T) {
|
||||
let offset = self as *const _ as usize - __cpu_local_start as usize;
|
||||
// SAFETY: The CPU-local object is defined in the `.cpu_local` section,
|
||||
|
|
|
@ -114,6 +114,7 @@ pub trait SingleInstructionBitXorAssign<Rhs = Self> {
|
|||
/// # Safety
|
||||
///
|
||||
/// Please refer to the module-level documentation of [`self`].
|
||||
#[allow(unused)]
|
||||
unsafe fn bitxor_assign(offset: *mut Self, rhs: Rhs);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,24 +2,20 @@
|
|||
|
||||
//! The standard library for Asterinas and other Rust OSes.
|
||||
#![feature(alloc_error_handler)]
|
||||
#![feature(const_mut_refs)]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(const_ptr_sub_ptr)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(coroutines)]
|
||||
#![feature(fn_traits)]
|
||||
#![feature(generic_const_exprs)]
|
||||
#![feature(is_none_or)]
|
||||
#![feature(iter_from_coroutine)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(new_uninit)]
|
||||
#![feature(panic_info_message)]
|
||||
#![feature(ptr_sub_ptr)]
|
||||
#![feature(strict_provenance)]
|
||||
#![feature(sync_unsafe_cell)]
|
||||
#![feature(allocator_api)]
|
||||
// The `generic_const_exprs` feature is incomplete however required for the page table
|
||||
// const generic implementation. We are using this feature in a conservative manner.
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -81,7 +77,8 @@ pub unsafe fn init() {
|
|||
// SAFETY: This function is called only once and only on the BSP.
|
||||
unsafe { cpu::local::early_init_bsp_local_base() };
|
||||
|
||||
mm::heap_allocator::init();
|
||||
// SAFETY: This function is called only once and only on the BSP.
|
||||
unsafe { mm::heap_allocator::init() };
|
||||
|
||||
boot::init();
|
||||
logger::init();
|
||||
|
|
|
@ -199,7 +199,7 @@ pub struct FrameRef<'a> {
|
|||
_marker: PhantomData<&'a Frame>,
|
||||
}
|
||||
|
||||
impl<'a> Deref for FrameRef<'a> {
|
||||
impl Deref for FrameRef<'_> {
|
||||
type Target = Frame;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
@ -210,7 +210,10 @@ impl<'a> Deref for FrameRef<'a> {
|
|||
// SAFETY: `Frame` is essentially an `*const MetaSlot` that could be used as a `*const` pointer.
|
||||
// The pointer is also aligned to 4.
|
||||
unsafe impl xarray::ItemEntry for Frame {
|
||||
type Ref<'a> = FrameRef<'a> where Self: 'a;
|
||||
type Ref<'a>
|
||||
= FrameRef<'a>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
fn into_raw(self) -> *const () {
|
||||
let ptr = self.page.ptr;
|
||||
|
|
|
@ -31,11 +31,16 @@ const INIT_KERNEL_HEAP_SIZE: usize = PAGE_SIZE * 256;
|
|||
#[repr(align(4096))]
|
||||
struct InitHeapSpace([u8; INIT_KERNEL_HEAP_SIZE]);
|
||||
|
||||
static mut HEAP_SPACE: InitHeapSpace = InitHeapSpace([0; INIT_KERNEL_HEAP_SIZE]);
|
||||
|
||||
pub fn init() {
|
||||
/// Initialize the heap allocator.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This function should be called only once.
|
||||
pub unsafe fn init() {
|
||||
static mut HEAP_SPACE: InitHeapSpace = InitHeapSpace([0; INIT_KERNEL_HEAP_SIZE]);
|
||||
// SAFETY: The HEAP_SPACE is a static memory range, so it's always valid.
|
||||
unsafe {
|
||||
#[allow(static_mut_refs)]
|
||||
HEAP_ALLOCATOR.init(HEAP_SPACE.0.as_ptr(), INIT_KERNEL_HEAP_SIZE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -222,6 +222,7 @@ impl Heap {
|
|||
|
||||
/// Returns bounds on the guaranteed usable size of a successful
|
||||
/// allocation created with the specified `layout`.
|
||||
#[allow(unused)]
|
||||
pub fn usable_size(&self, layout: Layout) -> (usize, usize) {
|
||||
match Heap::layout_to_allocator(&layout) {
|
||||
HeapAllocator::Slab64Bytes => (layout.size(), 64),
|
||||
|
@ -257,6 +258,7 @@ impl Heap {
|
|||
}
|
||||
|
||||
/// Returns total memory size in bytes of the heap.
|
||||
#[allow(unused)]
|
||||
pub fn total_bytes(&self) -> usize {
|
||||
self.slab_64_bytes.total_blocks() * 64
|
||||
+ self.slab_128_bytes.total_blocks() * 128
|
||||
|
@ -269,6 +271,7 @@ impl Heap {
|
|||
}
|
||||
|
||||
/// Returns allocated memory size in bytes.
|
||||
#[allow(unused)]
|
||||
pub fn used_bytes(&self) -> usize {
|
||||
self.slab_64_bytes.used_blocks() * 64
|
||||
+ self.slab_128_bytes.used_blocks() * 128
|
||||
|
@ -281,6 +284,7 @@ impl Heap {
|
|||
}
|
||||
|
||||
/// Returns available memory size in bytes.
|
||||
#[allow(unused)]
|
||||
pub fn available_bytes(&self) -> usize {
|
||||
self.total_bytes() - self.used_bytes()
|
||||
}
|
||||
|
|
|
@ -45,10 +45,12 @@ impl<const BLK_SIZE: usize> Slab<BLK_SIZE> {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn total_blocks(&self) -> usize {
|
||||
self.total_blocks
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn used_blocks(&self) -> usize {
|
||||
self.total_blocks - self.free_block_list.len()
|
||||
}
|
||||
|
@ -120,6 +122,7 @@ impl<const BLK_SIZE: usize> FreeBlockList<BLK_SIZE> {
|
|||
}
|
||||
|
||||
fn pop(&mut self) -> Option<&'static mut FreeBlock> {
|
||||
#[allow(clippy::manual_inspect)]
|
||||
self.head.take().map(|node| {
|
||||
self.head = node.next.take();
|
||||
self.len -= 1;
|
||||
|
|
|
@ -543,7 +543,7 @@ impl<'a> VmReader<'a, Infallible> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> VmReader<'a, Fallible> {
|
||||
impl VmReader<'_, Fallible> {
|
||||
/// Constructs a `VmReader` from a pointer and a length, which represents
|
||||
/// a memory range in user space.
|
||||
///
|
||||
|
@ -608,7 +608,7 @@ impl<'a> VmReader<'a, Fallible> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, Fallibility> VmReader<'a, Fallibility> {
|
||||
impl<Fallibility> VmReader<'_, Fallibility> {
|
||||
/// Returns the number of bytes for the remaining data.
|
||||
pub const fn remain(&self) -> usize {
|
||||
// SAFETY: the end is equal to or greater than the cursor.
|
||||
|
@ -794,7 +794,7 @@ impl<'a> VmWriter<'a, Infallible> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> VmWriter<'a, Fallible> {
|
||||
impl VmWriter<'_, Fallible> {
|
||||
/// Constructs a `VmWriter` from a pointer and a length, which represents
|
||||
/// a memory range in user space.
|
||||
///
|
||||
|
@ -870,7 +870,7 @@ impl<'a> VmWriter<'a, Fallible> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, Fallibility> VmWriter<'a, Fallibility> {
|
||||
impl<Fallibility> VmWriter<'_, Fallibility> {
|
||||
/// Returns the number of bytes for the available space.
|
||||
pub const fn avail(&self) -> usize {
|
||||
// SAFETY: the end is equal to or greater than the cursor.
|
||||
|
|
|
@ -334,8 +334,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, M: PageTableMode, E: PageTableEntryTrait, C: PagingConstsTrait> Iterator
|
||||
for Cursor<'a, M, E, C>
|
||||
impl<M: PageTableMode, E: PageTableEntryTrait, C: PagingConstsTrait> Iterator
|
||||
for Cursor<'_, M, E, C>
|
||||
where
|
||||
[(); C::NR_LEVELS as usize]:,
|
||||
{
|
||||
|
|
|
@ -147,17 +147,6 @@ fn test_user_copy_on_write() {
|
|||
assert!(child_pt.query(from.start + 10).is_none());
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct BasePagingConsts {}
|
||||
|
||||
impl PagingConstsTrait for BasePagingConsts {
|
||||
const NR_LEVELS: PagingLevel = 4;
|
||||
const BASE_PAGE_SIZE: usize = PAGE_SIZE;
|
||||
const ADDRESS_WIDTH: usize = 48;
|
||||
const HIGHEST_TRANSLATION_LEVEL: PagingLevel = 1;
|
||||
const PTE_SIZE: usize = core::mem::size_of::<PageTableEntry>();
|
||||
}
|
||||
|
||||
impl<M: PageTableMode, E: PageTableEntryTrait, C: PagingConstsTrait> PageTable<M, E, C>
|
||||
where
|
||||
[(); C::NR_LEVELS as usize]:,
|
||||
|
|
|
@ -22,6 +22,8 @@ cpu_local_cell! {
|
|||
static IN_PANIC: bool = false;
|
||||
}
|
||||
|
||||
/// The asterinas panic handler.
|
||||
///
|
||||
/// The panic handler must be defined in the binary crate or in the crate that the binary
|
||||
/// crate explicitly declares by `extern crate`. We cannot let the base crate depend on OSTD
|
||||
/// due to prismatic dependencies. That's why we export this symbol and state the
|
||||
|
|
|
@ -116,7 +116,7 @@ impl<'a> Iter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Iter<'a> {
|
||||
impl Iterator for Iter<'_> {
|
||||
type Item = bool;
|
||||
|
||||
fn next(&mut self) -> Option<bool> {
|
||||
|
@ -171,7 +171,7 @@ impl<'a> OnesIter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for OnesIter<'a> {
|
||||
impl Iterator for OnesIter<'_> {
|
||||
type Item = usize;
|
||||
|
||||
fn next(&mut self) -> Option<usize> {
|
||||
|
@ -236,7 +236,7 @@ impl<'a> ZeroesIter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for ZeroesIter<'a> {
|
||||
impl Iterator for ZeroesIter<'_> {
|
||||
type Item = usize;
|
||||
|
||||
fn next(&mut self) -> Option<usize> {
|
||||
|
|
|
@ -26,13 +26,6 @@ pub struct KernelStack {
|
|||
}
|
||||
|
||||
impl KernelStack {
|
||||
pub fn new() -> Result<Self> {
|
||||
Ok(Self {
|
||||
segment: FrameAllocOptions::new(STACK_SIZE_IN_PAGES as usize).alloc_contiguous()?,
|
||||
has_guard_page: false,
|
||||
})
|
||||
}
|
||||
|
||||
/// Generates a kernel stack with a guard page.
|
||||
/// An additional page is allocated and be regarded as a guard page, which should not be accessed.
|
||||
pub fn new_with_guard_page() -> Result<Self> {
|
||||
|
|
|
@ -118,7 +118,7 @@ pub struct UserMode<'a> {
|
|||
}
|
||||
|
||||
// An instance of `UserMode` is bound to the current task. So it must not be sent to other tasks.
|
||||
impl<'a> !Send for UserMode<'a> {}
|
||||
impl !Send for UserMode<'_> {}
|
||||
// Note that implementing `!Sync` is unnecessary
|
||||
// because entering the user space via `UserMode` requires taking a mutable reference.
|
||||
|
||||
|
|
Loading…
Reference in New Issue