1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 08:06:17 +04:00

Add thread table, allocate tid instead of pid

This commit is contained in:
Jiajie Chen 2020-06-19 18:53:33 +08:00
parent c230cd7b63
commit 7672dd45e3
5 changed files with 102 additions and 77 deletions

View File

@ -1,7 +1,7 @@
//! File handle for process
use crate::memory::GlobalFrameAlloc;
use crate::process::INodeForMap;
use crate::process::{current_thread, INodeForMap};
use crate::syscall::{MmapProt, SysResult, TimeSpec};
use alloc::{string::String, sync::Arc};
use core::fmt;
@ -235,8 +235,7 @@ impl FileHandle {
match self.inode.metadata()?.type_ {
FileType::File => {
let prot = MmapProt::from_bits_truncate(area.prot);
/*
let thread = unsafe { current_thread() };
let thread = current_thread().unwrap();
thread.vm.lock().push(
area.start_vaddr,
area.end_vaddr,
@ -250,7 +249,6 @@ impl FileHandle {
},
"mmap_file",
);
*/
Ok(())
}
FileType::CharDevice => self.inode.mmap(area),

View File

@ -38,16 +38,17 @@ pub fn init() {
info!("process: init end");
}
static mut THREADS: [Option<Arc<Thread>>; MAX_CPU_NUM] = [None; MAX_CPU_NUM];
static mut PROCESSORS: [Option<Arc<Thread>>; MAX_CPU_NUM] = [None; MAX_CPU_NUM];
/// Get current thread
///
/// `Thread` is a thread-local object.
/// It is safe to call this once, and pass `&mut Thread` as a function argument.
/// Should only be called in kernel trap handler
///
/// Don't use it unless necessary.
pub fn current_thread() -> Option<Arc<Thread>> {
let cpu_id = cpu::id();
unsafe { THREADS[cpu_id].clone() }
unsafe { PROCESSORS[cpu_id].clone() }
}
pub fn spawn(thread: Arc<Thread>) {
@ -120,7 +121,7 @@ impl Future for PageTableSwitchWrapper {
// TODO: task local?
let cpu_id = cpu::id();
unsafe {
THREADS[cpu_id] = Some(self.thread.clone());
PROCESSORS[cpu_id] = Some(self.thread.clone());
}
// vmtoken won't change
unsafe {
@ -131,7 +132,7 @@ impl Future for PageTableSwitchWrapper {
}
let res = self.inner.lock().as_mut().poll(cx);
unsafe {
THREADS[cpu_id] = None;
PROCESSORS[cpu_id] = None;
}
res
}

View File

@ -9,6 +9,7 @@ use crate::ipc::SemProc;
use crate::memory::{
phys_to_virt, ByFrame, Delay, File, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet, Read,
};
use crate::process::thread::THREADS;
use crate::sync::{Condvar, Event, EventBus, SpinLock, SpinNoIrqLock as Mutex};
use crate::{
signal::{Siginfo, Signal, SignalAction, SignalStack, Sigset},
@ -47,7 +48,7 @@ use xmas_elf::{
/// Pid type
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Pid(usize);
pub struct Pid(pub usize);
impl Pid {
pub const INIT: usize = 1;
@ -156,24 +157,18 @@ pub fn process_group(pgid: Pgid) -> Vec<Arc<Mutex<Process>>> {
.collect::<Vec<_>>()
}
/// Set pid and put itself to global process table.
pub fn add_to_process_table(proc: Arc<Mutex<Process>>, pid: Pid) {
let mut process_table = PROCESSES.write();
// set pid
proc.lock().pid = pid;
// put to process table
process_table.insert(pid.get(), proc.clone());
}
impl Process {
/// Assign a pid and put itself to global process table.
pub fn add_to_table(mut self) -> Arc<Mutex<Self>> {
let mut process_table = PROCESSES.write();
// assign pid, do not start from 0
let pid = (Pid::INIT..)
.find(|i| process_table.get(i).is_none())
.unwrap();
self.pid = Pid(pid);
// put to process table
let self_ref = Arc::new(Mutex::new(self));
process_table.insert(pid, self_ref.clone());
self_ref
}
/// Get lowest free fd
fn get_free_fd(&self) -> usize {
(0..).find(|i| !self.files.contains_key(i)).unwrap()
@ -220,8 +215,10 @@ impl Process {
// quit all threads
// this must be after setting the value of subprocess, or the threads will be treated exit before actually exits
// remove from thread table
let mut thread_table = THREADS.write();
for tid in self.threads.iter() {
//thread_manager().exit(*tid, 1);
thread_table.remove(tid);
}
self.threads.clear();

View File

@ -1,6 +1,6 @@
use super::{
abi::{self, ProcInitInfo},
Pid, Process,
add_to_process_table, Pid, Process,
};
use crate::arch::interrupt::TrapFrame;
use crate::arch::paging::*;
@ -74,7 +74,30 @@ pub struct Thread {
pub sig_mask: Sigset,
}
lazy_static! {
/// Records the mapping between pid and Process struct.
pub static ref THREADS: RwLock<BTreeMap<usize, Arc<Thread>>> =
RwLock::new(BTreeMap::new());
}
impl Thread {
/// Assign a tid and put itself to global thread table.
pub fn add_to_table(mut self) -> Arc<Self> {
let mut thread_table = THREADS.write();
// assign tid, do not start from 0
let tid = (Pid::INIT..)
.find(|i| thread_table.get(i).is_none())
.unwrap();
self.tid = tid;
// put to thread table
let self_ref = Arc::new(self);
thread_table.insert(tid, self_ref.clone());
self_ref
}
/// Construct virtual memory of a new user process from ELF at `inode`.
/// Return `(MemorySet, entry_point, ustack_top)`
pub fn new_user_vm(
@ -259,21 +282,21 @@ impl Thread {
context.general.rsp = ustack_top;
context.general.rflags = 0x3202;
Arc::new(Thread {
tid: 1, // default is init
let thread = Thread {
tid: 0, // allocated below
inner: Mutex::new(ThreadInner {
context: Some(Box::from(context)),
clear_child_tid: 0,
}),
vm: vm.clone(),
proc: Process {
proc: Arc::new(Mutex::new(Process {
vm,
files,
cwd: String::from("/"),
exec_path: String::from(exec_path),
futexes: BTreeMap::default(),
semaphores: SemProc::default(),
pid: Pid::new(), // allocated in add_to_table()
pid: Pid::new(), // allocated later
pgid: 0,
parent: (Pid::new(), Weak::new()),
children: Vec::new(),
@ -284,10 +307,16 @@ impl Thread {
dispositions: [SignalAction::default(); Signal::RTMAX + 1],
sigaltstack: SignalStack::default(),
eventbus: EventBus::new(),
}
.add_to_table(),
})),
sig_mask: Sigset::default(),
})
};
let res = thread.add_to_table();
// set pid to tid
add_to_process_table(res.proc.clone(), Pid(res.tid));
res
}
/// Fork a new process from current one
@ -304,14 +333,14 @@ impl Thread {
let mut proc = self.proc.lock();
let new_proc = Process {
let new_proc = Arc::new(Mutex::new(Process {
vm: vm.clone(),
files: proc.files.clone(), // share open file descriptions
cwd: proc.cwd.clone(),
exec_path: proc.exec_path.clone(),
futexes: BTreeMap::default(),
semaphores: proc.semaphores.clone(),
pid: Pid::new(),
pid: Pid::new(), // assigned later
pgid: proc.pgid,
parent: (proc.pid.clone(), Arc::downgrade(&self.proc)),
children: Vec::new(),
@ -322,22 +351,15 @@ impl Thread {
dispositions: proc.dispositions.clone(),
sigaltstack: Default::default(),
eventbus: EventBus::new(),
}
.add_to_table();
// link to parent
let child_pid = new_proc.lock().pid.clone();
proc.children.push((child_pid, Arc::downgrade(&new_proc)));
// set init thread tid
new_proc.lock().threads.push(child_pid.get());
}));
// new thread
// this part in linux manpage seems ambiguous:
// Each of the threads in a process has its own signal mask.
// A child created via fork(2) inherits a copy of its parent's signal
// mask; the signal mask is preserved across execve(2).
Arc::new(Thread {
tid: child_pid.get(), // tid = pid
let new_thread = Thread {
tid: 0, // allocated below
inner: Mutex::new(ThreadInner {
context: Some(Box::new(context)),
clear_child_tid: 0,
@ -345,19 +367,31 @@ impl Thread {
vm,
proc: new_proc,
sig_mask: self.sig_mask,
})
}
.add_to_table();
// link thread and process
let child_pid = Pid(new_thread.tid);
add_to_process_table(new_thread.proc.clone(), Pid(new_thread.tid));
new_thread.proc.lock().threads.push(new_thread.tid);
// link to parent
proc.children
.push((child_pid, Arc::downgrade(&new_thread.proc)));
new_thread
}
/// Create a new thread in the same process.
pub fn clone(
pub fn new_clone(
&self,
tf: &TrapFrame,
tf: &UserContext,
stack_top: usize,
tls: usize,
clear_child_tid: usize,
) -> Box<Thread> {
) -> Arc<Thread> {
let vm_token = self.vm.lock().token();
Box::new(Thread {
let thread = Thread {
tid: 0,
inner: Mutex::new(ThreadInner {
clear_child_tid,
@ -366,7 +400,10 @@ impl Thread {
vm: self.vm.clone(),
proc: self.proc.clone(),
sig_mask: self.sig_mask,
})
};
let res = thread.add_to_table();
res.proc.lock().threads.push(res.tid);
res
}
pub fn begin_running(&self) -> Box<UserContext> {

View File

@ -56,36 +56,28 @@ impl Syscall<'_> {
return self.sys_fork();
}
if (flags != 0x7d0f00) && (flags != 0x5d0f00) {
//0x5d0f00 is the args from gcc of alpine linux
//warn!("sys_clone only support musl pthread_create");
panic!(
"sys_clone only support sys_fork OR musl pthread_create without flags{:x}",
// 0x5d0f00 is the args from gcc of alpine linux
warn!(
"sys_clone only support sys_fork or musl pthread_create without flags{:x}",
flags
);
//return Err(SysError::ENOSYS);
return Err(SysError::ENOSYS);
}
let parent_tid_ref = unsafe { self.vm().check_write_ptr(parent_tid)? };
// child_tid buffer should not be set because CLONE_CHILD_SETTID flag is not specified in the current implementation
// let child_tid_ref = unsafe { self.vm().check_write_ptr(child_tid)? };
todo!();
/*
//let mut new_thread = self
//.thread
//.clone(self.tf, newsp, newtls, child_tid as usize);
let child_tid_ref = unsafe { self.vm().check_write_ptr(child_tid)? };
let mut new_thread = self
.thread
.new_clone(self.context, newsp, newtls, child_tid as usize);
if clone_flags.contains(CloneFlags::CHILD_CLEARTID) {
//new_thread.clear_child_tid = child_tid as usize;
new_thread.inner.lock().clear_child_tid = child_tid as usize;
}
//let tid = thread_manager().add(new_thread);
let tid: usize = todo!();
//thread_manager().detach(tid);
info!("clone: {} -> {}",
0,
//thread::current().id(),
tid);
let tid: usize = new_thread.tid;
info!("clone: {} -> {}", self.thread.tid, tid);
*parent_tid_ref = tid as u32;
// *child_tid_ref = tid as u32;
*child_tid_ref = tid as u32;
spawn(new_thread);
Ok(tid)
*/
}
/// Wait for the process exit.
@ -292,8 +284,8 @@ impl Syscall<'_> {
pid = self.process().pid.get();
}
info!("getpgid: get pgid of process {}", pid);
let process_table = PROCESSES.read();
// let process_table: BTreeMap<usize, Weak<Mutex<Process>>> = BTreeMap::new();
let proc = process_table.get(&pid);
if let Some(proc) = proc {
let proc = proc.lock();