int __thread theft = 0;
static void flush_local_count_sig(int unused)
{
if (READ_ONCE(theft) != THEFT_REQ) (*)
return;
smp_mb();
WRITE_ONCE(theft, THEFT_ACK)
if (!counting) {
WRITE_ONCE(theft, THEFT_READY);
}
smp_mb();
}
В https://mirrors.edge.kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.2018.12.08a.pdf на 416 странице возникает вопрос:
Почему существуют обертки READ_ONCE
и WRITE_ONCE
для использования
переменная кража для потока?
И ответ
Первый (с пометкой (*)) можно считать ненужным.
Почему первый READ_ONCE
не нужен? В конце концов, компилятор может попытаться быть слишком умным и оптимизировать его.
int __thread theft = 0;
static void flush_local_count_sig(int unused)
{
if (theft != THEFT_REQ)
return;
smp_mb(); (*)
WRITE_ONCE(theft, THEFT_ACK)
if (!counting) {
WRITE_ONCE(theft, THEFT_READY);
}
smp_mb();
}
theft
не доступен одновременно - к нему обращается один поток и обработчик сигнала.
Как насчет правильности, если мы удалим строку с пометкой (*)?