增加gettid以及线程组group leader相关的逻辑 (#430)

* 增加gettid以及线程组group leader相关的逻辑
This commit is contained in:
LoGin 2023-11-09 16:48:45 +08:00 committed by GitHub
parent 0facf623d6
commit 393f691574
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 99 additions and 11 deletions

View File

@ -24,9 +24,10 @@ pub const STACK_ALIGN: u64 = 16;
/// 信号最大值
pub const MAX_SIG_NUM: usize = 64;
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, Eq)]
#[derive(Eq)]
#[repr(usize)]
#[allow(non_camel_case_types)]
#[atomic_enum]
pub enum Signal {
INVALID = 0,
SIGHUP = 1,

View File

@ -57,6 +57,8 @@ mod virt;
#[macro_use]
extern crate alloc;
#[macro_use]
extern crate atomic_enum;
#[macro_use]
extern crate bitflags;
extern crate elf;
#[macro_use]

View File

@ -197,7 +197,7 @@ pub trait Socket: Sync + Send + Debug {
_optval: &[u8],
) -> Result<(), SystemError> {
kwarn!("setsockopt is not implemented");
return Err(SystemError::ENOSYS);
return Ok(());
}
}

View File

@ -1,7 +1,9 @@
use core::{intrinsics::unlikely, sync::atomic::Ordering};
use alloc::{string::ToString, sync::Arc};
use crate::{
arch::interrupt::TrapFrame,
arch::{interrupt::TrapFrame, ipc::signal::Signal},
filesystem::procfs::procfs_register_pid,
ipc::signal::flush_signal_handlers,
libs::rwlock::RwLock,
@ -88,7 +90,8 @@ pub struct KernelCloneArgs {
pub parent_tid: VirtAddr,
pub set_tid: VirtAddr,
pub exit_signal: i32,
/// 进程退出时发送的信号
pub exit_signal: Signal,
pub stack: usize,
// clone3用到
@ -115,7 +118,7 @@ impl KernelCloneArgs {
child_tid: null_addr,
parent_tid: null_addr,
set_tid: null_addr,
exit_signal: 0,
exit_signal: Signal::SIGCHLD,
stack: 0,
stack_size: 0,
tls: 0,
@ -157,6 +160,8 @@ impl ProcessManager {
let mut args = KernelCloneArgs::new();
args.flags = clone_flags;
args.exit_signal = Signal::SIGCHLD;
Self::copy_process(&current_pcb, &pcb, args, current_trapframe)?;
ProcessManager::add_pcb(pcb.clone());
@ -394,7 +399,13 @@ impl ProcessManager {
)
});
// todo: 拷贝信号相关数据
// 拷贝信号相关数据
Self::copy_sighand(&clone_flags, &current_pcb, &pcb).map_err(|e| {
panic!(
"fork: Failed to copy sighand from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
current_pcb.pid(), pcb.pid(), e
)
})?;
// 拷贝线程
Self::copy_thread(&current_pcb, &pcb, clone_args,&current_trapframe).unwrap_or_else(|e| {
@ -404,6 +415,50 @@ impl ProcessManager {
)
});
// 设置线程组id、组长
if clone_flags.contains(CloneFlags::CLONE_THREAD) {
pcb.thread.write().group_leader = current_pcb.thread.read().group_leader.clone();
unsafe {
let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
(*ptr).tgid = current_pcb.tgid;
}
} else {
pcb.thread.write().group_leader = Arc::downgrade(&pcb);
unsafe {
let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
(*ptr).tgid = pcb.tgid;
}
}
// CLONE_PARENT re-uses the old parent
if clone_flags.contains(CloneFlags::CLONE_PARENT | CloneFlags::CLONE_THREAD) {
*pcb.real_parent_pcb.write() = current_pcb.real_parent_pcb.read().clone();
if clone_flags.contains(CloneFlags::CLONE_THREAD) {
pcb.exit_signal.store(Signal::INVALID, Ordering::SeqCst);
} else {
let leader = current_pcb.thread.read().group_leader();
if unlikely(leader.is_none()) {
panic!(
"fork: Failed to get leader of current process, current pid: [{:?}]",
current_pcb.pid()
);
}
pcb.exit_signal.store(
leader.unwrap().exit_signal.load(Ordering::SeqCst),
Ordering::SeqCst,
);
}
} else {
// 新创建的进程,设置其父进程为当前进程
*pcb.real_parent_pcb.write() = Arc::downgrade(&current_pcb);
pcb.exit_signal
.store(clone_args.exit_signal, Ordering::SeqCst);
}
// todo: 增加线程组相关的逻辑。 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/kernel/fork.c#2437
Ok(())
}
}

View File

@ -15,7 +15,7 @@ use hashbrown::HashMap;
use crate::{
arch::{
ipc::signal::{SigSet, Signal},
ipc::signal::{AtomicSignal, SigSet, Signal},
process::ArchPCBInfo,
sched::sched,
CurrentIrqArch,
@ -308,7 +308,8 @@ impl ProcessManager {
parent_pcb.pid()
);
}
// todo: 当信号机制重写后这里需要向父进程发送SIGCHLD信号
// todo: 这里需要向父进程发送SIGCHLD信号
// todo: 这里还需要根据线程组的信息,决定信号的发送
}
}
@ -511,6 +512,8 @@ bitflags! {
pub struct ProcessControlBlock {
/// 当前进程的pid
pid: Pid,
/// 当前进程的线程组id这个值在同一个线程组内永远不变
tgid: Pid,
basic: RwLock<ProcessBasicInfo>,
/// 当前进程的自旋锁持有计数
@ -532,9 +535,13 @@ pub struct ProcessControlBlock {
sig_info: RwLock<ProcessSignalInfo>,
/// 信号处理结构体
sig_struct: SpinLock<SignalStruct>,
/// 退出信号S
exit_signal: AtomicSignal,
/// 父进程指针
parent_pcb: RwLock<Weak<ProcessControlBlock>>,
/// 真实父进程指针
real_parent_pcb: RwLock<Weak<ProcessControlBlock>>,
/// 子进程链表
children: RwLock<Vec<Pid>>,
@ -593,6 +600,7 @@ impl ProcessControlBlock {
let pcb = Self {
pid,
tgid: pid,
basic: basic_info,
preempt_count,
flags,
@ -603,7 +611,9 @@ impl ProcessControlBlock {
arch_info,
sig_info: RwLock::new(ProcessSignalInfo::default()),
sig_struct: SpinLock::new(SignalStruct::default()),
parent_pcb: RwLock::new(ppcb),
exit_signal: AtomicSignal::new(Signal::SIGCHLD),
parent_pcb: RwLock::new(ppcb.clone()),
real_parent_pcb: RwLock::new(ppcb),
children: RwLock::new(Vec::new()),
wait_queue: WaitQueue::INIT,
thread: RwLock::new(ThreadInfo::new()),
@ -768,6 +778,11 @@ impl ProcessControlBlock {
return self.pid;
}
#[inline(always)]
pub fn tgid(&self) -> Pid {
return self.tgid;
}
/// 获取文件描述符表的Arc指针
#[inline(always)]
pub fn fd_table(&self) -> Arc<RwLock<FileDescriptorVec>> {
@ -895,6 +910,8 @@ pub struct ThreadInfo {
set_child_tid: Option<VirtAddr>,
vfork_done: Option<Arc<Completion>>,
/// 线程组的组长
group_leader: Weak<ProcessControlBlock>,
}
impl ThreadInfo {
@ -903,8 +920,13 @@ impl ThreadInfo {
clear_child_tid: None,
set_child_tid: None,
vfork_done: None,
group_leader: Weak::default(),
}
}
pub fn group_leader(&self) -> Option<Arc<ProcessControlBlock>> {
return self.group_leader.upgrade();
}
}
/// 进程的基本信息

View File

@ -202,7 +202,7 @@ impl Syscall {
/// @brief 获取当前进程的pid
pub fn getpid() -> Result<Pid, SystemError> {
let current_pcb = ProcessManager::current_pcb();
return Ok(current_pcb.pid());
return Ok(current_pcb.tgid());
}
/// @brief 获取指定进程的pgid
@ -295,4 +295,9 @@ impl Syscall {
pcb.thread.write().clear_child_tid = Some(VirtAddr::new(ptr));
Ok(pcb.pid.0)
}
pub fn gettid() -> Result<Pid, SystemError> {
let pcb = ProcessManager::current_pcb();
Ok(pcb.pid)
}
}

View File

@ -415,6 +415,8 @@ pub const SYS_REBOOT: usize = 169;
pub const SYS_GETPPID: usize = 110;
pub const SYS_GETPGID: usize = 121;
pub const SYS_GETTID: usize = 186;
pub const SYS_MKNOD: usize = 133;
#[allow(dead_code)]
@ -1134,6 +1136,7 @@ impl Syscall {
kwarn!("SYS_MADVISE has not yet been implemented");
Ok(0)
}
SYS_GETTID => Self::gettid().map(|tid| tid.into()),
_ => panic!("Unsupported syscall ID: {}", syscall_num),
};

View File

@ -77,7 +77,7 @@ QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev
# QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -net nic,model=e1000e,netdev=hostnet0,id=net0 -netdev user,id=hostnet1,hostfwd=tcp::12581-:12581 -device virtio-net-pci,vectors=5,netdev=hostnet1,id=net1 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 "
QEMU_ARGUMENT="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d -monitor ${QEMU_MONITOR} -d ${qemu_trace_std} "
QEMU_ARGUMENT+="-s -S ${QEMU_MACHINE} -cpu ${QEMU_CPU_FEATURES} -rtc ${QEMU_RTC_CLOCK} -serial ${QEMU_SERIAL} -drive ${QEMU_DRIVE} ${QEMU_DEVICES}"
QEMU_ARGUMENT+="-s ${QEMU_MACHINE} -cpu ${QEMU_CPU_FEATURES} -rtc ${QEMU_RTC_CLOCK} -serial ${QEMU_SERIAL} -drive ${QEMU_DRIVE} ${QEMU_DEVICES}"
QEMU_ARGUMENT+=" ${QEMU_SHM_OBJECT} "
QEMU_ARGUMENT+=" ${QEMU_ACCELARATE} "