|  | /* | 
|  | * Copyright (c) 2018,2024 Intel Corporation | 
|  | * | 
|  | * SPDX-License-Identifier: Apache-2.0 | 
|  | */ | 
|  | #include <zephyr/kernel.h> | 
|  | #include <ksched.h> | 
|  | #include <zephyr/spinlock.h> | 
|  |  | 
|  | extern struct k_spinlock _sched_spinlock; | 
|  |  | 
|  |  | 
|  | # ifdef CONFIG_SMP | 
|  | /* Right now we use a two byte for this mask */ | 
|  | BUILD_ASSERT(CONFIG_MP_MAX_NUM_CPUS <= 16, "Too many CPUs for mask word"); | 
|  | # endif /* CONFIG_SMP */ | 
|  |  | 
|  |  | 
|  | static int cpu_mask_mod(k_tid_t thread, uint32_t enable_mask, uint32_t disable_mask) | 
|  | { | 
|  | int ret = 0; | 
|  |  | 
|  | #ifdef CONFIG_SCHED_CPU_MASK_PIN_ONLY | 
|  | __ASSERT(z_is_thread_prevented_from_running(thread), | 
|  | "Running threads cannot change CPU pin"); | 
|  | #endif /* CONFIG_SCHED_CPU_MASK_PIN_ONLY */ | 
|  |  | 
|  | K_SPINLOCK(&_sched_spinlock) { | 
|  | if (z_is_thread_prevented_from_running(thread)) { | 
|  | thread->base.cpu_mask |= enable_mask; | 
|  | thread->base.cpu_mask  &= ~disable_mask; | 
|  | } else { | 
|  | ret = -EINVAL; | 
|  | } | 
|  | } | 
|  |  | 
|  | #if defined(CONFIG_ASSERT) && defined(CONFIG_SCHED_CPU_MASK_PIN_ONLY) | 
|  | int m = thread->base.cpu_mask; | 
|  |  | 
|  | __ASSERT((m == 0) || ((m & (m - 1)) == 0), | 
|  | "Only one CPU allowed in mask when PIN_ONLY"); | 
|  | #endif /* defined(CONFIG_ASSERT) && defined(CONFIG_SCHED_CPU_MASK_PIN_ONLY) */ | 
|  |  | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | int k_thread_cpu_mask_clear(k_tid_t thread) | 
|  | { | 
|  | return cpu_mask_mod(thread, 0, 0xffffffff); | 
|  | } | 
|  |  | 
|  | int k_thread_cpu_mask_enable_all(k_tid_t thread) | 
|  | { | 
|  | return cpu_mask_mod(thread, 0xffffffff, 0); | 
|  | } | 
|  |  | 
|  | int k_thread_cpu_mask_enable(k_tid_t thread, int cpu) | 
|  | { | 
|  | return cpu_mask_mod(thread, BIT(cpu), 0); | 
|  | } | 
|  |  | 
|  | int k_thread_cpu_mask_disable(k_tid_t thread, int cpu) | 
|  | { | 
|  | return cpu_mask_mod(thread, 0, BIT(cpu)); | 
|  | } | 
|  |  | 
|  | int k_thread_cpu_pin(k_tid_t thread, int cpu) | 
|  | { | 
|  | uint32_t mask = BIT(cpu); | 
|  |  | 
|  | return cpu_mask_mod(thread, mask, ~mask); | 
|  | } |