Aracılığıyla paylaş


İç işlevleri _InterlockedCompareExchange128

Microsoft'a Özgü

128 bit birbirine kenetlenmiş karşılaştırma ve değişim gerçekleştirir.

Sözdizimi

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

Parametreler

Hedef
[in, out] 128 bit alan olarak kabul edilen iki 64 bit tamsayı dizisi olan hedefe yönelik işaretçi. Genel koruma hatasını önlemek için hedef verilerin 16 bayt hizalanmış olması gerekir.

ExchangeHigh
[in] Hedefin yüksek bölümüyle değiştirilebilen 64 bitlik bir tamsayı.

ExchangeLow
[in] Hedefin düşük bölümüyle değiştirilebilen 64 bitlik bir tamsayı.

ComparandResult
[in, out] Hedefle karşılaştırmak için iki adet 64 bit tamsayı (128 bit alan olarak kabul edilir) dizisinin işaretçisi. Çıktıda, bu dizinin üzerine hedefin özgün değeri yazılır.

Dönüş değeri

128 bit karşılaştırılıp hedefin özgün değerine eşitse 1. ExchangeHigh ve ExchangeLow 128 bit hedefin üzerine yaz.

0, comparand hedefin özgün değerine eşit değilse. Hedefin değeri değiştirilmez ve comparand değerinin üzerine hedefin değeri yazılır.

Gereksinimler

Içsel Mimari
_InterlockedCompareExchange128 x64, ARM64
_InterlockedCompareExchange128_acq, _InterlockedCompareExchange128_nf, _InterlockedCompareExchange128_rel ARM64
_InterlockedCompareExchange128_np x64

intrin.h üst bilgi dosyası<>

Açıklamalar

_InterlockedCompareExchange128, 128 bit kilitli karşılaştırma ve değişim gerçekleştirme yönergesini lock (ön ekiyle) oluştururcmpxchg16b. AMD 64 bit donanımının ilk sürümleri bu yönergeyi desteklemez. Yönergeye yönelik donanım desteğini denetlemek için cmpxchg16b ile iç InfoType=0x00000001 (standard function 1)öğesini çağırın__cpuid. Yönerge destekleniyorsa bit 13 / CPUInfo[2] (ECX) 1'dir.

Not

değerinin ComparandResult her zaman üzerine yazılır. Yönergeden lock sonra bu iç, ilk değerini Destination hemen olarak ComparandResultkopyalar. Bu nedenle ve ComparandResult Destination beklenmeyen davranışlardan kaçınmak için ayrı bellek konumlarına işaret etmelidir.

Alt düzey iş parçacığı eşitlemesi için kullanabilirsiniz _InterlockedCompareExchange128 , ancak bunun yerine daha küçük eşitleme işlevleri (diğer _InterlockedCompareExchange iç işlevler gibi) kullanabiliyorsanız 128 bitten fazla eşitleme yapmanız gerekmez. Bellekteki 128 bit değere atomik erişim istiyorsanız kullanın _InterlockedCompareExchange128 .

Yönergeyi desteklemeyen cmpxchg16b donanımda iç kodunu kullanan bir kod çalıştırırsanız, sonuçlar tahmin edilemez.

ARM platformlarında, kritik bir bölümün başında ve _rel sonunda olduğu gibi alma ve yayın semantiği için iç _acq bilgileri ve soneklerini kullanın. Bir ("çit yok") soneki olan _nf ARM iç bilgileri bellek engeli görevi görmez.

Bir ("ön ek yok") soneki olan _np içler, olası bir ön işlem derleyici tarafından eklenmesini engeller.

Bu yordam yalnızca iç yordam olarak kullanılabilir.

Örnek

Bu örnek, iki 64 bitlik tamsayıdan oluşan bir dizinin yüksek sözcüğünü yüksek ve düşük sözcüklerin toplamıyla değiştirmek ve düşük sözcüğü artırmak için kullanır _InterlockedCompareExchange128 . Diziye BigInt.Int erişim atomiktir, ancak bu örnek tek bir iş parçacığı kullanır ve basitlik için kilitlemeyi yoksayar.

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

END Microsoft'a Özgü

Ayrıca bkz.

Derleyici iç bilgileri
İç işlevleri _InterlockedCompareExchange
x86 Derleyicisi ile Çakışma