mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-20 04:56:32 +00:00
Move Tid from Thread to PosixThread
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
ceb6e2b242
commit
81b0f265b5
@ -133,10 +133,7 @@ fn ap_init() -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init_thread() {
|
fn init_thread() {
|
||||||
println!(
|
println!("[kernel] Spawn init thread");
|
||||||
"[kernel] Spawn init thread, tid = {}",
|
|
||||||
current_thread!().tid()
|
|
||||||
);
|
|
||||||
// Work queue should be initialized before interrupt is enabled,
|
// Work queue should be initialized before interrupt is enabled,
|
||||||
// in case any irq handler uses work queue as bottom half
|
// in case any irq handler uses work queue as bottom half
|
||||||
thread::work_queue::init();
|
thread::work_queue::init();
|
||||||
@ -146,15 +143,8 @@ fn init_thread() {
|
|||||||
// driver::pci::virtio::block::block_device_test();
|
// driver::pci::virtio::block::block_device_test();
|
||||||
let thread = Thread::spawn_kernel_thread(ThreadOptions::new(|| {
|
let thread = Thread::spawn_kernel_thread(ThreadOptions::new(|| {
|
||||||
println!("[kernel] Hello world from kernel!");
|
println!("[kernel] Hello world from kernel!");
|
||||||
let current = current_thread!();
|
|
||||||
let tid = current.tid();
|
|
||||||
debug!("current tid = {}", tid);
|
|
||||||
}));
|
}));
|
||||||
thread.join();
|
thread.join();
|
||||||
info!(
|
|
||||||
"[aster-nix/lib.rs] spawn kernel thread, tid = {}",
|
|
||||||
thread.tid()
|
|
||||||
);
|
|
||||||
|
|
||||||
print_banner();
|
print_banner();
|
||||||
|
|
||||||
|
@ -18,7 +18,8 @@ use crate::{
|
|||||||
cpu::LinuxAbi,
|
cpu::LinuxAbi,
|
||||||
fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask},
|
fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
thread::{allocate_tid, thread_table, Thread, Tid},
|
process::posix_thread::allocate_posix_tid,
|
||||||
|
thread::{thread_table, Thread, Tid},
|
||||||
};
|
};
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
@ -180,7 +181,7 @@ fn clone_child_thread(
|
|||||||
// Inherit sigmask from current thread
|
// Inherit sigmask from current thread
|
||||||
let sig_mask = posix_thread.sig_mask().load(Ordering::Relaxed).into();
|
let sig_mask = posix_thread.sig_mask().load(Ordering::Relaxed).into();
|
||||||
|
|
||||||
let child_tid = allocate_tid();
|
let child_tid = allocate_posix_tid();
|
||||||
let child_thread = {
|
let child_thread = {
|
||||||
let credentials = {
|
let credentials = {
|
||||||
let credentials = ctx.posix_thread.credentials();
|
let credentials = ctx.posix_thread.credentials();
|
||||||
@ -262,7 +263,7 @@ fn clone_child_process(
|
|||||||
// inherit parent's nice value
|
// inherit parent's nice value
|
||||||
let child_nice = process.nice().load(Ordering::Relaxed);
|
let child_nice = process.nice().load(Ordering::Relaxed);
|
||||||
|
|
||||||
let child_tid = allocate_tid();
|
let child_tid = allocate_posix_tid();
|
||||||
|
|
||||||
let child = {
|
let child = {
|
||||||
let child_elf_path = process.executable_path();
|
let child_elf_path = process.executable_path();
|
||||||
@ -295,7 +296,7 @@ fn clone_child_process(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Deals with clone flags
|
// Deals with clone flags
|
||||||
let child_thread = thread_table::get_thread(child_tid).unwrap();
|
let child_thread = thread_table::get_posix_thread(child_tid).unwrap();
|
||||||
let child_posix_thread = child_thread.as_posix_thread().unwrap();
|
let child_posix_thread = child_thread.as_posix_thread().unwrap();
|
||||||
clone_parent_settid(child_tid, clone_args.parent_tidptr, clone_flags)?;
|
clone_parent_settid(child_tid, clone_args.parent_tidptr, clone_flags)?;
|
||||||
clone_child_cleartid(child_posix_thread, clone_args.child_tidptr, clone_flags)?;
|
clone_child_cleartid(child_posix_thread, clone_args.child_tidptr, clone_flags)?;
|
||||||
|
@ -4,7 +4,7 @@ use super::{process_table, Pid, Process, TermStatus};
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{
|
process::{
|
||||||
posix_thread::do_exit,
|
posix_thread::{do_exit, PosixThreadExt},
|
||||||
signal::{constants::SIGCHLD, signals::kernel::KernelSignal},
|
signal::{constants::SIGCHLD, signals::kernel::KernelSignal},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -20,7 +20,7 @@ pub fn do_exit_group(term_status: TermStatus) {
|
|||||||
// Exit all threads
|
// Exit all threads
|
||||||
let threads = current.threads().lock().clone();
|
let threads = current.threads().lock().clone();
|
||||||
for thread in threads {
|
for thread in threads {
|
||||||
if let Err(e) = do_exit(thread, term_status) {
|
if let Err(e) = do_exit(&thread, thread.as_posix_thread().unwrap(), term_status) {
|
||||||
debug!("Ignore error when call exit: {:?}", e);
|
debug!("Ignore error when call exit: {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ pub fn kill_group(pgid: Pgid, signal: Option<UserSignal>, ctx: &Context) -> Resu
|
|||||||
/// If `signal` is `None`, this method will only check permission without sending
|
/// If `signal` is `None`, this method will only check permission without sending
|
||||||
/// any signal.
|
/// any signal.
|
||||||
pub fn tgkill(tid: Tid, tgid: Pid, signal: Option<UserSignal>, ctx: &Context) -> Result<()> {
|
pub fn tgkill(tid: Tid, tgid: Pid, signal: Option<UserSignal>, ctx: &Context) -> Result<()> {
|
||||||
let thread = thread_table::get_thread(tid)
|
let thread = thread_table::get_posix_thread(tid)
|
||||||
.ok_or_else(|| Error::with_message(Errno::ESRCH, "target thread does not exist"))?;
|
.ok_or_else(|| Error::with_message(Errno::ESRCH, "target thread does not exist"))?;
|
||||||
|
|
||||||
if thread.status().is_exited() {
|
if thread.status().is_exited() {
|
||||||
|
@ -95,6 +95,7 @@ impl PosixThreadBuilder {
|
|||||||
|
|
||||||
let posix_thread = PosixThread {
|
let posix_thread = PosixThread {
|
||||||
process,
|
process,
|
||||||
|
tid,
|
||||||
name: Mutex::new(thread_name),
|
name: Mutex::new(thread_name),
|
||||||
set_child_tid: Mutex::new(set_child_tid),
|
set_child_tid: Mutex::new(set_child_tid),
|
||||||
clear_child_tid: Mutex::new(clear_child_tid),
|
clear_child_tid: Mutex::new(clear_child_tid),
|
||||||
@ -110,9 +111,9 @@ impl PosixThreadBuilder {
|
|||||||
prof_timer_manager,
|
prof_timer_manager,
|
||||||
};
|
};
|
||||||
|
|
||||||
Thread::new(tid, task, posix_thread, status)
|
Thread::new(task, posix_thread, status)
|
||||||
});
|
});
|
||||||
thread_table::add_thread(thread.clone());
|
thread_table::add_posix_thread(tid, thread.clone());
|
||||||
thread
|
thread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::{futex::futex_wake, robust_list::wake_robust_futex, PosixThread, PosixThreadExt};
|
use super::{futex::futex_wake, robust_list::wake_robust_futex, PosixThread};
|
||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{do_exit_group, TermStatus},
|
process::{do_exit_group, TermStatus},
|
||||||
@ -12,15 +12,13 @@ use crate::{
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// If the thread is not a POSIX thread, this method will panic.
|
/// If the thread is not a POSIX thread, this method will panic.
|
||||||
pub fn do_exit(thread: Arc<Thread>, term_status: TermStatus) -> Result<()> {
|
pub fn do_exit(thread: &Thread, posix_thread: &PosixThread, term_status: TermStatus) -> Result<()> {
|
||||||
if thread.status().is_exited() {
|
if thread.status().is_exited() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
thread.exit();
|
thread.exit();
|
||||||
|
|
||||||
let tid = thread.tid();
|
let tid = posix_thread.tid;
|
||||||
|
|
||||||
let posix_thread = thread.as_posix_thread().unwrap();
|
|
||||||
|
|
||||||
let mut clear_ctid = posix_thread.clear_child_tid().lock();
|
let mut clear_ctid = posix_thread.clear_child_tid().lock();
|
||||||
// If clear_ctid !=0 ,do a futex wake and write zero to the clear_ctid addr.
|
// If clear_ctid !=0 ,do a futex wake and write zero to the clear_ctid addr.
|
||||||
@ -38,7 +36,7 @@ pub fn do_exit(thread: Arc<Thread>, term_status: TermStatus) -> Result<()> {
|
|||||||
if tid != posix_thread.process().pid() {
|
if tid != posix_thread.process().pid() {
|
||||||
// We don't remove main thread.
|
// We don't remove main thread.
|
||||||
// The main thread is removed when the process is reaped.
|
// The main thread is removed when the process is reaped.
|
||||||
thread_table::remove_thread(tid);
|
thread_table::remove_posix_thread(tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if posix_thread.is_main_thread(tid) || posix_thread.is_last_thread() {
|
if posix_thread.is_main_thread(tid) || posix_thread.is_last_thread() {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use core::sync::atomic::Ordering;
|
use core::sync::atomic::{AtomicU32, Ordering};
|
||||||
|
|
||||||
use aster_rights::{ReadOp, WriteOp};
|
use aster_rights::{ReadOp, WriteOp};
|
||||||
use ostd::sync::Waker;
|
use ostd::sync::Waker;
|
||||||
@ -42,6 +42,8 @@ pub use robust_list::RobustListHead;
|
|||||||
pub struct PosixThread {
|
pub struct PosixThread {
|
||||||
// Immutable part
|
// Immutable part
|
||||||
process: Weak<Process>,
|
process: Weak<Process>,
|
||||||
|
tid: Tid,
|
||||||
|
|
||||||
// Mutable part
|
// Mutable part
|
||||||
name: Mutex<Option<ThreadName>>,
|
name: Mutex<Option<ThreadName>>,
|
||||||
|
|
||||||
@ -87,6 +89,11 @@ impl PosixThread {
|
|||||||
Weak::clone(&self.process)
|
Weak::clone(&self.process)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the thread id
|
||||||
|
pub fn tid(&self) -> Tid {
|
||||||
|
self.tid
|
||||||
|
}
|
||||||
|
|
||||||
pub fn thread_name(&self) -> &Mutex<Option<ThreadName>> {
|
pub fn thread_name(&self) -> &Mutex<Option<ThreadName>> {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
@ -292,3 +299,10 @@ impl PosixThread {
|
|||||||
self.credentials.dup().restrict()
|
self.credentials.dup().restrict()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static POSIX_TID_ALLOCATOR: AtomicU32 = AtomicU32::new(0);
|
||||||
|
|
||||||
|
/// Allocates a new tid for the new posix thread
|
||||||
|
pub fn allocate_posix_tid() -> Tid {
|
||||||
|
POSIX_TID_ALLOCATOR.fetch_add(1, Ordering::SeqCst)
|
||||||
|
}
|
||||||
|
@ -13,6 +13,14 @@ use crate::{
|
|||||||
thread::{Thread, Tid},
|
thread::{Thread, Tid},
|
||||||
};
|
};
|
||||||
pub trait PosixThreadExt {
|
pub trait PosixThreadExt {
|
||||||
|
/// Returns the thread id.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// If the thread is not posix thread, this method will panic.
|
||||||
|
fn tid(&self) -> Tid {
|
||||||
|
self.as_posix_thread().unwrap().tid()
|
||||||
|
}
|
||||||
fn as_posix_thread(&self) -> Option<&PosixThread>;
|
fn as_posix_thread(&self) -> Option<&PosixThread>;
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn new_posix_thread_from_executable(
|
fn new_posix_thread_from_executable(
|
||||||
|
@ -4,7 +4,7 @@ use core::sync::atomic::Ordering;
|
|||||||
|
|
||||||
use self::timer_manager::PosixTimerManager;
|
use self::timer_manager::PosixTimerManager;
|
||||||
use super::{
|
use super::{
|
||||||
posix_thread::PosixThreadExt,
|
posix_thread::{allocate_posix_tid, PosixThreadExt},
|
||||||
process_table,
|
process_table,
|
||||||
process_vm::{Heap, InitStackReader, ProcessVm},
|
process_vm::{Heap, InitStackReader, ProcessVm},
|
||||||
rlimit::ResourceLimits,
|
rlimit::ResourceLimits,
|
||||||
@ -21,7 +21,7 @@ use crate::{
|
|||||||
fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask},
|
fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
sched::nice::Nice,
|
sched::nice::Nice,
|
||||||
thread::{allocate_tid, Thread},
|
thread::Thread,
|
||||||
time::clocks::ProfClock,
|
time::clocks::ProfClock,
|
||||||
vm::vmar::Vmar,
|
vm::vmar::Vmar,
|
||||||
};
|
};
|
||||||
@ -236,7 +236,7 @@ impl Process {
|
|||||||
envp: Vec<CString>,
|
envp: Vec<CString>,
|
||||||
) -> Result<Arc<Self>> {
|
) -> Result<Arc<Self>> {
|
||||||
let process_builder = {
|
let process_builder = {
|
||||||
let pid = allocate_tid();
|
let pid = allocate_posix_tid();
|
||||||
let parent = Weak::new();
|
let parent = Weak::new();
|
||||||
|
|
||||||
let credentials = Credentials::new_root();
|
let credentials = Credentials::new_root();
|
||||||
@ -710,7 +710,7 @@ mod test {
|
|||||||
fn new_process(parent: Option<Arc<Process>>) -> Arc<Process> {
|
fn new_process(parent: Option<Arc<Process>>) -> Arc<Process> {
|
||||||
crate::util::random::init();
|
crate::util::random::init();
|
||||||
crate::fs::rootfs::init_root_mount();
|
crate::fs::rootfs::init_root_mount();
|
||||||
let pid = allocate_tid();
|
let pid = allocate_posix_tid();
|
||||||
let parent = if let Some(parent) = parent {
|
let parent = if let Some(parent) = parent {
|
||||||
Arc::downgrade(&parent)
|
Arc::downgrade(&parent)
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use super::{
|
use super::{process_filter::ProcessFilter, signal::constants::SIGCHLD, ExitCode, Pid, Process};
|
||||||
process_filter::ProcessFilter,
|
use crate::{
|
||||||
signal::{constants::SIGCHLD, with_signal_blocked},
|
prelude::*,
|
||||||
ExitCode, Pid, Process,
|
process::{posix_thread::PosixThreadExt, process_table, signal::with_signal_blocked},
|
||||||
|
thread::thread_table,
|
||||||
};
|
};
|
||||||
use crate::{prelude::*, process::process_table, thread::thread_table};
|
|
||||||
|
|
||||||
// The definition of WaitOptions is from Occlum
|
// The definition of WaitOptions is from Occlum
|
||||||
bitflags! {
|
bitflags! {
|
||||||
@ -86,7 +86,7 @@ fn reap_zombie_child(process: &Process, pid: Pid) -> ExitCode {
|
|||||||
let child_process = process.children().lock().remove(&pid).unwrap();
|
let child_process = process.children().lock().remove(&pid).unwrap();
|
||||||
assert!(child_process.is_zombie());
|
assert!(child_process.is_zombie());
|
||||||
for thread in &*child_process.threads().lock() {
|
for thread in &*child_process.threads().lock() {
|
||||||
thread_table::remove_thread(thread.tid());
|
thread_table::remove_posix_thread(thread.tid());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock order: session table -> group table -> process table -> group of process
|
// Lock order: session table -> group table -> process table -> group of process
|
||||||
|
@ -136,7 +136,7 @@ pub fn read_clock(clockid: clockid_t, ctx: &Context) -> Result<Duration> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicClockIdInfo::Tid(tid, clock_type) => {
|
DynamicClockIdInfo::Tid(tid, clock_type) => {
|
||||||
let thread = thread_table::get_thread(tid)
|
let thread = thread_table::get_posix_thread(tid)
|
||||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid clock ID"))?;
|
.ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid clock ID"))?;
|
||||||
let posix_thread = thread.as_posix_thread().unwrap();
|
let posix_thread = thread.as_posix_thread().unwrap();
|
||||||
match clock_type {
|
match clock_type {
|
||||||
|
@ -6,12 +6,11 @@ use crate::{
|
|||||||
syscall::SyscallReturn,
|
syscall::SyscallReturn,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_exit(exit_code: i32, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_exit(exit_code: i32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("exid code = {}", exit_code);
|
debug!("exid code = {}", exit_code);
|
||||||
|
|
||||||
let current_thread = current_thread!();
|
|
||||||
let term_status = TermStatus::Exited(exit_code as _);
|
let term_status = TermStatus::Exited(exit_code as _);
|
||||||
do_exit(current_thread, term_status)?;
|
do_exit(ctx.thread, ctx.posix_thread, term_status)?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,6 @@ pub fn sys_futex(
|
|||||||
_ => panic!("Unsupported futex operations"),
|
_ => panic!("Unsupported futex operations"),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
debug!("futex returns, tid= {} ", ctx.thread.tid());
|
debug!("futex returns, tid= {} ", ctx.posix_thread.tid());
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,6 @@ use super::SyscallReturn;
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_gettid(ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_gettid(ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let tid = ctx.thread.tid();
|
let tid = ctx.posix_thread.tid();
|
||||||
Ok(SyscallReturn::Return(tid as _))
|
Ok(SyscallReturn::Return(tid as _))
|
||||||
}
|
}
|
||||||
|
@ -345,7 +345,10 @@ macro_rules! log_syscall_entry {
|
|||||||
if log::log_enabled!(log::Level::Info) {
|
if log::log_enabled!(log::Level::Info) {
|
||||||
let syscall_name_str = stringify!($syscall_name);
|
let syscall_name_str = stringify!($syscall_name);
|
||||||
let pid = $crate::current!().pid();
|
let pid = $crate::current!().pid();
|
||||||
let tid = $crate::current_thread!().tid();
|
let tid = {
|
||||||
|
use $crate::process::posix_thread::PosixThreadExt;
|
||||||
|
$crate::current_thread!().tid()
|
||||||
|
};
|
||||||
log::info!(
|
log::info!(
|
||||||
"[pid={}][tid={}][id={}][{}]",
|
"[pid={}][tid={}][id={}][{}]",
|
||||||
pid,
|
pid,
|
||||||
|
@ -13,6 +13,6 @@ pub fn sys_set_tid_address(tidptr: Vaddr, ctx: &Context) -> Result<SyscallReturn
|
|||||||
} else {
|
} else {
|
||||||
*clear_child_tid = tidptr;
|
*clear_child_tid = tidptr;
|
||||||
}
|
}
|
||||||
let tid = ctx.thread.tid();
|
let tid = ctx.posix_thread.tid();
|
||||||
Ok(SyscallReturn::Return(tid as _))
|
Ok(SyscallReturn::Return(tid as _))
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ pub fn sys_timer_create(
|
|||||||
// Send a signal to the specified thread when the timer is expired.
|
// Send a signal to the specified thread when the timer is expired.
|
||||||
SigNotify::SIGEV_THREAD_ID => {
|
SigNotify::SIGEV_THREAD_ID => {
|
||||||
let tid = sig_event.sigev_un.read_tid() as u32;
|
let tid = sig_event.sigev_un.read_tid() as u32;
|
||||||
let thread = thread_table::get_thread(tid).ok_or_else(|| {
|
let thread = thread_table::get_posix_thread(tid).ok_or_else(|| {
|
||||||
Error::with_message(Errno::EINVAL, "target thread does not exist")
|
Error::with_message(Errno::EINVAL, "target thread does not exist")
|
||||||
})?;
|
})?;
|
||||||
let posix_thread = thread.as_posix_thread().unwrap();
|
let posix_thread = thread.as_posix_thread().unwrap();
|
||||||
@ -132,7 +132,7 @@ pub fn sys_timer_create(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicClockIdInfo::Tid(tid, clock_type) => {
|
DynamicClockIdInfo::Tid(tid, clock_type) => {
|
||||||
let thread = thread_table::get_thread(tid)
|
let thread = thread_table::get_posix_thread(tid)
|
||||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid clock id"))?;
|
.ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid clock id"))?;
|
||||||
let posix_thread = thread.as_posix_thread().unwrap();
|
let posix_thread = thread.as_posix_thread().unwrap();
|
||||||
match clock_type {
|
match clock_type {
|
||||||
|
@ -5,7 +5,7 @@ use ostd::{
|
|||||||
task::{Priority, TaskOptions},
|
task::{Priority, TaskOptions},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{allocate_tid, status::ThreadStatus, thread_table, Thread};
|
use super::{status::ThreadStatus, thread_table, Thread};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
/// The inner data of a kernel thread
|
/// The inner data of a kernel thread
|
||||||
@ -38,21 +38,21 @@ impl KernelThreadExt for Thread {
|
|||||||
let current_thread = current_thread!();
|
let current_thread = current_thread!();
|
||||||
// ensure the thread is exit
|
// ensure the thread is exit
|
||||||
current_thread.exit();
|
current_thread.exit();
|
||||||
|
thread_table::remove_kernel_thread(current_thread);
|
||||||
};
|
};
|
||||||
let tid = allocate_tid();
|
|
||||||
let thread = Arc::new_cyclic(|thread_ref| {
|
let thread = Arc::new_cyclic(|thread_ref| {
|
||||||
let weal_thread = thread_ref.clone();
|
let weak_thread = thread_ref.clone();
|
||||||
let task = TaskOptions::new(thread_fn)
|
let task = TaskOptions::new(thread_fn)
|
||||||
.data(weal_thread)
|
.data(weak_thread)
|
||||||
.priority(thread_options.priority)
|
.priority(thread_options.priority)
|
||||||
.cpu_affinity(thread_options.cpu_affinity)
|
.cpu_affinity(thread_options.cpu_affinity)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let status = ThreadStatus::Init;
|
let status = ThreadStatus::Init;
|
||||||
let kernel_thread = KernelThread;
|
let kernel_thread = KernelThread;
|
||||||
Thread::new(tid, task, kernel_thread, status)
|
Thread::new(task, kernel_thread, status)
|
||||||
});
|
});
|
||||||
thread_table::add_thread(thread.clone());
|
thread_table::add_kernel_thread(thread.clone());
|
||||||
thread
|
thread
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
//! Posix thread implementation
|
//! Posix thread implementation
|
||||||
|
|
||||||
use core::sync::atomic::{AtomicU32, Ordering};
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
use ostd::task::Task;
|
use ostd::task::Task;
|
||||||
|
|
||||||
@ -18,13 +18,9 @@ pub mod work_queue;
|
|||||||
|
|
||||||
pub type Tid = u32;
|
pub type Tid = u32;
|
||||||
|
|
||||||
static TID_ALLOCATOR: AtomicU32 = AtomicU32::new(0);
|
|
||||||
|
|
||||||
/// A thread is a wrapper on top of task.
|
/// A thread is a wrapper on top of task.
|
||||||
pub struct Thread {
|
pub struct Thread {
|
||||||
// immutable part
|
// immutable part
|
||||||
/// Thread id
|
|
||||||
tid: Tid,
|
|
||||||
/// Low-level info
|
/// Low-level info
|
||||||
task: Arc<Task>,
|
task: Arc<Task>,
|
||||||
/// Data: Posix thread info/Kernel thread Info
|
/// Data: Posix thread info/Kernel thread Info
|
||||||
@ -36,14 +32,8 @@ pub struct Thread {
|
|||||||
|
|
||||||
impl Thread {
|
impl Thread {
|
||||||
/// Never call these function directly
|
/// Never call these function directly
|
||||||
pub fn new(
|
pub fn new(task: Arc<Task>, data: impl Send + Sync + Any, status: ThreadStatus) -> Self {
|
||||||
tid: Tid,
|
|
||||||
task: Arc<Task>,
|
|
||||||
data: impl Send + Sync + Any,
|
|
||||||
status: ThreadStatus,
|
|
||||||
) -> Self {
|
|
||||||
Thread {
|
Thread {
|
||||||
tid,
|
|
||||||
task,
|
task,
|
||||||
data: Box::new(data),
|
data: Box::new(data),
|
||||||
status: AtomicThreadStatus::new(status),
|
status: AtomicThreadStatus::new(status),
|
||||||
@ -94,10 +84,6 @@ impl Thread {
|
|||||||
Task::yield_now()
|
Task::yield_now()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tid(&self) -> Tid {
|
|
||||||
self.tid
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the associated data.
|
/// Returns the associated data.
|
||||||
///
|
///
|
||||||
/// The return type must be borrowed box, otherwise the `downcast_ref` will fail.
|
/// The return type must be borrowed box, otherwise the `downcast_ref` will fail.
|
||||||
@ -106,8 +92,3 @@ impl Thread {
|
|||||||
&self.data
|
&self.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocates a new tid for the new thread
|
|
||||||
pub fn allocate_tid() -> Tid {
|
|
||||||
TID_ALLOCATOR.fetch_add(1, Ordering::SeqCst)
|
|
||||||
}
|
|
||||||
|
@ -47,7 +47,7 @@ pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>
|
|||||||
// in the child process.
|
// in the child process.
|
||||||
if is_userspace_vaddr(child_tid_ptr) {
|
if is_userspace_vaddr(child_tid_ptr) {
|
||||||
CurrentUserSpace::get()
|
CurrentUserSpace::get()
|
||||||
.write_val(child_tid_ptr, ¤t_thread.tid())
|
.write_val(child_tid_ptr, ¤t_posix_thread.tid())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>
|
|||||||
// If current is suspended, wait for a signal to wake up self
|
// If current is suspended, wait for a signal to wake up self
|
||||||
while current_thread.status().is_stopped() {
|
while current_thread.status().is_stopped() {
|
||||||
Thread::yield_now();
|
Thread::yield_now();
|
||||||
debug!("{} is suspended.", current_thread.tid());
|
debug!("{} is suspended.", current_posix_thread.tid());
|
||||||
handle_pending_signal(user_ctx, ¤t_thread).unwrap();
|
handle_pending_signal(user_ctx, ¤t_thread).unwrap();
|
||||||
}
|
}
|
||||||
if current_thread.status().is_exited() {
|
if current_thread.status().is_exited() {
|
||||||
|
@ -1,21 +1,30 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
use keyable_arc::KeyableArc;
|
||||||
|
|
||||||
use super::{Thread, Tid};
|
use super::{Thread, Tid};
|
||||||
use crate::prelude::*;
|
use crate::{prelude::*, process::posix_thread::PosixThreadExt};
|
||||||
|
|
||||||
lazy_static! {
|
static POSIX_THREAD_TABLE: SpinLock<BTreeMap<Tid, Arc<Thread>>> = SpinLock::new(BTreeMap::new());
|
||||||
static ref 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 add_thread(thread: Arc<Thread>) {
|
pub fn remove_posix_thread(tid: Tid) {
|
||||||
let tid = thread.tid();
|
POSIX_THREAD_TABLE.lock().remove(&tid);
|
||||||
THREAD_TABLE.lock().insert(tid, thread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_thread(tid: Tid) {
|
pub fn get_posix_thread(tid: Tid) -> Option<Arc<Thread>> {
|
||||||
THREAD_TABLE.lock().remove(&tid);
|
POSIX_THREAD_TABLE.lock().get(&tid).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_thread(tid: Tid) -> Option<Arc<Thread>> {
|
pub(super) fn add_kernel_thread(thread: Arc<Thread>) {
|
||||||
THREAD_TABLE.lock().get(&tid).cloned()
|
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));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user