You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: thread.rs
    path of file: ./repos/rCore/kernel/src/process
    
    the code of the file until where you have to start completion: use super::{
    abi::{self, ProcInitInfo},
    add_to_process_table, Pid, Process, PROCESSORS,
};
use crate::arch::interrupt::consts::{
    is_intr, is_page_fault, is_reserved_inst, is_syscall, is_timer_intr,
};
use crate::arch::interrupt::{get_trap_num, handle_reserved_inst};
use crate::arch::{
    cpu,
    fp::FpState,
    memory::{get_page_fault_addr, set_page_table},
    paging::*,
};
use crate::drivers::IRQ_MANAGER;
use crate::fs::{FileHandle, FileLike, OpenOptions, FOLLOW_MAX_DEPTH};
use crate::ipc::{SemProc, ShmProc};
use crate::memory::{
    phys_to_virt, ByFrame, Delay, File, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet, Read,
};
use crate::process::structs::ElfExt;
use crate::sync::{EventBus, SpinLock, SpinNoIrqLock as Mutex};
use crate::{
    signal::{handle_signal, Siginfo, Signal, SignalAction, SignalStack, Sigset},
    syscall::handle_syscall,
};
use alloc::{
    boxed::Box, collections::BTreeMap, collections::VecDeque, string::String, sync::Arc,
    sync::Weak, vec::Vec,
};
use bitflags::_core::cell::Ref;
use core::fmt;
use core::str;
use core::{
    future::Future,
    mem::MaybeUninit,
    pin::Pin,
    task::{Context, Poll},
};
use log::*;
use num::FromPrimitive;
use pc_keyboard::KeyCode::BackTick;
use rcore_fs::vfs::INode;
use rcore_memory::{Page, PAGE_SIZE};
use spin::RwLock;
use trapframe::TrapFrame;
use trapframe::UserContext;
use xmas_elf::{
    header,
    program::{Flags, SegmentData, Type},
    ElfFile,
};

/// Tid type
pub type Tid = usize;

pub struct ThreadContext {
    user: Box<UserContext>,
    /// TODO: lazy fp
    fp: Box<FpState>,
}

/// Mutable part of a thread struct
#[derive(Default)]
pub struct ThreadInner {
    /// user context
    /// None when thread is running i
    
    pub fn fork(&self, tf: &UserContext) -> Arc<Thread> {
        // clone virtual memory
        let vm = self.vm.lock().clone();
        let vm_token = vm.token();
        let vm = Arc::new(Mutex::new(vm));

        // context of new thread
        let mut context = tf.clone();
        context.set_syscall_ret(0);

        let mut proc = self.proc.lock();

        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(), // assigned later
            pgid: proc.pgid,
            parent: (proc.pid.clone(), Arc::downgrade(&self.proc)),
            children: Vec::new(),
            threads: Vec::new(),
            exit_code: 0,
            pending_sigset: Sigset::empty(),
            sig_queue: VecDeque::new(),
            dispositions: proc.dispositions.clone(),
            eventbus: EventBus::new(),
            shm_identifiers: proc.shm_identifiers.clone(),
        }));

        // 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).
        let sig_mask = self.inner.lock().sig_mask;
        let sigaltstack = self.inner.lock().signal_alternate_stack;
        let new_thread = Thread {
            tid: 0, // allocated below
            inner: Mutex::new(ThreadInner {
                context: Some(ThreadContext {
                    user: Box::new(context),
                    fp: Box::new(FpState::new()),
                }),
                clear_child_tid: 0,
                sig_mask,
                signal_alternate_stack: sigaltstack,
            }),
            vm,
            proc: new_proc,
        }
        .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
    }