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: AtomicUsizeTask 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: usizeThread Group ID (TGID)
max_stack_size: usize§max_data_size: usize§max_text_size: usize§state: AtomicTaskStateTask state with atomic transitions
priority: AtomicU32Task priority
time_slice: AtomicU32Time slice for scheduling
stack_size: AtomicUsizeStack size in bytes
data_size: AtomicUsizeData segment size in bytes
text_size: AtomicUsizeText segment size in bytes
exit_status: AtomicI32Exit 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: VirtualMemoryManagerVirtual 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: HandleTableHandle table for kernel objects (already thread-safe internally)
sleep_waker: WakerWaker 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
impl Task
Sourcepub fn new_with_namespace(
name: String,
priority: u32,
task_type: TaskType,
ns: Arc<TaskNamespace>,
) -> Self
pub fn new_with_namespace( name: String, priority: u32, task_type: TaskType, ns: Arc<TaskNamespace>, ) -> Self
pub fn init(&self)
pub fn get_id(&self) -> usize
Sourcepub fn set_namespace_id(&self, namespace_id: usize)
pub fn set_namespace_id(&self, namespace_id: usize)
Set the namespace ID (used by TaskPool during task addition)
Sourcepub fn get_namespace_id(&self) -> usize
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
Sourcepub fn get_namespace(&self) -> Arc<TaskNamespace>
pub fn get_namespace(&self) -> Arc<TaskNamespace>
Sourcepub fn set_namespace(&self, ns: Arc<TaskNamespace>)
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
Sourcepub fn get_tgid(&self) -> usize
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
Sourcepub fn set_tgid(&mut self, tgid: usize)
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
Sourcepub fn allocate_pages(
&self,
vaddr: usize,
num_of_pages: usize,
permissions: usize,
) -> Result<VirtualMemoryMap, &'static str>
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 allocatesegment- 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.
Sourcepub fn free_pages(&self, vaddr: usize, num_of_pages: usize)
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
Sourcepub fn allocate_text_pages(
&self,
vaddr: usize,
num_of_pages: usize,
) -> Result<VirtualMemoryMap, &'static str>
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.
Sourcepub fn free_text_pages(&self, vaddr: usize, num_of_pages: usize)
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
Sourcepub fn allocate_stack_pages(
&self,
vaddr: usize,
num_of_pages: usize,
) -> Result<VirtualMemoryMap, &'static str>
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.
Sourcepub fn free_stack_pages(&self, vaddr: usize, num_of_pages: usize)
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
Sourcepub fn allocate_data_pages(
&self,
vaddr: usize,
num_of_pages: usize,
) -> Result<VirtualMemoryMap, &'static str>
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.
Sourcepub fn free_data_pages(&self, vaddr: usize, num_of_pages: usize)
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
Sourcepub fn allocate_guard_pages(
&self,
vaddr: usize,
num_of_pages: usize,
) -> Result<VirtualMemoryMap, &'static str>
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.
Sourcepub fn add_managed_page(&self, pages: ManagedPage)
pub fn add_managed_page(&self, pages: ManagedPage)
Sourcefn get_managed_page(&self, vaddr: usize) -> Option<ManagedPage>
fn get_managed_page(&self, vaddr: usize) -> Option<ManagedPage>
Sourcepub fn remove_managed_page(&self, vaddr: usize) -> Option<ManagedPage>
pub fn remove_managed_page(&self, vaddr: usize) -> Option<ManagedPage>
pub fn set_entry_point(&self, entry: usize)
Sourcepub fn get_parent_id(&self) -> Option<usize>
pub fn get_parent_id(&self) -> Option<usize>
Sourcepub fn set_parent_id(&mut self, parent_id: usize)
pub fn set_parent_id(&mut self, parent_id: usize)
Sourcepub fn remove_child(&self, child_id: usize) -> bool
pub fn remove_child(&self, child_id: usize) -> bool
Sourcepub fn get_children(&self) -> Vec<usize>
pub fn get_children(&self) -> Vec<usize>
Sourcepub fn set_exit_status(&self, status: i32)
pub fn set_exit_status(&self, status: i32)
Sourcepub fn get_exit_status(&self) -> Option<i32>
pub fn get_exit_status(&self) -> Option<i32>
Sourcepub fn with_resolve_abi_mut<R, F>(&self, addr: usize, f: F) -> Rwhere
F: FnOnce(&mut (dyn AbiModule + Send + Sync)) -> R,
pub fn with_resolve_abi_mut<R, F>(&self, addr: usize, f: F) -> Rwhere
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 issuedf- Closure to call with the ABI module
§Returns
The result of the closure
Sourcepub fn with_default_abi<F, R>(&self, f: F) -> Rwhere
F: FnOnce(&(dyn AbiModule + Send + Sync)) -> R,
pub fn with_default_abi<F, R>(&self, f: F) -> Rwhere
F: FnOnce(&(dyn AbiModule + Send + Sync)) -> R,
Sourcepub fn with_default_abi_mut<R, F>(&self, f: F) -> R
pub fn with_default_abi_mut<R, F>(&self, f: F) -> 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.
Sourcepub fn clone_task(&self, flags: CloneFlags) -> Result<Task, &'static str>
pub fn clone_task(&self, flags: CloneFlags) -> Result<Task, &'static str>
Sourcepub fn exit_group(&self, status: i32)
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
Sourcepub fn sleep(&self, trapframe: &mut Trapframe, ticks: u64)
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 stateticks- The number of ticks to sleep
Sourcepub fn set_vfs(&self, vfs: Arc<VfsManager>)
pub fn set_vfs(&self, vfs: Arc<VfsManager>)
Sourcepub fn get_vfs(&self) -> Option<Arc<VfsManager>>
pub fn get_vfs(&self) -> Option<Arc<VfsManager>>
Get a reference to the VFS
pub fn add_software_timer_handler(&self, timer: Arc<dyn TimerHandler>)
pub fn remove_software_timer_handler(&self, timer: &Arc<dyn TimerHandler>)
Sourcepub fn enable_events(&self)
pub fn enable_events(&self)
Enable event processing for this task (similar to enabling interrupts)
Sourcepub fn disable_events(&self)
pub fn disable_events(&self)
Disable event processing for this task (similar to disabling interrupts)
Sourcepub fn events_enabled(&self) -> bool
pub fn events_enabled(&self) -> bool
Check if events are enabled for this task
Sourcepub fn process_pending_events(&self) -> Result<(), &'static str>
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
Sourcefn is_critical_event(&self, event: &Event) -> bool
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
pub fn with_kernel_context<R>( &self, f: impl FnOnce(&mut KernelContext) -> R, ) -> R
Sourcepub fn get_kernel_stack_bottom_paddr(&self) -> u64
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
Sourcepub fn get_kernel_stack_memory_area_paddr(&self) -> MemoryArea
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
Sourcepub fn get_trapframe(&self) -> &mut Trapframe
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
Sourcepub fn set_kernel_stack_window_base(&self, base: Option<(usize, usize)>)
pub fn set_kernel_stack_window_base(&self, base: Option<(usize, usize)>)
Internal: set kernel stack window base (slot index and base vaddr)
Sourcepub fn get_kernel_stack_window_base(&self) -> Option<(usize, usize)>
pub fn get_kernel_stack_window_base(&self) -> Option<(usize, usize)>
Get kernel stack window base (slot index and base vaddr)