📄 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 __cplusplus
class 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 class
class 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 + -