_InterlockedCompareExchange128 funzioni intrinseche

Sezione specifica Microsoft

Esegue un confronto e uno scambio interlock a 128 bit.

Sintassi

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
);

Parametri

Destinazione
[in, out] Puntatore alla destinazione, ovvero una matrice di due interi a 64 bit considerati come campo a 128 bit. I dati di destinazione devono essere allineati a 16 byte per evitare un errore di protezione generale.

ExchangeHigh
[in] Intero a 64 bit che può essere scambiato con la parte alta della destinazione.

ExchangeLow
[in] Intero a 64 bit che può essere scambiato con la parte bassa della destinazione.

ComparandResult
[in, out] Puntatore a una matrice di due interi a 64 bit (considerato come campo a 128 bit) da confrontare con la destinazione. Nell'output, questa matrice viene sovrascritta con il valore originale della destinazione.

Valore restituito

1 se il comparand a 128 bit è uguale al valore originale della destinazione. ExchangeHigh e ExchangeLow sovrascrivere la destinazione a 128 bit.

0 se il comparand non è uguale al valore originale della destinazione. Il valore della destinazione è invariato e il valore del comparand viene sovrascritto con il valore della destinazione.

Requisiti

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

<File di intestazione intrin.h>

Osservazioni:

L'intrinseco _InterlockedCompareExchange128 genera l'istruzione cmpxchg16b (con il lock prefisso) per eseguire un confronto e uno scambio a 128 bit bloccati. Le versioni precedenti dell'hardware AMD a 64 bit non supportano questa istruzione. Per verificare la presenza del supporto hardware per l'istruzione cmpxchg16b , chiamare l'intrinseco __cpuid con InfoType=0x00000001 (standard function 1). Bit 13 di CPUInfo[2] (ECX) è 1 se l'istruzione è supportata.

Nota

Il valore di ComparandResult viene sempre sovrascritto. Dopo l'istruzione lock , questo intrinseco copia immediatamente il valore iniziale di Destination in ComparandResult. Per questo motivo, ComparandResult e Destination deve puntare a posizioni di memoria separate per evitare comportamenti imprevisti.

Sebbene sia possibile usare _InterlockedCompareExchange128 per la sincronizzazione di thread di basso livello, non è necessario sincronizzare più di 128 bit se invece è possibile usare funzioni di sincronizzazione più piccole , ad esempio le altre _InterlockedCompareExchange funzioni intrinseche. Usare _InterlockedCompareExchange128 se si vuole l'accesso atomico a un valore a 128 bit in memoria.

Se si esegue codice che usa l'intrinseco sull'hardware che non supporta l'istruzione cmpxchg16b , i risultati sono imprevedibili.

Sulle piattaforme ARM usare le funzioni intrinseche con i suffissi _acq e _rel per la semantica di acquisizione e di rilascio, ad esempio all'inizio e alla fine di una sezione critica. Gli intrinseci ARM con un _nf suffisso ("nessun recinto") non fungono da barriera di memoria.

Le funzioni intrinseche con suffisso _np ("nessuna prelettura") impediscono l'inserimento di una possibile operazione di prelettura da parte del compilatore.

Questa routine è disponibile solo come intrinseco.

Esempio

Questo esempio usa _InterlockedCompareExchange128 per sostituire la parola alta di una matrice di due interi a 64 bit con la somma delle parole elevate e basse e per incrementare la parola bassa. L'accesso BigInt.Int alla matrice è atomico, ma questo esempio usa un singolo thread e ignora il blocco per semplicità.

// 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

Fine sezione specifica Microsoft

Vedi anche

Intrinseci del compilatore
_InterlockedCompareExchange funzioni intrinseche
Conflitti con il compilatore x86