функция инициализации спин-блокировки - PullRequest
0 голосов
/ 28 сентября 2018

Для инициализации спин-блокировки в ядре v4.19-rc5 необходимо использовать макрос spin_lock_init, определенный следующим образом:

#define spin_lock_init(_lock)               \
do {    \
       spinlock_check(_lock);               \
       raw_spin_lock_init(&(_lock)->rlock);     \
} while (0)

Функция spinlock_check(_lock) просто возвращает &lock->rlock. В этой статье объясняется, что:

Реализация spinlock_check довольно проста, эта функция просто возвращает raw_spinlock_t данного спинлока, чтобы быть уверенным, что мы получили именно нормальный необработанный спинлок
Я не понимаю, как эта функция выполняет проверку .Я ожидал несколько if операторов в функции ckeck.Извините, но я новичок в программировании ядра.

1 Ответ

0 голосов
/ 28 сентября 2018

Ему не нужны никакие операторы if, поскольку он существует для проверки времени компиляции .

Здесь видно, что большинство операций спин-блокировки определены какмакросы, поэтому они не могут ограничивать тип своего аргумента.

Рассмотрим следующий пример:

struct not_a_spinlock {
    raw_spinlock_t rlock;
};

Без spinlock_check Я мог бы использовать spin_lock_init для его инициализации:

struct not_a_spinlock spin;
spin_lock_init(&spin);

Но благодаря spinlock_check это не будет работать.Это делает эти макросы ограниченными по типу, поэтому они действуют больше как функции.

Причина, по которой он возвращает &lock->rlock, связана с удобством - его возвращаемое значение может быть передано следующей функции.

Таквозможно, стоит переписать макрос из вашего примера следующим образом:

#define spin_lock_init(_lock)                         \
do {                                                  \
       raw_spin_lock_init(spinlock_check(_lock));     \
} while (0)

Подобные методы можно использовать с макросами для некоторого ограничения их типов аргументов, как показано здесь :

#define min(x, y) ({                \
    typeof(x) _min1 = (x);          \
    typeof(y) _min2 = (y);          \
    (void) (&_min1 == &_min2);      \
    _min1 < _min2 ? _min1 : _min2; })
...