Атомные чтения в C

В соответствии с Считываются и записываются С++ читы int Atomic? из-за проблем с кешированием процессора, чтениями ints (и, соответственно, указателями - или так я предполагаю ) не являются атомами в C. Итак, мой вопрос в том, есть ли какая-то сборка, которую я мог бы использовать, чтобы сделать чтение атомом, или мне нужно использовать блокировку? Я рассмотрел несколько наборов библиотек атомных операций и пока еще не могу найти функцию для атомного чтения.

EDIT: Компилятор: Clang 2.9 EDIT: платформа: x86 (64-разрядная версия)

Спасибо.

Ответ 1

В общем, простая атомная выборка не предоставляется библиотеками атомных операций, потому что она редко используется; вы читаете значение, а затем делаете что-то с ним, и блокировку нужно удерживать во время этого, чтобы вы знали, что значение, которое вы прочитали, не изменилось. Таким образом, вместо атомарного чтения существует некоторый атомный тест-набор (например, gcc __sync_fetch_and_add()), который выполняет блокировку, а затем вы выполняете нормальные несинхронизированные чтения во время блокировки.

Исключение - это драйверы устройств, где вам может потребоваться фактически заблокировать системную шину, чтобы получить атомарность по отношению к другим устройствам на шине или при реализации блокирующих примитивов для библиотек атомных операций; они по своей сути зависят от машины, и вам придется углубиться в язык ассемблера. На процессорах x86 существуют различные атомарные инструкции, плюс префикс lock, который может применяться к большинству операций, которые обращаются к памяти и удерживают блокировку шины в течение всего периода работы; другие платформы (SPARC, MIPS и т.д.) имеют схожие механизмы, но часто мелкие детали различаются. Вам нужно будет знать процессор, который вы программируете, и, вероятно, в этом случае нужно что-то узнать о архитектуре машинной шины. И библиотеки для этого редко имеют смысл, потому что вы не можете удерживать блокировку шины или памяти во входе/выходе функции, и даже с помощью библиотеки макросов нужно быть осторожным из-за импликации, чтобы можно было пересечь обычные операции между вызовами макросов, когда в что может нарушить блокировку. Почти всегда лучше просто закодировать весь критический раздел на ассемблере.

Ответ 2

gcc имеет набор атомных встроенных функций, но у него нет простой атомной выборки, однако вы можете сделать что-то вроде __sync_fetch_and_add(&<your variable here>, 0);, чтобы обойти это

Документы GCC здесь, и там это сообщение в блоге выше

EDIT: Ах, clang, я знаю, что LLVM IR имеет атомайзер в нем, но я не знаю, подвергает ли их clang каким-либо образом, но, возможно, стоит подумать, не жалуется ли он на использование gcc, он может их поддержать. EDIT: хм, похоже, что-то есть... clang docs не делает столько, сколько gcc, хотя документы, похоже, подсказывают, что это может также делают gcc.