1 /*
2 * Copyright (c) 2018,2024 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/kernel.h>
7 #include <ksched.h>
8 #include <zephyr/spinlock.h>
9
10 extern struct k_spinlock _sched_spinlock;
11
12
13 # ifdef CONFIG_SMP
14 /* Right now we use a two byte for this mask */
15 BUILD_ASSERT(CONFIG_MP_MAX_NUM_CPUS <= 16, "Too many CPUs for mask word");
16 # endif /* CONFIG_SMP */
17
18
cpu_mask_mod(k_tid_t thread,uint32_t enable_mask,uint32_t disable_mask)19 static int cpu_mask_mod(k_tid_t thread, uint32_t enable_mask, uint32_t disable_mask)
20 {
21 int ret = 0;
22
23 #ifdef CONFIG_SCHED_CPU_MASK_PIN_ONLY
24 __ASSERT(z_is_thread_prevented_from_running(thread),
25 "Running threads cannot change CPU pin");
26 #endif /* CONFIG_SCHED_CPU_MASK_PIN_ONLY */
27
28 K_SPINLOCK(&_sched_spinlock) {
29 if (z_is_thread_prevented_from_running(thread)) {
30 thread->base.cpu_mask |= enable_mask;
31 thread->base.cpu_mask &= ~disable_mask;
32 } else {
33 ret = -EINVAL;
34 }
35 }
36
37 #if defined(CONFIG_ASSERT) && defined(CONFIG_SCHED_CPU_MASK_PIN_ONLY)
38 int m = thread->base.cpu_mask;
39
40 __ASSERT((m == 0) || ((m & (m - 1)) == 0),
41 "Only one CPU allowed in mask when PIN_ONLY");
42 #endif /* defined(CONFIG_ASSERT) && defined(CONFIG_SCHED_CPU_MASK_PIN_ONLY) */
43
44 return ret;
45 }
46
k_thread_cpu_mask_clear(k_tid_t thread)47 int k_thread_cpu_mask_clear(k_tid_t thread)
48 {
49 return cpu_mask_mod(thread, 0, 0xffffffff);
50 }
51
k_thread_cpu_mask_enable_all(k_tid_t thread)52 int k_thread_cpu_mask_enable_all(k_tid_t thread)
53 {
54 return cpu_mask_mod(thread, 0xffffffff, 0);
55 }
56
k_thread_cpu_mask_enable(k_tid_t thread,int cpu)57 int k_thread_cpu_mask_enable(k_tid_t thread, int cpu)
58 {
59 return cpu_mask_mod(thread, BIT(cpu), 0);
60 }
61
k_thread_cpu_mask_disable(k_tid_t thread,int cpu)62 int k_thread_cpu_mask_disable(k_tid_t thread, int cpu)
63 {
64 return cpu_mask_mod(thread, 0, BIT(cpu));
65 }
66
k_thread_cpu_pin(k_tid_t thread,int cpu)67 int k_thread_cpu_pin(k_tid_t thread, int cpu)
68 {
69 int ret;
70
71 ret = k_thread_cpu_mask_clear(thread);
72 if (ret == 0) {
73 return k_thread_cpu_mask_enable(thread, cpu);
74 }
75 return ret;
76 }
77