6.51 Встроенные функции __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,typevalue, ...)- type
__sync_fetch_and_sub (type*ptr,typevalue, ...)- type
__sync_fetch_and_or (type*ptr,typevalue, ...)- type
__sync_fetch_and_and (type*ptr,typevalue, ...)- type
__sync_fetch_and_xor (type*ptr,typevalue, ...)- type
__sync_fetch_and_nand (type*ptr,typevalue, ...) - type
- Эти встроенные функции выполняют операцию, указанную в имени, и возвращают значение, которое ранее находилось в памяти. То есть,
{ 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,typevalue, ...)- type
__sync_sub_and_fetch (type*ptr,typevalue, ...)- type
__sync_or_and_fetch (type*ptr,typevalue, ...)- type
__sync_and_and_fetch (type*ptr,typevalue, ...)- type
__sync_xor_and_fetch (type*ptr,typevalue, ...)- type
__sync_nand_and_fetch (type*ptr,typevalue, ...) - type
- Эти встроенные функции выполняют операцию, указанную в имени, и возвращают новое значение. То есть,
{ *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,typeoldval,typenewval, ...)- type
__sync_val_compare_and_swap (type*ptr,typeoldval,typenewval, ...) - type
- Эти встроенные функции выполняют атомарное сравнение и обмен. То есть, если текущее значение
*ptr равно oldval, то запишите newval в*ptr.Версия «bool» возвращает true, если сравнение успешно и newval записано. Версия «val» возвращает содержимое
*ptr до выполнения операции. __sync_synchronize (...)- Эта встроенная функция устанавливает полный барьер памяти.
-
type
__sync_lock_test_and_set (type*ptr,typevalue, ...) - Эта встроенная функция, как описано в Intel, не является традиционной операцией test-and-set, а атомарной операцией обмена. Она записывает value в
*ptr и возвращает предыдущее содержимое*ptr.Многие целевые системы имеют лишь минимальную поддержку таких блокировок и не поддерживают полную операцию обмена. В этом случае целевая система может поддерживать здесь уменьшенную функциональность, при которой единственное допустимое значение для записи — это непосредственная константа 1. Точное значение, фактически записанное в
*ptr, определяется реализацией.Эта встроенная функция не является полным барьером, а является барьером приобретения. Это означает, что ссылки после операции не могут перемещаться к (или быть спекулируемыми) до операции, но предыдущие записи в память могут ещё не быть глобально видимыми, а предыдущие загрузки из памяти могут ещё не быть выполнены.
-
void __sync_lock_release (type*ptr, ...) - Эта встроенная функция освобождает блокировку, полученную с помощью
__sync_lock_test_and_set. Обычно это означает запись константы 0 в*ptr.Эта встроенная функция не является полным барьером, а является барьером выпуска. Это означает, что все предыдущие записи в память глобально видимы, и все предыдущие загрузки из памяти выполнены, но последующие чтения из памяти не запрещаются от спекулятивного перемещения к позиции до барьера.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/_005f_005fsync-Builtins.html