Remove `user_ctx` from `Task`
This commit is contained in:
parent
60bc63b0e2
commit
923982c2e5
|
|
@ -260,7 +260,7 @@ fn clone_child_task(
|
|||
// Clone FPU context
|
||||
let child_fpu_context = thread_local.fpu().clone_context();
|
||||
|
||||
let child_user_ctx = Arc::new(clone_user_ctx(
|
||||
let child_user_ctx = Box::new(clone_user_ctx(
|
||||
parent_context,
|
||||
clone_args.stack,
|
||||
clone_args.stack_size,
|
||||
|
|
@ -327,7 +327,7 @@ fn clone_child_process(
|
|||
};
|
||||
|
||||
// Clone the user context
|
||||
let child_user_ctx = Arc::new(clone_user_ctx(
|
||||
let child_user_ctx = Box::new(clone_user_ctx(
|
||||
parent_context,
|
||||
clone_args.stack,
|
||||
clone_args.stack_size,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ use crate::{
|
|||
pub struct PosixThreadBuilder {
|
||||
// The essential part
|
||||
tid: Tid,
|
||||
user_ctx: Arc<UserContext>,
|
||||
user_ctx: Box<UserContext>,
|
||||
process: Weak<Process>,
|
||||
credentials: Credentials,
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ pub struct PosixThreadBuilder {
|
|||
}
|
||||
|
||||
impl PosixThreadBuilder {
|
||||
pub fn new(tid: Tid, user_ctx: Arc<UserContext>, credentials: Credentials) -> Self {
|
||||
pub fn new(tid: Tid, user_ctx: Box<UserContext>, credentials: Credentials) -> Self {
|
||||
Self {
|
||||
tid,
|
||||
user_ctx,
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ fn create_init_task(
|
|||
user_ctx.set_instruction_pointer(elf_load_info.entry_point as _);
|
||||
user_ctx.set_stack_pointer(elf_load_info.user_stack_top as _);
|
||||
let thread_name = Some(ThreadName::new_from_executable_path(executable_path)?);
|
||||
let thread_builder = PosixThreadBuilder::new(tid, Arc::new(user_ctx), credentials)
|
||||
let thread_builder = PosixThreadBuilder::new(tid, Box::new(user_ctx), credentials)
|
||||
.thread_name(thread_name)
|
||||
.process(process)
|
||||
.fs(Arc::new(fs));
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ use crate::{
|
|||
|
||||
/// create new task with userspace and parent process
|
||||
pub fn create_new_user_task(
|
||||
user_ctx: Arc<UserContext>,
|
||||
user_ctx: Box<UserContext>,
|
||||
thread_ref: Arc<Thread>,
|
||||
thread_local: ThreadLocal,
|
||||
) -> Task {
|
||||
fn user_task_entry() {
|
||||
fn user_task_entry(user_ctx: UserContext) {
|
||||
let current_task = Task::current().unwrap();
|
||||
let current_thread = current_task.as_thread().unwrap();
|
||||
let current_posix_thread = current_thread.as_posix_thread().unwrap();
|
||||
|
|
@ -35,10 +35,8 @@ pub fn create_new_user_task(
|
|||
let current_process = current_posix_thread.process();
|
||||
let (stop_waiter, _) = Waiter::new_pair();
|
||||
|
||||
let user_ctx = current_task
|
||||
.user_ctx()
|
||||
.expect("user task should have user context");
|
||||
let mut user_mode = UserMode::new(UserContext::clone(user_ctx));
|
||||
let mut user_mode = UserMode::new(user_ctx);
|
||||
user_mode.context_mut().activate_tls_pointer();
|
||||
debug!(
|
||||
"[Task entry] rip = 0x{:x}",
|
||||
user_mode.context().instruction_pointer()
|
||||
|
|
@ -52,11 +50,10 @@ pub fn create_new_user_task(
|
|||
user_mode.context().syscall_ret()
|
||||
);
|
||||
|
||||
let child_tid_ptr = current_thread_local.set_child_tid().get();
|
||||
|
||||
// The `clone` syscall may require child process to write the thread pid to the specified address.
|
||||
// Make sure the store operation completes before the clone call returns control to user space
|
||||
// in the child process.
|
||||
let child_tid_ptr = current_thread_local.set_child_tid().get();
|
||||
if is_userspace_vaddr(child_tid_ptr) {
|
||||
current_userspace!()
|
||||
.write_val(child_tid_ptr, ¤t_posix_thread.tid())
|
||||
|
|
@ -116,14 +113,15 @@ pub fn create_new_user_task(
|
|||
}
|
||||
}
|
||||
|
||||
TaskOptions::new(|| {
|
||||
let user_task_func = move || user_task_entry(*user_ctx);
|
||||
|
||||
TaskOptions::new(move || {
|
||||
// TODO: If a kernel "oops" is caught, we should kill the entire
|
||||
// process rather than just ending the thread.
|
||||
let _ = oops::catch_panics_as_oops(user_task_entry);
|
||||
let _ = oops::catch_panics_as_oops(user_task_func);
|
||||
})
|
||||
.data(thread_ref)
|
||||
.local_data(thread_local)
|
||||
.user_ctx(Some(user_ctx))
|
||||
.build()
|
||||
.expect("spawn task failed")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ pub use self::{
|
|||
scheduler::info::{AtomicCpuId, TaskScheduleInfo},
|
||||
};
|
||||
pub(crate) use crate::arch::task::{context_switch, TaskContext};
|
||||
use crate::{cpu::context::UserContext, prelude::*, trap::in_interrupt_context};
|
||||
use crate::{prelude::*, trap::in_interrupt_context};
|
||||
|
||||
static PRE_SCHEDULE_HANDLER: Once<fn()> = Once::new();
|
||||
|
||||
|
|
@ -57,7 +57,6 @@ pub struct Task {
|
|||
data: Box<dyn Any + Send + Sync>,
|
||||
local_data: ForceSync<Box<dyn Any + Send>>,
|
||||
|
||||
user_ctx: Option<Arc<UserContext>>,
|
||||
ctx: SyncUnsafeCell<TaskContext>,
|
||||
/// kernel stack, note that the top is SyscallFrame/TrapFrame
|
||||
kstack: KernelStack,
|
||||
|
|
@ -128,15 +127,6 @@ impl Task {
|
|||
pub fn schedule_info(&self) -> &TaskScheduleInfo {
|
||||
&self.schedule_info
|
||||
}
|
||||
|
||||
/// Returns the user context of this task, if it has.
|
||||
pub fn user_ctx(&self) -> Option<&Arc<UserContext>> {
|
||||
if self.user_ctx.is_some() {
|
||||
Some(self.user_ctx.as_ref().unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Options to create or spawn a new task.
|
||||
|
|
@ -144,7 +134,6 @@ pub struct TaskOptions {
|
|||
func: Option<Box<dyn FnOnce() + Send>>,
|
||||
data: Option<Box<dyn Any + Send + Sync>>,
|
||||
local_data: Option<Box<dyn Any + Send>>,
|
||||
user_ctx: Option<Arc<UserContext>>,
|
||||
}
|
||||
|
||||
impl TaskOptions {
|
||||
|
|
@ -157,7 +146,6 @@ impl TaskOptions {
|
|||
func: Some(Box::new(func)),
|
||||
data: None,
|
||||
local_data: None,
|
||||
user_ctx: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,12 +176,6 @@ impl TaskOptions {
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the user context associated with the task.
|
||||
pub fn user_ctx(mut self, user_ctx: Option<Arc<UserContext>>) -> Self {
|
||||
self.user_ctx = user_ctx;
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds a new task without running it immediately.
|
||||
pub fn build(self) -> Result<Task> {
|
||||
/// all task will entering this function
|
||||
|
|
@ -225,12 +207,8 @@ impl TaskOptions {
|
|||
|
||||
let kstack = KernelStack::new_with_guard_page()?;
|
||||
|
||||
let mut ctx = SyncUnsafeCell::new(TaskContext::default());
|
||||
if let Some(user_ctx) = self.user_ctx.as_ref() {
|
||||
ctx.get_mut().set_tls_pointer(user_ctx.tls_pointer());
|
||||
};
|
||||
ctx.get_mut()
|
||||
.set_instruction_pointer(kernel_task_entry as usize);
|
||||
let mut ctx = TaskContext::default();
|
||||
ctx.set_instruction_pointer(kernel_task_entry as usize);
|
||||
// We should reserve space for the return address in the stack, otherwise
|
||||
// we will write across the page boundary due to the implementation of
|
||||
// the context switch.
|
||||
|
|
@ -239,14 +217,13 @@ impl TaskOptions {
|
|||
// to at least 16 bytes. And a larger alignment is needed if larger arguments
|
||||
// are passed to the function. The `kernel_task_entry` function does not
|
||||
// have any arguments, so we only need to align the stack pointer to 16 bytes.
|
||||
ctx.get_mut().set_stack_pointer(kstack.end_vaddr() - 16);
|
||||
ctx.set_stack_pointer(kstack.end_vaddr() - 16);
|
||||
|
||||
let new_task = Task {
|
||||
func: ForceSync::new(Cell::new(self.func)),
|
||||
data: self.data.unwrap_or_else(|| Box::new(())),
|
||||
local_data: ForceSync::new(self.local_data.unwrap_or_else(|| Box::new(()))),
|
||||
user_ctx: self.user_ctx,
|
||||
ctx,
|
||||
ctx: SyncUnsafeCell::new(ctx),
|
||||
kstack,
|
||||
schedule_info: TaskScheduleInfo {
|
||||
cpu: AtomicCpuId::default(),
|
||||
|
|
|
|||
Loading…
Reference in New Issue