_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
Intrinsische Compilerfunktionen
_InterlockedCompareExchange systeminternen Funktionen
Konflikt mit dem x86-Compiler