zoukankan      html  css  js  c++  java
  • InterlockedCompareExchange128

    InterlockedCompareExchange128
    Visual Studio 2010 - Visual C++
    _InterlockedCompareExchange128

    Microsoft Specific

    Performs a 128-bit interlocked compare and exchange.

    unsigned char _InterlockedCompareExchange128(
       __int64 volatile * Destination,
       __int64 ExchangeHigh,
       __int64 ExchangeLow,
       __int64 * ComparandResult
    );
    Parameters
    [in, out] Destination

    Pointer to the destination, which is an array of two 64-bit integers considered as a 128-bit field. The destination data must be 16-byte aligned to avoid a general protection fault.

    [in] ExchangeHigh

    A 64-bit integer that may be exchanged with the high part of the destination.

    [in] ExchangeLow

    A 64-bit integer that may be exchanged with the low part of the destination.

    [in, out] ComparandResult

    Pointer to an array of two 64-bit integers (considered as a 128-bit field) to compare with the destination. On output, this is overwritten with the original value of the destination.

    Return Value

    1 if the 128-bit comparand equals the original value of the destination. ExchangeHigh and ExchangeLow overwrite the 128-bit destination.

    0 if the comparand does not equal the original value of the destination. The value of the destination is unchanged and the value of the comparand is overwritten with the value of the destination.

    Requirements

    Intrinsic

    Architecture

    _InterlockedCompareExchange128

    x64

    Header file <intrin.h>

    Remarks

    This intrinsic generates the cmpxchg16b instruction (with the lock prefix) to perform a 128-bit locked compare and exchange. Early versions of AMD 64-bit hardware do not support this instruction. To check for hardware support for the cmpxchg16b instruction, call the __cpuid intrinsic with InfoType=0x00000001 (standard function 1). Bit 13 of CPUInfo[2] (ECX) is 1 if the instruction is supported.

    NoteNote

    The value of ComparandResult is always overwritten. After the lock instruction, this intrinsic immediately copies the initial value of Destination to ComparandResult. For this reason, ComparandResult and Destination should point to separate memory locations to avoid unexpected behavior.

    Although you can use _InterlockedCompareExchange128 for low-level thread synchronization, you do not need to synchronize over 128 bits if you can use smaller synchronization functions (such as the other _InterlockedCompareExchange intrinsics) instead. Use _InterlockedCompareExchange128 if you want atomic access to a 128-bit value in memory.

    If you run code that uses this intrinsic on hardware that does not support the cmpxchg16b instruction, the results are unpredictable.

    This routine is available only as an intrinsic.

    Example

    This example uses _InterlockedCompareExchange128 to replace the high word of an array of two 64-bit integers with the sum of its high and low words and to increment the low word. The access to the BigInt.Int array is atomic, but this example uses a single thread and ignores the locking for simplicity.

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

    Copyright 2007 by Advanced Micro Devices, Inc. All rights reserved. Reproduced with permission from Advanced Micro Devices, Inc.

  • 相关阅读:
    75张图带你了解网络设备、网络地址规划、静态路由、实战演练
    37张图详解MAC地址、以太网、二层转发、VLAN
    用Python计算最长公共子序列和最长公共子串(转)
    python多线程为什么不能利用多核cpu
    python实现leetcode算法题库-maxLengthofRepeatedSubarray-最长公共子序列(718)
    python实现leetcode算法题库-twoSum-两数之和(1)
    python字符串与列表及字典的相互转化
    python sorted函数的使用
    python 2/3重定向输出文件
    elasticsearch查询时设置最大返回数 max_result_window | 限制字段总数超1000
  • 原文地址:https://www.cnblogs.com/xiayong123/p/3717125.html
Copyright © 2011-2022 走看看