mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2025-12-23 22:47:55 -05:00
Merge pull request #75 from arihant2math/fix-thread-join
This commit is contained in:
@@ -169,7 +169,7 @@ pub async fn handle_syscall() {
|
||||
}
|
||||
0x50 => sys_fstat(arg1.into(), TUA::from_value(arg2 as _)).await,
|
||||
0x51 => sys_sync().await,
|
||||
0x5d => sys_exit(arg1 as _),
|
||||
0x5d => sys_exit(arg1 as _).await,
|
||||
0x5e => sys_exit_group(arg1 as _),
|
||||
0x60 => sys_set_tid_address(VA::from_value(arg1 as _)).await,
|
||||
0x62 => {
|
||||
@@ -255,8 +255,8 @@ pub async fn handle_syscall() {
|
||||
sys_clone(
|
||||
arg1 as _,
|
||||
UA::from_value(arg2 as _),
|
||||
UA::from_value(arg3 as _),
|
||||
UA::from_value(arg5 as _),
|
||||
TUA::from_value(arg3 as _),
|
||||
TUA::from_value(arg5 as _),
|
||||
arg4 as _,
|
||||
)
|
||||
.await
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
use super::{ctx::Context, thread_group::signal::SigSet};
|
||||
use crate::memory::uaccess::copy_to_user;
|
||||
use crate::{
|
||||
process::{TASK_LIST, Task, TaskState},
|
||||
sched::{self, current_task},
|
||||
sync::SpinLock,
|
||||
};
|
||||
use bitflags::bitflags;
|
||||
use libkernel::memory::address::TUA;
|
||||
use libkernel::{
|
||||
error::{KernelError, Result},
|
||||
memory::address::UA,
|
||||
};
|
||||
use ringbuf::Arc;
|
||||
|
||||
use super::{ctx::Context, thread_group::signal::SigSet};
|
||||
|
||||
bitflags! {
|
||||
#[derive(Debug)]
|
||||
pub struct CloneFlags: u32 {
|
||||
@@ -44,8 +45,8 @@ bitflags! {
|
||||
pub async fn sys_clone(
|
||||
flags: u32,
|
||||
newsp: UA,
|
||||
_arent_tidptr: UA,
|
||||
_child_tidptr: UA,
|
||||
parent_tidptr: TUA<u32>,
|
||||
child_tidptr: TUA<u32>,
|
||||
tls: usize,
|
||||
) -> Result<usize> {
|
||||
let flags = CloneFlags::from_bits_truncate(flags);
|
||||
@@ -146,6 +147,11 @@ pub async fn sys_clone(
|
||||
state: Arc::new(SpinLock::new(TaskState::Runnable)),
|
||||
last_run: SpinLock::new(None),
|
||||
robust_list: SpinLock::new(None),
|
||||
child_tid_ptr: SpinLock::new(if !child_tidptr.is_null() {
|
||||
Some(child_tidptr)
|
||||
} else {
|
||||
None
|
||||
}),
|
||||
}
|
||||
};
|
||||
|
||||
@@ -157,5 +163,13 @@ pub async fn sys_clone(
|
||||
|
||||
sched::insert_task(Arc::new(new_task));
|
||||
|
||||
// Honour CLONE_*SETTID semantics for the parent and (shared-VM) child.
|
||||
if flags.contains(CloneFlags::CLONE_PARENT_SETTID) && !parent_tidptr.is_null() {
|
||||
copy_to_user(parent_tidptr, tid.value()).await?;
|
||||
}
|
||||
if flags.contains(CloneFlags::CLONE_CHILD_SETTID) && !child_tidptr.is_null() {
|
||||
copy_to_user(child_tidptr, tid.value()).await?;
|
||||
}
|
||||
|
||||
Ok(tid.value() as _)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use crate::sched::current_task;
|
||||
use alloc::vec::Vec;
|
||||
use libkernel::error::Result;
|
||||
use ringbuf::Arc;
|
||||
|
||||
use super::{
|
||||
TaskState,
|
||||
thread_group::{ProcessState, Tgid, ThreadGroup, signal::SigId, wait::ChildState},
|
||||
};
|
||||
use crate::memory::uaccess::copy_to_user;
|
||||
use crate::process::threading::futex_wake_addr;
|
||||
use crate::sched::current_task;
|
||||
use alloc::vec::Vec;
|
||||
use libkernel::error::Result;
|
||||
use ringbuf::Arc;
|
||||
|
||||
pub fn do_exit_group(exit_code: ChildState) {
|
||||
let task = current_task();
|
||||
@@ -99,8 +100,18 @@ pub fn sys_exit_group(exit_code: usize) -> Result<usize> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn sys_exit(exit_code: usize) -> Result<usize> {
|
||||
pub async fn sys_exit(exit_code: usize) -> Result<usize> {
|
||||
let task = current_task();
|
||||
|
||||
// Honour CLONE_CHILD_CLEARTID: clear the user TID word and futex-wake any waiters.
|
||||
let ptr = task.child_tid_ptr.lock_save_irq().take();
|
||||
if let Some(ptr) = ptr {
|
||||
copy_to_user(ptr, 0u32).await?;
|
||||
|
||||
// Wake any thread waiting on this futex.
|
||||
futex_wake_addr(ptr, 1);
|
||||
}
|
||||
|
||||
let process = Arc::clone(&task.process);
|
||||
let mut thread_lock = process.threads.lock_save_irq();
|
||||
|
||||
|
||||
@@ -181,6 +181,7 @@ pub struct Task {
|
||||
pub last_run: SpinLock<Option<Instant>>,
|
||||
pub state: Arc<SpinLock<TaskState>>,
|
||||
pub robust_list: SpinLock<Option<TUA<RobustListHead>>>,
|
||||
pub child_tid_ptr: SpinLock<Option<TUA<u32>>>,
|
||||
}
|
||||
|
||||
impl Task {
|
||||
@@ -214,6 +215,7 @@ impl Task {
|
||||
fd_table: Arc::new(SpinLock::new(FileDescriptorTable::new())),
|
||||
last_run: SpinLock::new(None),
|
||||
robust_list: SpinLock::new(None),
|
||||
child_tid_ptr: SpinLock::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,6 +243,7 @@ impl Task {
|
||||
)),
|
||||
last_run: SpinLock::new(None),
|
||||
robust_list: SpinLock::new(None),
|
||||
child_tid_ptr: SpinLock::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,25 @@ const FUTEX_WAIT_BITSET: i32 = 9;
|
||||
const FUTEX_WAKE_BITSET: i32 = 10;
|
||||
const FUTEX_PRIVATE_FLAG: i32 = 128;
|
||||
|
||||
/// Wake up to `nr` waiters sleeping on the futex word located at `uaddr`.
|
||||
/// Returns the number of tasks actually woken.
|
||||
pub fn futex_wake_addr(uaddr: TUA<u32>, nr: usize) -> usize {
|
||||
let mut woke = 0;
|
||||
|
||||
if let Some(table) = FUTEX_TABLE.get()
|
||||
&& let Some(waitq_arc) = table.lock_save_irq().get(&uaddr).cloned()
|
||||
{
|
||||
let mut waitq = waitq_arc.lock_save_irq();
|
||||
for _ in 0..nr {
|
||||
waitq.wakeups = waitq.wakeups.saturating_add(1);
|
||||
waitq.wakers.wake_one();
|
||||
woke += 1;
|
||||
}
|
||||
}
|
||||
|
||||
woke
|
||||
}
|
||||
|
||||
pub async fn sys_futex(
|
||||
uaddr: TUA<u32>,
|
||||
op: i32,
|
||||
@@ -132,21 +151,7 @@ pub async fn sys_futex(
|
||||
|
||||
FUTEX_WAKE | FUTEX_WAKE_BITSET => {
|
||||
let nr_wake = val as usize;
|
||||
let mut woke = 0;
|
||||
|
||||
if let Some(table) = FUTEX_TABLE.get()
|
||||
&& let Some(waitq_arc) = table.lock_save_irq().get(&uaddr).cloned()
|
||||
{
|
||||
let mut waitq = waitq_arc.lock_save_irq();
|
||||
for _ in 0..nr_wake {
|
||||
// Record a pending wake-up and attempt to wake a single waiter.
|
||||
waitq.wakeups = waitq.wakeups.saturating_add(1);
|
||||
waitq.wakers.wake_one();
|
||||
woke += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(woke)
|
||||
Ok(futex_wake_addr(uaddr, nr_wake))
|
||||
}
|
||||
|
||||
_ => Err(KernelError::NotSupported),
|
||||
|
||||
Reference in New Issue
Block a user