Fix multiple issues pointed out by the new compiler

This commit is contained in:
Zhang Junyang 2024-10-13 21:39:47 +08:00 committed by Tate, Hongliang Tian
parent 5f2bd9d0ac
commit 9e4257b655
62 changed files with 211 additions and 178 deletions

10
Cargo.lock generated
View File

@ -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]]

View File

@ -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,

View File

@ -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,

View File

@ -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;
}

View File

@ -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,

View File

@ -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<()>;
}

View File

@ -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.

View File

@ -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:

View File

@ -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)),

View File

@ -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

View File

@ -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(),

View File

@ -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);

View File

@ -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
}

View File

@ -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> {

View File

@ -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> {

View File

@ -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");
}

View File

@ -15,7 +15,6 @@ use crate::{
mod cap_last_cap;
/// Represents the inode at `/proc/sys/kernel`.
pub struct KernelDirOps;
impl KernelDirOps {

View File

@ -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();

View File

@ -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.

View File

@ -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)]

View File

@ -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");
})
});

View File

@ -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,

View File

@ -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> {

View File

@ -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 {

View File

@ -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 {

View File

@ -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)]

View File

@ -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

View File

@ -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() {

View File

@ -218,6 +218,7 @@ impl MMapOptions {
self.typ
}
#[allow(unused)]
pub fn flags(&self) -> MMapFlags {
self.flags
}

View File

@ -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 {

View File

@ -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>>>,

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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)?)
}

View File

@ -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..];

View File

@ -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,

View File

@ -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"] }

View File

@ -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()
}

View File

@ -28,6 +28,7 @@ pub struct KtestModule {
}
impl KtestModule {
#[allow(dead_code)]
pub fn nr_this_tests(&self) -> usize {
self.tests.len()
}

View File

@ -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" }

View File

@ -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);

View File

@ -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() {

View File

@ -65,7 +65,6 @@
//!
#![cfg_attr(not(test), no_std)]
#![feature(panic_info_message)]
extern crate alloc;
use alloc::{boxed::Box, string::String};

View File

@ -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 {

View File

@ -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()
}

View File

@ -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 {

View File

@ -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();

View File

@ -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,

View File

@ -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);
}

View File

@ -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();

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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()
}

View File

@ -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;

View File

@ -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.

View File

@ -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]:,
{

View File

@ -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]:,

View File

@ -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

View File

@ -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> {

View File

@ -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> {

View File

@ -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.