Compartir a través de


Funciones intrínsecas _InterlockedCompareExchange128

Específicos de Microsoft

Realiza una comparación e intercambio entrelazados de 128 bits.

Sintaxis

unsigned char _InterlockedCompareExchange128(
   __int64 volatile * Destination,
   __int64 ExchangeHigh,
   __int64 ExchangeLow,
   __int64 * ComparandResult
);
unsigned char _InterlockedCompareExchange128_acq(
   __int64 volatile * Destination,
   __int64 ExchangeHigh,
   __int64 ExchangeLow,
   __int64 * ComparandResult
);
unsigned char _InterlockedCompareExchange128_nf(
   __int64 volatile * Destination,
   __int64 ExchangeHigh,
   __int64 ExchangeLow,
   __int64 * ComparandResult
);
unsigned char _InterlockedCompareExchange128_np(
   __int64 volatile * Destination,
   __int64 ExchangeHigh,
   __int64 ExchangeLow,
   __int64 * ComparandResult
);
unsigned char _InterlockedCompareExchange128_rel(
   __int64 volatile * Destination,
   __int64 ExchangeHigh,
   __int64 ExchangeLow,
   __int64 * ComparandResult
);

Parámetros

Destino
[in, out] Puntero al destino, que es una matriz de dos enteros de 64 bits considerada como un campo de 128 bits. Los datos de destino deben estar alineados en 16 bytes para evitar un error de protección general.

ExchangeHigh
[in] Un entero de 64 bits que se puede intercambiar con la parte alta del destino.

ExchangeLow
[in] Un entero de 64 bits que se puede intercambiar con la parte baja del destino.

ComparandResult
[in, out] Puntero a una matriz de dos enteros de 64 bits (considerada como un campo de 128 bits) para comparación con el destino. En la salida, esta matriz se sobrescribe con el valor original del destino.

Valor devuelto

1 si el comparando de 128 bits es igual al valor original del destino. ExchangeHigh y ExchangeLow sobrescriben el destino de 128 bits.

0 si el comparando no es igual al valor original del destino. El valor del destino no cambia y el valor del comparador se sobrescribe con el valor del destino.

Requisitos

Intrinsic Architecture
_InterlockedCompareExchange128 x64, ARM64
_InterlockedCompareExchange128_acq, _InterlockedCompareExchange128_nf, _InterlockedCompareExchange128_rel ARM64
_InterlockedCompareExchange128_np x64

Archivo de encabezado<intrin.h>

Comentarios

La función intrínseca _InterlockedCompareExchange128 genera la instrucción cmpxchg16b (con el prefijo lock) para realizar una comparación e intercambio entrelazados de 128 bits. Las versiones anteriores de hardware AMD de 64 bits no admiten esta instrucción. Para comprobar la compatibilidad de hardware con la instrucción cmpxchg16b, llame a la función intrínseca __cpuid con InfoType=0x00000001 (standard function 1). El bit 13 de CPUInfo[2] (ECX) es 1 si se admite la instrucción.

Nota:

Siempre se sobrescribe el valor de ComparandResult. Después de la instrucción lock, esta función intrínseca copia de inmediato el valor inicial de Destination en ComparandResult. Por este motivo, ComparandResult y Destination deben apuntar a ubicaciones de memoria independientes para evitar un comportamiento inesperado.

Aunque puede usar _InterlockedCompareExchange128 para la sincronización de subprocesos de bajo nivel, no es necesario sincronizar más de 128 bits si puede usar funciones de sincronización más pequeñas (como las demás funciones intrínsecas _InterlockedCompareExchange) en su lugar. Use _InterlockedCompareExchange128 si desea tener acceso atómico a un valor de 128 bits en memoria.

Si ejecuta código que usa el intrínseco en hardware que no admite la instrucción cmpxchg16b, los resultados son impredecibles.

En plataformas ARM, utilice los intrínsecos con sufijos _acq y _rel para adquirir y liberar semántica, como al principio y al final de una sección crítica. Los intrínsecos de ARM con un sufijo _nf ("sin barrera") no actúan como una barrera de memoria.

Los intrínsecos con un sufijo _np ("sin captura previa") impiden que el compilador inserte una posible operación de captura previa.

Esta rutina solo está disponible como función intrínseca.

Ejemplo

En este ejemplo, se usa _InterlockedCompareExchange128 para reemplazar la palabra alta de una matriz de dos enteros de 64 bits por la suma de sus palabras altas y bajas y para incrementar la palabra baja. El acceso a la matriz BigInt.Int es atómico, pero en este ejemplo se usa un subproceso único y se omite el bloqueo por motivos de simplicidad.

// cmpxchg16b.c
// processor: x64
// compile with: /EHsc /O2
#include <stdio.h>
#include <intrin.h>

typedef struct _LARGE_INTEGER_128 {
    __int64 Int[2];
} LARGE_INTEGER_128, *PLARGE_INTEGER_128;

volatile LARGE_INTEGER_128 BigInt;

// This AtomicOp() function atomically performs:
//   BigInt.Int[1] += BigInt.Int[0]
//   BigInt.Int[0] += 1
void AtomicOp ()
{
    LARGE_INTEGER_128 Comparand;
    Comparand.Int[0] = BigInt.Int[0];
    Comparand.Int[1] = BigInt.Int[1];
    do {
        ; // nothing
    } while (_InterlockedCompareExchange128(BigInt.Int,
                                            Comparand.Int[0] + Comparand.Int[1],
                                            Comparand.Int[0] + 1,
                                            Comparand.Int) == 0);
}

// In a real application, several threads contend for the value
// of BigInt.
// Here we focus on the compare and exchange for simplicity.
int main(void)
{
   BigInt.Int[1] = 23;
   BigInt.Int[0] = 11;
   AtomicOp();
   printf("BigInt.Int[1] = %d, BigInt.Int[0] = %d\n",
      BigInt.Int[1],BigInt.Int[0]);
}
BigInt.Int[1] = 34, BigInt.Int[0] = 12

FIN de Específicos de Microsoft

Consulte también

Intrínsecos del compilador
Funciones intrínsecas _InterlockedCompareExchange
Conflictos con el compilador de x86