Операция над переменной preempt_count не является атомарной. Планировщик гарантирует, что область кода между inc и dec preempt_count потока не будет выключена планировщиком. Переключение контекста из текущего потока в этой области кода может происходить только при последующих встроенных исключениях или прерываниях. После завершения первой операции inc дальнейшие обработчики увидят, что переменная ненулевая, поэтому переключение контекста не происходит. До завершения inc поток может быть отключен, но это нормально, так как код не достиг охраняемой области.
Некоторые подробности: определение атомарной переменной должно выглядеть примерно так: «Атомные переменные - это те, для которых операция чтения с изменением записи выполняется как одна инструкция без какого-либо прерывания» . Операция «Read-Modify-Write» на preempt_count может быть прервана другим обработчиком исключений или обработчиком прерываний, но только строго встроенным образом, это предусмотрено конструкцией ядра. Поскольку эти встроенные операции выполняются парами, значение preempt_count не будет в конечном итоге повреждено. Хотя операция R-M-W может быть прервана, и текущий поток может быть отключен (только если ни один из множества встроенных элементов inc не завершен), но это нормально, поскольку код не достиг защищаемой области. Как только поток переключается обратно, он продолжает завершать операцию R-M-W, и с этого момента текущий поток не будет выключен, пока все сопряженные dec (s) все не завершат.