From e282dccf81b4e016abc84515da60cd48a4ef5d29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=9D=E5=80=89=E6=B0=B4=E5=B8=8C?= Date: Wed, 3 Dec 2025 21:01:29 +0800 Subject: [PATCH 1/8] wip --- modules/axmm/src/aspace.rs | 4 ++++ modules/axnet/src/lib.rs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/modules/axmm/src/aspace.rs b/modules/axmm/src/aspace.rs index 2db594db95..1f5ac2921d 100644 --- a/modules/axmm/src/aspace.rs +++ b/modules/axmm/src/aspace.rs @@ -113,6 +113,10 @@ impl AddrSpace { self.areas.find(vaddr) } + pub fn find_area(&self, vaddr: VirtAddr) -> Option<&MemoryArea> { + self.areas.find(vaddr) + } + /// Add a new linear mapping. /// /// See [`Backend`] for more details about the mapping backends. diff --git a/modules/axnet/src/lib.rs b/modules/axnet/src/lib.rs index 60abd15ad4..02f3689df5 100644 --- a/modules/axnet/src/lib.rs +++ b/modules/axnet/src/lib.rs @@ -13,6 +13,8 @@ //! [smoltcp]: https://github.com/smoltcp-rs/smoltcp #![no_std] +#![feature(ip_from)] +#![feature(maybe_uninit_slice)] #[macro_use] extern crate log; From 67943f3bf7fd2bd0fa91f8b88de29816f01ec9d3 Mon Sep 17 00:00:00 2001 From: David Hua Date: Tue, 9 Dec 2025 22:59:14 +0800 Subject: [PATCH 2/8] feat(executor): added async task --- modules/axtask/src/api.rs | 1 + modules/axtask/src/executor.rs | 136 +++++++++++++++++++++++++++++++ modules/axtask/src/future/mod.rs | 12 ++- modules/axtask/src/lib.rs | 1 + modules/axtask/src/task.rs | 2 +- modules/axtask/src/tests.rs | 106 +++++++++++++++++++++++- 6 files changed, 253 insertions(+), 5 deletions(-) create mode 100644 modules/axtask/src/executor.rs diff --git a/modules/axtask/src/api.rs b/modules/axtask/src/api.rs index 33fe68fdfc..2331f94f2b 100644 --- a/modules/axtask/src/api.rs +++ b/modules/axtask/src/api.rs @@ -96,6 +96,7 @@ pub fn init_scheduler_with_cpu_num(cpu_num: usize) { CPU_NUM.store(cpu_num, core::sync::atomic::Ordering::Relaxed); crate::run_queue::init(); + crate::executor::init(); info!(" use {} scheduler.", Scheduler::scheduler_name()); } diff --git a/modules/axtask/src/executor.rs b/modules/axtask/src/executor.rs new file mode 100644 index 0000000000..c25b7f565a --- /dev/null +++ b/modules/axtask/src/executor.rs @@ -0,0 +1,136 @@ +use alloc::{boxed::Box, collections::VecDeque, sync::Arc, task::Wake}; +use core::{ + future::Future, + pin::Pin, + sync::atomic::{AtomicBool, AtomicUsize, Ordering}, + task::{Context, Poll, Waker}, +}; + +use kspin::SpinNoIrq; +use lazyinit::LazyInit; + +use crate::TaskId; + +/// Global ready queue for async tasks. +/// +/// This queue stores `AsyncTask`s that are ready to be polled. +/// The executor loop will pop tasks from this queue and run them. +static READY_QUEUE: LazyInit>>> = LazyInit::new(); +static READY_QUEUE_INITED: AtomicBool = AtomicBool::new(false); +/// Wake counter: incremented on spawn/wake, used by runners to detect new tasks. +static WAKE_COUNT: AtomicUsize = AtomicUsize::new(0); + +/// Initialize the executor module. +pub(crate) fn init() { + if READY_QUEUE_INITED.swap(true, Ordering::AcqRel) { + return; + } + READY_QUEUE.init_once(SpinNoIrq::new(VecDeque::new())); +} + +/// An asynchronous task that wraps a future. +pub struct AsyncTask { + id: TaskId, + /// The future to be executed. + /// + /// It is wrapped in `SpinNoIrq` to provide interior mutability, which is required + /// because `poll` takes `&self` (via `Arc`) but the future's `poll` method + /// requires `Pin<&mut F>`. + future: SpinNoIrq + Send + 'static>>>, +} + +impl AsyncTask { + /// Creates a new `AsyncTask` with the given future. + pub fn new(future: impl Future + Send + 'static) -> Arc { + Arc::new(Self { + id: TaskId::new(), + future: SpinNoIrq::new(Box::pin(future)), + }) + } + + /// Returns the unique identifier of the task. + pub fn id(&self) -> TaskId { + self.id + } + + /// Polls the inner future. + /// + /// This creates a `Waker` from the `Arc` and passes it to the future's context. + pub(crate) fn poll(self: &Arc) -> Poll<()> { + let waker = Waker::from(self.clone()); + let mut cx = Context::from_waker(&waker); + let mut future = self.future.lock(); + future.as_mut().poll(&mut cx) + } +} + +impl Wake for AsyncTask { + fn wake(self: Arc) { + self.wake_by_ref(); + } + + fn wake_by_ref(self: &Arc) { + READY_QUEUE.lock().push_back(self.clone()); + WAKE_COUNT.fetch_add(1, Ordering::Release); + } +} + +/// Spawns a future as an asynchronous task. +/// +/// The task is immediately added to the ready queue. +pub fn spawn(future: F) +where + F: Future + Send + 'static, +{ + let task = AsyncTask::new(future); + READY_QUEUE.lock().push_back(task); + WAKE_COUNT.fetch_add(1, Ordering::Release); +} + +/// Poll one ready task if present. +pub fn run_once() -> bool { + if let Some(task) = READY_QUEUE.lock().pop_front() { + let _ = task.poll(); + true + } else { + false + } +} + +/// Run up to `max_steps` tasks; returns true if any task ran. +pub fn run_for(max_steps: usize) -> bool { + let mut ran = false; + for _ in 0..max_steps { + if !run_once() { + break; + } + ran = true; + } + ran +} + +/// Runs the executor loop until no ready tasks remain. +/// +/// This function drains all ready tasks. It uses an atomic counter to detect +/// if new tasks arrive while draining; if so, it continues. It returns once +/// the queue is empty and no new wakes have occurred. +pub fn run_until_idle() { + loop { + // Snapshot the wake counter before draining. + let seen = WAKE_COUNT.load(Ordering::Acquire); + + // Drain all currently ready tasks. + while run_once() {} + + // If queue is empty, check whether any new wakes happened. + if READY_QUEUE.lock().is_empty() { + // Re-check counter: if unchanged, no new tasks arrived, we're done. + if WAKE_COUNT.load(Ordering::Acquire) == seen { + break; + } + // Otherwise, new wake happened; continue to drain. + } + // Yield CPU briefly to avoid tight spin. + core::hint::spin_loop(); + } +} \ No newline at end of file diff --git a/modules/axtask/src/future/mod.rs b/modules/axtask/src/future/mod.rs index ff781970e5..500f79fb54 100644 --- a/modules/axtask/src/future/mod.rs +++ b/modules/axtask/src/future/mod.rs @@ -12,7 +12,10 @@ use core::{ use kernel_guard::NoPreemptIrqSave; -use crate::{AxTaskRef, WeakAxTaskRef, current, current_run_queue, select_run_queue}; +use crate::{ + executor, + AxTaskRef, WeakAxTaskRef, current, current_run_queue, select_run_queue, +}; mod poll; pub use poll::*; @@ -66,7 +69,12 @@ pub fn block_on(f: F) -> F::Output { loop { woke.store(false, Ordering::Release); - match fut.as_mut().poll(&mut cx) { + let result = fut.as_mut().poll(&mut cx); + + // Polling the executor to run three async tasks. + let _ = executor::run_for(3); + + match result { Poll::Pending => { if !woke.load(Ordering::Acquire) { current_run_queue::().blocked_resched(); diff --git a/modules/axtask/src/lib.rs b/modules/axtask/src/lib.rs index b2a5444ffe..97040b0bd3 100644 --- a/modules/axtask/src/lib.rs +++ b/modules/axtask/src/lib.rs @@ -41,6 +41,7 @@ cfg_if::cfg_if! { #[macro_use] mod run_queue; mod task; + pub mod executor; mod api; mod wait_queue; diff --git a/modules/axtask/src/task.rs b/modules/axtask/src/task.rs index d61b8da7ad..5cb7f2419f 100644 --- a/modules/axtask/src/task.rs +++ b/modules/axtask/src/task.rs @@ -97,7 +97,7 @@ pub struct TaskInner { } impl TaskId { - fn new() -> Self { + pub(crate) fn new() -> Self { static ID_COUNTER: AtomicU64 = AtomicU64::new(1); Self(ID_COUNTER.fetch_add(1, Ordering::Relaxed)) } diff --git a/modules/axtask/src/tests.rs b/modules/axtask/src/tests.rs index 7c2e328d2c..81bf2b1b27 100644 --- a/modules/axtask/src/tests.rs +++ b/modules/axtask/src/tests.rs @@ -1,7 +1,8 @@ -use core::sync::atomic::{AtomicUsize, Ordering}; +use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::{Mutex, Once}; -use crate::{WaitQueue, api as axtask, current}; +use crate::{api as axtask, current, executor, WaitQueue}; +use core::future::poll_fn; static INIT: Once = Once::new(); static SERIAL: Mutex<()> = Mutex::new(()); @@ -125,3 +126,104 @@ fn test_task_join() { assert_eq!(task.join(), i as _); } } + +fn init_env() { + INIT.call_once(axtask::init_scheduler); +} + +/// Test for the executor running tasks manually with run_until_idle. +#[test] +fn test_async_executor_basic_completion() { + let _lock = SERIAL.lock(); + init_env(); + + static DONE: AtomicBool = AtomicBool::new(false); + + executor::spawn(async { + DONE.store(true, Ordering::Release); + }); + + executor::run_until_idle(); + assert!(DONE.load(Ordering::Acquire)); +} + +#[test] +fn test_async_executor_self_wake() { + let _lock = SERIAL.lock(); + init_env(); + + static POLL_COUNT: AtomicUsize = AtomicUsize::new(0); + + executor::spawn(async { + poll_fn(|cx| { + let prev = POLL_COUNT.fetch_add(1, Ordering::AcqRel); + if prev == 0 { + cx.waker().wake_by_ref(); + return core::task::Poll::Pending; + } + core::task::Poll::Ready(()) + }) + .await + }); + + executor::run_until_idle(); + assert_eq!(POLL_COUNT.load(Ordering::Acquire), 2); +} + +#[test] +fn test_async_executor_two_task_fairness() { + let _lock = SERIAL.lock(); + init_env(); + + static ORDER: Mutex> = Mutex::new(Vec::new()); + + fn two_step_task(name: &'static str) -> impl core::future::Future + Send { + let state = std::sync::Arc::new(AtomicUsize::new(0)); + async move { + poll_fn(move |cx| { + let seq = state.fetch_add(1, Ordering::AcqRel); + let mut order = ORDER.lock().unwrap(); + order.push(format!("{}-{}", name, seq + 1)); + if seq == 0 { + cx.waker().wake_by_ref(); + core::task::Poll::Pending + } else { + core::task::Poll::Ready(()) + } + }) + .await + } + } + + executor::spawn(two_step_task("A")); + executor::spawn(two_step_task("B")); + + executor::run_until_idle(); + + let order = ORDER.lock().unwrap().clone(); + assert_eq!(order, ["A-1", "B-1", "A-2", "B-2"]); +} + +/// Test for the executor running tasks manually with run_for. +#[test] +fn test_async_executor_run_for_progress() { + let _lock = SERIAL.lock(); + init_env(); + + static CNT: AtomicUsize = AtomicUsize::new(0); + + executor::spawn(async { + CNT.fetch_add(1, Ordering::Release); + }); + executor::spawn(async { + CNT.fetch_add(1, Ordering::Release); + }); + + // Drive executor manually, one task per step. + executor::run_for(1); + assert_eq!(CNT.load(Ordering::Acquire), 1); + + executor::run_for(1); + assert_eq!(CNT.load(Ordering::Acquire), 2); +} + From b7f81800dc5b3a71e656a6e8ec131c32a71d10ec Mon Sep 17 00:00:00 2001 From: David Hua Date: Thu, 11 Dec 2025 22:30:12 +0800 Subject: [PATCH 3/8] fix(executor): improved return value --- Cargo.lock | 425 +++++++++++++++++++++++-------- modules/axtask/src/executor.rs | 28 +- modules/axtask/src/future/mod.rs | 3 +- 3 files changed, 340 insertions(+), 116 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7be437fa83..b9889098c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,6 +63,12 @@ dependencies = [ "slab_allocator", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -162,10 +168,7 @@ dependencies = [ name = "arceos-shell" version = "0.1.0" dependencies = [ - "axfs_ramfs", - "axfs_vfs", "axstd", - "crate_interface", ] [[package]] @@ -177,7 +180,7 @@ dependencies = [ "axdisplay", "axdma", "axdriver", - "axerrno 0.1.2", + "axerrno 0.2.2", "axfeat", "axfs", "axhal", @@ -197,7 +200,7 @@ version = "0.2.0" dependencies = [ "axalloc", "axconfig", - "axerrno 0.1.2", + "axerrno 0.2.2", "axfeat", "axfs", "axhal", @@ -207,7 +210,7 @@ dependencies = [ "axruntime", "axsync", "axtask", - "bindgen 0.72.1", + "bindgen", "flatten_objects", "lazy_static", "scope-local", @@ -247,12 +250,30 @@ dependencies = [ "chrono", ] +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "as-any" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0f477b951e452a0b6b4a10b53ccd569042d1d01729b519e02074a9c0958a063" +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + [[package]] name = "async-trait" version = "0.1.89" @@ -285,7 +306,7 @@ version = "0.2.0" dependencies = [ "allocator", "axbacktrace", - "axerrno 0.1.2", + "axerrno 0.2.2", "cfg-if", "kspin", "log", @@ -351,7 +372,7 @@ dependencies = [ "loongArch64", "memory_addr", "page_table_entry", - "page_table_multiarch", + "page_table_multiarch 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", "percpu", "riscv", "static_assertions", @@ -377,7 +398,7 @@ dependencies = [ "allocator", "axalloc", "axconfig", - "axerrno 0.1.2", + "axerrno 0.2.2", "axhal", "axmm", "kspin", @@ -401,7 +422,7 @@ dependencies = [ "axdriver_pci", "axdriver_virtio", "axdriver_vsock", - "axerrno 0.1.2", + "axerrno 0.2.2", "axhal", "axklib", "axmm", @@ -431,7 +452,6 @@ dependencies = [ "bcm2835-sdhci", "log", "simple-sdmmc", - "simple-ahci", ] [[package]] @@ -539,56 +559,44 @@ dependencies = [ name = "axfs" version = "0.2.0" dependencies = [ + "axalloc", "axdriver", - "axdriver_block", - "axerrno 0.1.2", - "axfs_devfs", - "axfs_ramfs", - "axfs_vfs", + "axerrno 0.2.2", + "axfs-ng-vfs", + "axhal", "axio", + "axpoll", "axsync", - "axtask", - "cap_access", + "bitflags 2.10.0", "cfg-if", - "crate_interface", + "chrono", + "env_logger", "fatfs", - "lazyinit", + "intrusive-collections", + "kspin", "log", + "lru", "lwext4_rust", "scope-local", + "slab", + "spin 0.10.0", ] [[package]] -name = "axfs_devfs" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b87ae981272ca8d5d8f106a4452c63f4b5ac36e17ee8f848ee1b250538b9f8" -dependencies = [ - "axfs_vfs", - "log", - "spin 0.9.8", -] - -[[package]] -name = "axfs_ramfs" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50c26614485d837a3fc09a92f24a226caddc25a30df7e6aaf4bd19b304c399" -dependencies = [ - "axfs_vfs", - "log", - "spin 0.9.8", -] - -[[package]] -name = "axfs_vfs" -version = "0.1.2" +name = "axfs-ng-vfs" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcba2006898d7879d456a9c34b9c9460cb536f5bf69d1d5d7d0e0f19f073368d" +checksum = "bf0d501c182116576111dc04ba89f48fea639b7080e0455393be5dbc41cfacef" dependencies = [ - "axerrno 0.1.2", + "axerrno 0.2.2", + "axpoll", "bitflags 2.10.0", + "cfg-if", + "hashbrown 0.15.5", + "inherit-methods-macro", "log", + "smallvec", + "spin 0.10.0", ] [[package]] @@ -611,7 +619,7 @@ dependencies = [ "linkme", "log", "memory_addr", - "page_table_multiarch", + "page_table_multiarch 0.5.7 (git+https://github.com/arceos-org/page_table_multiarch.git?tag=dev-v05)", "percpu", ] @@ -631,7 +639,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23e797ff4cfd17460c7b8742222a2cadd72a2f4966f0057d36b5925fabf534f7" dependencies = [ - "axerrno 0.1.2", + "axerrno 0.2.2", ] [[package]] @@ -661,10 +669,10 @@ name = "axlibc" version = "0.2.0" dependencies = [ "arceos_posix_api", - "axerrno 0.1.2", + "axerrno 0.2.2", "axfeat", "axio", - "bindgen 0.72.1", + "bindgen", ] [[package]] @@ -685,29 +693,45 @@ version = "0.2.0" dependencies = [ "axalloc", "axconfig", - "axerrno 0.1.2", + "axerrno 0.2.2", + "axfs-ng-vfs", "axhal", + "axsync", + "axtask", + "enum_dispatch", "kspin", "lazyinit", "log", "memory_addr", "memory_set", - "page_table_multiarch", + "page_table_multiarch 0.5.7 (git+https://github.com/arceos-org/page_table_multiarch.git?tag=dev-v05)", ] [[package]] name = "axnet" version = "0.2.0" dependencies = [ + "async-channel", + "async-trait", + "axconfig", "axdriver", - "axerrno 0.1.2", + "axerrno 0.2.2", + "axfs", + "axfs-ng-vfs", "axhal", "axio", + "axpoll", "axsync", "axtask", + "bitflags 2.10.0", "cfg-if", + "enum_dispatch", + "event-listener", + "hashbrown 0.16.1", + "lazy_static", "lazyinit", "log", + "ringbuf", "smoltcp 0.12.0", "spin 0.10.0", ] @@ -920,7 +944,7 @@ name = "axstd" version = "0.2.0" dependencies = [ "arceos_api", - "axerrno 0.1.2", + "axerrno 0.2.2", "axfeat", "axio", "kspin", @@ -944,7 +968,7 @@ name = "axtask" version = "0.2.0" dependencies = [ "axconfig", - "axerrno 0.1.2", + "axerrno 0.2.2", "axhal", "axpoll", "axsched", @@ -991,26 +1015,6 @@ dependencies = [ "volatile 0.2.7", ] -[[package]] -name = "bindgen" -version = "0.71.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" -dependencies = [ - "bitflags 2.10.0", - "cexpr", - "clang-sys", - "itertools", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.111", -] - [[package]] name = "bindgen" version = "0.72.1" @@ -1099,15 +1103,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" -[[package]] -name = "cap_access" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b24894fa5f73bbf9c72196e7f495a1f81d6218a548280a09ada4a937157692" -dependencies = [ - "bitflags 2.10.0", -] - [[package]] name = "cc" version = "1.2.47" @@ -1176,7 +1171,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] @@ -1312,6 +1307,41 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + [[package]] name = "defmt" version = "0.3.100" @@ -1409,6 +1439,29 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "env_filter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -1425,6 +1478,16 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + [[package]] name = "extern-trait" version = "0.2.0" @@ -1445,7 +1508,7 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fatfs" version = "0.4.0" -source = "git+https://github.com/rafalh/rust-fatfs?rev=4eccb50#4eccb50d011146fbed20e133d33b22f3c27292e7" +source = "git+https://github.com/Starry-OS/rust-fatfs.git?rev=2685439#2685439e679cc832a67fd21340258b7c018c0f33" dependencies = [ "bitflags 2.10.0", "log", @@ -1472,6 +1535,24 @@ dependencies = [ "bitmaps", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "futures" version = "0.3.31" @@ -1594,11 +1675,27 @@ dependencies = [ "byteorder", ] +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.1.5", +] + [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] [[package]] name = "heapless" @@ -1663,6 +1760,12 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "indexmap" version = "2.12.1" @@ -1670,7 +1773,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.1", ] [[package]] @@ -1682,12 +1785,33 @@ dependencies = [ "rustversion", ] +[[package]] +name = "inherit-methods-macro" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831739f8836b05db933f3a84783a5af48bd605915dcd10c7435bc74e7947a030" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "int_ratio" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6045ea39e8d2862506c0dff6c65d068da362335df698bb1634033492740d2170" +[[package]] +name = "intrusive-collections" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "189d0897e4cbe8c75efedf3502c18c887b05046e59d28404d4d8e46cbc4d1e86" +dependencies = [ + "memoffset", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1715,6 +1839,30 @@ dependencies = [ "volatile 0.3.0", ] +[[package]] +name = "jiff" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-static" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "js-sys" version = "0.3.83" @@ -1862,12 +2010,21 @@ dependencies = [ "bitflags 2.10.0", ] +[[package]] +name = "lru" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96051b46fc183dc9cd4a223960ef37b9af631b55191852a8274bfef064cda20f" +dependencies = [ + "hashbrown 0.16.1", +] + [[package]] name = "lwext4_rust" version = "0.2.0" -source = "git+https://github.com/Josen-B/lwext4_rust.git?rev=99b3e5c#99b3e5c7262718db2002411fe55ea0362a23fdfc" +source = "git+https://github.com/Starry-OS/lwext4_rust.git?rev=033fa2c#033fa2cc848c7495651b00af6695dc07de06d596" dependencies = [ - "bindgen 0.71.1", + "bindgen", "log", ] @@ -1883,6 +2040,15 @@ version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "memory_addr" version = "0.4.1" @@ -1963,6 +2129,20 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa11a21844255e14aa6688ef0eafb058d7be19338633024fb59417f1bfb07f8" dependencies = [ + "log", + "memory_addr", + "page_table_entry", + "riscv", + "x86", +] + +[[package]] +name = "page_table_multiarch" +version = "0.5.7" +source = "git+https://github.com/arceos-org/page_table_multiarch.git?tag=dev-v05#4594a765e361bca2a8b6ef6773a37ae6d8539840" +dependencies = [ + "arrayvec", + "axerrno 0.1.2", "bitmaps", "log", "memory_addr", @@ -2038,6 +2218,21 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + [[package]] name = "prettyplease" version = "0.2.37" @@ -2221,6 +2416,16 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +[[package]] +name = "ringbuf" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe47b720588c8702e34b5979cb3271a8b1842c7cb6f57408efa70c779363488c" +dependencies = [ + "crossbeam-utils", + "portable-atomic-util", +] + [[package]] name = "riscv" version = "0.14.0" @@ -2342,6 +2547,26 @@ version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2359,16 +2584,10 @@ dependencies = [ ] [[package]] -name = "simple-ahci" -version = "0.1.0" -source = "git+https://github.com/Starry-OS/simple-ahci.git?rev=36d0979#36d0979fedb17c7846b78d1a63f944da31f96186" -dependencies = [ - "bitfield-struct", - "log", - "thiserror", - "volatile 0.6.1", -] - +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "slab_allocator" @@ -2401,7 +2620,7 @@ dependencies = [ [[package]] name = "smoltcp" version = "0.12.0" -source = "git+https://github.com/rcore-os/smoltcp.git?rev=21a2f82#21a2f82b062ec88442eb624d7fcec1feeb886496" +source = "git+https://github.com/Starry-OS/smoltcp.git?rev=7401a54#7401a54b041924a78971b077cd62140b26d441dc" dependencies = [ "bitflags 1.3.2", "byteorder", @@ -2451,6 +2670,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" diff --git a/modules/axtask/src/executor.rs b/modules/axtask/src/executor.rs index c25b7f565a..9794208856 100644 --- a/modules/axtask/src/executor.rs +++ b/modules/axtask/src/executor.rs @@ -87,13 +87,17 @@ where WAKE_COUNT.fetch_add(1, Ordering::Release); } -/// Poll one ready task if present. -pub fn run_once() -> bool { +/// Polls one ready task if present. +/// +/// Returns: +/// - `None`: The ready queue is empty. +/// - `Some(Poll::Ready(()))`: A task ran and finished. +/// - `Some(Poll::Pending)`: A task ran and is pending (will be woken later). +pub fn run_once() -> Option> { if let Some(task) = READY_QUEUE.lock().pop_front() { - let _ = task.poll(); - true + Some(task.poll()) } else { - false + None } } @@ -101,7 +105,7 @@ pub fn run_once() -> bool { pub fn run_for(max_steps: usize) -> bool { let mut ran = false; for _ in 0..max_steps { - if !run_once() { + if run_once().is_none() { break; } ran = true; @@ -112,25 +116,19 @@ pub fn run_for(max_steps: usize) -> bool { /// Runs the executor loop until no ready tasks remain. /// /// This function drains all ready tasks. It uses an atomic counter to detect -/// if new tasks arrive while draining; if so, it continues. It returns once -/// the queue is empty and no new wakes have occurred. +/// if new tasks arrive while draining; if so, it continues. pub fn run_until_idle() { loop { - // Snapshot the wake counter before draining. let seen = WAKE_COUNT.load(Ordering::Acquire); // Drain all currently ready tasks. - while run_once() {} + while run_once().is_some() {} - // If queue is empty, check whether any new wakes happened. if READY_QUEUE.lock().is_empty() { - // Re-check counter: if unchanged, no new tasks arrived, we're done. if WAKE_COUNT.load(Ordering::Acquire) == seen { break; } - // Otherwise, new wake happened; continue to drain. } - // Yield CPU briefly to avoid tight spin. core::hint::spin_loop(); } -} \ No newline at end of file +} diff --git a/modules/axtask/src/future/mod.rs b/modules/axtask/src/future/mod.rs index 500f79fb54..3517591c69 100644 --- a/modules/axtask/src/future/mod.rs +++ b/modules/axtask/src/future/mod.rs @@ -71,7 +71,8 @@ pub fn block_on(f: F) -> F::Output { woke.store(false, Ordering::Release); let result = fut.as_mut().poll(&mut cx); - // Polling the executor to run three async tasks. + // Polling the executor to run up to three async tasks + // (may run fewer if the queue has fewer ready tasks). let _ = executor::run_for(3); match result { From abb0073600a653ec3f49468dcd63fb0e2047f4b6 Mon Sep 17 00:00:00 2001 From: David Hua Date: Thu, 11 Dec 2025 22:38:35 +0800 Subject: [PATCH 4/8] fix(cargo): restored Cargo.lock --- Cargo.lock | 427 +++++++++++++---------------------------------------- 1 file changed, 101 insertions(+), 326 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b9889098c2..8c89af98f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,12 +63,6 @@ dependencies = [ "slab_allocator", ] -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -168,7 +162,10 @@ dependencies = [ name = "arceos-shell" version = "0.1.0" dependencies = [ + "axfs_ramfs", + "axfs_vfs", "axstd", + "crate_interface", ] [[package]] @@ -180,7 +177,7 @@ dependencies = [ "axdisplay", "axdma", "axdriver", - "axerrno 0.2.2", + "axerrno 0.1.2", "axfeat", "axfs", "axhal", @@ -200,7 +197,7 @@ version = "0.2.0" dependencies = [ "axalloc", "axconfig", - "axerrno 0.2.2", + "axerrno 0.1.2", "axfeat", "axfs", "axhal", @@ -210,7 +207,7 @@ dependencies = [ "axruntime", "axsync", "axtask", - "bindgen", + "bindgen 0.72.1", "flatten_objects", "lazy_static", "scope-local", @@ -250,30 +247,12 @@ dependencies = [ "chrono", ] -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - [[package]] name = "as-any" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0f477b951e452a0b6b4a10b53ccd569042d1d01729b519e02074a9c0958a063" -[[package]] -name = "async-channel" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - [[package]] name = "async-trait" version = "0.1.89" @@ -306,7 +285,7 @@ version = "0.2.0" dependencies = [ "allocator", "axbacktrace", - "axerrno 0.2.2", + "axerrno 0.1.2", "cfg-if", "kspin", "log", @@ -372,7 +351,7 @@ dependencies = [ "loongArch64", "memory_addr", "page_table_entry", - "page_table_multiarch 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", + "page_table_multiarch", "percpu", "riscv", "static_assertions", @@ -398,7 +377,7 @@ dependencies = [ "allocator", "axalloc", "axconfig", - "axerrno 0.2.2", + "axerrno 0.1.2", "axhal", "axmm", "kspin", @@ -422,7 +401,7 @@ dependencies = [ "axdriver_pci", "axdriver_virtio", "axdriver_vsock", - "axerrno 0.2.2", + "axerrno 0.1.2", "axhal", "axklib", "axmm", @@ -452,6 +431,7 @@ dependencies = [ "bcm2835-sdhci", "log", "simple-sdmmc", + "simple-ahci", ] [[package]] @@ -559,44 +539,56 @@ dependencies = [ name = "axfs" version = "0.2.0" dependencies = [ - "axalloc", "axdriver", - "axerrno 0.2.2", - "axfs-ng-vfs", - "axhal", + "axdriver_block", + "axerrno 0.1.2", + "axfs_devfs", + "axfs_ramfs", + "axfs_vfs", "axio", - "axpoll", "axsync", - "bitflags 2.10.0", + "axtask", + "cap_access", "cfg-if", - "chrono", - "env_logger", + "crate_interface", "fatfs", - "intrusive-collections", - "kspin", + "lazyinit", "log", - "lru", "lwext4_rust", "scope-local", - "slab", - "spin 0.10.0", ] [[package]] -name = "axfs-ng-vfs" -version = "0.1.0" +name = "axfs_devfs" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf0d501c182116576111dc04ba89f48fea639b7080e0455393be5dbc41cfacef" +checksum = "81b87ae981272ca8d5d8f106a4452c63f4b5ac36e17ee8f848ee1b250538b9f8" dependencies = [ - "axerrno 0.2.2", - "axpoll", + "axfs_vfs", + "log", + "spin 0.9.8", +] + +[[package]] +name = "axfs_ramfs" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f50c26614485d837a3fc09a92f24a226caddc25a30df7e6aaf4bd19b304c399" +dependencies = [ + "axfs_vfs", + "log", + "spin 0.9.8", +] + +[[package]] +name = "axfs_vfs" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcba2006898d7879d456a9c34b9c9460cb536f5bf69d1d5d7d0e0f19f073368d" +dependencies = [ + "axerrno 0.1.2", "bitflags 2.10.0", - "cfg-if", - "hashbrown 0.15.5", - "inherit-methods-macro", "log", - "smallvec", - "spin 0.10.0", ] [[package]] @@ -619,7 +611,7 @@ dependencies = [ "linkme", "log", "memory_addr", - "page_table_multiarch 0.5.7 (git+https://github.com/arceos-org/page_table_multiarch.git?tag=dev-v05)", + "page_table_multiarch", "percpu", ] @@ -639,7 +631,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23e797ff4cfd17460c7b8742222a2cadd72a2f4966f0057d36b5925fabf534f7" dependencies = [ - "axerrno 0.2.2", + "axerrno 0.1.2", ] [[package]] @@ -669,10 +661,10 @@ name = "axlibc" version = "0.2.0" dependencies = [ "arceos_posix_api", - "axerrno 0.2.2", + "axerrno 0.1.2", "axfeat", "axio", - "bindgen", + "bindgen 0.72.1", ] [[package]] @@ -693,45 +685,29 @@ version = "0.2.0" dependencies = [ "axalloc", "axconfig", - "axerrno 0.2.2", - "axfs-ng-vfs", + "axerrno 0.1.2", "axhal", - "axsync", - "axtask", - "enum_dispatch", "kspin", "lazyinit", "log", "memory_addr", "memory_set", - "page_table_multiarch 0.5.7 (git+https://github.com/arceos-org/page_table_multiarch.git?tag=dev-v05)", + "page_table_multiarch", ] [[package]] name = "axnet" version = "0.2.0" dependencies = [ - "async-channel", - "async-trait", - "axconfig", "axdriver", - "axerrno 0.2.2", - "axfs", - "axfs-ng-vfs", + "axerrno 0.1.2", "axhal", "axio", - "axpoll", "axsync", "axtask", - "bitflags 2.10.0", "cfg-if", - "enum_dispatch", - "event-listener", - "hashbrown 0.16.1", - "lazy_static", "lazyinit", "log", - "ringbuf", "smoltcp 0.12.0", "spin 0.10.0", ] @@ -944,7 +920,7 @@ name = "axstd" version = "0.2.0" dependencies = [ "arceos_api", - "axerrno 0.2.2", + "axerrno 0.1.2", "axfeat", "axio", "kspin", @@ -968,7 +944,7 @@ name = "axtask" version = "0.2.0" dependencies = [ "axconfig", - "axerrno 0.2.2", + "axerrno 0.1.2", "axhal", "axpoll", "axsched", @@ -1015,6 +991,26 @@ dependencies = [ "volatile 0.2.7", ] +[[package]] +name = "bindgen" +version = "0.71.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" +dependencies = [ + "bitflags 2.10.0", + "cexpr", + "clang-sys", + "itertools", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.111", +] + [[package]] name = "bindgen" version = "0.72.1" @@ -1103,6 +1099,15 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "cap_access" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9b24894fa5f73bbf9c72196e7f495a1f81d6218a548280a09ada4a937157692" +dependencies = [ + "bitflags 2.10.0", +] + [[package]] name = "cc" version = "1.2.47" @@ -1171,7 +1176,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.1", + "strsim", ] [[package]] @@ -1307,41 +1312,6 @@ dependencies = [ "syn 2.0.111", ] -[[package]] -name = "darling" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" -dependencies = [ - "darling_core", - "quote", - "syn 1.0.109", -] - [[package]] name = "defmt" version = "0.3.100" @@ -1439,29 +1409,6 @@ dependencies = [ "syn 2.0.111", ] -[[package]] -name = "env_filter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "jiff", - "log", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -1478,16 +1425,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener", - "pin-project-lite", -] - [[package]] name = "extern-trait" version = "0.2.0" @@ -1508,7 +1445,7 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fatfs" version = "0.4.0" -source = "git+https://github.com/Starry-OS/rust-fatfs.git?rev=2685439#2685439e679cc832a67fd21340258b7c018c0f33" +source = "git+https://github.com/rafalh/rust-fatfs?rev=4eccb50#4eccb50d011146fbed20e133d33b22f3c27292e7" dependencies = [ "bitflags 2.10.0", "log", @@ -1535,24 +1472,6 @@ dependencies = [ "bitmaps", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "foldhash" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" - [[package]] name = "futures" version = "0.3.31" @@ -1675,27 +1594,11 @@ dependencies = [ "byteorder", ] -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash 0.1.5", -] - [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash 0.2.0", -] [[package]] name = "heapless" @@ -1760,12 +1663,6 @@ dependencies = [ "cc", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "indexmap" version = "2.12.1" @@ -1773,7 +1670,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown", ] [[package]] @@ -1785,33 +1682,12 @@ dependencies = [ "rustversion", ] -[[package]] -name = "inherit-methods-macro" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831739f8836b05db933f3a84783a5af48bd605915dcd10c7435bc74e7947a030" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "int_ratio" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6045ea39e8d2862506c0dff6c65d068da362335df698bb1634033492740d2170" -[[package]] -name = "intrusive-collections" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "189d0897e4cbe8c75efedf3502c18c887b05046e59d28404d4d8e46cbc4d1e86" -dependencies = [ - "memoffset", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1839,30 +1715,6 @@ dependencies = [ "volatile 0.3.0", ] -[[package]] -name = "jiff" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" -dependencies = [ - "jiff-static", - "log", - "portable-atomic", - "portable-atomic-util", - "serde_core", -] - -[[package]] -name = "jiff-static" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - [[package]] name = "js-sys" version = "0.3.83" @@ -2010,21 +1862,12 @@ dependencies = [ "bitflags 2.10.0", ] -[[package]] -name = "lru" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96051b46fc183dc9cd4a223960ef37b9af631b55191852a8274bfef064cda20f" -dependencies = [ - "hashbrown 0.16.1", -] - [[package]] name = "lwext4_rust" version = "0.2.0" -source = "git+https://github.com/Starry-OS/lwext4_rust.git?rev=033fa2c#033fa2cc848c7495651b00af6695dc07de06d596" +source = "git+https://github.com/Josen-B/lwext4_rust.git?rev=99b3e5c#99b3e5c7262718db2002411fe55ea0362a23fdfc" dependencies = [ - "bindgen", + "bindgen 0.71.1", "log", ] @@ -2040,15 +1883,6 @@ version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - [[package]] name = "memory_addr" version = "0.4.1" @@ -2129,20 +1963,6 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa11a21844255e14aa6688ef0eafb058d7be19338633024fb59417f1bfb07f8" dependencies = [ - "log", - "memory_addr", - "page_table_entry", - "riscv", - "x86", -] - -[[package]] -name = "page_table_multiarch" -version = "0.5.7" -source = "git+https://github.com/arceos-org/page_table_multiarch.git?tag=dev-v05#4594a765e361bca2a8b6ef6773a37ae6d8539840" -dependencies = [ - "arrayvec", - "axerrno 0.1.2", "bitmaps", "log", "memory_addr", @@ -2218,21 +2038,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "portable-atomic" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" - -[[package]] -name = "portable-atomic-util" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" -dependencies = [ - "portable-atomic", -] - [[package]] name = "prettyplease" version = "0.2.37" @@ -2416,16 +2221,6 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" -[[package]] -name = "ringbuf" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe47b720588c8702e34b5979cb3271a8b1842c7cb6f57408efa70c779363488c" -dependencies = [ - "crossbeam-utils", - "portable-atomic-util", -] - [[package]] name = "riscv" version = "0.14.0" @@ -2547,26 +2342,6 @@ version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - [[package]] name = "shlex" version = "1.3.0" @@ -2584,10 +2359,16 @@ dependencies = [ ] [[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +name = "simple-ahci" +version = "0.1.0" +source = "git+https://github.com/Starry-OS/simple-ahci.git?rev=36d0979#36d0979fedb17c7846b78d1a63f944da31f96186" +dependencies = [ + "bitfield-struct", + "log", + "thiserror", + "volatile 0.6.1", +] + [[package]] name = "slab_allocator" @@ -2620,7 +2401,7 @@ dependencies = [ [[package]] name = "smoltcp" version = "0.12.0" -source = "git+https://github.com/Starry-OS/smoltcp.git?rev=7401a54#7401a54b041924a78971b077cd62140b26d441dc" +source = "git+https://github.com/rcore-os/smoltcp.git?rev=21a2f82#21a2f82b062ec88442eb624d7fcec1feeb886496" dependencies = [ "bitflags 1.3.2", "byteorder", @@ -2670,12 +2451,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strsim" version = "0.11.1" @@ -3086,4 +2861,4 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.111", -] +] \ No newline at end of file From 9376630c19a23384ca52c0d0771e9c6c0c7a560c Mon Sep 17 00:00:00 2001 From: David Hua Date: Fri, 12 Dec 2025 23:13:43 +0800 Subject: [PATCH 5/8] fix(executor): fixed race condition in run_until_idle --- Cargo.lock | 459 ++++++++++++++++++++++++--------- modules/axtask/src/executor.rs | 25 +- 2 files changed, 363 insertions(+), 121 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c89af98f0..6bbd0df5da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,6 +63,12 @@ dependencies = [ "slab_allocator", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -162,10 +168,7 @@ dependencies = [ name = "arceos-shell" version = "0.1.0" dependencies = [ - "axfs_ramfs", - "axfs_vfs", "axstd", - "crate_interface", ] [[package]] @@ -177,7 +180,7 @@ dependencies = [ "axdisplay", "axdma", "axdriver", - "axerrno 0.1.2", + "axerrno 0.2.2", "axfeat", "axfs", "axhal", @@ -197,7 +200,7 @@ version = "0.2.0" dependencies = [ "axalloc", "axconfig", - "axerrno 0.1.2", + "axerrno 0.2.2", "axfeat", "axfs", "axhal", @@ -207,7 +210,7 @@ dependencies = [ "axruntime", "axsync", "axtask", - "bindgen 0.72.1", + "bindgen", "flatten_objects", "lazy_static", "scope-local", @@ -247,12 +250,30 @@ dependencies = [ "chrono", ] +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "as-any" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0f477b951e452a0b6b4a10b53ccd569042d1d01729b519e02074a9c0958a063" +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + [[package]] name = "async-trait" version = "0.1.89" @@ -285,7 +306,7 @@ version = "0.2.0" dependencies = [ "allocator", "axbacktrace", - "axerrno 0.1.2", + "axerrno 0.2.2", "cfg-if", "kspin", "log", @@ -351,7 +372,7 @@ dependencies = [ "loongArch64", "memory_addr", "page_table_entry", - "page_table_multiarch", + "page_table_multiarch 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", "percpu", "riscv", "static_assertions", @@ -377,7 +398,7 @@ dependencies = [ "allocator", "axalloc", "axconfig", - "axerrno 0.1.2", + "axerrno 0.2.2", "axhal", "axmm", "kspin", @@ -401,7 +422,7 @@ dependencies = [ "axdriver_pci", "axdriver_virtio", "axdriver_vsock", - "axerrno 0.1.2", + "axerrno 0.2.2", "axhal", "axklib", "axmm", @@ -420,24 +441,23 @@ dependencies = [ [[package]] name = "axdriver_base" version = "0.1.2" -source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#cada10715c1f4c08b63d5d60345d2bedbc39bcd8" +source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#16f1ae864e1317f67d4e22a645fcb7399ae86596" [[package]] name = "axdriver_block" version = "0.1.2" -source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#cada10715c1f4c08b63d5d60345d2bedbc39bcd8" +source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#16f1ae864e1317f67d4e22a645fcb7399ae86596" dependencies = [ "axdriver_base", "bcm2835-sdhci", "log", "simple-sdmmc", - "simple-ahci", ] [[package]] name = "axdriver_display" version = "0.1.2" -source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#cada10715c1f4c08b63d5d60345d2bedbc39bcd8" +source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#16f1ae864e1317f67d4e22a645fcb7399ae86596" dependencies = [ "axdriver_base", ] @@ -445,7 +465,7 @@ dependencies = [ [[package]] name = "axdriver_input" version = "0.1.2" -source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#cada10715c1f4c08b63d5d60345d2bedbc39bcd8" +source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#16f1ae864e1317f67d4e22a645fcb7399ae86596" dependencies = [ "axdriver_base", "strum", @@ -454,7 +474,7 @@ dependencies = [ [[package]] name = "axdriver_net" version = "0.1.2" -source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#cada10715c1f4c08b63d5d60345d2bedbc39bcd8" +source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#16f1ae864e1317f67d4e22a645fcb7399ae86596" dependencies = [ "axdriver_base", "fxmac_rs", @@ -466,7 +486,7 @@ dependencies = [ [[package]] name = "axdriver_pci" version = "0.1.2" -source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#cada10715c1f4c08b63d5d60345d2bedbc39bcd8" +source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#16f1ae864e1317f67d4e22a645fcb7399ae86596" dependencies = [ "virtio-drivers", ] @@ -474,7 +494,7 @@ dependencies = [ [[package]] name = "axdriver_virtio" version = "0.1.2" -source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#cada10715c1f4c08b63d5d60345d2bedbc39bcd8" +source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#16f1ae864e1317f67d4e22a645fcb7399ae86596" dependencies = [ "axdriver_base", "axdriver_block", @@ -489,7 +509,7 @@ dependencies = [ [[package]] name = "axdriver_vsock" version = "0.1.2" -source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#cada10715c1f4c08b63d5d60345d2bedbc39bcd8" +source = "git+https://github.com/arceos-org/axdriver_crates.git?tag=dev-v01#16f1ae864e1317f67d4e22a645fcb7399ae86596" dependencies = [ "axdriver_base", "log", @@ -539,56 +559,44 @@ dependencies = [ name = "axfs" version = "0.2.0" dependencies = [ + "axalloc", "axdriver", - "axdriver_block", - "axerrno 0.1.2", - "axfs_devfs", - "axfs_ramfs", - "axfs_vfs", + "axerrno 0.2.2", + "axfs-ng-vfs", + "axhal", "axio", + "axpoll", "axsync", - "axtask", - "cap_access", + "bitflags 2.10.0", "cfg-if", - "crate_interface", + "chrono", + "env_logger", "fatfs", - "lazyinit", + "intrusive-collections", + "kspin", "log", + "lru", "lwext4_rust", "scope-local", + "slab", + "spin 0.10.0", ] [[package]] -name = "axfs_devfs" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b87ae981272ca8d5d8f106a4452c63f4b5ac36e17ee8f848ee1b250538b9f8" -dependencies = [ - "axfs_vfs", - "log", - "spin 0.9.8", -] - -[[package]] -name = "axfs_ramfs" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50c26614485d837a3fc09a92f24a226caddc25a30df7e6aaf4bd19b304c399" -dependencies = [ - "axfs_vfs", - "log", - "spin 0.9.8", -] - -[[package]] -name = "axfs_vfs" -version = "0.1.2" +name = "axfs-ng-vfs" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcba2006898d7879d456a9c34b9c9460cb536f5bf69d1d5d7d0e0f19f073368d" +checksum = "bf0d501c182116576111dc04ba89f48fea639b7080e0455393be5dbc41cfacef" dependencies = [ - "axerrno 0.1.2", + "axerrno 0.2.2", + "axpoll", "bitflags 2.10.0", + "cfg-if", + "hashbrown 0.15.5", + "inherit-methods-macro", "log", + "smallvec", + "spin 0.10.0", ] [[package]] @@ -611,7 +619,7 @@ dependencies = [ "linkme", "log", "memory_addr", - "page_table_multiarch", + "page_table_multiarch 0.5.7 (git+https://github.com/arceos-org/page_table_multiarch.git?tag=dev-v05)", "percpu", ] @@ -631,7 +639,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23e797ff4cfd17460c7b8742222a2cadd72a2f4966f0057d36b5925fabf534f7" dependencies = [ - "axerrno 0.1.2", + "axerrno 0.2.2", ] [[package]] @@ -661,10 +669,10 @@ name = "axlibc" version = "0.2.0" dependencies = [ "arceos_posix_api", - "axerrno 0.1.2", + "axerrno 0.2.2", "axfeat", "axio", - "bindgen 0.72.1", + "bindgen", ] [[package]] @@ -685,29 +693,45 @@ version = "0.2.0" dependencies = [ "axalloc", "axconfig", - "axerrno 0.1.2", + "axerrno 0.2.2", + "axfs-ng-vfs", "axhal", + "axsync", + "axtask", + "enum_dispatch", "kspin", "lazyinit", "log", "memory_addr", "memory_set", - "page_table_multiarch", + "page_table_multiarch 0.5.7 (git+https://github.com/arceos-org/page_table_multiarch.git?tag=dev-v05)", ] [[package]] name = "axnet" version = "0.2.0" dependencies = [ + "async-channel", + "async-trait", + "axconfig", "axdriver", - "axerrno 0.1.2", + "axerrno 0.2.2", + "axfs", + "axfs-ng-vfs", "axhal", "axio", + "axpoll", "axsync", "axtask", + "bitflags 2.10.0", "cfg-if", + "enum_dispatch", + "event-listener", + "hashbrown 0.16.1", + "lazy_static", "lazyinit", "log", + "ringbuf", "smoltcp 0.12.0", "spin 0.10.0", ] @@ -920,7 +944,7 @@ name = "axstd" version = "0.2.0" dependencies = [ "arceos_api", - "axerrno 0.1.2", + "axerrno 0.2.2", "axfeat", "axio", "kspin", @@ -944,7 +968,7 @@ name = "axtask" version = "0.2.0" dependencies = [ "axconfig", - "axerrno 0.1.2", + "axerrno 0.2.2", "axhal", "axpoll", "axsched", @@ -991,26 +1015,6 @@ dependencies = [ "volatile 0.2.7", ] -[[package]] -name = "bindgen" -version = "0.71.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" -dependencies = [ - "bitflags 2.10.0", - "cexpr", - "clang-sys", - "itertools", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.111", -] - [[package]] name = "bindgen" version = "0.72.1" @@ -1099,20 +1103,11 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" -[[package]] -name = "cap_access" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b24894fa5f73bbf9c72196e7f495a1f81d6218a548280a09ada4a937157692" -dependencies = [ - "bitflags 2.10.0", -] - [[package]] name = "cc" -version = "1.2.47" +version = "1.2.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" +checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" dependencies = [ "find-msvc-tools", "shlex", @@ -1176,7 +1171,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] @@ -1312,6 +1307,41 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + [[package]] name = "defmt" version = "0.3.100" @@ -1409,6 +1439,29 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "env_filter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -1425,6 +1478,16 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + [[package]] name = "extern-trait" version = "0.2.0" @@ -1445,7 +1508,7 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fatfs" version = "0.4.0" -source = "git+https://github.com/rafalh/rust-fatfs?rev=4eccb50#4eccb50d011146fbed20e133d33b22f3c27292e7" +source = "git+https://github.com/Starry-OS/rust-fatfs.git?rev=2685439#2685439e679cc832a67fd21340258b7c018c0f33" dependencies = [ "bitflags 2.10.0", "log", @@ -1472,6 +1535,24 @@ dependencies = [ "bitmaps", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "futures" version = "0.3.31" @@ -1594,11 +1675,27 @@ dependencies = [ "byteorder", ] +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.1.5", +] + [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] [[package]] name = "heapless" @@ -1663,6 +1760,12 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "indexmap" version = "2.12.1" @@ -1670,7 +1773,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.1", ] [[package]] @@ -1682,12 +1785,33 @@ dependencies = [ "rustversion", ] +[[package]] +name = "inherit-methods-macro" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831739f8836b05db933f3a84783a5af48bd605915dcd10c7435bc74e7947a030" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "int_ratio" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6045ea39e8d2862506c0dff6c65d068da362335df698bb1634033492740d2170" +[[package]] +name = "intrusive-collections" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "189d0897e4cbe8c75efedf3502c18c887b05046e59d28404d4d8e46cbc4d1e86" +dependencies = [ + "memoffset", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1715,6 +1839,30 @@ dependencies = [ "volatile 0.3.0", ] +[[package]] +name = "jiff" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-static" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "js-sys" version = "0.3.83" @@ -1727,9 +1875,9 @@ dependencies = [ [[package]] name = "kernel_guard" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307e6be468f3d6b6d895e191f63c11602e4e76575ecca68325d8c8dbebe2870e" +checksum = "d10c55bedf6789bc3748e0d8756ee639df1ae25144fd3525ed311044bd9a739f" dependencies = [ "cfg-if", "crate_interface", @@ -1791,9 +1939,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.177" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libloading" @@ -1848,9 +1996,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "loongArch64" @@ -1862,12 +2010,21 @@ dependencies = [ "bitflags 2.10.0", ] +[[package]] +name = "lru" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96051b46fc183dc9cd4a223960ef37b9af631b55191852a8274bfef064cda20f" +dependencies = [ + "hashbrown 0.16.1", +] + [[package]] name = "lwext4_rust" version = "0.2.0" -source = "git+https://github.com/Josen-B/lwext4_rust.git?rev=99b3e5c#99b3e5c7262718db2002411fe55ea0362a23fdfc" +source = "git+https://github.com/Starry-OS/lwext4_rust.git?rev=033fa2c#033fa2cc848c7495651b00af6695dc07de06d596" dependencies = [ - "bindgen 0.71.1", + "bindgen", "log", ] @@ -1883,6 +2040,15 @@ version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "memory_addr" version = "0.4.1" @@ -1963,6 +2129,20 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa11a21844255e14aa6688ef0eafb058d7be19338633024fb59417f1bfb07f8" dependencies = [ + "log", + "memory_addr", + "page_table_entry", + "riscv", + "x86", +] + +[[package]] +name = "page_table_multiarch" +version = "0.5.7" +source = "git+https://github.com/arceos-org/page_table_multiarch.git?tag=dev-v05#4594a765e361bca2a8b6ef6773a37ae6d8539840" +dependencies = [ + "arrayvec", + "axerrno 0.1.2", "bitmaps", "log", "memory_addr", @@ -2038,6 +2218,21 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + [[package]] name = "prettyplease" version = "0.2.37" @@ -2221,6 +2416,16 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +[[package]] +name = "ringbuf" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe47b720588c8702e34b5979cb3271a8b1842c7cb6f57408efa70c779363488c" +dependencies = [ + "crossbeam-utils", + "portable-atomic-util", +] + [[package]] name = "riscv" version = "0.14.0" @@ -2342,6 +2547,26 @@ version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2359,16 +2584,10 @@ dependencies = [ ] [[package]] -name = "simple-ahci" -version = "0.1.0" -source = "git+https://github.com/Starry-OS/simple-ahci.git?rev=36d0979#36d0979fedb17c7846b78d1a63f944da31f96186" -dependencies = [ - "bitfield-struct", - "log", - "thiserror", - "volatile 0.6.1", -] - +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "slab_allocator" @@ -2401,7 +2620,7 @@ dependencies = [ [[package]] name = "smoltcp" version = "0.12.0" -source = "git+https://github.com/rcore-os/smoltcp.git?rev=21a2f82#21a2f82b062ec88442eb624d7fcec1feeb886496" +source = "git+https://github.com/Starry-OS/smoltcp.git?rev=7401a54#7401a54b041924a78971b077cd62140b26d441dc" dependencies = [ "bitflags 1.3.2", "byteorder", @@ -2451,6 +2670,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" @@ -2861,4 +3086,4 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.111", -] \ No newline at end of file +] diff --git a/modules/axtask/src/executor.rs b/modules/axtask/src/executor.rs index 9794208856..fc6c2b6906 100644 --- a/modules/axtask/src/executor.rs +++ b/modules/axtask/src/executor.rs @@ -89,6 +89,11 @@ where /// Polls one ready task if present. /// +/// This function dequeues a single task from the global ready queue and polls it once. +/// - If the task completes (`Poll::Ready`), it is dropped. +/// - If the task is still pending (`Poll::Pending`), it is NOT automatically re-queued by this function. +/// It will be re-queued only when its `Waker` is triggered. +/// /// Returns: /// - `None`: The ready queue is empty. /// - `Some(Poll::Ready(()))`: A task ran and finished. @@ -121,14 +126,26 @@ pub fn run_until_idle() { loop { let seen = WAKE_COUNT.load(Ordering::Acquire); - // Drain all currently ready tasks. while run_once().is_some() {} - if READY_QUEUE.lock().is_empty() { - if WAKE_COUNT.load(Ordering::Acquire) == seen { - break; + let done = { + let _guard = kernel_guard::NoPreempt::new(); + + if READY_QUEUE.lock().is_empty() { + if WAKE_COUNT.load(Ordering::Acquire) == seen { + true + } else { + false + } + } else { + false } + }; + + if done { + break; } + core::hint::spin_loop(); } } From d2d68ab9acaaba1828394358c8b48e72bcde7866 Mon Sep 17 00:00:00 2001 From: David Hua Date: Sat, 13 Dec 2025 00:14:07 +0800 Subject: [PATCH 6/8] feat(executor): added per-cpu ready queue --- modules/axtask/src/executor.rs | 30 +++++++++++++++++------------- modules/axtask/src/tests.rs | 23 +++++++++++++++++++++++ 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/modules/axtask/src/executor.rs b/modules/axtask/src/executor.rs index fc6c2b6906..4ca12eed3c 100644 --- a/modules/axtask/src/executor.rs +++ b/modules/axtask/src/executor.rs @@ -15,19 +15,23 @@ use crate::TaskId; /// /// This queue stores `AsyncTask`s that are ready to be polled. /// The executor loop will pop tasks from this queue and run them. + +#[percpu::def_percpu] static READY_QUEUE: LazyInit>>> = LazyInit::new(); + static READY_QUEUE_INITED: AtomicBool = AtomicBool::new(false); -/// Wake counter: incremented on spawn/wake, used by runners to detect new tasks. + +#[percpu::def_percpu] static WAKE_COUNT: AtomicUsize = AtomicUsize::new(0); /// Initialize the executor module. pub(crate) fn init() { - if READY_QUEUE_INITED.swap(true, Ordering::AcqRel) { - return; - } - READY_QUEUE.init_once(SpinNoIrq::new(VecDeque::new())); + READY_QUEUE.with_current(|q| { + q.init_once(SpinNoIrq::new(VecDeque::new())); + }); } + /// An asynchronous task that wraps a future. pub struct AsyncTask { id: TaskId, @@ -70,8 +74,8 @@ impl Wake for AsyncTask { } fn wake_by_ref(self: &Arc) { - READY_QUEUE.lock().push_back(self.clone()); - WAKE_COUNT.fetch_add(1, Ordering::Release); + READY_QUEUE.with_current(|q| q.lock().push_back(self.clone())); + WAKE_COUNT.with_current(|c| c.fetch_add(1, Ordering::Release)); } } @@ -83,8 +87,8 @@ where F: Future + Send + 'static, { let task = AsyncTask::new(future); - READY_QUEUE.lock().push_back(task); - WAKE_COUNT.fetch_add(1, Ordering::Release); + READY_QUEUE.with_current(|q| q.lock().push_back(task)); + WAKE_COUNT.with_current(|c| c.fetch_add(1, Ordering::Release)); } /// Polls one ready task if present. @@ -99,7 +103,7 @@ where /// - `Some(Poll::Ready(()))`: A task ran and finished. /// - `Some(Poll::Pending)`: A task ran and is pending (will be woken later). pub fn run_once() -> Option> { - if let Some(task) = READY_QUEUE.lock().pop_front() { + if let Some(task) = READY_QUEUE.with_current(|q| q.lock().pop_front()) { Some(task.poll()) } else { None @@ -124,15 +128,15 @@ pub fn run_for(max_steps: usize) -> bool { /// if new tasks arrive while draining; if so, it continues. pub fn run_until_idle() { loop { - let seen = WAKE_COUNT.load(Ordering::Acquire); + let seen = WAKE_COUNT.with_current(|c| c.load(Ordering::Acquire)); while run_once().is_some() {} let done = { let _guard = kernel_guard::NoPreempt::new(); - if READY_QUEUE.lock().is_empty() { - if WAKE_COUNT.load(Ordering::Acquire) == seen { + if READY_QUEUE.with_current(|q| q.lock().is_empty()) { + if WAKE_COUNT.with_current(|c| c.load(Ordering::Acquire)) == seen { true } else { false diff --git a/modules/axtask/src/tests.rs b/modules/axtask/src/tests.rs index 81bf2b1b27..b7e65e19bb 100644 --- a/modules/axtask/src/tests.rs +++ b/modules/axtask/src/tests.rs @@ -227,3 +227,26 @@ fn test_async_executor_run_for_progress() { assert_eq!(CNT.load(Ordering::Acquire), 2); } +#[test] +fn test_async_executor_percpu_correctness() { + let _lock = SERIAL.lock(); + init_env(); + + // This test verifies that the per-cpu executor works correctly on the current CPU. + // Since we are in a unit test environment, we effectively test the "primary" CPU behavior. + // It ensures that the per-cpu READY_QUEUE is initialized and accessible. + + static COUNTER: AtomicUsize = AtomicUsize::new(0); + const ITERATIONS: usize = 100; + + for _ in 0..ITERATIONS { + executor::spawn(async { + COUNTER.fetch_add(1, Ordering::Relaxed); + }); + } + + executor::run_until_idle(); + + assert_eq!(COUNTER.load(Ordering::Relaxed), ITERATIONS); +} + From 290b4a37bd0ebef989c255bba3b834031230559e Mon Sep 17 00:00:00 2001 From: David Hua Date: Sun, 21 Dec 2025 20:01:06 +0800 Subject: [PATCH 7/8] refactor(executor): improved block_on function and async waker --- modules/axtask/src/executor.rs | 138 ++++++++++++++++++------------- modules/axtask/src/future/mod.rs | 49 +++++++---- modules/axtask/src/tests.rs | 2 +- 3 files changed, 114 insertions(+), 75 deletions(-) diff --git a/modules/axtask/src/executor.rs b/modules/axtask/src/executor.rs index 4ca12eed3c..31af18f2ad 100644 --- a/modules/axtask/src/executor.rs +++ b/modules/axtask/src/executor.rs @@ -2,64 +2,106 @@ use alloc::{boxed::Box, collections::VecDeque, sync::Arc, task::Wake}; use core::{ future::Future, pin::Pin, - sync::atomic::{AtomicBool, AtomicUsize, Ordering}, + sync::atomic::{AtomicUsize, Ordering}, task::{Context, Poll, Waker}, }; +use kernel_guard::NoPreemptIrqSave; use kspin::SpinNoIrq; use lazyinit::LazyInit; -use crate::TaskId; +use crate::{select_run_queue, TaskId, WeakAxTaskRef}; -/// Global ready queue for async tasks. -/// -/// This queue stores `AsyncTask`s that are ready to be polled. -/// The executor loop will pop tasks from this queue and run them. +pub struct AxExecutor { + queue: SpinNoIrq>>, +} -#[percpu::def_percpu] -static READY_QUEUE: LazyInit>>> = LazyInit::new(); +impl AxExecutor { + pub fn new() -> Self { + Self { + queue: SpinNoIrq::new(VecDeque::new()), + } + } -static READY_QUEUE_INITED: AtomicBool = AtomicBool::new(false); + pub fn add_task(&self, task: Arc) { + self.queue.lock().push_back(task); + } + + pub fn pop_task(&self) -> Option> { + self.queue.lock().pop_front() + } + + pub fn is_empty(&self) -> bool { + self.queue.lock().is_empty() + } +} + +impl Default for AxExecutor { + fn default() -> Self { + Self::new() + } +} + +#[percpu::def_percpu] +static READY_QUEUE: LazyInit> = LazyInit::new(); #[percpu::def_percpu] static WAKE_COUNT: AtomicUsize = AtomicUsize::new(0); -/// Initialize the executor module. +#[percpu::def_percpu] +static BLOCKED_TASK: SpinNoIrq> = SpinNoIrq::new(None); + pub(crate) fn init() { READY_QUEUE.with_current(|q| { - q.init_once(SpinNoIrq::new(VecDeque::new())); + q.init_once(Arc::new(AxExecutor::new())); }); } +pub fn set_blocked_task(task: WeakAxTaskRef) { + BLOCKED_TASK.with_current(|t| { + *t.lock() = Some(task); + }); +} + +pub fn clear_blocked_task() { + BLOCKED_TASK.with_current(|t| { + *t.lock() = None; + }); +} + +fn wake_blocked_task() { + BLOCKED_TASK.with_current(|t| { + if let Some(weak) = t.lock().as_ref() { + if let Some(task) = weak.upgrade() { + select_run_queue::(&task).unblock_task(task, false); + } + } + }); +} /// An asynchronous task that wraps a future. pub struct AsyncTask { id: TaskId, - /// The future to be executed. - /// - /// It is wrapped in `SpinNoIrq` to provide interior mutability, which is required - /// because `poll` takes `&self` (via `Arc`) but the future's `poll` method - /// requires `Pin<&mut F>`. future: SpinNoIrq + Send + 'static>>>, + executor: Arc, } impl AsyncTask { - /// Creates a new `AsyncTask` with the given future. - pub fn new(future: impl Future + Send + 'static) -> Arc { + pub fn new( + future: impl Future + Send + 'static, + executor: Arc, + ) -> Arc { Arc::new(Self { id: TaskId::new(), future: SpinNoIrq::new(Box::pin(future)), + executor, }) } - /// Returns the unique identifier of the task. pub fn id(&self) -> TaskId { self.id } - /// Polls the inner future. - /// - /// This creates a `Waker` from the `Arc` and passes it to the future's context. pub(crate) fn poll(self: &Arc) -> Poll<()> { let waker = Waker::from(self.clone()); let mut cx = Context::from_waker(&waker); @@ -74,43 +116,30 @@ impl Wake for AsyncTask { } fn wake_by_ref(self: &Arc) { - READY_QUEUE.with_current(|q| q.lock().push_back(self.clone())); + self.executor.add_task(self.clone()); WAKE_COUNT.with_current(|c| c.fetch_add(1, Ordering::Release)); + wake_blocked_task(); } } -/// Spawns a future as an asynchronous task. -/// -/// The task is immediately added to the ready queue. pub fn spawn(future: F) where F: Future + Send + 'static, { - let task = AsyncTask::new(future); - READY_QUEUE.with_current(|q| q.lock().push_back(task)); + let executor = READY_QUEUE.with_current(|q| q.clone()); + let task = AsyncTask::new(future, executor.clone()); + executor.add_task(task); WAKE_COUNT.with_current(|c| c.fetch_add(1, Ordering::Release)); } -/// Polls one ready task if present. -/// -/// This function dequeues a single task from the global ready queue and polls it once. -/// - If the task completes (`Poll::Ready`), it is dropped. -/// - If the task is still pending (`Poll::Pending`), it is NOT automatically re-queued by this function. -/// It will be re-queued only when its `Waker` is triggered. -/// -/// Returns: -/// - `None`: The ready queue is empty. -/// - `Some(Poll::Ready(()))`: A task ran and finished. -/// - `Some(Poll::Pending)`: A task ran and is pending (will be woken later). pub fn run_once() -> Option> { - if let Some(task) = READY_QUEUE.with_current(|q| q.lock().pop_front()) { + if let Some(task) = READY_QUEUE.with_current(|q| q.pop_task()) { Some(task.poll()) } else { None } } -/// Run up to `max_steps` tasks; returns true if any task ran. pub fn run_for(max_steps: usize) -> bool { let mut ran = false; for _ in 0..max_steps { @@ -122,34 +151,29 @@ pub fn run_for(max_steps: usize) -> bool { ran } -/// Runs the executor loop until no ready tasks remain. -/// -/// This function drains all ready tasks. It uses an atomic counter to detect -/// if new tasks arrive while draining; if so, it continues. +pub fn wake_count() -> usize { + WAKE_COUNT.with_current(|c| c.load(Ordering::Acquire)) +} + +pub fn is_empty() -> bool { + READY_QUEUE.with_current(|q| q.is_empty()) +} + pub fn run_until_idle() { loop { - let seen = WAKE_COUNT.with_current(|c| c.load(Ordering::Acquire)); + let seen = wake_count(); while run_once().is_some() {} let done = { let _guard = kernel_guard::NoPreempt::new(); - - if READY_QUEUE.with_current(|q| q.lock().is_empty()) { - if WAKE_COUNT.with_current(|c| c.load(Ordering::Acquire)) == seen { - true - } else { - false - } - } else { - false - } + is_empty() && wake_count() == seen }; if done { break; } - + core::hint::spin_loop(); } } diff --git a/modules/axtask/src/future/mod.rs b/modules/axtask/src/future/mod.rs index 3517591c69..2edaecd951 100644 --- a/modules/axtask/src/future/mod.rs +++ b/modules/axtask/src/future/mod.rs @@ -52,8 +52,13 @@ impl Wake for AxWaker { /// Blocks the current task until the given future is resolved. /// -/// Note that this doesn't handle interruption and is not recommended for direct -/// use in most cases. +/// While waiting for the main future, this function also drives other async tasks +/// in the per-CPU executor. The thread only blocks when both: +/// - The main future is pending (not yet ready) +/// - The per-CPU executor has no ready tasks to run +/// +/// When async tasks in the executor are woken, they will also wake up this +/// blocked thread, ensuring that the executor continues to make progress. pub fn block_on(f: F) -> F::Output { let mut fut = pin!(f.into_future()); @@ -69,22 +74,32 @@ pub fn block_on(f: F) -> F::Output { loop { woke.store(false, Ordering::Release); - let result = fut.as_mut().poll(&mut cx); - - // Polling the executor to run up to three async tasks - // (may run fewer if the queue has fewer ready tasks). - let _ = executor::run_for(3); - - match result { - Poll::Pending => { - if !woke.load(Ordering::Acquire) { - current_run_queue::().blocked_resched(); - } else { - // Immediately woken - crate::yield_now(); - } + + if let Poll::Ready(output) = fut.as_mut().poll(&mut cx) { + return output; + } + + // While waiting for the main future, this function also drives other async tasks + loop { + let seen = executor::wake_count(); + + while executor::run_once().is_some() {} + + let should_block = { + let _guard = kernel_guard::NoPreempt::new(); + executor::is_empty() + && executor::wake_count() == seen + && !woke.load(Ordering::Acquire) + }; + + if should_block { + executor::set_blocked_task(Arc::downgrade(&task)); + current_run_queue::().blocked_resched(); + executor::clear_blocked_task(); + break; + } else if woke.load(Ordering::Acquire) { + break; } - Poll::Ready(output) => break output, } } } diff --git a/modules/axtask/src/tests.rs b/modules/axtask/src/tests.rs index b7e65e19bb..272c13ff71 100644 --- a/modules/axtask/src/tests.rs +++ b/modules/axtask/src/tests.rs @@ -235,7 +235,7 @@ fn test_async_executor_percpu_correctness() { // This test verifies that the per-cpu executor works correctly on the current CPU. // Since we are in a unit test environment, we effectively test the "primary" CPU behavior. // It ensures that the per-cpu READY_QUEUE is initialized and accessible. - + static COUNTER: AtomicUsize = AtomicUsize::new(0); const ITERATIONS: usize = 100; From 42518ad66cd2ac5a44688ec8836d8f3f3e10d7ec Mon Sep 17 00:00:00 2001 From: David Hua Date: Tue, 23 Dec 2025 00:06:10 +0800 Subject: [PATCH 8/8] feat(executor): added enqueued flag --- modules/axtask/src/executor.rs | 42 +++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/modules/axtask/src/executor.rs b/modules/axtask/src/executor.rs index 31af18f2ad..95763cbd9c 100644 --- a/modules/axtask/src/executor.rs +++ b/modules/axtask/src/executor.rs @@ -2,7 +2,7 @@ use alloc::{boxed::Box, collections::VecDeque, sync::Arc, task::Wake}; use core::{ future::Future, pin::Pin, - sync::atomic::{AtomicUsize, Ordering}, + sync::atomic::{AtomicBool, AtomicUsize, Ordering}, task::{Context, Poll, Waker}, }; @@ -10,7 +10,7 @@ use kernel_guard::NoPreemptIrqSave; use kspin::SpinNoIrq; use lazyinit::LazyInit; -use crate::{select_run_queue, TaskId, WeakAxTaskRef}; +use crate::{current_run_queue, select_run_queue, TaskId, WeakAxTaskRef}; pub struct AxExecutor { queue: SpinNoIrq>>, @@ -84,6 +84,7 @@ pub struct AsyncTask { id: TaskId, future: SpinNoIrq + Send + 'static>>>, executor: Arc, + enqueued: AtomicBool, } impl AsyncTask { @@ -95,6 +96,7 @@ impl AsyncTask { id: TaskId::new(), future: SpinNoIrq::new(Box::pin(future)), executor, + enqueued: AtomicBool::new(false), }) } @@ -103,11 +105,25 @@ impl AsyncTask { } pub(crate) fn poll(self: &Arc) -> Poll<()> { + self.enqueued.store(false, Ordering::Release); let waker = Waker::from(self.clone()); let mut cx = Context::from_waker(&waker); let mut future = self.future.lock(); future.as_mut().poll(&mut cx) } + + fn enqueue(self: &Arc) -> bool { + if self + .enqueued + .compare_exchange(false, true, Ordering::AcqRel, Ordering::Acquire) + .is_ok() + { + self.executor.add_task(self.clone()); + true + } else { + false + } + } } impl Wake for AsyncTask { @@ -116,9 +132,10 @@ impl Wake for AsyncTask { } fn wake_by_ref(self: &Arc) { - self.executor.add_task(self.clone()); - WAKE_COUNT.with_current(|c| c.fetch_add(1, Ordering::Release)); - wake_blocked_task(); + if self.enqueue() { + WAKE_COUNT.with_current(|c| c.fetch_add(1, Ordering::Release)); + wake_blocked_task(); + } } } @@ -128,8 +145,9 @@ where { let executor = READY_QUEUE.with_current(|q| q.clone()); let task = AsyncTask::new(future, executor.clone()); - executor.add_task(task); - WAKE_COUNT.with_current(|c| c.fetch_add(1, Ordering::Release)); + if task.enqueue() { + WAKE_COUNT.with_current(|c| c.fetch_add(1, Ordering::Release)); + } } pub fn run_once() -> Option> { @@ -160,6 +178,8 @@ pub fn is_empty() -> bool { } pub fn run_until_idle() { + const SPIN_LIMIT: usize = 64; + let mut spin_count = 0; loop { let seen = wake_count(); @@ -174,6 +194,12 @@ pub fn run_until_idle() { break; } - core::hint::spin_loop(); + if spin_count < SPIN_LIMIT { + spin_count += 1; + core::hint::spin_loop(); + } else { + spin_count = 0; + current_run_queue::().yield_current(); + } } }