xref: /nrf52832-nimble/rt-thread/src/cpu.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * Copyright (c) 2006-2018, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-10-30     Bernard      The first version
9  */
10 
11 #include <rtthread.h>
12 #include <rthw.h>
13 
14 #ifdef RT_USING_SMP
15 
16 static struct rt_cpu rt_cpus[RT_CPUS_NR];
17 rt_hw_spinlock_t _cpus_lock;
18 
19 /**
20  * This fucntion will return current cpu.
21  */
rt_cpu_self(void)22 struct rt_cpu *rt_cpu_self(void)
23 {
24     return &rt_cpus[rt_hw_cpu_id()];
25 }
26 
rt_cpu_index(int index)27 struct rt_cpu *rt_cpu_index(int index)
28 {
29     return &rt_cpus[index];
30 }
31 
32 /**
33  * This function will lock all cpus's scheduler and disable local irq.
34  */
rt_cpus_lock(void)35 rt_base_t rt_cpus_lock(void)
36 {
37     rt_base_t level;
38     struct rt_cpu* pcpu;
39 
40     level = rt_hw_local_irq_disable();
41 
42     pcpu = rt_cpu_self();
43     if (pcpu->current_thread != RT_NULL)
44     {
45         if (pcpu->current_thread->cpus_lock_nest++ == 0)
46         {
47             pcpu->current_thread->scheduler_lock_nest++;
48             rt_hw_spin_lock(&_cpus_lock);
49         }
50     }
51     return level;
52 }
53 RTM_EXPORT(rt_cpus_lock);
54 
55 /**
56  * This function will restore all cpus's scheduler and restore local irq.
57  */
rt_cpus_unlock(rt_base_t level)58 void rt_cpus_unlock(rt_base_t level)
59 {
60     struct rt_cpu* pcpu = rt_cpu_self();
61 
62     if (pcpu->current_thread != RT_NULL)
63     {
64         if (--pcpu->current_thread->cpus_lock_nest == 0)
65         {
66             pcpu->current_thread->scheduler_lock_nest--;
67             rt_hw_spin_unlock(&_cpus_lock);
68         }
69     }
70     rt_hw_local_irq_enable(level);
71 }
72 RTM_EXPORT(rt_cpus_unlock);
73 
74 /**
75  * This function is invoked by scheduler.
76  * It will restore the lock state to whatever the thread's counter expects.
77  * If target thread not locked the cpus then unlock the cpus lock.
78  */
rt_cpus_lock_status_restore(struct rt_thread * thread)79 void rt_cpus_lock_status_restore(struct rt_thread *thread)
80 {
81     struct rt_cpu* pcpu = rt_cpu_self();
82 
83     pcpu->current_thread = thread;
84     if (!thread->cpus_lock_nest)
85     {
86         rt_hw_spin_unlock(&_cpus_lock);
87     }
88 }
89 RTM_EXPORT(rt_cpus_lock_status_restore);
90 
91 #endif
92