diff --git a/kernel/src/process/posix_thread/builder.rs b/kernel/src/process/posix_thread/builder.rs index d6085553f..408767e1c 100644 --- a/kernel/src/process/posix_thread/builder.rs +++ b/kernel/src/process/posix_thread/builder.rs @@ -2,7 +2,7 @@ #![allow(dead_code)] -use ostd::{task::Task, user::UserSpace}; +use ostd::{cpu::CpuSet, task::Task, user::UserSpace}; use super::{thread_table, PosixThread}; use crate::{ @@ -113,11 +113,13 @@ impl PosixThreadBuilder { let status = ThreadStatus::Init; let priority = Priority::default(); + let cpu_affinity = CpuSet::new_full(); let thread = Arc::new(Thread::new( weak_task.clone(), posix_thread, status, priority, + cpu_affinity, )); thread_table::add_thread(tid, thread.clone()); diff --git a/kernel/src/sched/priority_scheduler.rs b/kernel/src/sched/priority_scheduler.rs index 4f6726616..f84f55236 100644 --- a/kernel/src/sched/priority_scheduler.rs +++ b/kernel/src/sched/priority_scheduler.rs @@ -2,6 +2,7 @@ use ostd::{ cpu::{num_cpus, CpuSet, PinCurrentCpu}, + sync::PreemptDisabled, task::{ scheduler::{inject_scheduler, EnqueueFlags, LocalRunQueue, Scheduler, UpdateFlags}, AtomicCpuId, Task, @@ -259,8 +260,11 @@ impl PreemptSchedInfo for Task { &self.schedule_info().cpu } - fn cpu_affinity(&self) -> &CpuSet { - &self.schedule_info().cpu_affinity + fn cpu_affinity(&self) -> SpinLockGuard { + self.data() + .downcast_ref::>() + .unwrap() + .lock_cpu_affinity() } } @@ -272,7 +276,7 @@ trait PreemptSchedInfo { fn cpu(&self) -> &AtomicCpuId; - fn cpu_affinity(&self) -> &CpuSet; + fn cpu_affinity(&self) -> SpinLockGuard; fn is_real_time(&self) -> bool { self.priority() < Self::REAL_TIME_TASK_PRIORITY diff --git a/kernel/src/thread/kernel_thread.rs b/kernel/src/thread/kernel_thread.rs index bd30cebbb..fc7a342d5 100644 --- a/kernel/src/thread/kernel_thread.rs +++ b/kernel/src/thread/kernel_thread.rs @@ -55,19 +55,17 @@ pub fn create_new_kernel_task(mut thread_options: ThreadOptions) -> Arc { let kernel_thread = KernelThread; let status = ThreadStatus::Init; let priority = thread_options.priority; + let cpu_affinity = thread_options.cpu_affinity; Arc::new(Thread::new( weak_task.clone(), kernel_thread, status, priority, + cpu_affinity, )) }; - TaskOptions::new(thread_fn) - .data(thread) - .cpu_affinity(thread_options.cpu_affinity) - .build() - .unwrap() + TaskOptions::new(thread_fn).data(thread).build().unwrap() }) } diff --git a/kernel/src/thread/mod.rs b/kernel/src/thread/mod.rs index ceb830209..afe26b827 100644 --- a/kernel/src/thread/mod.rs +++ b/kernel/src/thread/mod.rs @@ -4,7 +4,7 @@ use core::sync::atomic::Ordering; -use ostd::task::Task; +use ostd::{cpu::CpuSet, sync::PreemptDisabled, task::Task}; use self::status::{AtomicThreadStatus, ThreadStatus}; use crate::{ @@ -33,6 +33,8 @@ pub struct Thread { status: AtomicThreadStatus, /// Thread priority priority: AtomicPriority, + /// Thread cpu affinity + cpu_affinity: SpinLock, } impl Thread { @@ -42,12 +44,14 @@ impl Thread { data: impl Send + Sync + Any, status: ThreadStatus, priority: Priority, + cpu_affinity: CpuSet, ) -> Self { Thread { task, data: Box::new(data), status: AtomicThreadStatus::new(status), priority: AtomicPriority::new(priority), + cpu_affinity: SpinLock::new(cpu_affinity), } } @@ -111,6 +115,16 @@ impl Thread { self.priority.store(new_priority, Ordering::Relaxed) } + /// Acquires the lock of cpu affinity. + pub fn lock_cpu_affinity(&self) -> SpinLockGuard { + self.cpu_affinity.lock() + } + + /// Updates the cpu affinity with the new value. + pub fn set_cpu_affinity(&self, new_cpu_affinity: CpuSet) { + *self.cpu_affinity.lock() = new_cpu_affinity; + } + pub fn yield_now() { Task::yield_now() } diff --git a/ostd/src/task/mod.rs b/ostd/src/task/mod.rs index 706bd6425..61d7fe0c4 100644 --- a/ostd/src/task/mod.rs +++ b/ostd/src/task/mod.rs @@ -19,7 +19,7 @@ pub use self::{ scheduler::info::{AtomicCpuId, TaskScheduleInfo}, }; pub(crate) use crate::arch::task::{context_switch, TaskContext}; -use crate::{cpu::CpuSet, prelude::*, user::UserSpace}; +use crate::{prelude::*, user::UserSpace}; /// A task that executes a function to the end. /// @@ -124,7 +124,6 @@ pub struct TaskOptions { func: Option>, data: Option>, user_space: Option>, - cpu_affinity: CpuSet, } impl TaskOptions { @@ -137,7 +136,6 @@ impl TaskOptions { func: Some(Box::new(func)), data: None, user_space: None, - cpu_affinity: CpuSet::new_full(), } } @@ -165,15 +163,6 @@ impl TaskOptions { self } - /// Sets the CPU affinity mask for the task. - /// - /// The `cpu_affinity` parameter represents - /// the desired set of CPUs to run the task on. - pub fn cpu_affinity(mut self, cpu_affinity: CpuSet) -> Self { - self.cpu_affinity = cpu_affinity; - self - } - /// Builds a new task without running it immediately. pub fn build(self) -> Result { /// all task will entering this function @@ -212,7 +201,6 @@ impl TaskOptions { kstack, schedule_info: TaskScheduleInfo { cpu: AtomicCpuId::default(), - cpu_affinity: self.cpu_affinity, }, }; diff --git a/ostd/src/task/scheduler/info.rs b/ostd/src/task/scheduler/info.rs index e6c633bb3..8b45f6c05 100644 --- a/ostd/src/task/scheduler/info.rs +++ b/ostd/src/task/scheduler/info.rs @@ -4,8 +4,6 @@ use core::sync::atomic::{AtomicU32, Ordering}; -use crate::cpu::CpuSet; - /// Fields of a task that OSTD will never touch. /// /// The type ought to be defined by the OSTD user and injected into the task. @@ -17,8 +15,6 @@ use crate::cpu::CpuSet; pub struct TaskScheduleInfo { /// The CPU that the task would like to be running on. pub cpu: AtomicCpuId, - /// The CPUs that this task can run on. - pub cpu_affinity: CpuSet, } /// An atomic CPUID container.