Make the file lookup faster

This commit is contained in:
Ruihan Li
2024-12-26 21:35:56 +08:00
committed by Tate, Hongliang Tian
parent fb8f493b43
commit b9ce3e64ad
59 changed files with 483 additions and 390 deletions

View File

@ -4,6 +4,7 @@ use core::{num::NonZeroU64, sync::atomic::Ordering};
use ostd::{
cpu::UserContext,
sync::RwArc,
task::Task,
user::{UserContextApi, UserSpace},
};
@ -215,6 +216,7 @@ fn clone_child_task(
let Context {
process,
thread_local,
posix_thread,
..
} = ctx;
@ -223,7 +225,7 @@ fn clone_child_task(
clone_sysvsem(clone_flags)?;
// clone file table
let child_file_table = clone_files(posix_thread.file_table(), clone_flags);
let child_file_table = clone_files(&thread_local.file_table().borrow(), clone_flags);
// clone fs
let child_fs = clone_fs(posix_thread.fs(), clone_flags);
@ -281,6 +283,7 @@ fn clone_child_process(
) -> Result<Arc<Process>> {
let Context {
process,
thread_local,
posix_thread,
..
} = ctx;
@ -310,7 +313,7 @@ fn clone_child_process(
};
// clone file table
let child_file_table = clone_files(posix_thread.file_table(), clone_flags);
let child_file_table = clone_files(&thread_local.file_table().borrow(), clone_flags);
// clone fs
let child_fs = clone_fs(posix_thread.fs(), clone_flags);
@ -466,17 +469,14 @@ fn clone_fs(parent_fs: &Arc<ThreadFsInfo>, clone_flags: CloneFlags) -> Arc<Threa
}
}
fn clone_files(
parent_file_table: &Arc<SpinLock<FileTable>>,
clone_flags: CloneFlags,
) -> Arc<SpinLock<FileTable>> {
fn clone_files(parent_file_table: &RwArc<FileTable>, clone_flags: CloneFlags) -> RwArc<FileTable> {
// if CLONE_FILES is set, the child and parent shares the same file table
// Otherwise, the child will deep copy a new file table.
// FIXME: the clone may not be deep copy.
if clone_flags.contains(CloneFlags::CLONE_FILES) {
parent_file_table.clone()
} else {
Arc::new(SpinLock::new(parent_file_table.lock().clone()))
RwArc::new(parent_file_table.read().clone())
}
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
use super::{posix_thread::PosixThread, process_table, Pid, Process};
use super::{posix_thread::ThreadLocal, process_table, Pid, Process};
use crate::{prelude::*, process::signal::signals::kernel::KernelSignal};
/// Exits the current POSIX process.
@ -10,12 +10,12 @@ use crate::{prelude::*, process::signal::signals::kernel::KernelSignal};
///
/// [`do_exit`]: crate::process::posix_thread::do_exit
/// [`do_exit_group`]: crate::process::posix_thread::do_exit_group
pub(super) fn exit_process(current_thread: &PosixThread, current_process: &Process) {
pub(super) fn exit_process(thread_local: &ThreadLocal, current_process: &Process) {
current_process.status().set_zombie();
// FIXME: This is obviously wrong in a number of ways, since different threads can have
// different file tables, and different processes can share the same file table.
current_thread.file_table().lock().close_all();
thread_local.file_table().borrow().write().close_all();
send_parent_death_signal(current_process);

View File

@ -2,7 +2,7 @@
#![allow(dead_code)]
use ostd::{cpu::CpuSet, task::Task, user::UserSpace};
use ostd::{cpu::CpuSet, sync::RwArc, task::Task, user::UserSpace};
use super::{thread_table, PosixThread, ThreadLocal};
use crate::{
@ -30,7 +30,7 @@ pub struct PosixThreadBuilder {
thread_name: Option<ThreadName>,
set_child_tid: Vaddr,
clear_child_tid: Vaddr,
file_table: Option<Arc<SpinLock<FileTable>>>,
file_table: Option<RwArc<FileTable>>,
fs: Option<Arc<ThreadFsInfo>>,
sig_mask: AtomicSigMask,
sig_queues: SigQueues,
@ -75,7 +75,7 @@ impl PosixThreadBuilder {
self
}
pub fn file_table(mut self, file_table: Arc<SpinLock<FileTable>>) -> Self {
pub fn file_table(mut self, file_table: RwArc<FileTable>) -> Self {
self.file_table = Some(file_table);
self
}
@ -111,8 +111,7 @@ impl PosixThreadBuilder {
priority,
} = self;
let file_table =
file_table.unwrap_or_else(|| Arc::new(SpinLock::new(FileTable::new_with_stdio())));
let file_table = file_table.unwrap_or_else(|| RwArc::new(FileTable::new_with_stdio()));
let fs = fs.unwrap_or_else(|| Arc::new(ThreadFsInfo::default()));
@ -127,7 +126,7 @@ impl PosixThreadBuilder {
tid,
name: Mutex::new(thread_name),
credentials,
file_table,
file_table: file_table.clone_ro(),
fs,
sig_mask,
sig_queues,
@ -146,7 +145,7 @@ impl PosixThreadBuilder {
cpu_affinity,
));
let thread_local = ThreadLocal::new(set_child_tid, clear_child_tid);
let thread_local = ThreadLocal::new(set_child_tid, clear_child_tid, file_table);
thread_table::add_thread(tid, thread.clone());
task::create_new_user_task(user_space, thread, thread_local)

View File

@ -80,7 +80,7 @@ fn exit_internal(term_status: TermStatus, is_exiting_group: bool) {
}
if is_last_thread {
exit_process(posix_thread, &posix_process);
exit_process(thread_local, &posix_process);
}
}

View File

@ -5,7 +5,7 @@
use core::sync::atomic::{AtomicU32, Ordering};
use aster_rights::{ReadOp, WriteOp};
use ostd::sync::Waker;
use ostd::sync::{RoArc, Waker};
use super::{
kill::SignalSenderIds,
@ -57,7 +57,7 @@ pub struct PosixThread {
// Files
/// File table
file_table: Arc<SpinLock<FileTable>>,
file_table: RoArc<FileTable>,
/// File system
fs: Arc<ThreadFsInfo>,
@ -98,7 +98,7 @@ impl PosixThread {
&self.name
}
pub fn file_table(&self) -> &Arc<SpinLock<FileTable>> {
pub fn file_table(&self) -> &RoArc<FileTable> {
&self.file_table
}

View File

@ -2,10 +2,10 @@
use core::cell::{Cell, RefCell};
use ostd::{mm::Vaddr, task::CurrentTask};
use ostd::{mm::Vaddr, sync::RwArc, task::CurrentTask};
use super::RobustListHead;
use crate::process::signal::SigStack;
use crate::{fs::file_table::FileTable, process::signal::SigStack};
/// Local data for a POSIX thread.
pub struct ThreadLocal {
@ -18,6 +18,9 @@ pub struct ThreadLocal {
// https://man7.org/linux/man-pages/man2/get_robust_list.2.html
robust_list: RefCell<Option<RobustListHead>>,
// Files.
file_table: RefCell<RwArc<FileTable>>,
// Signal.
/// `ucontext` address for the signal handler.
// FIXME: This field may be removed. For glibc applications with RESTORER flag set, the
@ -28,11 +31,16 @@ pub struct ThreadLocal {
}
impl ThreadLocal {
pub(super) fn new(set_child_tid: Vaddr, clear_child_tid: Vaddr) -> Self {
pub(super) fn new(
set_child_tid: Vaddr,
clear_child_tid: Vaddr,
file_table: RwArc<FileTable>,
) -> Self {
Self {
set_child_tid: Cell::new(set_child_tid),
clear_child_tid: Cell::new(clear_child_tid),
robust_list: RefCell::new(None),
file_table: RefCell::new(file_table),
sig_context: Cell::new(None),
sig_stack: RefCell::new(None),
}
@ -50,6 +58,10 @@ impl ThreadLocal {
&self.robust_list
}
pub fn file_table(&self) -> &RefCell<RwArc<FileTable>> {
&self.file_table
}
pub fn sig_context(&self) -> &Cell<Option<Vaddr>> {
&self.sig_context
}

View File

@ -12,7 +12,7 @@ use crate::{
fs::{
fs_resolver::{FsPath, FsResolver, AT_FDCWD},
path::Dentry,
utils::Permission,
utils::{InodeType, Permission},
},
prelude::*,
};
@ -74,6 +74,10 @@ pub fn check_executable_file(dentry: &Dentry) -> Result<()> {
return_errno_with_message!(Errno::EISDIR, "the file is a directory");
}
if dentry.type_() == InodeType::SymLink {
return_errno_with_message!(Errno::ELOOP, "the file is a symbolic link");
}
if !dentry.type_().is_regular_file() {
return_errno_with_message!(Errno::EACCES, "the dentry is not a regular file");
}