问题
To initialize a spinlock in kernel v4.19-rc5 one must use the spin_lock_init
macro defined as follows:
#define spin_lock_init(_lock) \
do { \
spinlock_check(_lock); \
raw_spin_lock_init(&(_lock)->rlock); \
} while (0)
The function spinlock_check(_lock)
just return &lock->rlock
. This article explains that:
The implementation of the spinlock_check is pretty easy, this function just returns the raw_spinlock_t of the given spinlock to be sure that we got exactly normal raw spinlockI dont't understand how this function performs a check. I was expecting some
if
statements in a ckeck function. I'm sorry but I'm new to kernel programming.
回答1:
It doesn't need any if
statements because it exists for compile time checking.
You can see here that most spinlock operations are defined as macros, so they are not able to restrict type of their argument.
Consider the following example:
struct not_a_spinlock {
raw_spinlock_t rlock;
};
Without spinlock_check
I could use spin_lock_init
to initialize it:
struct not_a_spinlock spin;
spin_lock_init(&spin);
But thanks to spinlock_check
, this will not work. This makes those macros type-restricted so they act more like functions.
The reason it returns &lock->rlock
is due to convenience - its returned value can be passed to the next function.
So it could be worth rewriting the macro from your example as:
#define spin_lock_init(_lock) \
do { \
raw_spin_lock_init(spinlock_check(_lock)); \
} while (0)
Similar techniques can be used with macros to somewhat restrict their argument types, like shown here:
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
来源:https://stackoverflow.com/questions/52551594/spinlock-initialization-function