mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 21:06: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)]
|
||||
unsafe {
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use crate::task::{set_scheduler, FifoScheduler, Scheduler, TaskOptions};
|
||||
|
||||
crate::init();
|
||||
// The whitelists that will be generated by OSDK runner as static consts.
|
||||
extern "Rust" {
|
||||
static KTEST_TEST_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::{
|
||||
priority::Priority,
|
||||
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},
|
||||
};
|
||||
|
@ -1,5 +1,7 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use alloc::collections::VecDeque;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
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>) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
#[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 {
|
||||
fn enqueue(&self, task: Arc<Task>) {
|
||||
if task.is_real_time() {
|
||||
self.real_time_tasks
|
||||
.lock_irq_disabled()
|
||||
.push_back(task.clone());
|
||||
self.real_time_tasks.lock_irq_disabled().push_back(task);
|
||||
} else {
|
||||
self.normal_tasks
|
||||
.lock_irq_disabled()
|
||||
.push_back(task.clone());
|
||||
self.normal_tasks.lock_irq_disabled().push_back(task);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user