asterinas/kernel/src/thread/mod.rs

114 lines
2.6 KiB
Rust
Raw Normal View History

2024-01-03 03:22:36 +00:00
// SPDX-License-Identifier: MPL-2.0
2022-12-15 06:53:43 +00:00
//! Posix thread implementation
use core::sync::atomic::{AtomicU32, Ordering};
2022-12-15 06:53:43 +00:00
2024-06-19 08:18:39 +00:00
use ostd::task::Task;
2022-12-15 06:53:43 +00:00
use self::status::{AtomicThreadStatus, ThreadStatus};
use crate::prelude::*;
2022-12-20 06:12:22 +00:00
pub mod exception;
pub mod kernel_thread;
pub mod status;
2022-12-15 06:53:43 +00:00
pub mod task;
2022-12-20 06:12:22 +00:00
pub mod thread_table;
pub mod work_queue;
2022-12-15 06:53:43 +00:00
pub type Tid = u32;
2022-12-15 06:53:43 +00:00
static TID_ALLOCATOR: AtomicU32 = AtomicU32::new(0);
2022-12-20 06:12:22 +00:00
2022-12-15 06:53:43 +00:00
/// A thread is a wrapper on top of task.
pub struct Thread {
2022-12-20 06:12:22 +00:00
// immutable part
2022-12-15 06:53:43 +00:00
/// Thread id
tid: Tid,
/// Low-level info
task: Arc<Task>,
2022-12-20 06:12:22 +00:00
/// Data: Posix thread info/Kernel thread Info
data: Box<dyn Send + Sync + Any>,
// mutable part
status: AtomicThreadStatus,
2022-12-15 06:53:43 +00:00
}
impl Thread {
2022-12-20 06:12:22 +00:00
/// Never call these function directly
pub fn new(
2022-12-15 06:53:43 +00:00
tid: Tid,
2022-12-20 06:12:22 +00:00
task: Arc<Task>,
data: impl Send + Sync + Any,
status: ThreadStatus,
) -> Self {
Thread {
tid,
task,
data: Box::new(data),
status: AtomicThreadStatus::new(status),
2022-12-20 06:12:22 +00:00
}
2022-12-15 06:53:43 +00:00
}
/// Returns the current thread.
2024-07-10 17:41:24 +00:00
///
/// This function returns `None` if the current task is not associated with
/// a thread, or if called within the bootstrap context.
2024-07-10 17:41:24 +00:00
pub fn current() -> Option<Arc<Self>> {
Task::current()?
2022-12-15 06:53:43 +00:00
.data()
2024-07-10 17:41:24 +00:00
.downcast_ref::<Weak<Thread>>()?
2022-12-15 06:53:43 +00:00
.upgrade()
}
pub(in crate::thread) fn task(&self) -> &Arc<Task> {
&self.task
}
/// Runs this thread at once.
2022-12-15 06:53:43 +00:00
pub fn run(&self) {
self.set_status(ThreadStatus::Running);
2022-12-15 06:53:43 +00:00
self.task.run();
}
pub(super) fn exit(&self) {
self.set_status(ThreadStatus::Exited);
2022-12-20 06:12:22 +00:00
}
/// Returns the reference to the atomic status.
pub fn atomic_status(&self) -> &AtomicThreadStatus {
&self.status
2023-09-01 03:40:22 +00:00
}
/// Returns the current status.
pub fn status(&self) -> ThreadStatus {
self.status.load(Ordering::Acquire)
}
/// Updates the status with the `new` value.
pub fn set_status(&self, new_status: ThreadStatus) {
self.status.store(new_status, Ordering::Release);
2022-12-20 06:12:22 +00:00
}
2022-12-15 06:53:43 +00:00
pub fn yield_now() {
Task::yield_now()
}
2022-12-20 06:12:22 +00:00
pub fn tid(&self) -> Tid {
self.tid
}
/// Returns the associated data.
///
/// The return type must be borrowed box, otherwise the `downcast_ref` will fail.
2023-09-04 03:04:42 +00:00
#[allow(clippy::borrowed_box)]
2022-12-20 06:12:22 +00:00
pub fn data(&self) -> &Box<dyn Send + Sync + Any> {
&self.data
}
}
/// Allocates a new tid for the new thread
2022-12-20 06:12:22 +00:00
pub fn allocate_tid() -> Tid {
TID_ALLOCATOR.fetch_add(1, Ordering::SeqCst)
2022-12-15 06:53:43 +00:00
}