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)22struct rt_cpu *rt_cpu_self(void) 23 { 24 return &rt_cpus[rt_hw_cpu_id()]; 25 } 26 rt_cpu_index(int index)27struct 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)35rt_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)58void 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)79void 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