mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-28 20:03:22 +00:00
Make task store Arc<Thread> and process store Arc<Task>
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
81b0f265b5
commit
f3174dbbbc
@ -2,23 +2,22 @@
|
||||
|
||||
use ostd::{
|
||||
cpu::CpuSet,
|
||||
task::{Priority, TaskOptions},
|
||||
task::{Priority, Task, TaskOptions},
|
||||
};
|
||||
|
||||
use super::{status::ThreadStatus, thread_table, Thread};
|
||||
use super::{status::ThreadStatus, Thread};
|
||||
use crate::prelude::*;
|
||||
|
||||
/// The inner data of a kernel thread
|
||||
pub struct KernelThread;
|
||||
|
||||
pub trait KernelThreadExt {
|
||||
/// get the kernel_thread structure
|
||||
/// Gets the kernel_thread structure
|
||||
fn as_kernel_thread(&self) -> Option<&KernelThread>;
|
||||
/// create a new kernel thread structure, **NOT** run the thread.
|
||||
fn new_kernel_thread(thread_options: ThreadOptions) -> Arc<Thread>;
|
||||
/// create a new kernel thread structure, and then run the thread.
|
||||
/// Creates a new kernel thread, and then run the thread.
|
||||
fn spawn_kernel_thread(thread_options: ThreadOptions) -> Arc<Thread> {
|
||||
let thread = Self::new_kernel_thread(thread_options);
|
||||
let task = create_new_kernel_task(thread_options);
|
||||
let thread = Thread::borrow_from_task(&task).clone();
|
||||
thread.run();
|
||||
thread
|
||||
}
|
||||
@ -31,31 +30,6 @@ impl KernelThreadExt for Thread {
|
||||
self.data().downcast_ref::<KernelThread>()
|
||||
}
|
||||
|
||||
fn new_kernel_thread(mut thread_options: ThreadOptions) -> Arc<Self> {
|
||||
let task_fn = thread_options.take_func();
|
||||
let thread_fn = move || {
|
||||
task_fn();
|
||||
let current_thread = current_thread!();
|
||||
// ensure the thread is exit
|
||||
current_thread.exit();
|
||||
thread_table::remove_kernel_thread(current_thread);
|
||||
};
|
||||
let thread = Arc::new_cyclic(|thread_ref| {
|
||||
let weak_thread = thread_ref.clone();
|
||||
let task = TaskOptions::new(thread_fn)
|
||||
.data(weak_thread)
|
||||
.priority(thread_options.priority)
|
||||
.cpu_affinity(thread_options.cpu_affinity)
|
||||
.build()
|
||||
.unwrap();
|
||||
let status = ThreadStatus::Init;
|
||||
let kernel_thread = KernelThread;
|
||||
Thread::new(task, kernel_thread, status)
|
||||
});
|
||||
thread_table::add_kernel_thread(thread.clone());
|
||||
thread
|
||||
}
|
||||
|
||||
fn join(&self) {
|
||||
loop {
|
||||
if self.status().is_exited() {
|
||||
@ -67,6 +41,31 @@ impl KernelThreadExt for Thread {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 || {
|
||||
task_fn();
|
||||
// Ensures the thread is exit
|
||||
current_thread!().exit();
|
||||
};
|
||||
|
||||
Arc::new_cyclic(|weak_task| {
|
||||
let thread = {
|
||||
let kernel_thread = KernelThread;
|
||||
let status = ThreadStatus::Init;
|
||||
Arc::new(Thread::new(weak_task.clone(), kernel_thread, status))
|
||||
};
|
||||
|
||||
TaskOptions::new(thread_fn)
|
||||
.data(thread)
|
||||
.priority(thread_options.priority)
|
||||
.cpu_affinity(thread_options.cpu_affinity)
|
||||
.build()
|
||||
.unwrap()
|
||||
})
|
||||
}
|
||||
|
||||
/// Options to create or spawn a new thread.
|
||||
pub struct ThreadOptions {
|
||||
func: Option<Box<dyn Fn() + Send + Sync>>,
|
||||
|
@ -13,7 +13,6 @@ pub mod exception;
|
||||
pub mod kernel_thread;
|
||||
pub mod status;
|
||||
pub mod task;
|
||||
pub mod thread_table;
|
||||
pub mod work_queue;
|
||||
|
||||
pub type Tid = u32;
|
||||
@ -22,7 +21,7 @@ pub type Tid = u32;
|
||||
pub struct Thread {
|
||||
// immutable part
|
||||
/// Low-level info
|
||||
task: Arc<Task>,
|
||||
task: Weak<Task>,
|
||||
/// Data: Posix thread info/Kernel thread Info
|
||||
data: Box<dyn Send + Sync + Any>,
|
||||
|
||||
@ -32,7 +31,7 @@ pub struct Thread {
|
||||
|
||||
impl Thread {
|
||||
/// Never call these function directly
|
||||
pub fn new(task: Arc<Task>, data: impl Send + Sync + Any, status: ThreadStatus) -> Self {
|
||||
pub fn new(task: Weak<Task>, data: impl Send + Sync + Any, status: ThreadStatus) -> Self {
|
||||
Thread {
|
||||
task,
|
||||
data: Box::new(data),
|
||||
@ -47,18 +46,23 @@ impl Thread {
|
||||
pub fn current() -> Option<Arc<Self>> {
|
||||
Task::current()?
|
||||
.data()
|
||||
.downcast_ref::<Weak<Thread>>()?
|
||||
.upgrade()
|
||||
.downcast_ref::<Arc<Thread>>()
|
||||
.cloned()
|
||||
}
|
||||
|
||||
pub(in crate::thread) fn task(&self) -> &Arc<Task> {
|
||||
&self.task
|
||||
/// Gets the Thread from task's data.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This method panics if the task is not a thread.
|
||||
pub fn borrow_from_task(task: &Arc<Task>) -> &Arc<Self> {
|
||||
task.data().downcast_ref::<Arc<Thread>>().unwrap()
|
||||
}
|
||||
|
||||
/// Runs this thread at once.
|
||||
pub fn run(&self) {
|
||||
self.set_status(ThreadStatus::Running);
|
||||
self.task.run();
|
||||
self.task.upgrade().unwrap().run();
|
||||
}
|
||||
|
||||
pub(super) fn exit(&self) {
|
||||
|
@ -16,12 +16,12 @@ use crate::{
|
||||
};
|
||||
|
||||
/// create new task with userspace and parent process
|
||||
pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>) -> Arc<Task> {
|
||||
pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Arc<Thread>) -> Task {
|
||||
fn user_task_entry() {
|
||||
let current_thread = current_thread!();
|
||||
let current_posix_thread = current_thread.as_posix_thread().unwrap();
|
||||
let current_process = current_posix_thread.process();
|
||||
let current_task = current_thread.task();
|
||||
let current_task = Task::current().unwrap();
|
||||
|
||||
let user_space = current_task
|
||||
.user_space()
|
||||
|
@ -1,30 +0,0 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use keyable_arc::KeyableArc;
|
||||
|
||||
use super::{Thread, Tid};
|
||||
use crate::{prelude::*, process::posix_thread::PosixThreadExt};
|
||||
|
||||
static POSIX_THREAD_TABLE: SpinLock<BTreeMap<Tid, Arc<Thread>>> = SpinLock::new(BTreeMap::new());
|
||||
static KERNEL_THREAD_TABLE: SpinLock<BTreeSet<KeyableArc<Thread>>> = SpinLock::new(BTreeSet::new());
|
||||
|
||||
pub fn add_posix_thread(tid: Tid, thread: Arc<Thread>) {
|
||||
debug_assert_eq!(tid, thread.tid());
|
||||
POSIX_THREAD_TABLE.lock().insert(tid, thread);
|
||||
}
|
||||
|
||||
pub fn remove_posix_thread(tid: Tid) {
|
||||
POSIX_THREAD_TABLE.lock().remove(&tid);
|
||||
}
|
||||
|
||||
pub fn get_posix_thread(tid: Tid) -> Option<Arc<Thread>> {
|
||||
POSIX_THREAD_TABLE.lock().get(&tid).cloned()
|
||||
}
|
||||
|
||||
pub(super) fn add_kernel_thread(thread: Arc<Thread>) {
|
||||
KERNEL_THREAD_TABLE.lock().insert(KeyableArc::from(thread));
|
||||
}
|
||||
|
||||
pub(super) fn remove_kernel_thread(thread: Arc<Thread>) {
|
||||
KERNEL_THREAD_TABLE.lock().remove(&KeyableArc::from(thread));
|
||||
}
|
@ -2,12 +2,15 @@
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use ostd::{cpu::CpuSet, task::Priority};
|
||||
use ostd::{
|
||||
cpu::CpuSet,
|
||||
task::{Priority, Task},
|
||||
};
|
||||
|
||||
use super::worker_pool::WorkerPool;
|
||||
use crate::{
|
||||
prelude::*,
|
||||
thread::kernel_thread::{KernelThreadExt, ThreadOptions},
|
||||
thread::kernel_thread::{create_new_kernel_task, ThreadOptions},
|
||||
Thread,
|
||||
};
|
||||
|
||||
@ -17,7 +20,7 @@ use crate::{
|
||||
/// added to the `WorkerPool`.
|
||||
pub(super) struct Worker {
|
||||
worker_pool: Weak<WorkerPool>,
|
||||
bound_thread: Arc<Thread>,
|
||||
bound_task: Arc<Task>,
|
||||
bound_cpu: u32,
|
||||
inner: SpinLock<WorkerInner>,
|
||||
}
|
||||
@ -51,14 +54,14 @@ impl Worker {
|
||||
if worker_pool.upgrade().unwrap().is_high_priority() {
|
||||
priority = Priority::high();
|
||||
}
|
||||
let bound_thread = Thread::new_kernel_thread(
|
||||
let bound_task = create_new_kernel_task(
|
||||
ThreadOptions::new(task_fn)
|
||||
.cpu_affinity(cpu_affinity)
|
||||
.priority(priority),
|
||||
);
|
||||
Self {
|
||||
worker_pool,
|
||||
bound_thread,
|
||||
bound_task,
|
||||
bound_cpu,
|
||||
inner: SpinLock::new(WorkerInner {
|
||||
worker_status: WorkerStatus::Running,
|
||||
@ -68,7 +71,8 @@ impl Worker {
|
||||
}
|
||||
|
||||
pub(super) fn run(&self) {
|
||||
self.bound_thread.run();
|
||||
let thread = Thread::borrow_from_task(&self.bound_task);
|
||||
thread.run();
|
||||
}
|
||||
|
||||
/// The thread function bound to normal workers.
|
||||
@ -97,8 +101,8 @@ impl Worker {
|
||||
self.exit();
|
||||
}
|
||||
|
||||
pub(super) fn bound_thread(&self) -> &Arc<Thread> {
|
||||
&self.bound_thread
|
||||
pub(super) fn bound_task(&self) -> &Arc<Task> {
|
||||
&self.bound_task
|
||||
}
|
||||
|
||||
pub(super) fn is_idle(&self) -> bool {
|
||||
|
@ -7,12 +7,16 @@ use core::{
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use ostd::{cpu::CpuSet, sync::WaitQueue, task::Priority};
|
||||
use ostd::{
|
||||
cpu::CpuSet,
|
||||
sync::WaitQueue,
|
||||
task::{Priority, Task},
|
||||
};
|
||||
|
||||
use super::{simple_scheduler::SimpleScheduler, worker::Worker, WorkItem, WorkPriority, WorkQueue};
|
||||
use crate::{
|
||||
prelude::*,
|
||||
thread::kernel_thread::{KernelThreadExt, ThreadOptions},
|
||||
thread::kernel_thread::{create_new_kernel_task, ThreadOptions},
|
||||
Thread,
|
||||
};
|
||||
|
||||
@ -60,7 +64,7 @@ pub trait WorkerScheduler: Sync + Send {
|
||||
/// are found processing in the pool.
|
||||
pub struct Monitor {
|
||||
worker_pool: Weak<WorkerPool>,
|
||||
bound_thread: Arc<Thread>,
|
||||
bound_task: Arc<Task>,
|
||||
}
|
||||
|
||||
impl LocalWorkerPool {
|
||||
@ -77,7 +81,7 @@ impl LocalWorkerPool {
|
||||
fn add_worker(&self) {
|
||||
let worker = Worker::new(self.parent.clone(), self.cpu_id);
|
||||
self.workers.disable_irq().lock().push_back(worker.clone());
|
||||
worker.bound_thread().run();
|
||||
Thread::borrow_from_task(worker.bound_task()).run();
|
||||
}
|
||||
|
||||
fn remove_worker(&self) {
|
||||
@ -236,20 +240,20 @@ impl Monitor {
|
||||
WorkPriority::High => Priority::high(),
|
||||
WorkPriority::Normal => Priority::normal(),
|
||||
};
|
||||
let bound_thread = Thread::new_kernel_thread(
|
||||
let bound_task = create_new_kernel_task(
|
||||
ThreadOptions::new(task_fn)
|
||||
.cpu_affinity(cpu_affinity)
|
||||
.priority(priority),
|
||||
);
|
||||
Self {
|
||||
worker_pool,
|
||||
bound_thread,
|
||||
bound_task,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn run(&self) {
|
||||
self.bound_thread.run();
|
||||
Thread::borrow_from_task(&self.bound_task).run()
|
||||
}
|
||||
|
||||
fn run_monitor_loop(self: &Arc<Self>) {
|
||||
|
Reference in New Issue
Block a user