Встроенные функции gcc

http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Atomic-Builtins.html

Я считаю, что следующий код увеличивает значение var атомарно.

volatile int var = 0; __sync_fetch_and_add( &var, 1 ) 

Я понял приведенные выше коды как следующую логику :

  1. Загрузите адрес переменной var
  2. напишите номер 1 на переменную var atomically – через регистр / кеш, как-то

Однако я сомневаюсь, что следующее атомное

 volatile int var = 0; volatile int num = 1; __sync_fetch_and_add( &var, num ) 

Поскольку это можно интерпретировать как

  1. Загрузите адрес переменной var
  2. Загрузите значение переменной num в регистр
  3. напишите значение на переменную var.

После # 2 выполняется, но до # 3 процессор / stream прерывается, а другой CPU / thread обновляет значение переменной num.

Другими словами, при использовании _ sync * () gcc, могу ли я использовать переменную, а не константу, как второй аргумент?

Разве это не разрушает атомарность?

    Операция – это действительно две операции.

     __sync_fetch_and_add( &var, num ) 

    Загрузка num является атомарной. Добавление его в var является атомарным. Но две атомные операции не выполняют атомную операцию при объединении. Вот почему так сложно изобретать новые блокированные структуры данных. Как правило, две поточно-безопасные операции не обязательно обеспечивают streamобезопасную работу при составлении. Вот почему так сложно делать правильные многопоточные приложения.

    Вы видите, что __sync_fetch_and_add действительно является атомарным, но ведет себя как обычная функция, поэтому в качестве параметра он принимает текущее значение «num». Не совсем правильно сказать, что атомарность функции нарушена – потому что ответственность за загрузку значения из числа не зависит от вызывающего, и это не является частью интерфейса функции. Я мог бы также жаловаться на это:

     __sync_fetch_and_add(&var, some_really_long_function()); 

    Или хуже,

     __sync_fetch_and_add(long_function_1(), long_function_2()); 

    Вы говорите, что это “может быть истолковано как”

    1. Загрузите адрес переменной var
    2. Загрузите значение переменной num
    3. Выполнить атомное добавление

    Но в соответствии с спецификацией C, это не значит, что это может быть истолковано таким образом, но, скорее, оно должно быть истолковано таким образом, иначе компилятор не будет соответствовать (на самом деле он может заменить # 1 и # 2, но это не важно Вот).