mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-09 13:26:48 +00:00
Enable kernel mode unit tests in kernel threads
This commit is contained in:
parent
57cb922253
commit
c335873d12
@ -119,13 +119,26 @@ pub fn call_aster_main() -> ! {
|
|||||||
}
|
}
|
||||||
#[cfg(ktest)]
|
#[cfg(ktest)]
|
||||||
unsafe {
|
unsafe {
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
|
||||||
|
use crate::task::{set_scheduler, FifoScheduler, Scheduler, TaskOptions};
|
||||||
|
|
||||||
crate::init();
|
crate::init();
|
||||||
// The whitelists that will be generated by OSDK runner as static consts.
|
// The whitelists that will be generated by OSDK runner as static consts.
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
static KTEST_TEST_WHITELIST: Option<&'static [&'static str]>;
|
static KTEST_TEST_WHITELIST: Option<&'static [&'static str]>;
|
||||||
static KTEST_CRATE_WHITELIST: Option<&'static [&'static str]>;
|
static KTEST_CRATE_WHITELIST: Option<&'static [&'static str]>;
|
||||||
}
|
}
|
||||||
run_ktests(KTEST_TEST_WHITELIST, KTEST_CRATE_WHITELIST);
|
// Set the global scheduler a FIFO scheduler.
|
||||||
|
let simple_scheduler = Box::new(FifoScheduler::new());
|
||||||
|
let static_scheduler: &'static dyn Scheduler = Box::leak(simple_scheduler);
|
||||||
|
set_scheduler(static_scheduler);
|
||||||
|
|
||||||
|
let test_task = move || {
|
||||||
|
run_ktests(KTEST_TEST_WHITELIST, KTEST_CRATE_WHITELIST);
|
||||||
|
};
|
||||||
|
let _ = TaskOptions::new(test_task).data(()).spawn();
|
||||||
|
unreachable!("The spawn method will NOT return in the boot context")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,6 @@ mod task;
|
|||||||
pub use self::{
|
pub use self::{
|
||||||
priority::Priority,
|
priority::Priority,
|
||||||
processor::{current_task, disable_preempt, preempt, schedule, DisablePreemptGuard},
|
processor::{current_task, disable_preempt, preempt, schedule, DisablePreemptGuard},
|
||||||
scheduler::{add_task, set_scheduler, Scheduler},
|
scheduler::{add_task, set_scheduler, FifoScheduler, Scheduler},
|
||||||
task::{Task, TaskAdapter, TaskOptions, TaskStatus},
|
task::{Task, TaskAdapter, TaskOptions, TaskStatus},
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
use alloc::collections::VecDeque;
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use crate::{prelude::*, sync::SpinLock, task::Task};
|
use crate::{prelude::*, sync::SpinLock, task::Task};
|
||||||
@ -60,3 +62,40 @@ pub fn fetch_task() -> Option<Arc<Task>> {
|
|||||||
pub fn add_task(task: Arc<Task>) {
|
pub fn add_task(task: Arc<Task>) {
|
||||||
GLOBAL_SCHEDULER.lock_irq_disabled().enqueue(task);
|
GLOBAL_SCHEDULER.lock_irq_disabled().enqueue(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A simple FIFO (First-In-First-Out) task scheduler.
|
||||||
|
pub struct FifoScheduler {
|
||||||
|
/// A thread-safe queue to hold tasks waiting to be executed.
|
||||||
|
task_queue: SpinLock<VecDeque<Arc<Task>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FifoScheduler {
|
||||||
|
/// Creates a new instance of `FifoScheduler`.
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
FifoScheduler {
|
||||||
|
task_queue: SpinLock::new(VecDeque::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for FifoScheduler {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Scheduler for FifoScheduler {
|
||||||
|
/// Enqueues a task to the end of the queue.
|
||||||
|
fn enqueue(&self, task: Arc<Task>) {
|
||||||
|
self.task_queue.lock_irq_disabled().push_back(task);
|
||||||
|
}
|
||||||
|
/// Dequeues a task from the front of the queue, if any.
|
||||||
|
fn dequeue(&self) -> Option<Arc<Task>> {
|
||||||
|
self.task_queue.lock_irq_disabled().pop_front()
|
||||||
|
}
|
||||||
|
/// In this simple implementation, task preemption is not supported.
|
||||||
|
/// Once a task starts running, it will continue to run until completion.
|
||||||
|
fn should_preempt(&self, _task: &Arc<Task>) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -303,3 +303,26 @@ impl TaskOptions {
|
|||||||
Ok(task)
|
Ok(task)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(ktest)]
|
||||||
|
mod test {
|
||||||
|
#[ktest]
|
||||||
|
fn create_task() {
|
||||||
|
let task = || {
|
||||||
|
assert_eq!(1, 1);
|
||||||
|
};
|
||||||
|
let task_option = crate::task::TaskOptions::new(task)
|
||||||
|
.data(())
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
task_option.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ktest]
|
||||||
|
fn spawn_task() {
|
||||||
|
let task = || {
|
||||||
|
assert_eq!(1, 1);
|
||||||
|
};
|
||||||
|
let _ = crate::task::TaskOptions::new(task).data(()).spawn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -36,13 +36,9 @@ impl PreemptScheduler {
|
|||||||
impl Scheduler for PreemptScheduler {
|
impl Scheduler for PreemptScheduler {
|
||||||
fn enqueue(&self, task: Arc<Task>) {
|
fn enqueue(&self, task: Arc<Task>) {
|
||||||
if task.is_real_time() {
|
if task.is_real_time() {
|
||||||
self.real_time_tasks
|
self.real_time_tasks.lock_irq_disabled().push_back(task);
|
||||||
.lock_irq_disabled()
|
|
||||||
.push_back(task.clone());
|
|
||||||
} else {
|
} else {
|
||||||
self.normal_tasks
|
self.normal_tasks.lock_irq_disabled().push_back(task);
|
||||||
.lock_irq_disabled()
|
|
||||||
.push_back(task.clone());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user