Spec-Zone.ru › GCC 5

6.50 Функции __sync встроенные для атомарного доступа к памяти

Следующие встроенные функции предназначены для совместимости с функциями, описанными в спецификации Intel Itanium Processor-specific Application Binary Interface, раздел 7.4. Поэтому они отклоняются от обычной практики GCC, использующей префикс ‘__builtin_’, и перегружены, чтобы работать с несколькими типами.

Определение, приведенное в документации Intel, допускает использование только типов int, long, long long и их беззнаковых аналогов. GCC допускает любые целочисленные скалярные или указательные типы длиной 1, 2, 4 или 8 байт.

Не все операции поддерживаются всеми целевыми процессорами. Если определенная операция не может быть реализована на целевом процессоре, генерируется предупреждение и вызов внешней функции. Внешняя функция имеет то же имя, что и встроенная версия, с дополнительным суффиксом ‘_n’, где n — размер типа данных.

В большинстве случаев эти встроенные функции считаются полной барьером. То есть ни один операнд памяти не перемещается через операцию, ни вперёд, ни назад. Кроме того, по мере необходимости выдаются инструкции, чтобы предотвратить предположение процессором загрузки до операции и формирование очереди сохранений после операции.

Все процедуры описаны в документации Intel как принимающие «необязательный список переменных, защищённых барьером памяти». Неясно, что это означает; это может означать, что только следующие переменные защищены, или это может означать, что эти переменные должны быть защищены дополнительно. В настоящее время 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, ...)

Эти встроенные функции выполняют операцию, подразумеваемую именем, и возвращают значение, которое ранее находилось в памяти. То есть,

{ 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, ...)

Эти встроенные функции выполняют операцию, подразумеваемую именем, и возвращают новое значение. То есть,

{ *ptr op= value; return *ptr; }
{ *ptr = ~(*ptr & value); return *ptr; }   // nand

Примечание: 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, не является традиционной операцией test-and-set, а атомарной операцией обмена. Она записывает 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-5.5.0/gcc/_005f_005fsync-Builtins.html

Spec-Zone.ru

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