Share via


_InterlockedCompareExchange128 systeminternen Funktionen

Microsoft-spezifisch

Führt einen 128-Bit-übergreifenden Vergleich und Austausch durch.

Syntax

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

Parameter

Ziel
[in, out] Zeiger auf das Ziel, bei dem es sich um ein Array von zwei 64-Bit-Ganzzahlen handelt, die als 128-Bit-Feld betrachtet werden. Die Zieldaten müssen 16 Byte ausgerichtet sein, um einen allgemeinen Schutzfehler zu vermeiden.

ExchangeHigh
[in] Eine 64-Bit-Ganzzahl, die mit dem hohen Teil des Ziels ausgetauscht werden kann.

ExchangeLow
[in] Eine 64-Bit-Ganzzahl, die mit dem niedrigen Teil des Ziels ausgetauscht werden kann.

ComparandResult
[in, out] Zeigen Sie auf ein Array mit zwei 64-Bit-Ganzzahlen (als 128-Bit-Feld betrachtet), um mit dem Ziel zu vergleichen. Bei der Ausgabe wird dieses Array mit dem ursprünglichen Wert des Ziels überschrieben.

Rückgabewert

1, wenn der 128-Bit-Vergleich gleich dem ursprünglichen Wert des Ziels ist. ExchangeHigh und ExchangeLow überschreiben Sie das 128-Bit-Ziel.

0, wenn der Vergleich nicht dem ursprünglichen Wert des Ziels entspricht. Der Wert des Ziels ist unverändert, und der Wert des Vergleichs wird mit dem Wert des Ziels überschrieben.

Anforderungen

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

Headerdatei<intrin.h>

Hinweise

Die _InterlockedCompareExchange128 systeminterne Generiert die cmpxchg16b Anweisung (mit dem lock Präfix), um einen gesperrten 128-Bit-Vergleich und -Austausch durchzuführen. Frühe Versionen von AMD 64-Bit-Hardware unterstützen diese Anweisung nicht. Rufen Sie die __cpuid systeminterne InfoType=0x00000001 (standard function 1)Verbindung auf, um die Hardwareunterstützung für die cmpxchg16b Anweisung zu überprüfen. Bit 13 von CPUInfo[2] (ECX) ist 1, wenn die Anweisung unterstützt wird.

Hinweis

Der Wert von ComparandResult wird immer überschrieben. Nach der lock Anweisung kopiert diese systeminterne Anweisung sofort den Anfangswert von Destination in ComparandResult. Aus diesem Grund sollten Sie Destination auf separate Speicherspeicherorte verweisen, ComparandResult um unerwartetes Verhalten zu vermeiden.

Obwohl Sie für die Threadsynchronisierung mit niedriger Ebene verwenden _InterlockedCompareExchange128 können, müssen Sie nicht mehr als 128 Bit synchronisieren, wenn Sie stattdessen kleinere Synchronisierungsfunktionen (z. B. die anderen _InterlockedCompareExchange systeminternen Funktionen) verwenden können. Verwenden Sie _InterlockedCompareExchange128 diesen Wert, wenn Sie einen atombasierten Zugriff auf einen 128-Bit-Wert im Arbeitsspeicher wünschen.

Wenn Sie Code ausführen, der die systeminterne Hardware verwendet, die die cmpxchg16b Anweisung nicht unterstützt, sind die Ergebnisse unvorhersehbar.

Verwenden Sie auf ARM-Plattformen die systeminternen Funktionen mit den Suffixen _acq und _rel für Semantiken zum Abrufen bzw. Freigeben, z. B. am Beginn und am Ende eines kritischen Abschnitts. Die systeminternen ARM-Dateien mit einem _nf Suffix ("kein Zaun") wirken nicht als Speicherbarriere.

Die systeminternen Funktionen mit dem Suffix _np („no prefetch“) verhindern, dass ein möglicher Vorabrufvorgang vom Compiler eingefügt wird.

Diese Routine ist nur als systeminterne Routine verfügbar.

Beispiel

In diesem Beispiel wird _InterlockedCompareExchange128 das hohe Wort eines Arrays mit zwei 64-Bit-Ganzzahlen durch die Summe der hohen und niedrigen Wörter ersetzt und das niedrige Wort erhöht. Der Zugriff auf das BigInt.Int Array ist atomar, aber in diesem Beispiel wird ein einzelner Thread verwendet und die Sperrung aus Gründen der Einfachheit ignoriert.

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

Ende Microsoft-spezifisch

Siehe auch

Systeminterne Compiler
_InterlockedCompareExchange systeminternen Funktionen
Konflikt mit dem x86-Compiler