Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 97 additions & 11 deletions docs/arceos-modules/task/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,49 @@ 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> {
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());
}

/// 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() {
Expand All @@ -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 {
Expand All @@ -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: 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
Expand All @@ -81,11 +112,12 @@ pub fn spawn<F>(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
Expand All @@ -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::<NoPreemptIrqSave>().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::<NoPreemptIrqSave>().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.
Expand Down Expand Up @@ -141,4 +227,4 @@ fn task_function() {
yield_now();
// 继续执行任务逻辑
}
```
```