allocate pid independently from tid. fix sys_fork return value.

toolchain_update
WangRunji 6 years ago
parent 091902ae0d
commit ab62d542fd

@ -32,41 +32,23 @@ pub struct Thread {
/// Pid type /// Pid type
/// For strong type separation /// For strong type separation
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Pid(Option<usize>); pub struct Pid(usize);
impl Pid { impl Pid {
pub fn uninitialized() -> Self {
Pid(None)
}
/// Return if it was uninitialized before this call
/// When returning true, it usually means this is the first thread
pub fn set_if_uninitialized(&mut self, tid: Tid) -> bool {
if self.0 == None {
self.0 = Some(tid as usize);
true
} else {
false
}
}
pub fn get(&self) -> usize { pub fn get(&self) -> usize {
self.0.unwrap() self.0
} }
/// Return whether this pid represents the init process /// Return whether this pid represents the init process
pub fn is_init(&self) -> bool { pub fn is_init(&self) -> bool {
self.0 == Some(0) self.0 == 0
} }
} }
impl fmt::Display for Pid { impl fmt::Display for Pid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.0 { write!(f, "{}", self.0)
Some(pid) => write!(f, "{}", pid),
None => write!(f, "None"),
}
} }
} }
@ -103,21 +85,9 @@ impl rcore_thread::Context for Thread {
} }
fn set_tid(&mut self, tid: Tid) { fn set_tid(&mut self, tid: Tid) {
// set pid=tid if unspecified
let mut proc = self.proc.lock(); let mut proc = self.proc.lock();
if proc.pid.set_if_uninitialized(tid) {
// first thread in the process
// link to its ppid
if let Some(parent) = &proc.parent {
let mut parent = parent.lock();
parent.children.push(Arc::downgrade(&self.proc));
}
}
// add it to threads // add it to threads
proc.threads.push(tid); proc.threads.push(tid);
PROCESSES
.write()
.insert(proc.pid.get(), Arc::downgrade(&self.proc));
} }
} }
@ -140,18 +110,19 @@ impl Thread {
kstack, kstack,
clear_child_tid: 0, clear_child_tid: 0,
// TODO: kernel thread should not have a process // TODO: kernel thread should not have a process
proc: Arc::new(Mutex::new(Process { proc: Process {
vm, vm,
files: BTreeMap::default(), files: BTreeMap::default(),
cwd: String::from("/"), cwd: String::from("/"),
futexes: BTreeMap::default(), futexes: BTreeMap::default(),
pid: Pid::uninitialized(), pid: Pid(0),
parent: None, parent: None,
children: Vec::new(), children: Vec::new(),
threads: Vec::new(), threads: Vec::new(),
child_exit: Arc::new(Condvar::new()), child_exit: Arc::new(Condvar::new()),
child_exit_code: BTreeMap::new(), child_exit_code: BTreeMap::new(),
})), }
.add_to_table(),
}) })
} }
@ -290,18 +261,19 @@ impl Thread {
}, },
kstack, kstack,
clear_child_tid: 0, clear_child_tid: 0,
proc: Arc::new(Mutex::new(Process { proc: Process {
vm, vm,
files, files,
cwd: String::from("/"), cwd: String::from("/"),
futexes: BTreeMap::default(), futexes: BTreeMap::default(),
pid: Pid::uninitialized(), pid: Pid(0),
parent: None, parent: None,
children: Vec::new(), children: Vec::new(),
threads: Vec::new(), threads: Vec::new(),
child_exit: Arc::new(Condvar::new()), child_exit: Arc::new(Condvar::new()),
child_exit_code: BTreeMap::new(), child_exit_code: BTreeMap::new(),
})), }
.add_to_table(),
}) })
} }
@ -330,18 +302,19 @@ impl Thread {
context: unsafe { Context::new_fork(tf, kstack.top(), vm.token()) }, context: unsafe { Context::new_fork(tf, kstack.top(), vm.token()) },
kstack, kstack,
clear_child_tid: 0, clear_child_tid: 0,
proc: Arc::new(Mutex::new(Process { proc: Process {
vm, vm,
files, files,
cwd, cwd,
futexes: BTreeMap::default(), futexes: BTreeMap::default(),
pid: Pid::uninitialized(), pid: Pid(0),
parent, parent,
children: Vec::new(), children: Vec::new(),
threads: Vec::new(), threads: Vec::new(),
child_exit: Arc::new(Condvar::new()), child_exit: Arc::new(Condvar::new()),
child_exit_code: BTreeMap::new(), child_exit_code: BTreeMap::new(),
})), }
.add_to_table(),
}) })
} }
@ -365,9 +338,39 @@ impl Thread {
} }
impl Process { impl Process {
pub fn get_free_fd(&self) -> usize { /// Assign a pid and put itself to global process table.
fn add_to_table(mut self) -> Arc<Mutex<Self>> {
let mut process_table = PROCESSES.write();
// assign pid
let pid = (0..)
.find(|i| match process_table.get(i) {
Some(p) if p.upgrade().is_some() => false,
_ => true,
})
.unwrap();
self.pid = Pid(pid);
// put to process table
let self_ref = Arc::new(Mutex::new(self));
process_table.insert(pid, Arc::downgrade(&self_ref));
// link to parent
if let Some(parent) = &self_ref.lock().parent {
parent.lock().children.push(Arc::downgrade(&self_ref));
}
self_ref
}
fn get_free_fd(&self) -> usize {
(0..).find(|i| !self.files.contains_key(i)).unwrap() (0..).find(|i| !self.files.contains_key(i)).unwrap()
} }
/// Add a file to the process, return its fd.
pub fn add_file(&mut self, file_like: FileLike) -> usize {
let fd = self.get_free_fd();
self.files.insert(fd, file_like);
fd
}
pub fn get_futex(&mut self, uaddr: usize) -> Arc<Condvar> { pub fn get_futex(&mut self, uaddr: usize) -> Arc<Condvar> {
if !self.futexes.contains_key(&uaddr) { if !self.futexes.contains_key(&uaddr) {
self.futexes.insert(uaddr, Arc::new(Condvar::new())); self.futexes.insert(uaddr, Arc::new(Condvar::new()));

@ -277,10 +277,8 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) ->
proc.lookup_inode_at(dir_fd, &path, true)? proc.lookup_inode_at(dir_fd, &path, true)?
}; };
let fd = proc.get_free_fd();
let file = FileHandle::new(inode, flags.to_options()); let file = FileHandle::new(inode, flags.to_options());
proc.files.insert(fd, FileLike::File(file)); let fd = proc.add_file(FileLike::File(file));
Ok(fd) Ok(fd)
} }
@ -636,9 +634,7 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult {
proc.vm.check_write_array(fds, 2)?; proc.vm.check_write_array(fds, 2)?;
let (read, write) = Pipe::create_pair(); let (read, write) = Pipe::create_pair();
let read_fd = proc.get_free_fd(); let read_fd = proc.add_file(
proc.files.insert(
read_fd,
FileLike::File(FileHandle::new( FileLike::File(FileHandle::new(
Arc::new(read), Arc::new(read),
OpenOptions { OpenOptions {
@ -649,9 +645,7 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult {
)), )),
); );
let write_fd = proc.get_free_fd(); let write_fd = proc.add_file(
proc.files.insert(
write_fd,
FileLike::File(FileHandle::new( FileLike::File(FileHandle::new(
Arc::new(write), Arc::new(write),
OpenOptions { OpenOptions {

@ -39,8 +39,7 @@ pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResu
}, },
_ => return Err(SysError::EAFNOSUPPORT), _ => return Err(SysError::EAFNOSUPPORT),
}; };
let fd = proc.get_free_fd(); let fd = proc.add_file(FileLike::Socket(socket));
proc.files.insert(fd, FileLike::Socket(socket));
Ok(fd) Ok(fd)
} }
@ -237,8 +236,7 @@ pub fn sys_accept(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> SysResu
let socket = proc.get_socket(fd)?; let socket = proc.get_socket(fd)?;
let (new_socket, remote_endpoint) = socket.accept()?; let (new_socket, remote_endpoint) = socket.accept()?;
let new_fd = proc.get_free_fd(); let new_fd = proc.add_file(FileLike::Socket(new_socket));
proc.files.insert(new_fd, FileLike::Socket(new_socket));
if !addr.is_null() { if !addr.is_null() {
let sockaddr_in = SockAddr::from(remote_endpoint); let sockaddr_in = SockAddr::from(remote_endpoint);

@ -6,7 +6,8 @@ use crate::fs::INodeExt;
/// Fork the current process. Return the child's PID. /// Fork the current process. Return the child's PID.
pub fn sys_fork(tf: &TrapFrame) -> SysResult { pub fn sys_fork(tf: &TrapFrame) -> SysResult {
let new_thread = current_thread().fork(tf); let new_thread = current_thread().fork(tf);
let pid = processor().manager().add(new_thread); let pid = new_thread.proc.lock().pid.get();
processor().manager().add(new_thread);
info!("fork: {} -> {}", thread::current().id(), pid); info!("fork: {} -> {}", thread::current().id(), pid);
Ok(pid) Ok(pid)
} }

Loading…
Cancel
Save