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:
parent
c230cd7b63
commit
7672dd45e3
@ -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),
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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> {
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user