mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-28 20:03:22 +00:00
Remove KernelThreadExt
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
7850f7e60a
commit
a4a8807a20
@ -8,68 +8,10 @@ use ostd::{
|
||||
use super::{oops, status::ThreadStatus, Thread};
|
||||
use crate::{prelude::*, sched::priority::Priority};
|
||||
|
||||
/// The inner data of a kernel thread
|
||||
pub struct KernelThread;
|
||||
/// The inner data of a kernel thread.
|
||||
struct KernelThread;
|
||||
|
||||
pub trait KernelThreadExt {
|
||||
/// Gets the kernel_thread structure
|
||||
fn as_kernel_thread(&self) -> Option<&KernelThread>;
|
||||
/// Creates a new kernel thread, and then run the thread.
|
||||
fn spawn_kernel_thread(thread_options: ThreadOptions) -> Arc<Thread> {
|
||||
let task = create_new_kernel_task(thread_options);
|
||||
let thread = Thread::borrow_from_task(&task).clone();
|
||||
thread.run();
|
||||
thread
|
||||
}
|
||||
/// join a kernel thread, returns if the kernel thread exit
|
||||
fn join(&self);
|
||||
}
|
||||
|
||||
impl KernelThreadExt for Thread {
|
||||
fn as_kernel_thread(&self) -> Option<&KernelThread> {
|
||||
self.data().downcast_ref::<KernelThread>()
|
||||
}
|
||||
|
||||
fn join(&self) {
|
||||
loop {
|
||||
if self.is_exited() {
|
||||
return;
|
||||
} else {
|
||||
Thread::yield_now();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new task of kernel thread, **NOT** run the thread.
|
||||
pub fn create_new_kernel_task(mut thread_options: ThreadOptions) -> Arc<Task> {
|
||||
let task_fn = thread_options.take_func();
|
||||
let thread_fn = move || {
|
||||
let _ = oops::catch_panics_as_oops(task_fn);
|
||||
// Ensure that the thread exits.
|
||||
current_thread!().exit();
|
||||
};
|
||||
|
||||
Arc::new_cyclic(|weak_task| {
|
||||
let thread = {
|
||||
let kernel_thread = KernelThread;
|
||||
let status = ThreadStatus::Init;
|
||||
let priority = thread_options.priority;
|
||||
let cpu_affinity = thread_options.cpu_affinity;
|
||||
Arc::new(Thread::new(
|
||||
weak_task.clone(),
|
||||
kernel_thread,
|
||||
status,
|
||||
priority,
|
||||
cpu_affinity,
|
||||
))
|
||||
};
|
||||
|
||||
TaskOptions::new(thread_fn).data(thread).build().unwrap()
|
||||
})
|
||||
}
|
||||
|
||||
/// Options to create or spawn a new thread.
|
||||
/// Options to create or spawn a new kernel thread.
|
||||
pub struct ThreadOptions {
|
||||
func: Option<Box<dyn Fn() + Send + Sync>>,
|
||||
priority: Priority,
|
||||
@ -77,6 +19,7 @@ pub struct ThreadOptions {
|
||||
}
|
||||
|
||||
impl ThreadOptions {
|
||||
/// Creates the thread options with the thread function.
|
||||
pub fn new<F>(func: F) -> Self
|
||||
where
|
||||
F: Fn() + Send + Sync + 'static,
|
||||
@ -89,25 +32,53 @@ impl ThreadOptions {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn func<F>(mut self, func: F) -> Self
|
||||
where
|
||||
F: Fn() + Send + Sync + 'static,
|
||||
{
|
||||
self.func = Some(Box::new(func));
|
||||
self
|
||||
}
|
||||
|
||||
fn take_func(&mut self) -> Box<dyn Fn() + Send + Sync> {
|
||||
self.func.take().unwrap()
|
||||
}
|
||||
|
||||
/// Sets the priority of the new thread.
|
||||
pub fn priority(mut self, priority: Priority) -> Self {
|
||||
self.priority = priority;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the CPU affinity of the new thread.
|
||||
pub fn cpu_affinity(mut self, cpu_affinity: CpuSet) -> Self {
|
||||
self.cpu_affinity = cpu_affinity;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl ThreadOptions {
|
||||
/// Builds a new kernel thread without running it immediately.
|
||||
pub fn build(mut self) -> Arc<Task> {
|
||||
let task_fn = self.func.take().unwrap();
|
||||
let thread_fn = move || {
|
||||
let _ = oops::catch_panics_as_oops(task_fn);
|
||||
// Ensure that the thread exits.
|
||||
current_thread!().exit();
|
||||
};
|
||||
|
||||
Arc::new_cyclic(|weak_task| {
|
||||
let thread = {
|
||||
let kernel_thread = KernelThread;
|
||||
let status = ThreadStatus::Init;
|
||||
let priority = self.priority;
|
||||
let cpu_affinity = self.cpu_affinity;
|
||||
Arc::new(Thread::new(
|
||||
weak_task.clone(),
|
||||
kernel_thread,
|
||||
status,
|
||||
priority,
|
||||
cpu_affinity,
|
||||
))
|
||||
};
|
||||
|
||||
TaskOptions::new(thread_fn).data(thread).build().unwrap()
|
||||
})
|
||||
}
|
||||
|
||||
/// Builds a new kernel thread and runs it immediately.
|
||||
pub fn spawn(self) -> Arc<Thread> {
|
||||
let task = self.build();
|
||||
let thread = Thread::borrow_from_task(&task).clone();
|
||||
thread.run();
|
||||
thread
|
||||
}
|
||||
}
|
||||
|
@ -152,10 +152,22 @@ impl Thread {
|
||||
&self.cpu_affinity
|
||||
}
|
||||
|
||||
/// Yields the execution to another thread.
|
||||
///
|
||||
/// This method will return once the current thread is scheduled again.
|
||||
pub fn yield_now() {
|
||||
Task::yield_now()
|
||||
}
|
||||
|
||||
/// Joins the execution of the thread.
|
||||
///
|
||||
/// This method will return after the thread exits.
|
||||
pub fn join(&self) {
|
||||
while !self.is_exited() {
|
||||
Self::yield_now();
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the associated data.
|
||||
pub fn data(&self) -> &(dyn Send + Sync + Any) {
|
||||
&*self.data
|
||||
|
@ -11,7 +11,7 @@ use super::worker_pool::WorkerPool;
|
||||
use crate::{
|
||||
prelude::*,
|
||||
sched::priority::{Priority, PriorityRange},
|
||||
thread::kernel_thread::{create_new_kernel_task, ThreadOptions},
|
||||
thread::kernel_thread::ThreadOptions,
|
||||
Thread,
|
||||
};
|
||||
|
||||
@ -56,11 +56,10 @@ impl Worker {
|
||||
// FIXME: remove the use of real-time priority.
|
||||
priority = Priority::new(PriorityRange::new(0));
|
||||
}
|
||||
let bound_task = create_new_kernel_task(
|
||||
ThreadOptions::new(task_fn)
|
||||
.cpu_affinity(cpu_affinity)
|
||||
.priority(priority),
|
||||
);
|
||||
let bound_task = ThreadOptions::new(task_fn)
|
||||
.cpu_affinity(cpu_affinity)
|
||||
.priority(priority)
|
||||
.build();
|
||||
Self {
|
||||
worker_pool,
|
||||
bound_task,
|
||||
|
@ -17,7 +17,7 @@ use super::{simple_scheduler::SimpleScheduler, worker::Worker, WorkItem, WorkPri
|
||||
use crate::{
|
||||
prelude::*,
|
||||
sched::priority::{Priority, PriorityRange},
|
||||
thread::kernel_thread::{create_new_kernel_task, ThreadOptions},
|
||||
thread::kernel_thread::ThreadOptions,
|
||||
Thread,
|
||||
};
|
||||
|
||||
@ -246,11 +246,10 @@ impl Monitor {
|
||||
WorkPriority::High => Priority::new(PriorityRange::new(0)),
|
||||
WorkPriority::Normal => Priority::default(),
|
||||
};
|
||||
let bound_task = create_new_kernel_task(
|
||||
ThreadOptions::new(task_fn)
|
||||
.cpu_affinity(cpu_affinity)
|
||||
.priority(priority),
|
||||
);
|
||||
let bound_task = ThreadOptions::new(task_fn)
|
||||
.cpu_affinity(cpu_affinity)
|
||||
.priority(priority)
|
||||
.build();
|
||||
Self {
|
||||
worker_pool,
|
||||
bound_task,
|
||||
|
Reference in New Issue
Block a user