Spinlock is a spin lock for synchronization between threads, so it is extremely important because we want to use the two cores of BF561.
1 definition
Declaring a spinlock in the kernel can use the macro definition of Define_spinlock, which is defined in Include/linux/spinlock_types.h:
#define DEFINE_SPINLOCK (x) spinlock_t x = __spin_lock_unlocked (x)
Where spinlock_t is a structural body defined in Include/linux/spinlock_types.h:
typedef struct {
raw_spinlock_t raw_lock;
#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
unsigned int break_lock;
#endif
#ifdef CONFIG_DEBUG_SPINLOCK
unsigned int magic, owner_cpu;
void *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
} spinlock_t;
Because we only define CONFIG_SMP, so this structure is actually:
typedef struct {
raw_spinlock_t raw_lock;
} spinlock_t;
The definition of raw_spinlock_t is in Include/asm/spinlock_types.h:
typedef struct {
volatile unsigned int lock;
} raw_spinlock_t;
Before that, we simply set it to the type of volatile unsigned int, and now we want to use the VDSP library for nuclear synchronization, so we'll change the definition to:
typedef struct {
testset_t lock;
} raw_spinlock_t;
Because testset_t automatically is the volatile type, you don't have to declare it here.
2 VDSP support for inter-nuclear synchronization
The following are from VDSP Help:
Synchronization functions
visualdsp++ 5.0 provides functionality for synchronization. There are two compiler intrinsics built-in (functions three) and locking routines.
The compiler intrinsics are:
#include <ccblkfn.h>
int Testset (char *);
void Untestset (char *);
The Testset () intrinsic generates a native testset instruction, which can perform atomic on a updates memory. The intrinsic returns the result of the CC flag produced by the testset instruction. Refer to the instruction set reference for details.
The Untestset () intrinsic clears the memory location set by the
Testset () intrinsic. This intrinsic is recommended into place of a normal memory write because the Untestset () intrinsic acts as a stronger Barri Er to code movement during optimization.
The three locking routines are:
#include <ccblkfn.h>
void Adi_acquire_lock (testset_t *);
int Adi_try_lock (testset_t *);
void Adi_release_lock (testset_t *);
The Adi_acquire_lock () routine repeatedly attempts to claim the lock by issuing testset () until successful, whereupon it R Eturns to the caller. In contrast, the adi_try_lock () routine makes a single attempt-if it successfully claims the lock, it returns nonzero, oth Erwise it returns zero.
The Adi_release_lock () routine releases the lock obtained by either Adi_acquire_lock () or Adi_try_lock (). It assumes that "lock was" already claimed and makes no attempt to verify so its caller be in fact the current owner O f the lock. None of these intrinsics or functions disable Interrupts-that are left to the caller ' s discretion.
3 Spin_lock
The definition of Spin_lock is in Include/linux/spinlock.h:
#define SPIN_LOCK (Lock) _spin_lock (lock)
The definition of _spin_lock is in Include/linux/spinlock_api_smp.h:
void __lockfunc _spin_lock (spinlock_t *lock) __acquires (lock);