6.52 Legacy __sync Built-in Functions for Atomic Memory Access
Следующие встроенные функции предназначены для совместимости с функциями, описанными в спецификации Intel Itanium Processor-specific Application Binary Interface, раздел 7.4. В связи с этим они отличаются от обычной практики GCC, не используя префикс «__builtin_», а также перегружены для работы с несколькими типами.
Определение, данное в документации Intel, допускает использование только типов int, long, long long или их беззнаковых аналогов. GCC допускает любые скалярные типы размером 1, 2, 4 или 8 байт, кроме C-типа _Bool или C++-типа bool. Операции с указателями аргументов выполняются так, как будто операнды являются типа uintptr_t . То есть, они не масштабируются с размером типа, на который указывает указатель.
Эти функции реализуются на основе встроенных функций «__atomic» (см. __atomic Builtins). Их не следует использовать в новом коде, который должен использовать встроенные функции «__atomic» вместо них.
Не все операции поддерживаются всеми целевыми процессорами. Если определенная операция не может быть реализована на целевом процессоре, генерируется предупреждение и вызов внешней функции. Внешняя функция имеет то же имя, что и встроенная версия, с дополнительным суффиксом «_n», где n — размер типа данных.
В большинстве случаев эти встроенные функции считаются полной барьером. То есть, ни один операнд памяти не перемещается через операцию ни вперёд, ни назад. Кроме того, вызываются необходимые инструкции для предотвращения спекулятивных загрузок процессором через операцию и очередей сохранений после операции.
Все процедуры описаны в документации Intel, чтобы принимать «необязательный список переменных, защищенных барьером памяти». Неясно, что это значит; это может означать, что только указанные переменные защищены, или это может означать список дополнительных переменных для защиты. Список игнорируется GCC, который обрабатывает его как пустой. GCC интерпретирует пустой список как означающий, что все глобально доступные переменные должны быть защищены.
type __sync_fetch_and_add (type *ptr, type value, ...)type __sync_fetch_and_sub (type *ptr, type value, ...)type __sync_fetch_and_or (type *ptr, type value, ...)type __sync_fetch_and_and (type *ptr, type value, ...)type __sync_fetch_and_xor (type *ptr, type value, ...)type __sync_fetch_and_nand (type *ptr, type value, ...)-
Эти встроенные функции выполняют операцию, предложенную названием, и возвращают значение, которое ранее находилось в памяти. То есть, операции с целочисленными операндами имеют следующие семантику. Операции с указателями аргументов выполняются так, как будто операнды являются типа
uintptr_t. То есть, они не масштабируются с размером типа, на который указывает указатель.{ tmp = *ptr; *ptr op= value; return tmp; } { tmp = *ptr; *ptr = ~(tmp & value); return tmp; } // nandОбъект, на который указывает первый аргумент, должен быть целого или указателя типа. Он не должен быть булевого типа.
Примечание: GCC 4.4 и более поздние версии реализуют
__sync_fetch_and_nandкак*ptr = ~(tmp & value)вместо*ptr = ~tmp & value. type __sync_add_and_fetch (type *ptr, type value, ...)type __sync_sub_and_fetch (type *ptr, type value, ...)type __sync_or_and_fetch (type *ptr, type value, ...)type __sync_and_and_fetch (type *ptr, type value, ...)type __sync_xor_and_fetch (type *ptr, type value, ...)type __sync_nand_and_fetch (type *ptr, type value, ...)-
Эти встроенные функции выполняют операцию, предложенную названием, и возвращают новое значение. То есть, операции с целочисленными операндами имеют следующие семантику. Операции с указателями операндов выполняются так, как будто тип операнда был
uintptr_t.{ *ptr op= value; return *ptr; } { *ptr = ~(*ptr & value); return *ptr; } // nandПрименимы те же ограничения к аргументам, что и для соответствующих встроенных функций
__sync_op_and_fetch.Примечание: GCC 4.4 и более поздние версии реализуют
__sync_nand_and_fetchкак*ptr = ~(*ptr & value)вместо*ptr = ~*ptr & value. bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...)type __sync_val_compare_and_swap (type *ptr, type oldval, type newval, ...)-
Эти встроенные функции выполняют атомное сравнение и обмен. То есть, если текущее значение
*ptrравно oldval, то запишите newval в*ptr.Версия «bool» возвращает true, если сравнение успешно и newval записано. Версия «val» возвращает содержимое
*ptrдо операции. __sync_synchronize (...)-
Эта встроенная функция выдает полный барьер памяти.
type __sync_lock_test_and_set (type *ptr, type value, ...)-
Эта встроенная функция, как описано в Intel, не является традиционной операцией тестирования и установки, а атомарной операцией обмена. Она записывает value в
*ptr, и возвращает предыдущее содержимое*ptr.У многих целевых платформ есть только минимальная поддержка таких блокировок, и они не поддерживают полную операцию обмена. В этом случае целевая платформа может поддерживать сокращенную функциональность, при которой единственно допустимым значением для хранения является немедленная константа 1. Точное значение, фактически сохранённое в
*ptr, определяется реализацией.Эта встроенная функция не является полным барьером, а скорее барьером получения. Это означает, что ссылки после операции не могут переместиться в (или быть предположенными до) операции, но предыдущие сохранения памяти могут ещё не быть глобально видимыми, и предыдущие загрузки памяти могут ещё не быть выполнены.
void __sync_lock_release (type *ptr, ...)-
Эта встроенная функция освобождает блокировку, полученную функцией
__sync_lock_test_and_set. Обычно это означает запись константы 0 в*ptr.Эта встроенная функция не является полным барьером, а скорее барьером выпуска. Это означает, что все предыдущие сохранения памяти глобально видимы, и все предыдущие загрузки памяти выполнены, но последующие чтения из памяти не запрещаются от предположения до барьера.
Далее: __atomic Builtins, Предыдущее: Offsetof, Вверх: Расширения языка C [Содержание][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-7.5.0/gcc/_005f_005fsync-Builtins.html