6.51 Встроенные функции для операций с атомными данными с учётом модели памяти
Следующие встроенные функции приблизительно соответствуют требованиям модели памяти C++11. Многие из них похожи на встроенные функции с префиксом «__sync», но все также имеют параметр модели памяти. Все они идентифицируются префиксом «__atomic», и большинство из них перегружены так, чтобы работать с несколькими типами.
GCC позволяет использовать любой целочисленный скаляр или указатель длиной 1, 2, 4 или 8 байт. 16-байтовые целочисленные типы также разрешены, если архитектура поддерживает «__int128» (см. __int128).
Целевым архитектурам рекомендуется предоставлять собственные шаблоны для каждой из этих встроенных функций. Если целевая архитектура не указана, используются исходные атомарные встроенные функции «__sync» без учёта модели памяти, а также любые необходимые синхронизирующие ограждения вокруг них для достижения правильного поведения. В этом случае выполнение подчиняется тем же ограничениям, что и для этих встроенных функций.
Если нет шаблона или механизма для обеспечения последовательности инструкций без блокировки, вызывается внешняя процедура с теми же параметрами для разрешения в ходе выполнения.
Четыре функции, не относящиеся к арифметическим операциям (загрузка, сохранение, обмен и сравнение_с_обменом), также имеют общую версию. Эта общая версия работает с любым типом данных. Если размер типа данных соответствует одному из целочисленных размеров, которые могут поддерживать безблокировочные операции, общая версия использует встроенную функцию без блокировки. В противном случае вызов внешней процедуры остаётся для разрешения во время выполнения. Эта внешняя процедура имеет тот же формат, но с добавлением параметра «size_t», вставленного в качестве первого параметра, указывающего размер объекта, на который указывает указатель. Все объекты должны быть одинакового размера.
Существует 6 различных моделей памяти, которые можно указать. Они соответствуют тем же именам в стандарте C++11. Для более подробных определений обратитесь туда или к странице вики-справочника GCC об атомной синхронизации. Эти модели памяти интегрируют как барьеры для перемещения кода, так и требования к синхронизации с другими потоками. Они перечислены приблизительно в порядке возрастания силы. Также можно использовать специфичные для целевой архитектуры флаги для флагов модели памяти, такие как «Hardware Lock Elision».
__ATOMIC_RELAXEDБез барьеров и синхронизации.
__ATOMIC_CONSUMEТолько зависимость данных как для барьера, так и для синхронизации с другим потоком.
__ATOMIC_ACQUIREБарьер для подъёма кода и синхронизируется с операциями хранения с семантикой «освобождения» (или сильнее) из другого потока.
__ATOMIC_RELEASEБарьер для опускания кода и синхронизируется с операциями загрузки с семантикой «приобретения» (или сильнее) из другого потока.
__ATOMIC_ACQ_RELПолный барьер в обоих направлениях и синхронизируется с операциями загрузки «приобретения» и операциями хранения «освобождения» в другом потоке.
__ATOMIC_SEQ_CSTПолный барьер в обоих направлениях и синхронизируется с операциями загрузки «приобретения» и операциями хранения «освобождения» во всех потоках.
При реализации шаблонов для этих встроенных функций параметр модели памяти можно игнорировать, если шаблон реализует самую жёсткую __ATOMIC_SEQ_CST модель. Любые другие модели памяти выполняются корректно с этой моделью памяти, но они могут не выполняться так эффективно, как с более подходящей реализацией требований «релаксации».
Обратите внимание, что стандарт C++11 позволяет определять параметр модели памяти во время выполнения, а не во время компиляции. Эти встроенные функции отображают любое значение времени выполнения в __ATOMIC_SEQ_CST вместо вызова библиотечной функции во время выполнения или вставки оператора switch. Это соответствует стандарту, безопасно и является самым простым подходом на данный момент.
Параметр модели памяти — это целое число со знаком, но только младшие 16 бит зарезервированы для модели памяти. Остальная часть целого числа со знаком зарезервирована для использования целевой архитектурой и должна быть равна 0. Использование предопределённых атомных значений гарантирует правильное использование.
- Встроенная функция: тип __atomic_load_n (тип *ptr, int memmodel)
Эта встроенная функция реализует атомную операцию загрузки. Она возвращает содержимое
*ptr.Допустимые варианты модели памяти —
__ATOMIC_RELAXED,__ATOMIC_SEQ_CST,__ATOMIC_ACQUIRE, и__ATOMIC_CONSUME.
- Встроенная функция: void __atomic_load (тип *ptr, тип *ret, int memmodel)
Это общая версия атомной операции загрузки. Она возвращает содержимое
*ptrв*ret.
- Встроенная функция: void __atomic_store_n (тип *ptr, тип val, int memmodel)
Эта встроенная функция реализует атомную операцию сохранения. Она записывает
valв*ptr.Допустимые варианты модели памяти —
__ATOMIC_RELAXED,__ATOMIC_SEQ_CST, и__ATOMIC_RELEASE.
- Встроенная функция: void __atomic_store (тип *ptr, тип *val, int memmodel)
Это общая версия атомной операции сохранения. Она сохраняет значение
*valв*ptr.
- Встроенная функция: тип __atomic_exchange_n (тип *ptr, тип val, int memmodel)
Эта встроенная функция реализует атомную операцию обмена. Она записывает val в
*ptr, и возвращает предыдущее содержимое*ptr.Допустимые варианты модели памяти —
__ATOMIC_RELAXED,__ATOMIC_SEQ_CST,__ATOMIC_ACQUIRE,__ATOMIC_RELEASE, и__ATOMIC_ACQ_REL.
- Встроенная функция: void __atomic_exchange (тип *ptr, тип *val, тип *ret, int memmodel)
Это общая версия атомной операции обмена. Она записывает содержимое
*valв*ptr. Исходное значение*ptrкопируется в*ret.
- Встроенная функция: bool __atomic_compare_exchange_n (тип *ptr, тип *expected, тип desired, bool weak, int success_memmodel, int failure_memmodel)
Эта встроенная функция реализует атомную операцию сравнения и обмена. Она сравнивает содержимое
*ptrс содержимым*expectedи, если они равны, записывает desired в*ptr. Если они не равны, текущее содержимое*ptrзаписывается в*expected. weak имеет значение true для слабого сравнения_с_обменом и false для сильного варианта. Многие целевые архитектуры предлагают только сильный вариант и игнорируют этот параметр. В случае сомнений используйте сильный вариант.Возвращает true, если desired записано в
*ptrи выполнение соответствует модели памяти, указанной success_memmodel. Здесь нет ограничений на используемую модель памяти.В противном случае возвращает false, и выполнение соответствует модели памяти failure_memmodel. Эта модель памяти не может быть
__ATOMIC_RELEASEни__ATOMIC_ACQ_REL. Она также не может быть сильнее модели, указанной success_memmodel.
- Встроенная функция: bool __atomic_compare_exchange (тип *ptr, тип *expected, тип *desired, bool weak, int success_memmodel, int failure_memmodel)
Эта встроенная функция реализует общую версию
__atomic_compare_exchange. Функция практически идентична__atomic_compare_exchange_n, за исключением того, что значение «desired» также является указателем.
- Встроенная функция: тип __atomic_add_fetch (тип *ptr, тип val, int memmodel)
- ...
-
Эти встроенные функции выполняют операцию, предложенную именем, и возвращают результат операции. То есть,
{ *ptr op= val; return *ptr; }Все модели памяти допустимы.
- ...
-
Эти встроенные функции выполняют операцию, предложенную именем, и возвращают значение, которое ранее находилось в
*ptr. То есть,{ tmp = *ptr; *ptr op= val; return tmp; }Все модели памяти допустимы.
- Встроенная функция: bool __atomic_test_and_set (void *ptr, int memmodel)
Эта встроенная функция выполняет атомную операцию test-and-set для байта по адресу
*ptr. Байт устанавливается на некоторое реализационно определённое ненулевое «установленное» значение, а возвращаемое значение —trueтогда и только тогда, когда предыдущее содержимое было «установлено». Она должна использоваться только для операндов типаboolилиchar. Для других типов может быть установлена только часть значения.Все модели памяти допустимы.
- Встроенная функция: void __atomic_clear (bool *ptr, int memmodel)
-
Эта встроенная функция выполняет атомную операцию сброса значения для
*ptr. После выполнения операции*ptrсодержит 0. Она должна использоваться только для операндов типаboolилиchar, а также в сочетании с__atomic_test_and_set. Для других типов она может только частично сбросить значение. Если тип неbool, предпочтительнее использовать__atomic_store.Допустимые варианты модели памяти —
__ATOMIC_RELAXED,__ATOMIC_SEQ_CST, и__ATOMIC_RELEASE.
- Встроенная функция: void __atomic_thread_fence (int memmodel)
-
Эта встроенная функция действует как барьер синхронизации между потоками на основе указанной модели памяти.
Все порядки памяти допустимы.
- Встроенная функция: void __atomic_signal_fence (int memmodel)
-
Эта встроенная функция действует как барьер синхронизации между потоком и обработчиками сигналов в рамках того же потока.
Все порядки памяти допустимы.
- Встроенная функция: bool __atomic_always_lock_free (size_t size, void *ptr)
-
Эта встроенная функция возвращает true, если объекты размером size байт всегда генерируют атомные инструкции без блокировки для целевой архитектуры. size должен быть константой на этапе компиляции, а результат также должен быть константой на этапе компиляции.
ptr — это необязательный указатель на объект, который может использоваться для определения выравнивания. Значение 0 указывает, что следует использовать стандартное выравнивание. Компилятор также может игнорировать этот параметр.
if (_atomic_always_lock_free (sizeof (long long), 0))
- Встроенная функция: bool __atomic_is_lock_free (size_t size, void *ptr)
-
Эта встроенная функция возвращает true, если объекты размером size байт всегда генерируют атомные инструкции без блокировки для целевой архитектуры. Если известно, что это не блокировка, вызывается процедура runtime с именем
__atomic_is_lock_free.ptr — это необязательный указатель на объект, который может использоваться для определения выравнивания. Значение 0 указывает, что следует использовать стандартное выравнивание. Компилятор также может игнорировать этот параметр.
Далее: Встроенные функции для обработки переполнения целых чисел, Предыдущее: Встроенные функции __sync, Наверх: Расширения языка C [Оглавление][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.5.0/gcc/_005f_005fatomic-Builtins.html