mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 08:06:17 +04:00
split Process and Thread
This commit is contained in:
parent
1541282ad7
commit
0ec5ad8056
@ -1,6 +1,6 @@
|
|||||||
# 上下文切换
|
# 上下文切换
|
||||||
|
|
||||||
平台无关的代码位于 [kernel/src/process/context.rs](../../../kernel/src/process/context.rs) 中,而平台相关(aarch64)的代码位于 [kernel/src/arch/aarch64/interrupt/context.rs](../../../kernel/src/arch/aarch64/interrupt/context.rs) 中。
|
平台无关的代码位于 [kernel/src/process/context.rs](../../../kernel/src/process/structs.rs) 中,而平台相关(aarch64)的代码位于 [kernel/src/arch/aarch64/interrupt/context.rs](../../../kernel/src/arch/aarch64/interrupt/context.rs) 中。
|
||||||
|
|
||||||
## 相关数据结构
|
## 相关数据结构
|
||||||
|
|
||||||
@ -56,7 +56,7 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
每个进程控制块 `Process` ([kernel/src/process/context.rs](../../../kernel/src/process/context.rs#L13)) 都会维护一个平台相关的 `Context` 对象,在 AArch64 中包含下列信息:
|
每个进程控制块 `Process` ([kernel/src/process/context.rs](../../../kernel/src/process/structs.rs#L13)) 都会维护一个平台相关的 `Context` 对象,在 AArch64 中包含下列信息:
|
||||||
|
|
||||||
1. `stack_top`:内核栈顶地址
|
1. `stack_top`:内核栈顶地址
|
||||||
2. `ttbr`:页表基址
|
2. `ttbr`:页表基址
|
||||||
@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
## 切换流程
|
## 切换流程
|
||||||
|
|
||||||
在 [kernel/src/process/context.rs](../../../kernel/src/process/context.rs#L22) 里,`switch_to()` 是平台无关的切换函数,最终会调用 [kernel/src/arch/aarch64/interrupt/context.rs](../../../kernel/src/arch/aarch64/interrupt/context.rs#L129) 里平台相关的切换函数 `Context::switch()`:
|
在 [kernel/src/process/context.rs](../../../kernel/src/process/structs.rs#L22) 里,`switch_to()` 是平台无关的切换函数,最终会调用 [kernel/src/arch/aarch64/interrupt/context.rs](../../../kernel/src/arch/aarch64/interrupt/context.rs#L129) 里平台相关的切换函数 `Context::switch()`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
pub unsafe fn switch(&mut self, target: &mut Self) {
|
pub unsafe fn switch(&mut self, target: &mut Self) {
|
||||||
@ -190,7 +190,7 @@ ret
|
|||||||
2. 创建新的**用户线程**:解析 ELF 文件。
|
2. 创建新的**用户线程**:解析 ELF 文件。
|
||||||
3. 从一个线程 **fork** 出一个新线程:通过 `fork` 系统调用。
|
3. 从一个线程 **fork** 出一个新线程:通过 `fork` 系统调用。
|
||||||
|
|
||||||
三种线程的平台无关创建流程实现在 [kernel/src/process/context.rs](../../../kernel/src/process/context.rs#L40) 里,最终会分别调用 [kernel/src/arch/aarch64/interrupt/context.rs](../../../kernel/src/arch/aarch64/interrupt/context.rs#L146) 里的 `new_kernel_thread()`、`new_user_thread()` 和 `new_fork()` 这三个函数创建平台相关的 `Context` 结构。
|
三种线程的平台无关创建流程实现在 [kernel/src/process/context.rs](../../../kernel/src/process/structs.rs#L40) 里,最终会分别调用 [kernel/src/arch/aarch64/interrupt/context.rs](../../../kernel/src/arch/aarch64/interrupt/context.rs#L146) 里的 `new_kernel_thread()`、`new_user_thread()` 和 `new_fork()` 这三个函数创建平台相关的 `Context` 结构。
|
||||||
|
|
||||||
在这三个函数里,会构造 `ContextData` 与 `TrapFrame` 结构,构成一个 `InitStack`,并向新线程的内核栈压入 `InitStack` 结构,最后将新内核栈顶地址、页表基址等信息构成 `Context` 结构返回。这两个结构的构造方式如下:
|
在这三个函数里,会构造 `ContextData` 与 `TrapFrame` 结构,构成一个 `InitStack`,并向新线程的内核栈压入 `InitStack` 结构,最后将新内核栈顶地址、页表基址等信息构成 `Context` 结构返回。这两个结构的构造方式如下:
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
pub use self::context::Process;
|
pub use self::structs::*;
|
||||||
pub use rcore_thread::*;
|
pub use rcore_thread::*;
|
||||||
use crate::consts::{MAX_CPU_NUM, MAX_PROCESS_NUM};
|
use crate::consts::{MAX_CPU_NUM, MAX_PROCESS_NUM};
|
||||||
use crate::arch::cpu;
|
use crate::arch::cpu;
|
||||||
use alloc::{boxed::Box, sync::Arc};
|
use alloc::{boxed::Box, sync::Arc};
|
||||||
|
use spin::MutexGuard;
|
||||||
use log::*;
|
use log::*;
|
||||||
|
|
||||||
pub mod context;
|
pub mod structs;
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
// NOTE: max_time_slice <= 5 to ensure 'priority' test pass
|
// NOTE: max_time_slice <= 5 to ensure 'priority' test pass
|
||||||
@ -14,7 +15,7 @@ pub fn init() {
|
|||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
for cpu_id in 0..MAX_CPU_NUM {
|
for cpu_id in 0..MAX_CPU_NUM {
|
||||||
PROCESSORS[cpu_id].init(cpu_id, Process::new_init(), manager.clone());
|
PROCESSORS[cpu_id].init(cpu_id, Thread::new_init(), manager.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ pub fn init() {
|
|||||||
use core::str::FromStr;
|
use core::str::FromStr;
|
||||||
let cores = usize::from_str(env!("SMP")).unwrap();
|
let cores = usize::from_str(env!("SMP")).unwrap();
|
||||||
for i in 0..cores {
|
for i in 0..cores {
|
||||||
manager.add(Process::new_kernel(idle, i), 0);
|
manager.add(Thread::new_kernel(idle, i), 0);
|
||||||
}
|
}
|
||||||
crate::shell::run_user_shell();
|
crate::shell::run_user_shell();
|
||||||
|
|
||||||
@ -34,12 +35,17 @@ pub fn init() {
|
|||||||
|
|
||||||
static PROCESSORS: [Processor; MAX_CPU_NUM] = [Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new()];
|
static PROCESSORS: [Processor; MAX_CPU_NUM] = [Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new()];
|
||||||
|
|
||||||
/// Get current thread struct
|
/// Get current process
|
||||||
|
pub fn process() -> MutexGuard<'static, Process> {
|
||||||
|
current_thread().proc.lock()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get current thread
|
||||||
///
|
///
|
||||||
/// FIXME: It's obviously unsafe to get &mut !
|
/// FIXME: It's obviously unsafe to get &mut !
|
||||||
pub fn process() -> &'static mut Process {
|
pub fn current_thread() -> &'static mut Thread {
|
||||||
use core::mem::transmute;
|
use core::mem::transmute;
|
||||||
let (process, _): (&mut Process, *const ()) = unsafe {
|
let (process, _): (&mut Thread, *const ()) = unsafe {
|
||||||
transmute(processor().context())
|
transmute(processor().context())
|
||||||
};
|
};
|
||||||
process
|
process
|
||||||
@ -55,5 +61,5 @@ pub fn processor() -> &'static Processor {
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn new_kernel_context(entry: extern fn(usize) -> !, arg: usize) -> Box<Context> {
|
pub fn new_kernel_context(entry: extern fn(usize) -> !, arg: usize) -> Box<Context> {
|
||||||
Process::new_kernel(entry, arg)
|
Thread::new_kernel(entry, arg)
|
||||||
}
|
}
|
||||||
|
@ -3,54 +3,64 @@ use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, vec::V
|
|||||||
use log::*;
|
use log::*;
|
||||||
use simple_filesystem::file::File;
|
use simple_filesystem::file::File;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
use rcore_thread::Context;
|
|
||||||
use xmas_elf::{ElfFile, header, program::{Flags, Type}};
|
use xmas_elf::{ElfFile, header, program::{Flags, Type}};
|
||||||
|
|
||||||
use crate::arch::interrupt::{Context as ArchContext, TrapFrame};
|
use crate::arch::interrupt::{Context, TrapFrame};
|
||||||
use crate::memory::{ByFrame, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet};
|
use crate::memory::{ByFrame, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet};
|
||||||
|
|
||||||
// TODO: avoid pub
|
// TODO: avoid pub
|
||||||
pub struct Process {
|
pub struct Thread {
|
||||||
pub arch: ArchContext,
|
pub context: Context,
|
||||||
pub memory_set: MemorySet,
|
|
||||||
pub kstack: KernelStack,
|
pub kstack: KernelStack,
|
||||||
|
pub proc: Arc<Mutex<Process>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Process {
|
||||||
|
pub memory_set: MemorySet,
|
||||||
pub files: BTreeMap<usize, Arc<Mutex<File>>>,
|
pub files: BTreeMap<usize, Arc<Mutex<File>>>,
|
||||||
pub cwd: String,
|
pub cwd: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context for Process {
|
/// Let `rcore_thread` can switch between our `Thread`
|
||||||
unsafe fn switch_to(&mut self, target: &mut Context) {
|
impl rcore_thread::Context for Thread {
|
||||||
|
unsafe fn switch_to(&mut self, target: &mut rcore_thread::Context) {
|
||||||
use core::mem::transmute;
|
use core::mem::transmute;
|
||||||
let (target, _): (&mut Process, *const ()) = transmute(target);
|
let (target, _): (&mut Thread, *const ()) = transmute(target);
|
||||||
self.arch.switch(&mut target.arch);
|
self.context.switch(&mut target.context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Process {
|
impl Thread {
|
||||||
pub unsafe fn new_init() -> Box<Context> {
|
/// Make a struct for the init thread
|
||||||
Box::new(Process {
|
pub unsafe fn new_init() -> Box<Thread> {
|
||||||
arch: ArchContext::null(),
|
Box::new(Thread {
|
||||||
memory_set: MemorySet::new(),
|
context: Context::null(),
|
||||||
kstack: KernelStack::new(),
|
kstack: KernelStack::new(),
|
||||||
files: BTreeMap::default(),
|
proc: Arc::new(Mutex::new(Process {
|
||||||
cwd: String::new(),
|
memory_set: MemorySet::new(),
|
||||||
|
files: BTreeMap::default(),
|
||||||
|
cwd: String::new(),
|
||||||
|
})),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_kernel(entry: extern fn(usize) -> !, arg: usize) -> Box<Context> {
|
/// Make a new kernel thread starting from `entry` with `arg`
|
||||||
|
pub fn new_kernel(entry: extern fn(usize) -> !, arg: usize) -> Box<Thread> {
|
||||||
let memory_set = MemorySet::new();
|
let memory_set = MemorySet::new();
|
||||||
let kstack = KernelStack::new();
|
let kstack = KernelStack::new();
|
||||||
Box::new(Process {
|
Box::new(Thread {
|
||||||
arch: unsafe { ArchContext::new_kernel_thread(entry, arg, kstack.top(), memory_set.token()) },
|
context: unsafe { Context::new_kernel_thread(entry, arg, kstack.top(), memory_set.token()) },
|
||||||
memory_set,
|
|
||||||
kstack,
|
kstack,
|
||||||
files: BTreeMap::default(),
|
proc: Arc::new(Mutex::new(Process {
|
||||||
cwd: String::new(),
|
memory_set,
|
||||||
|
files: BTreeMap::default(),
|
||||||
|
cwd: String::new(),
|
||||||
|
})),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a new user thread from ELF data
|
/// Make a new user process from ELF `data`
|
||||||
pub fn new_user<'a, Iter>(data: &[u8], args: Iter) -> Box<Process>
|
pub fn new_user<'a, Iter>(data: &[u8], args: Iter) -> Box<Thread>
|
||||||
where Iter: Iterator<Item=&'a str>
|
where Iter: Iterator<Item=&'a str>
|
||||||
{
|
{
|
||||||
// Parse elf
|
// Parse elf
|
||||||
@ -94,23 +104,25 @@ impl Process {
|
|||||||
|
|
||||||
let kstack = KernelStack::new();
|
let kstack = KernelStack::new();
|
||||||
|
|
||||||
Box::new(Process {
|
Box::new(Thread {
|
||||||
arch: unsafe {
|
context: unsafe {
|
||||||
ArchContext::new_user_thread(
|
Context::new_user_thread(
|
||||||
entry_addr, ustack_top, kstack.top(), is32, memory_set.token())
|
entry_addr, ustack_top, kstack.top(), is32, memory_set.token())
|
||||||
},
|
},
|
||||||
memory_set,
|
|
||||||
kstack,
|
kstack,
|
||||||
files: BTreeMap::default(),
|
proc: Arc::new(Mutex::new(Process {
|
||||||
cwd: String::new(),
|
memory_set,
|
||||||
|
files: BTreeMap::default(),
|
||||||
|
cwd: String::new(),
|
||||||
|
})),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fork
|
/// Fork a new process from current one
|
||||||
pub fn fork(&self, tf: &TrapFrame) -> Box<Context> {
|
pub fn fork(&self, tf: &TrapFrame) -> Box<Thread> {
|
||||||
info!("COME into fork!");
|
info!("COME into fork!");
|
||||||
// Clone memory set, make a new page table
|
// Clone memory set, make a new page table
|
||||||
let memory_set = self.memory_set.clone();
|
let memory_set = self.proc.lock().memory_set.clone();
|
||||||
info!("finish mmset clone in fork!");
|
info!("finish mmset clone in fork!");
|
||||||
|
|
||||||
// MMU: copy data to the new space
|
// MMU: copy data to the new space
|
||||||
@ -126,12 +138,14 @@ impl Process {
|
|||||||
info!("temporary copy data!");
|
info!("temporary copy data!");
|
||||||
let kstack = KernelStack::new();
|
let kstack = KernelStack::new();
|
||||||
|
|
||||||
Box::new(Process {
|
Box::new(Thread {
|
||||||
arch: unsafe { ArchContext::new_fork(tf, kstack.top(), memory_set.token()) },
|
context: unsafe { Context::new_fork(tf, kstack.top(), memory_set.token()) },
|
||||||
memory_set,
|
|
||||||
kstack,
|
kstack,
|
||||||
files: BTreeMap::default(),
|
proc: Arc::new(Mutex::new(Process {
|
||||||
cwd: String::new(),
|
memory_set,
|
||||||
|
files: BTreeMap::default(),
|
||||||
|
cwd: String::new(),
|
||||||
|
})),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,9 +10,9 @@ pub fn run_user_shell() {
|
|||||||
println!("Going to user mode shell.");
|
println!("Going to user mode shell.");
|
||||||
println!("Use 'ls' to list available programs.");
|
println!("Use 'ls' to list available programs.");
|
||||||
let data = inode.read_as_vec().unwrap();
|
let data = inode.read_as_vec().unwrap();
|
||||||
processor().manager().add(Process::new_user(data.as_slice(), "sh".split(' ')), 0);
|
processor().manager().add(Thread::new_user(data.as_slice(), "sh".split(' ')), 0);
|
||||||
} else {
|
} else {
|
||||||
processor().manager().add(Process::new_kernel(shell, 0), 0);
|
processor().manager().add(Thread::new_kernel(shell, 0), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ pub extern fn shell(_arg: usize) -> ! {
|
|||||||
let name = cmd.split(' ').next().unwrap();
|
let name = cmd.split(' ').next().unwrap();
|
||||||
if let Ok(file) = ROOT_INODE.lookup(name) {
|
if let Ok(file) = ROOT_INODE.lookup(name) {
|
||||||
let data = file.read_as_vec().unwrap();
|
let data = file.read_as_vec().unwrap();
|
||||||
let pid = processor().manager().add(Process::new_user(data.as_slice(), cmd.split(' ')), thread::current().id());
|
let pid = processor().manager().add(Thread::new_user(data.as_slice(), cmd.split(' ')), thread::current().id());
|
||||||
unsafe { thread::JoinHandle::<()>::_of(pid) }.join().unwrap();
|
unsafe { thread::JoinHandle::<()>::_of(pid) }.join().unwrap();
|
||||||
} else {
|
} else {
|
||||||
println!("Program not exist");
|
println!("Program not exist");
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use simple_filesystem::{INode, file::File, FileInfo, FileType, FsError};
|
use simple_filesystem::{INode, file::File, FileInfo, FileType, FsError};
|
||||||
use core::{slice, str};
|
use core::{slice, str};
|
||||||
use alloc::{sync::Arc, vec::Vec, string::String};
|
use alloc::{sync::Arc, vec::Vec, string::String};
|
||||||
use spin::Mutex;
|
use spin::{Mutex, MutexGuard};
|
||||||
use log::*;
|
use log::*;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use crate::arch::interrupt::TrapFrame;
|
use crate::arch::interrupt::TrapFrame;
|
||||||
@ -61,7 +61,8 @@ fn sys_read(fd: usize, base: *mut u8, len: usize) -> SysResult {
|
|||||||
// TODO: check ptr
|
// TODO: check ptr
|
||||||
info!("read: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
|
info!("read: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
|
||||||
let slice = unsafe { slice::from_raw_parts_mut(base, len) };
|
let slice = unsafe { slice::from_raw_parts_mut(base, len) };
|
||||||
let len = get_file(fd)?.lock().read(slice)?;
|
let proc = process();
|
||||||
|
let len = get_file(&proc, fd)?.lock().read(slice)?;
|
||||||
Ok(len as isize)
|
Ok(len as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +70,8 @@ fn sys_write(fd: usize, base: *const u8, len: usize) -> SysResult {
|
|||||||
// TODO: check ptr
|
// TODO: check ptr
|
||||||
info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
|
info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
|
||||||
let slice = unsafe { slice::from_raw_parts(base, len) };
|
let slice = unsafe { slice::from_raw_parts(base, len) };
|
||||||
let len = get_file(fd)?.lock().write(slice)?;
|
let proc = process();
|
||||||
|
let len = get_file(&proc, fd)?.lock().write(slice)?;
|
||||||
Ok(len as isize)
|
Ok(len as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +105,8 @@ fn sys_close(fd: usize) -> SysResult {
|
|||||||
fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult {
|
fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult {
|
||||||
// TODO: check ptr
|
// TODO: check ptr
|
||||||
info!("fstat: {}", fd);
|
info!("fstat: {}", fd);
|
||||||
let file = get_file(fd)?;
|
let proc = process();
|
||||||
|
let file = get_file(&proc, fd)?;
|
||||||
let stat = Stat::from(file.lock().info()?);
|
let stat = Stat::from(file.lock().info()?);
|
||||||
unsafe { stat_ptr.write(stat); }
|
unsafe { stat_ptr.write(stat); }
|
||||||
Ok(0)
|
Ok(0)
|
||||||
@ -115,7 +118,8 @@ fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult {
|
|||||||
fn sys_getdirentry(fd: usize, dentry_ptr: *mut DirEntry) -> SysResult {
|
fn sys_getdirentry(fd: usize, dentry_ptr: *mut DirEntry) -> SysResult {
|
||||||
// TODO: check ptr
|
// TODO: check ptr
|
||||||
info!("getdirentry: {}", fd);
|
info!("getdirentry: {}", fd);
|
||||||
let file = get_file(fd)?;
|
let proc = process();
|
||||||
|
let file = get_file(&proc, fd)?;
|
||||||
let dentry = unsafe { &mut *dentry_ptr };
|
let dentry = unsafe { &mut *dentry_ptr };
|
||||||
if !dentry.check() {
|
if !dentry.check() {
|
||||||
return Err(SysError::Inval);
|
return Err(SysError::Inval);
|
||||||
@ -131,7 +135,8 @@ fn sys_getdirentry(fd: usize, dentry_ptr: *mut DirEntry) -> SysResult {
|
|||||||
|
|
||||||
fn sys_dup(fd1: usize, fd2: usize) -> SysResult {
|
fn sys_dup(fd1: usize, fd2: usize) -> SysResult {
|
||||||
info!("dup: {} {}", fd1, fd2);
|
info!("dup: {} {}", fd1, fd2);
|
||||||
let file = get_file(fd1)?;
|
let proc = process();
|
||||||
|
let file = get_file(&proc, fd1)?;
|
||||||
if process().files.contains_key(&fd2) {
|
if process().files.contains_key(&fd2) {
|
||||||
return Err(SysError::Inval);
|
return Err(SysError::Inval);
|
||||||
}
|
}
|
||||||
@ -141,7 +146,7 @@ fn sys_dup(fd1: usize, fd2: usize) -> SysResult {
|
|||||||
|
|
||||||
/// Fork the current process. Return the child's PID.
|
/// Fork the current process. Return the child's PID.
|
||||||
fn sys_fork(tf: &TrapFrame) -> SysResult {
|
fn sys_fork(tf: &TrapFrame) -> SysResult {
|
||||||
let context = process().fork(tf);
|
let context = current_thread().fork(tf);
|
||||||
let pid = processor().manager().add(context, thread::current().id());
|
let pid = processor().manager().add(context, thread::current().id());
|
||||||
info!("fork: {} -> {}", thread::current().id(), pid);
|
info!("fork: {} -> {}", thread::current().id(), pid);
|
||||||
Ok(pid as isize)
|
Ok(pid as isize)
|
||||||
@ -207,19 +212,19 @@ fn sys_exec(name: *const u8, argc: usize, argv: *const *const u8, tf: &mut TrapF
|
|||||||
unsafe { buf.set_len(size); }
|
unsafe { buf.set_len(size); }
|
||||||
inode.read_at(0, buf.as_mut_slice())?;
|
inode.read_at(0, buf.as_mut_slice())?;
|
||||||
|
|
||||||
// Make new Context
|
// Make new Thread
|
||||||
let iter = args.iter().map(|s| s.as_str());
|
let iter = args.iter().map(|s| s.as_str());
|
||||||
let mut context = Process::new_user(buf.as_slice(), iter);
|
let mut thread = Thread::new_user(buf.as_slice(), iter);
|
||||||
|
|
||||||
// Activate new page table
|
// Activate new page table
|
||||||
unsafe { context.memory_set.activate(); }
|
unsafe { thread.proc.lock().memory_set.activate(); }
|
||||||
|
|
||||||
// Modify the TrapFrame
|
// Modify the TrapFrame
|
||||||
*tf = unsafe { context.arch.get_init_tf() };
|
*tf = unsafe { thread.context.get_init_tf() };
|
||||||
|
|
||||||
// Swap Context but keep KStack
|
// Swap Context but keep KStack
|
||||||
::core::mem::swap(&mut process().kstack, &mut context.kstack);
|
::core::mem::swap(&mut current_thread().kstack, &mut thread.kstack);
|
||||||
::core::mem::swap(process(), &mut *context);
|
::core::mem::swap(current_thread(), &mut *thread);
|
||||||
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
@ -278,8 +283,8 @@ fn sys_putc(c: char) -> SysResult {
|
|||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_file(fd: usize) -> Result<&'static Arc<Mutex<File>>, SysError> {
|
fn get_file<'a>(proc: &'a MutexGuard<'static, Process>, fd: usize) -> Result<&'a Arc<Mutex<File>>, SysError> {
|
||||||
process().files.get(&fd).ok_or(SysError::Inval)
|
proc.files.get(&fd).ok_or(SysError::Inval)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type SysResult = Result<isize, SysError>;
|
pub type SysResult = Result<isize, SysError>;
|
||||||
|
Loading…
Reference in New Issue
Block a user