READ_ONCE и WRITE_ONCE в реальном примере - PullRequest
0 голосов
/ 06 июня 2019
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 не доступен одновременно - к нему обращается один поток и обработчик сигнала. Как насчет правильности, если мы удалим строку с пометкой (*)?

...