Task

Struct Task 

Source
pub struct Task {
Show 32 fields pub context: Context, pub preempt_count: usize, pub priority: u8, pub processor_id: usize, pub state: TaskState, pub tid: u32, pub pid: u32, pub ppid: u32, pub pgid: u32, pub children: Arc<SpinLock<Vec<Arc<SpinLock<Task>>>>>, pub wait_child: Arc<SpinLock<WaitQueue>>, pub kstack_base: usize, pub trap_frame_ptr: AtomicPtr<TrapFrame>, pub memory_space: Option<Arc<SpinLock<MemorySpace>>>, pub exit_code: Option<i32>, kstack_tracker: FrameRangeTracker, trap_frame_tracker: FrameTracker, pub blocked: SignalFlags, pub pending: SignalPending, pub shared_pending: Arc<SpinLock<SignalPending>>, pub signal_handlers: Arc<SpinLock<SignalHandlerTable>>, pub signal_stack: Arc<SpinLock<SignalStack>>, pub exit_signal: u8, pub uts_namespace: Arc<SpinLock<UtsNamespace>>, pub rlimit: Arc<SpinLock<RlimitStruct>>, pub robust_list: Option<usize>, pub set_child_tid: usize, pub clear_child_tid: usize, pub credential: Credential, pub umask: u32, pub fd_table: Arc<FDTable>, pub fs: Arc<SpinLock<FsStruct>>,
}
Expand description

任务 存放任务的核心信息 其中的信息可以分为几大类:

  1. 调度运行相关的信息,如上下文、状态、优先级等
  2. 任务标识信息,如 tid、pid、ppid、子任务等
  3. 任务资源信息,如内核栈、TrapFrame、内存空间等 表示进程的任务与表示线程的任务由本结构体统一表征 其区别仅在于:
  4. 进程的 pid 等于 tid,线程的 pid 不等于 tid
  5. 进程的返回值通过 exit_code 字段传递,线程的返回值通过 return_value 字段传递
  6. 对于所有3.类信息,均通过引用计数共享。创建时任务,进程需传入新的Arc<T>,而线程则共享父任务的资源。 注意:线程拥有自己独立的运行栈,和一套寄存器上下文。 TrapFrame,Context结构可以保证所有线程切换时保存和恢复寄存器状态。 每个任务的内核栈独立分配,互不干扰。内核线程只使用内核栈。 但是上层必须自己保证创建的用户线程在用户态运行时拥有独立的用户栈空间。 OPTIMIZE: 简单起见目前的设计中,Task 结构体包含了所有信息,包括调度相关的信息和资源管理相关的信息。 未来可以考虑将其拆分为 TaskInfo 和 TaskStruct 两个部分,以提高访问效率和模块化程度。

Fields§

§context: Context

任务的上下文信息,用于任务切换

§preempt_count: usize

任务的抢占计数器,表示当前任务被禁止抢占的次数 当该值大于0时,表示任务处于不可抢占状态。暂未使用

§priority: u8

任务的优先级,数值越小优先级越高。暂未使用

§processor_id: usize

任务所在的处理器id。暂未使用

§state: TaskState

任务当前的状态

§tid: u32

任务的id

§pid: u32

任务的所属进程id NOTE: 由于采用了统一的任务模型,一个任务组内任务的 pid 是相同的,等于父任务的 pid 而父任务的 pid 等于自己的 tid

§ppid: u32

父任务的id

§pgid: u32

任务的进程组id

§children: Arc<SpinLock<Vec<Arc<SpinLock<Task>>>>>

任务的子任务列表

§wait_child: Arc<SpinLock<WaitQueue>>

任务的等待队列

§kstack_base: usize

内核栈基址

§trap_frame_ptr: AtomicPtr<TrapFrame>

中断上下文。指向当前任务内核栈上的 TrapFrame,仅在任务被中断时有效。

§memory_space: Option<Arc<SpinLock<MemorySpace>>>

任务的内存空间 对于内核任务,该字段为 None

§exit_code: Option<i32>

退出码 存储任务退出时的状态码,通常用于表示任务的执行结果 由 exit 接口设置 对应于 waitpid 的 exit_status

§kstack_tracker: FrameRangeTracker

内核栈跟踪器

§trap_frame_tracker: FrameTracker

任务的 TrapFrame 跟踪器

§blocked: SignalFlags

信号屏蔽字

§pending: SignalPending

私有待处理信号集合

§shared_pending: Arc<SpinLock<SignalPending>>

待处理信号队列

§signal_handlers: Arc<SpinLock<SignalHandlerTable>>

信号处理动作表

§signal_stack: Arc<SpinLock<SignalStack>>

备用信号栈信息

§exit_signal: u8

退出信号, 当任务退出时发送给父任务的信号

§uts_namespace: Arc<SpinLock<UtsNamespace>>

UTS 命名空间

§rlimit: Arc<SpinLock<RlimitStruct>>

资源限制结构体

§robust_list: Option<usize>

健壮列表头地址及其大小

§set_child_tid: usize

线程ID地址

§clear_child_tid: usize

线程退出时清除的线程ID地址

§credential: Credential

任务凭证(用户、组、能力)

§umask: u32

文件创建掩码

§fd_table: Arc<FDTable>

文件描述符表

§fs: Arc<SpinLock<FsStruct>>

文件系统信息

Implementations§

Source§

impl Task

Source

pub fn ktask_create( tid: u32, pid: u32, ppid: u32, children: Arc<SpinLock<Vec<Arc<SpinLock<Task>>>>>, kstack_tracker: FrameRangeTracker, trap_frame_tracker: FrameTracker, signal_handlers: Arc<SpinLock<SignalHandlerTable>>, blocked: SignalFlags, signal: Arc<SpinLock<SignalPending>>, uts_namespace: Arc<SpinLock<UtsNamespace>>, rlimit: Arc<SpinLock<RlimitStruct>>, fd_table: Arc<FDTable>, fs: Arc<SpinLock<FsStruct>>, ) -> Self

为内核线程初始化任务上下文

§参数
  • tid: 任务ID
  • pid: 进程ID
  • ppid: 父任务ID
  • kstack_tracker: 内核栈的帧跟踪器
  • trap_frame_tracker: TrapFrame 的帧跟踪器
  • entry: 任务的入口地址
§返回值

新创建的任务 注意:调用者必须自己初始化TrapFrame内容

Source

pub fn utask_create( tid: u32, pid: u32, ppid: u32, pgid: u32, children: Arc<SpinLock<Vec<Arc<SpinLock<Task>>>>>, kstack_tracker: FrameRangeTracker, trap_frame_tracker: FrameTracker, memory_space: Arc<SpinLock<MemorySpace>>, signal_handlers: Arc<SpinLock<SignalHandlerTable>>, blocked: SignalFlags, signal: Arc<SpinLock<SignalPending>>, signal_stack: Arc<SpinLock<SignalStack>>, exit_signal: u8, uts_namespace: Arc<SpinLock<UtsNamespace>>, rlimit: Arc<SpinLock<RlimitStruct>>, fd_table: Arc<FDTable>, fs: Arc<SpinLock<FsStruct>>, ) -> Self

创建一个新的用户任务

§参数
  • ppid: 父任务ID
  • memory_space: 任务的内存空间
§返回值

新创建的任务 注意:调用者必须自己初始化TrapFrame内容

Source

pub fn execve( &mut self, new_memory_space: Arc<SpinLock<MemorySpace>>, entry_point: usize, sp_high: usize, argv: &[&str], envp: &[&str], phdr_addr: usize, phnum: usize, phent: usize, )

执行 execve 操作,替换当前任务的内存空间和上下文

§参数
  • new_memory_space: 新的内存空间
  • entry_point: 新程序的入口地址
  • sp: 新程序的栈指针
  • argv: 传递给新程序的参数列表
  • envp: 传递给新程序的环境变量列表
Source

pub fn check_child( &mut self, cond: impl FnMut(&Arc<SpinLock<Task>>) -> bool, remove: bool, ) -> Option<Arc<SpinLock<Task>>>

检查是否有满足条件的子任务

§参数
  • cond: 用于检查子任务的条件闭包
  • remove: 是否在找到后从子任务列表中移除该僵尸子任务(如果是)
§返回值

如果有,返回该子任务的共享句柄. 如果没有,返回 None 注意:此函数不阻塞,调用者需持有锁

Source

pub fn notify_child_exit(&mut self)

Source

pub fn is_kernel_thread(&self) -> bool

判断该任务是否为内核线程

Source

pub fn is_process(&self) -> bool

判断该任务是否为进程 / 主线程 对于进程,其 pid 等于 tid

Source

pub fn into_shared(self) -> Arc<SpinLock<Task>>

把已初始化的 TaskStruct 包装为共享任务句柄 返回值: 包装后的 SharedTask

Source

pub fn empty_children() -> Arc<SpinLock<Vec<Arc<SpinLock<Task>>>>>

返回一个空的子任务列表 用于创建新任务时初始化 children 字段

Source

fn new( tid: u32, pid: u32, ppid: u32, pgid: u32, children: Arc<SpinLock<Vec<Arc<SpinLock<Task>>>>>, kstack_tracker: FrameRangeTracker, trap_frame_tracker: FrameTracker, memory_space: Option<Arc<SpinLock<MemorySpace>>>, signal_handlers: Arc<SpinLock<SignalHandlerTable>>, blocked: SignalFlags, shared_pending: Arc<SpinLock<SignalPending>>, signal_stack: Arc<SpinLock<SignalStack>>, exit_signal: u8, uts_namespace: Arc<SpinLock<UtsNamespace>>, rlimit: Arc<SpinLock<RlimitStruct>>, fd_table: Arc<FDTable>, fs: Arc<SpinLock<FsStruct>>, ) -> Self

Trait Implementations§

Source§

impl Debug for Task

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for Task

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl !Freeze for Task

§

impl !RefUnwindSafe for Task

§

impl Send for Task

§

impl Sync for Task

§

impl Unpin for Task

§

impl !UnwindSafe for Task

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.