// SPDX-License-Identifier: MPL-2.0 //! Posix thread implementation use core::sync::atomic::{AtomicU32, Ordering}; use aster_frame::task::Task; use self::status::{AtomicThreadStatus, ThreadStatus}; use crate::prelude::*; 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; static TID_ALLOCATOR: AtomicU32 = AtomicU32::new(0); /// A thread is a wrapper on top of task. pub struct Thread { // immutable part /// Thread id tid: Tid, /// Low-level info task: Arc, /// Data: Posix thread info/Kernel thread Info data: Box, // mutable part status: AtomicThreadStatus, } impl Thread { /// Never call these function directly pub fn new( tid: Tid, task: Arc, data: impl Send + Sync + Any, status: ThreadStatus, ) -> Self { Thread { tid, task, data: Box::new(data), status: AtomicThreadStatus::new(status), } } pub fn current() -> Arc { let task = Task::current(); let thread = task .data() .downcast_ref::>() .expect("[Internal Error] task data should points to weak"); thread .upgrade() .expect("[Internal Error] current thread cannot be None") } pub(in crate::thread) fn task(&self) -> &Arc { &self.task } /// Run this thread at once. pub fn run(&self) { self.set_status(ThreadStatus::Running); self.task.run(); } pub fn exit(&self) { self.set_status(ThreadStatus::Exited); } /// Returns the reference to the atomic status. pub fn atomic_status(&self) -> &AtomicThreadStatus { &self.status } /// 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); } pub fn yield_now() { Task::yield_now() } pub fn tid(&self) -> Tid { self.tid } // The return type must be borrowed box, otherwise the downcast_ref will fail #[allow(clippy::borrowed_box)] pub fn data(&self) -> &Box { &self.data } } /// allocate a new pid for new process pub fn allocate_tid() -> Tid { TID_ALLOCATOR.fetch_add(1, Ordering::SeqCst) }