Spec-Zone.ru › GCC 8

6.52 Встроенные функции Legacy __sync для атомного доступа к памяти

Следующие встроенные функции предназначены для совместимости с функциями, описанными в спецификации 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). Их не следует использовать в новом коде, который должен использовать встроенные функции ‘__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, Предыдущее: Offsetof, Вверх: Расширения языка C [Содержание][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc/_005f_005fsync-Builtins.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API