Namespaces
Variants

atomic_compare_exchange_weak, atomic_compare_exchange_strong, atomic_compare_exchange_weak_explicit, atomic_compare_exchange_strong_explicit

From cppreference.net
Definido en el encabezado <stdatomic.h>
_Bool atomic_compare_exchange_strong ( volatile A * obj,
C * expected, C desired ) ;
(1) (desde C11)
_Bool atomic_compare_exchange_weak ( volatile A * obj,
C * expected, C desired ) ;
(2) (desde C11)
_Bool atomic_compare_exchange_strong_explicit ( volatile A * obj,

C * expected, C desired,
memory_order succ,

memory_order fail ) ;
(3) (desde C11)
_Bool atomic_compare_exchange_weak_explicit ( volatile A * obj,

C * expected, C desired,
memory_order succ,

memory_order fail ) ;
(4) (desde C11)

Compara atómicamente el contenido de la memoria señalada por obj con el contenido de la memoria señalada por expected , y si son bit a bit iguales, reemplaza el primero con desired (realiza una operación de lectura-modificación-escritura). De lo contrario, carga el contenido real de la memoria señalada por obj en *expected (realiza una operación de carga).

Los modelos de memoria para las operaciones de lectura-modificación-escritura y carga son succ y fail respectivamente. Las versiones (1-2) utilizan memory_order_seq_cst por defecto.

Las formas débiles ((2) y (4)) de las funciones pueden fallar espuriamente, es decir, actuar como si * obj ! = * expected incluso si son iguales. Cuando un compare-and-exchange está en un bucle, la versión débil proporcionará mejor rendimiento en algunas plataformas. Cuando un compare-and-exchange débil requeriría un bucle y uno fuerte no, el fuerte es preferible.

Esta es una función genérica definida para todos los tipos de objetos atómicos A . El argumento es un puntero a un tipo atómico volátil para aceptar direcciones de objetos atómicos tanto no volátiles como volátiles (por ejemplo, E/S mapeadas en memoria), y se preserva la semántica volátil cuando se aplica esta operación a objetos atómicos volátiles. C es el tipo no atómico correspondiente a A .

No está especificado si el nombre de una función genérica es una macro o un identificador declarado con vinculación externa. Si se suprime una definición de macro para acceder a una función real (por ejemplo, entre paréntesis como ( atomic_compare_exchange ) ( ... ) ), o un programa define un identificador externo con el nombre de una función genérica, el comportamiento no está definido.

Contenidos

Parámetros

obj - puntero al objeto atómico a probar y modificar
expected - puntero al valor esperado en el objeto atómico
desired - valor a almacenar en el objeto atómico si coincide con el esperado
succ - orden de sincronización de memoria para la operación de lectura-modificación-escritura si la comparación tiene éxito. Se permiten todos los valores.
fail - orden de sincronización de memoria para la operación de carga si la comparación falla. No puede ser memory_order_release o memory_order_acq_rel y no puede especificar un ordenamiento más fuerte que succ

Valor de retorno

El resultado de la comparación: true si *obj era igual a *exp , false en caso contrario.

Notas

El comportamiento de la familia atomic_compare_exchange_* es como si se ejecutara atómicamente lo siguiente:

if (memcmp(obj, expected, sizeof *obj) == 0) {
    memcpy(obj, &desired, sizeof *obj);
    return true;
} else {
    memcpy(expected, obj, sizeof *obj);
    return false;
}

Referencias

  • Estándar C17 (ISO/IEC 9899:2018):
  • 7.17.7.4 Las funciones genéricas atomic_compare_exchange (p: 207)
  • Estándar C11 (ISO/IEC 9899:2011):
  • 7.17.7.4 Las funciones genéricas atomic_compare_exchange (p: 283-284)

Véase también

intercambia un valor con el valor de un objeto atómico
(función)
Documentación de C++ para atomic_compare_exchange_weak , atomic_compare_exchange_strong , atomic_compare_exchange_weak_explicit , atomic_compare_exchange_strong_explicit