printk("%d\n", atomic_read(&v)); /* будет напечатано "7" */
Наиболее частое использование атомарных целочисленных операций — это инкремент счетчиков. Защищать один счетчик с помощью сложной системы блокировок — это глупо, поэтому разработчики используют вызовы atomic_inc()
и atomic_dec()
, которые значительно быстрее. Еще одно использование атомарных целочисленных операций — это атомарное выполнение операции с проверкой результата. Наиболее распространенный пример — это атомарные декремент и проверка результата, с помощью функции
int atomic_dec_and_test(atomic_t *v);
Эта функция уменьшает на единицу значение заданной переменной атомарного типа. Если результат выполнения операции равен нулю, то возвращается значение true
, иначе возвращается false
. Полный список всех атомарных операций с целыми числами (т.е. тех, которые доступны для всех аппаратных платформ) приведен в табл. 9.1. Все операции, которые реализованы для определенной аппаратной платформы, приведены в файле
.
Таблица 9.1. Полный список всех атомарных операций с целыми числами
Атомарная целочисленная операция | Описание |
---|---|
ATOMIC_INIT(int i) | Объявление и инициализация в значение i переменной типа atomic _t |
int atomic_ read(atomic_t *v) | Атомарное считывание значения целочисленной переменной v |
void atomic_set(atomic_t *v, int i) | Атомарно установить переменную v в значение i |
void atomic_add(int i, atomic_t *v) | Атомарно прибавить значение i к переменной v |
void atomic_sub(int i, atomic_t *v) | Атомарно вычесть значение 1 из переменной v |
void atomic_inc(atomic_t *v) | Атомарно прибавить единицу к переменной v |
void atomic_dec(atomic_t *v) | Атомарно вычесть единицу из переменной v |
int atomic_sub_and_test(int i, atomic_t *v) | Атомарно вычесть значение i из переменной v и возвратить true , если результат равен нулю, и false в противном случае |
int atomic_add_negative(int i, atomic_t *v) | Атомарно прибавить значение i к переменной v и возвратить true , если результат операции меньше нуля, иначе возвратить false |
int atomic_dec_and_test(atomic_t *v) | Атомарно вычесть единицу из переменной v и возвратить true , если результат операции равен нулю, иначе возвратить false |
int atomic_inc_and_test(atomic_t *v) | Атомарно прибавить единицу к переменной v и возвратить true , если результат операции равен нулю, иначе возвратить false |
Обычно атомарные операции реализованы как функции с подстановкой тела и встраиваемыми инструкциями на языке ассемблера (разработчики ядра любят inline
). В случае если какая-либо из функций обладает внутренней атомарностью, то обычно она выполняется в виде макроса. Например, для большинства нормальных аппаратных платформ считывание одного машинного слова данных — это атомарная операция. Операция считывания всегда возвращает машинное слово в непротиворечивом состоянии или перед операцией записи, или после нее, но во время операции записи чтение не может быть выполнено никогда. Следовательно, функция atomic_read()
обычно реализуется как макрос, который возвращает целочисленное значение переменной типа atomic_t
.