Task

Struct Task 

Source
pub struct Task {
Show 33 fields id: usize, namespace_id: AtomicUsize, namespace: RwLock<Arc<TaskNamespace>>, pub task_type: TaskType, pub entry: usize, parent_id: Option<usize>, tgid: usize, pub max_stack_size: usize, pub max_data_size: usize, pub max_text_size: usize, pub state: AtomicTaskState, pub priority: AtomicU32, pub time_slice: AtomicU32, pub stack_size: AtomicUsize, pub data_size: AtomicUsize, pub text_size: AtomicUsize, pub exit_status: AtomicI32, pub brk: Arc<AtomicUsize>, pub name: RwLock<String>, pub children: RwLock<Vec<usize>>, pub managed_pages: RwLock<Vec<ManagedPage>>, pub vfs: RwLock<Option<Arc<VfsManager>>>, pub software_timers_handlers: RwLock<Vec<Arc<dyn TimerHandler>>>, pub vcpu: Mutex<Vcpu>, pub kernel_context: Mutex<KernelContext>, pub vm_manager: VirtualMemoryManager, pub default_abi: TaskLocal<Option<Box<dyn AbiModule + Send + Sync>>>, pub abi_zones: TaskLocal<BTreeMap<usize, AbiZone>>, pub handle_table: HandleTable, pub sleep_waker: Waker, pub kernel_stack_window_base: Mutex<Option<(usize, usize)>>, pub event_queue: Mutex<TaskEventQueue>, pub events_enabled: Mutex<bool>,
}

Fields§

§id: usize§namespace_id: AtomicUsize

Task ID within the task’s namespace (may differ from global ID)

§namespace: RwLock<Arc<TaskNamespace>>

Task namespace for ID management

§task_type: TaskType§entry: usize§parent_id: Option<usize>§tgid: usize

Thread Group ID (TGID)

§max_stack_size: usize§max_data_size: usize§max_text_size: usize§state: AtomicTaskState

Task state with atomic transitions

§priority: AtomicU32

Task priority

§time_slice: AtomicU32

Time slice for scheduling

§stack_size: AtomicUsize

Stack size in bytes

§data_size: AtomicUsize

Data segment size in bytes

§text_size: AtomicUsize

Text segment size in bytes

§exit_status: AtomicI32

Exit status (i32::MIN represents None)

§brk: Arc<AtomicUsize>

Program break (already thread-safe)

§name: RwLock<String>

Task name

§children: RwLock<Vec<usize>>

List of child task IDs

§managed_pages: RwLock<Vec<ManagedPage>>

Managed pages (auto-freed on termination)

§vfs: RwLock<Option<Arc<VfsManager>>>

Virtual File System Manager

§Usage Patterns

  • None: Task uses global filesystem namespace (traditional Unix-like behavior)
  • Some(Arc<VfsManager>): Task has isolated filesystem namespace (container-like behavior)

§Thread Safety

VfsManager is thread-safe and can be shared between tasks using Arc. All internal operations use RwLock for concurrent access protection.

§software_timers_handlers: RwLock<Vec<Arc<dyn TimerHandler>>>

Software timer handlers

§vcpu: Mutex<Vcpu>

VCPU state for context switching

§kernel_context: Mutex<KernelContext>

Kernel context for context switching

§vm_manager: VirtualMemoryManager

Virtual memory manager (already thread-safe internally)

§default_abi: TaskLocal<Option<Box<dyn AbiModule + Send + Sync>>>

Default ABI module (task-local: only accessed by the executing hart)

§abi_zones: TaskLocal<BTreeMap<usize, AbiZone>>

ABI zones map (task-local: only accessed by the executing hart)

§handle_table: HandleTable

Handle table for kernel objects (already thread-safe internally)

§sleep_waker: Waker

Waker for sleep operations (already thread-safe internally)

§kernel_stack_window_base: Mutex<Option<(usize, usize)>>

Kernel stack window base (slot_index, base_vaddr)

§event_queue: Mutex<TaskEventQueue>

Task-local event queue with priority ordering

§events_enabled: Mutex<bool>

Event processing enabled flag

Implementations§

Source§

impl Task

Source

pub fn new(name: String, priority: u32, task_type: TaskType) -> Self

Create a new task with the root namespace.

§Arguments
  • name - Task name
  • priority - Task priority
  • task_type - Task type (Kernel or User)
§Returns

A new task in the root namespace

Source

pub fn new_with_namespace( name: String, priority: u32, task_type: TaskType, ns: Arc<TaskNamespace>, ) -> Self

Create a new task with a specific namespace.

§Arguments
  • name - Task name
  • priority - Task priority
  • task_type - Task type (Kernel or User)
  • ns - Task namespace
§Returns

A new task in the specified namespace

Source

pub fn init(&self)

Source

pub fn get_id(&self) -> usize

Source

pub fn set_id(&mut self, id: usize)

Set the task ID (used by TaskPool during task addition)

Source

pub fn set_namespace_id(&self, namespace_id: usize)

Set the namespace ID (used by TaskPool during task addition)

Source

pub fn get_namespace_id(&self) -> usize

Get the task ID within its namespace.

This ID is local to the task’s namespace and may differ from the global ID. This is the ID that should be exposed to user space and ABI syscalls.

§Returns

The namespace-local task ID

Source

pub fn get_namespace(&self) -> Arc<TaskNamespace>

Get the task’s namespace.

§Returns

Reference to the task’s namespace

Source

pub fn set_namespace(&self, ns: Arc<TaskNamespace>)

Set the task’s namespace.

This allows changing a task’s namespace, useful for ABI transitions or when moving tasks between namespace contexts.

Warning: This method allocates a new namespace-local ID each time it’s called. Changing a task’s namespace multiple times may lead to ID conflicts or unexpected behavior. This method should typically only be called once during task initialization or ABI transition.

§Arguments
  • ns - New namespace for the task
Source

pub fn get_tgid(&self) -> usize

Get the Thread Group ID (TGID)

The TGID identifies the thread group (process). For tasks created with CLONE_VM (threads), all threads in the group share the same TGID. For standalone tasks (no CLONE_VM), TGID equals the task ID.

§Returns

The thread group ID

Source

pub fn set_tgid(&mut self, tgid: usize)

Set the Thread Group ID (TGID)

This is used internally when cloning tasks with CLONE_VM to make the child thread share the parent’s thread group.

§Arguments
  • tgid - New thread group ID
Source

pub fn set_state(&self, state: TaskState)

Set the task state

§Arguments
  • state - The new task state
Source

pub fn get_state(&self) -> TaskState

Get the task state

§Returns

The task state

Source

pub fn get_size(&self) -> usize

Get the size of the task.

§Returns

The size of the task in bytes.

Source

pub fn get_brk(&self) -> usize

Get the program break (NOT work in Kernel task)

§Returns

The program break address

Source

pub fn set_brk(&self, brk: usize) -> Result<(), &'static str>

Set the program break (NOT work in Kernel task)

§Arguments
  • brk - The new program break address
§Returns

If successful, returns Ok(()), otherwise returns an error.

Source

pub fn allocate_pages( &self, vaddr: usize, num_of_pages: usize, permissions: usize, ) -> Result<VirtualMemoryMap, &'static str>

Allocate pages for the task.

§Arguments
  • vaddr - The virtual address to allocate pages (NOTE: The address must be page aligned)
  • num_of_pages - The number of pages to allocate
  • segment - The segment type to allocate pages
§Returns

The memory map of the allocated pages, if successful.

§Errors

If the address is not page aligned, or if the pages cannot be allocated.

§Note

This function don’t increment the size of the task. You must increment the size of the task manually.

Source

pub fn free_pages(&self, vaddr: usize, num_of_pages: usize)

Free pages for the task.

§Arguments
  • vaddr - The virtual address to free pages (NOTE: The address must be page aligned)
  • num_of_pages - The number of pages to free
Source

pub fn allocate_text_pages( &self, vaddr: usize, num_of_pages: usize, ) -> Result<VirtualMemoryMap, &'static str>

Allocate text pages for the task. And increment the size of the task.

§Arguments
  • vaddr - The virtual address to allocate pages (NOTE: The address must be page aligned)
  • num_of_pages - The number of pages to allocate
§Returns

The memory map of the allocated pages, if successful.

§Errors

If the address is not page aligned, or if the pages cannot be allocated.

Source

pub fn free_text_pages(&self, vaddr: usize, num_of_pages: usize)

Free text pages for the task. And decrement the size of the task.

§Arguments
  • vaddr - The virtual address to free pages (NOTE: The address must be page aligned)
  • num_of_pages - The number of pages to free
Source

pub fn allocate_stack_pages( &self, vaddr: usize, num_of_pages: usize, ) -> Result<VirtualMemoryMap, &'static str>

Allocate stack pages for the task. And increment the size of the task.

§Arguments
  • vaddr - The virtual address to allocate pages (NOTE: The address must be page aligned)
  • num_of_pages - The number of pages to allocate
§Returns

The memory map of the allocated pages, if successful.

§Errors

If the address is not page aligned, or if the pages cannot be allocated.

Source

pub fn free_stack_pages(&self, vaddr: usize, num_of_pages: usize)

Free stack pages for the task. And decrement the size of the task.

§Arguments
  • vaddr - The virtual address to free pages (NOTE: The address must be page aligned)
  • num_of_pages - The number of pages to free
Source

pub fn allocate_data_pages( &self, vaddr: usize, num_of_pages: usize, ) -> Result<VirtualMemoryMap, &'static str>

Allocate data pages for the task. And increment the size of the task.

§Arguments
  • vaddr - The virtual address to allocate pages (NOTE: The address must be page aligned)
  • num_of_pages - The number of pages to allocate
§Returns

The memory map of the allocated pages, if successful.

§Errors

If the address is not page aligned, or if the pages cannot be allocated.

Source

pub fn free_data_pages(&self, vaddr: usize, num_of_pages: usize)

Free data pages for the task. And decrement the size of the task.

§Arguments
  • vaddr - The virtual address to free pages (NOTE: The address must be page aligned)
  • num_of_pages - The number of pages to free
Source

pub fn allocate_guard_pages( &self, vaddr: usize, num_of_pages: usize, ) -> Result<VirtualMemoryMap, &'static str>

Allocate guard pages for the task.

§Arguments
  • vaddr - The virtual address to allocate pages (NOTE: The address must be page aligned)
  • num_of_pages - The number of pages to allocate
§Returns

The memory map of the allocated pages, if successful.

§Errors

If the address is not page aligned, or if the pages cannot be allocated.

§Note

Gurad pages are not allocated in the physical memory space. This function only maps the pages to the virtual memory space.

Source

pub fn add_managed_page(&self, pages: ManagedPage)

Add pages to the task

§Arguments
  • pages - The managed page to add
§Note

Pages added as ManagedPage of the Task will be automatically freed when the Task is terminated. So, you must not free them by calling free_raw_pages/free_boxed_pages manually.

Source

fn get_managed_page(&self, vaddr: usize) -> Option<ManagedPage>

Get managed page

§Arguments
  • vaddr - The virtual address of the page
§Returns

The managed page if found, otherwise None

Source

pub fn remove_managed_page(&self, vaddr: usize) -> Option<ManagedPage>

Remove managed page

§Arguments
  • vaddr - The virtual address of the page
§Returns

The removed managed page if found, otherwise None

Source

pub fn set_entry_point(&self, entry: usize)

Source

pub fn get_parent_id(&self) -> Option<usize>

Get the parent ID

§Returns

The parent task ID, or None if there is no parent

Source

pub fn set_parent_id(&mut self, parent_id: usize)

Set the parent task

§Arguments
  • parent_id - The ID of the parent task
Source

pub fn add_child(&self, child_id: usize)

Add a child task

§Arguments
  • child_id - The ID of the child task
Source

pub fn remove_child(&self, child_id: usize) -> bool

Remove a child task

§Arguments
  • child_id - The ID of the child task to remove
§Returns

true if the removal was successful, false if the child task was not found

Source

pub fn get_children(&self) -> Vec<usize>

Get the list of child tasks

§Returns

A vector of child task IDs

Source

pub fn set_exit_status(&self, status: i32)

Set the exit status

§Arguments
  • status - The exit status
Source

pub fn get_exit_status(&self) -> Option<i32>

Get the exit status

§Returns

The exit status, or None if not set

Source

pub fn with_resolve_abi_mut<R, F>(&self, addr: usize, f: F) -> R
where F: FnOnce(&mut (dyn AbiModule + Send + Sync)) -> R,

Resolve the ABI to use for the given address

This method calls a closure with the ABI module that should be used for a system call issued from the given address. It searches the ABI zones map and returns the appropriate ABI, falling back to the default ABI if no zone matches.

§Arguments
  • addr - The program counter address where the system call was issued
  • f - Closure to call with the ABI module
§Returns

The result of the closure

Source

pub fn with_default_abi<F, R>(&self, f: F) -> R
where F: FnOnce(&(dyn AbiModule + Send + Sync)) -> R,

Execute a closure with the default ABI

§Arguments
  • f - Closure to call with the default ABI
§Returns

The result of the closure

Source

pub fn with_default_abi_mut<R, F>(&self, f: F) -> R
where F: FnOnce(&mut (dyn AbiModule + Send + Sync), &Task) -> R,

Run a closure with mutable access to the default ABI and a reference to the task

Since default_abi is task-local (no lock), we can safely provide both &mut AbiModule and &Task without any take/restore dance.

Source

pub fn clone_task(&self, flags: CloneFlags) -> Result<Task, &'static str>

Get the file descriptor table

§Returns

A reference to the file descriptor table

Clone this task, creating a near-identical copy

§Arguments
§Returns

The cloned task

§Errors

If the task cannot be cloned, an error is returned.

Source

pub fn exit(&self, status: i32)

Exit the task

§Arguments
  • status - The exit status
Source

pub fn exit_group(&self, status: i32)

Exit all tasks in the thread group

This terminates all tasks with the same TGID (thread group). This is similar to Linux’s exit_group system call.

§Arguments
  • status - The exit status for all tasks in the group
§Behavior
  • Terminates all tasks with the same TGID
  • The calling task is set to Zombie/Terminated
  • Other tasks in the group are forcefully terminated
Source

pub fn wait(&self, child_id: usize) -> Result<i32, WaitError>

Wait for a child task to exit and collect its status

§Arguments
  • child_id - The ID of the child task to wait for
§Returns

The exit status of the child task, or an error if the child is not found or not in Zombie state

Source

pub fn sleep(&self, trapframe: &mut Trapframe, ticks: u64)

Sleep the current task for the specified number of ticks. This blocks the task and registers a timer to wake it up.

§Arguments
  • trapframe - The trapframe of the current CPU state
  • ticks - The number of ticks to sleep
Source

pub fn set_vfs(&self, vfs: Arc<VfsManager>)

Set the VFS manager

§Arguments
  • vfs - The VfsManager to set as the VFS
Source

pub fn get_vfs(&self) -> Option<Arc<VfsManager>>

Get a reference to the VFS

Source

pub fn add_software_timer_handler(&self, timer: Arc<dyn TimerHandler>)

Source

pub fn remove_software_timer_handler(&self, timer: &Arc<dyn TimerHandler>)

Source

pub fn enable_events(&self)

Enable event processing for this task (similar to enabling interrupts)

Source

pub fn disable_events(&self)

Disable event processing for this task (similar to disabling interrupts)

Source

pub fn events_enabled(&self) -> bool

Check if events are enabled for this task

Source

pub fn process_pending_events(&self) -> Result<(), &'static str>

Process pending events if events are enabled This should be called by the scheduler before resuming the task

Following signal-like semantics:

  • Process a limited number of events per scheduler cycle to avoid starvation
  • Critical events (like KILL) are processed immediately
  • Normal events are batched and processed in priority order
Source

fn is_critical_event(&self, event: &Event) -> bool

Check if an event is critical and should be processed immediately Critical events typically cannot be ignored and affect task state directly

Source

pub fn with_kernel_context<R>( &self, f: impl FnOnce(&mut KernelContext) -> R, ) -> R

Source

pub fn get_kernel_stack_bottom_paddr(&self) -> u64

Get the kernel stack bottom address for this task

§Returns

The kernel stack bottom address as u64, or 0 if no kernel stack is allocated

Source

pub fn get_kernel_stack_memory_area_paddr(&self) -> MemoryArea

Get the kernel stack memory area for this task

§Returns

The kernel stack memory area as a MemoryArea

Source

pub fn get_trapframe(&self) -> &mut Trapframe

Get a mutable reference to the trapframe for this task

The trapframe contains the user-space register state and is located at the top of the kernel stack. This provides access to modify the user context during system calls, interrupts, and context switches.

If a kernel stack window is mapped (high-VA), this returns a reference via the mapped virtual address. Otherwise, it returns a reference via the physical address directly.

§Returns

A mutable reference to the Trapframe

Source

pub fn set_kernel_stack_window_base(&self, base: Option<(usize, usize)>)

Internal: set kernel stack window base (slot index and base vaddr)

Source

pub fn get_kernel_stack_window_base(&self) -> Option<(usize, usize)>

Get kernel stack window base (slot index and base vaddr)

Trait Implementations§

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.