📄 smp.hxx
字号:
CYG_INTERRUPT_STATE s; HAL_DISABLE_INTERRUPTS(s); *state = s; spin(); }; // Clear the lock, and restore the interrupt state saved in // spin_intsave(). void clear_intsave(CYG_INTERRUPT_STATE state) { clear(); HAL_RESTORE_INTERRUPTS(state); };};#endif// -------------------------------------------------------------------------// Scheduler lock class// This uses the scheduler lock API defined by the HAL, or the defaults// defined above.class Cyg_Scheduler_SchedLock{ static volatile cyg_ucount32 sched_lock // lock counter CYGBLD_ATTRIB_ASM_ALIAS( cyg_scheduler_sched_lock ) CYGBLD_ANNOTATE_VARIABLE_SCHED ; static HAL_SMP_SCHEDLOCK_DATA_TYPE lock_data CYGBLD_ANNOTATE_VARIABLE_SCHED; protected: Cyg_Scheduler_SchedLock() { HAL_SMP_SCHEDLOCK_INIT( sched_lock, lock_data ); }; // Increment the scheduler lock. If this takes the lock from zero // to one then this code must also do whatever is necessary to // serialize CPUs through the scheduler. static void inc_sched_lock() { CYG_INSTRUMENT_SMP(LOCK_INC,CYG_KERNEL_CPU_THIS(),0); HAL_SMP_SCHEDLOCK_INC( sched_lock, lock_data ); }; // Zero the scheduler lock. This will release the CPU serializing // lock and allow another CPU in. static void zero_sched_lock() { CYG_INSTRUMENT_SMP(LOCK_ZERO,CYG_KERNEL_CPU_THIS(),0); CYG_ASSERT( sched_lock != 0, "Scheduler lock already zero"); HAL_SMP_SCHEDLOCK_ZERO( sched_lock, lock_data ); }; // Set the scheduler lock to a non-zero value. Both the scheduler // lock and the new value must be non-zero. static void set_sched_lock(cyg_uint32 new_lock) { CYG_INSTRUMENT_SMP(LOCK_SET,CYG_KERNEL_CPU_THIS(),new_lock); CYG_ASSERT( new_lock > 0, "New scheduler lock value == 0"); CYG_ASSERT( sched_lock > 0, "Scheduler lock == 0"); HAL_SMP_SCHEDLOCK_SET( sched_lock, lock_data, new_lock ); }; static cyg_ucount32 get_sched_lock() { return sched_lock; };};#define CYGIMP_KERNEL_SCHED_LOCK_DEFINITIONS \volatile cyg_ucount32 Cyg_Scheduler_SchedLock::sched_lock = 1; \HAL_SMP_SCHEDLOCK_DATA_TYPE Cyg_Scheduler_SchedLock::lock_data;#endif // __cplusplus// -------------------------------------------------------------------------#else // defined(CYGSEM_KERNEL_SMP_SUPPORT) && (CYGSEM_HAL_SMP_SUPPORT)//==========================================================================// SMP support is NOT included.#undef CYG_KERNEL_SMP_ENABLED// -------------------------------------------------------------------------// Defined values// Supply a set of values that describe a single CPU system.#ifndef HAL_SMP_CPU_TYPE#define HAL_SMP_CPU_TYPE cyg_uint32#endif#define CYGNUM_KERNEL_CPU_MAX 1#define CYG_KERNEL_CPU_COUNT() 1#define CYG_KERNEL_CPU_THIS() 0#define CYG_KERNEL_CPU_NONE -1#define CYG_KERNEL_CPU_LOWPRI() CYG_KERNEL_CPU_THIS()// -------------------------------------------------------------------------// SpinLock class// This single CPU version simply goes through the motions of setting// and clearing the lock variable for debugging purposes. #ifdef __cplusplusclass Cyg_SpinLock{ volatile cyg_uint32 lock;public: // Constructor, initialize the lock to clear Cyg_SpinLock() { lock = 0; }; ~Cyg_SpinLock() { CYG_ASSERT( lock == 0, "spinlock still claimed"); }; // Spin on the lock. In this case we just set it to 1 and proceed. void spin() { CYG_ASSERT( lock == 0, "spinlock already claimed!"); lock = 1; }; // Clear the lock. Again, just set the value. void clear() { CYG_ASSERT( lock != 0, "spinlock already cleared!"); lock = 0; }; // Try to claim the lock. Return true if successful, false if not. cyg_bool trylock() { if( lock ) return false; else { lock = 1; return true; } }; // Test the current value of the lock cyg_bool test() { return lock; }; // The following two member functions are only necessary if the // spinlock is to be used in an ISR. // Claim the spinlock, but also mask this CPU's interrupts while // we have it. void spin_intsave(CYG_INTERRUPT_STATE *state) { CYG_INTERRUPT_STATE s; HAL_DISABLE_INTERRUPTS(s); *state = s; spin(); }; // Clear the lock, and restore the interrupt state saved in // spin_intsave(). void clear_intsave(CYG_INTERRUPT_STATE state) { clear(); HAL_RESTORE_INTERRUPTS(state); };};// -------------------------------------------------------------------------// Scheduler lock classclass Cyg_Scheduler_SchedLock{ static volatile cyg_ucount32 sched_lock // lock counter CYGBLD_ATTRIB_ASM_ALIAS( cyg_scheduler_sched_lock ) CYGBLD_ANNOTATE_VARIABLE_SCHED ; // For non-SMP versions, the code here does the basic and obvious things.protected: Cyg_Scheduler_SchedLock() { sched_lock = 1; }; // Increment the scheduler lock, possibly taking it from zero to // one. static void inc_sched_lock() { sched_lock++; }; static void zero_sched_lock() { CYG_ASSERT( sched_lock != 0, "Scheduler lock already zero"); sched_lock = 0; }; // Set the scheduler lock to a non-zero value. Both the scheduler // lock and the new value must be non-zero. static void set_sched_lock(cyg_uint32 new_lock) { CYG_ASSERT( new_lock > 0, "New scheduler lock value == 0"); CYG_ASSERT( sched_lock > 0, "Scheduler lock == 0"); sched_lock = new_lock; }; static cyg_ucount32 get_sched_lock() { return sched_lock; };};#define CYGIMP_KERNEL_SCHED_LOCK_DEFINITIONS \volatile cyg_ucount32 Cyg_Scheduler_SchedLock::sched_lock = 1;#endif // __cplusplus#endif // defined(CYGSEM_KERNEL_SMP_SUPPORT) && (CYGSEM_HAL_SMP_SUPPORT)// -------------------------------------------------------------------------#endif // ifndef CYGONCE_KERNEL_SMP_HXX// EOF smp.hxx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -