mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-23 00:16:17 +04:00
impl sys_set_tid_address. ignore invalid 'clear_child_tid' on exit
This commit is contained in:
parent
98a99e33c6
commit
08d10522ff
@ -47,23 +47,21 @@ impl PageTable for ActivePageTable {
|
||||
fn map(&mut self, addr: usize, target: usize) -> &mut Entry {
|
||||
let flags = EF::PRESENT | EF::WRITABLE | EF::NO_EXECUTE;
|
||||
unsafe {
|
||||
if let Ok(flush) = self.0.map_to(
|
||||
self.0
|
||||
.map_to(
|
||||
Page::of_addr(addr),
|
||||
Frame::of_addr(target),
|
||||
flags,
|
||||
&mut FrameAllocatorForX86,
|
||||
) {
|
||||
flush.flush();
|
||||
}
|
||||
)
|
||||
.unwrap()
|
||||
.flush();
|
||||
}
|
||||
unsafe { &mut *(get_entry_ptr(addr, 1)) }
|
||||
}
|
||||
|
||||
fn unmap(&mut self, addr: usize) {
|
||||
// unmap and flush if it is mapped
|
||||
if let Ok((_, flush)) = self.0.unmap(Page::of_addr(addr)) {
|
||||
flush.flush();
|
||||
}
|
||||
self.0.unmap(Page::of_addr(addr)).unwrap().1.flush();
|
||||
}
|
||||
|
||||
fn get_entry(&mut self, addr: usize) -> Option<&mut Entry> {
|
||||
@ -238,6 +236,9 @@ impl InactivePageTable for InactivePageTable0 {
|
||||
|
||||
fn edit<T>(&mut self, f: impl FnOnce(&mut Self::Active) -> T) -> T {
|
||||
let target = Cr3::read().0.start_address().as_u64() as usize;
|
||||
if self.p4_frame == Cr3::read().0 {
|
||||
return f(&mut active_table());
|
||||
}
|
||||
active_table().with_temporary_map(target, |active_table, p4_table: &mut x86PageTable| {
|
||||
let backup = p4_table[0o777].clone();
|
||||
|
||||
|
@ -88,14 +88,6 @@ pub fn sys_mprotect(addr: usize, len: usize, prot: usize) -> SysResult {
|
||||
if memory_area.is_none() {
|
||||
return Err(SysError::ENOMEM);
|
||||
}
|
||||
proc.vm.edit(|pt| {
|
||||
for page in Page::range_of(addr, addr + len) {
|
||||
let entry = pt
|
||||
.get_entry(page.start_address())
|
||||
.expect("failed to get entry");
|
||||
attr.apply(entry);
|
||||
}
|
||||
});
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
|
||||
SYS_EXIT => sys_exit(args[0] as usize),
|
||||
SYS_EXIT_GROUP => sys_exit_group(args[0]),
|
||||
SYS_WAIT4 => sys_wait4(args[0] as isize, args[1] as *mut i32), // TODO: wait4
|
||||
SYS_SET_TID_ADDRESS => unimplemented("set_tid_address", Ok(thread::current().id())),
|
||||
SYS_SET_TID_ADDRESS => sys_set_tid_address(args[0] as *mut u32),
|
||||
SYS_FUTEX => sys_futex(
|
||||
args[0],
|
||||
args[1] as u32,
|
||||
|
@ -281,14 +281,17 @@ pub fn sys_exit(exit_code: usize) -> ! {
|
||||
// ref: http://man7.org/linux/man-pages/man2/set_tid_address.2.html
|
||||
// FIXME: do it in all possible ways a thread can exit
|
||||
// it has memory access so we can't move it to Thread::drop?
|
||||
let clear_child_tid = current_thread().clear_child_tid;
|
||||
if clear_child_tid != 0 {
|
||||
unsafe {
|
||||
(clear_child_tid as *mut u32).write(0);
|
||||
}
|
||||
let queue = process().get_futex(clear_child_tid);
|
||||
let mut proc = process();
|
||||
let clear_child_tid = current_thread().clear_child_tid as *mut u32;
|
||||
if !clear_child_tid.is_null() {
|
||||
info!("exit: futex {:#?} wake 1", clear_child_tid);
|
||||
if let Ok(clear_child_tid_ref) = unsafe { proc.vm.check_write_ptr(clear_child_tid) } {
|
||||
*clear_child_tid_ref = 0;
|
||||
let queue = proc.get_futex(clear_child_tid as usize);
|
||||
queue.notify_one();
|
||||
}
|
||||
}
|
||||
drop(proc);
|
||||
|
||||
processor().manager().exit(tid, exit_code as usize);
|
||||
processor().yield_now();
|
||||
@ -334,6 +337,12 @@ pub fn sys_set_priority(priority: usize) -> SysResult {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn sys_set_tid_address(tidptr: *mut u32) -> SysResult {
|
||||
info!("set_tid_address: {:?}", tidptr);
|
||||
current_thread().clear_child_tid = tidptr as usize;
|
||||
Ok(thread::current().id())
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct CloneFlags: usize {
|
||||
const CSIGNAL = 0x000000ff;
|
||||
|
Loading…
Reference in New Issue
Block a user