diff --git a/docs/arceos-modules/task/api.md b/docs/arceos-modules/task/api.md index ea11422..e072786 100644 --- a/docs/arceos-modules/task/api.md +++ b/docs/arceos-modules/task/api.md @@ -22,15 +22,38 @@ cfg_if::cfg_if! { * 如果启用 sched_cfs 特性,使用完全公平调度(CFS); * 否则,使用先进先出调度(FIFO)作为默认调度算法。 -#### 2. 任务调度器初始化 +#### 2. 获取当前任务 +```rust +/// Gets the current task, or returns [`None`] if the current task is not +/// initialized. +pub fn current_may_uninit() -> Option { + CurrentTask::try_get() +} + +/// Gets the current task. +/// +/// # Panics +/// +/// Panics if the current task is not initialized. +pub fn current() -> CurrentTask { + CurrentTask::get() +} +``` +current_may_uninit 与 current 函数都是用来获取当前任务,区别在于 current_may_uninit 在当前任务没有初始化时返回 `None`, current 则会直接 Panic + +#### 3. 任务调度器初始化 ```rust /// Initializes the task scheduler (for the primary CPU). pub fn init_scheduler() { + init_scheduler_with_cpu_num(axconfig::plat::CPU_NUM); +} + +/// Initializes the task scheduler with cpu_num (for the primary CPU). +pub fn init_scheduler_with_cpu_num(cpu_num: usize) { info!("Initialize scheduling..."); + CPU_NUM.store(cpu_num, core::sync::atomic::Ordering::Relaxed); crate::run_queue::init(); - #[cfg(feature = "irq")] - crate::timers::init(); info!(" use {} scheduler.", Scheduler::scheduler_name()); } @@ -38,12 +61,10 @@ pub fn init_scheduler() { /// Initializes the task scheduler for secondary CPUs. pub fn init_scheduler_secondary() { crate::run_queue::init_secondary(); - #[cfg(feature = "irq")] - crate::timers::init(); } ``` -init_scheduler 函数用于初始化主 CPU 的任务调度器; -init_scheduler_secondary 函数用于初始化辅助 CPU 的任务调度器。初始化过程包括运行队列的初始化和定时器的初始化(如果启用了 irq 特性)。 +init_scheduler 函数用于初始化主 CPU 的任务调度器,同时保存 CPU_NUM 记录 CPU 数量;init_scheduler_secondary 函数用于初始化辅助 CPU 的任务调度器。 +初始化过程以运行队列的初始化为主。 用例:在系统启动时调用 init_scheduler 函数: ```rust fn main() { @@ -52,7 +73,7 @@ fn main() { } ``` -#### 3. 任务创建 +#### 4. 任务创建 ```rust /// Adds the given task to the run queue, returns the task reference. pub fn spawn_task(task: TaskInner) -> AxTaskRef { @@ -71,6 +92,16 @@ where spawn_task(TaskInner::new(f, name, stack_size)) } +/// Spawns a new task with the given name and the default stack size ([`axconfig::TASK_STACK_SIZE`]). +/// +/// Returns the task reference. +pub fn spawn_with_name(f: F, name: String) -> AxTaskRef +where + F: FnOnce() + Send + 'static, +{ + spawn_raw(f, name, axconfig::TASK_STACK_SIZE) +} + /// Spawns a new task with the default parameters. /// /// The default task name is an empty string. The default task stack size is @@ -81,11 +112,12 @@ pub fn spawn(f: F) -> AxTaskRef where F: FnOnce() + Send + 'static, { - spawn_raw(f, "".into(), axconfig::TASK_STACK_SIZE) + spawn_with_name(f, String::new()) } ``` spawn_task 函数将一个 TaskInner 类型的任务添加到运行队列中,并返回任务的引用; spawn_raw 函数根据给定的任务入口函数、任务名称和栈大小创建一个新任务,并调用 spawn_task 函数将其添加到运行队列中; +spawn_with_name 函数根据给定的任务入口函数和名称,默认栈大小为 axconfig::TASK_STACK_SIZE ,调用spawn_raw; spawn 函数使用默认的任务名称和栈大小创建新任务。 用例:创建一个新任务: ```rust @@ -99,8 +131,62 @@ fn main() { // 其他操作 } ``` +#### 5. 任务相关设置 +```rust +/// Set the priority for current task. +/// +/// The range of the priority is dependent on the underlying scheduler. For +/// example, in the [CFS] scheduler, the priority is the nice value, ranging from +/// -20 to 19. +/// +/// Returns `true` if the priority is set successfully. +/// +/// [CFS]: https://en.wikipedia.org/wiki/Completely_Fair_Scheduler +pub fn set_priority(prio: isize) -> bool { + current_run_queue::().set_current_priority(prio) +} -#### 4. 任务调度相关操作 +/// Set the affinity for the current task. +/// [`AxCpuMask`] is used to specify the CPU affinity. +/// Returns `true` if the affinity is set successfully. +/// +/// TODO: support set the affinity for other tasks. +pub fn set_current_affinity(cpumask: AxCpuMask) -> bool { + if cpumask.is_empty() { + false + } else { + let curr = current().clone(); + + curr.set_cpumask(cpumask); + // After setting the affinity, we need to check if current cpu matches + // the affinity. If not, we need to migrate the task to the correct CPU. + #[cfg(feature = "smp")] + if !cpumask.get(axhal::percpu::this_cpu_id()) { + const MIGRATION_TASK_STACK_SIZE: usize = 4096; + // Spawn a new migration task for migrating. + let migration_task = TaskInner::new( + move || crate::run_queue::migrate_entry(curr), + "migration-task".into(), + MIGRATION_TASK_STACK_SIZE, + ) + .into_arc(); + + // Migrate the current task to the correct CPU using the migration task. + current_run_queue::().migrate_current(migration_task); + + assert!( + cpumask.get(axhal::percpu::this_cpu_id()), + "Migration failed" + ); + } + true + } +} +``` +set_priority 函数用于设置当前任务优先级,例如在 CFS 调度器中,可选的优先级为 -20 到 19。返回值为是否设置成功。 +set_current_affinity 函数用于通过 `cpumask` 设置当前任务的 CPU 亲和性,特殊的,如果给定的 `cpumask` 中不包括当前 CPU,则需要通过构造迁移任务将当前任务迁移到当前 CPU。返回值为是否设置成功。 + +#### 6. 任务调度相关操作 ```rust /// Current task gives up the CPU time voluntarily, and switches to another /// ready task. @@ -141,4 +227,4 @@ fn task_function() { yield_now(); // 继续执行任务逻辑 } -``` \ No newline at end of file +```