Alex Rivera | Logout

fastest way to atomically compare two integers in C?

Asked 2011-06-26T06:22:10.927
9
uint64_t n;      // two 32-bit integers

return ( (uint32_t)(n >> 32) == (uint32_t)n );

What is the fastest way to atomically compare the 32 most-significant bits to the 32 least-significant bits of a uint64_t?

I think one horrible solution is to do: acquire spinlock, read 32 LSB, read 32 MSB, compare to get result, release spinlock, return result. Is there any way to do this without having to take a spinlock?

Edit
Report

2 Answers

8

This whole operation (atomic comparison of two values in memory) is meaningless unless you can also ensure that writing them is always atomic. It's also subject to an inherent race condition; by the time you've determined that they're equal they may have changed, or vice versa. Whatever problem you're trying to solve almost surely calls for a lock, not atomic operations.

answered 2011-06-26T17:07:14.023
3
  1. You can do it without lock only if you are able to retrieve 64-bit number atomically on your platform. If it is possible then first - you atomically retrieve 64-bit value in your favorite way (e.g. InterlockedOr64(ptr,0) on 64-bit windows, there is no way if you have 32-bit x86 CPU - unless you have Intel CPU not older than Pentium and you make sure your 64-bit value is 64-bit aligned, not sure about other vendors' x86 CPUs), second - do your compare with the value you retrieved.

  2. You obviously cannot do it in portable way. On platforms where you cannot atomically get 64-bit number it is impossible to do it without lock.

EDIT

Since some severely misleading ideas gain serious popularity in this discussion I feel my duty to write some notes about failing to use Compare&Exchange of 32-bit numbers to solve the problem.

Let's assume we have x86 platform then we might write asm code:

    mov eax, [num+4]
    lock cmpxchg [num], eax
    jz  equal_case_code
    ; non-equal case code follows
equal_case_code:
    ; equal case code follows

Obviously this implementation is not atomic - thread may be interrupted between mov and cmpxchg instructions (as always two memory operands not allowed in one instruction).

32-bit based Compare&Exchange functions from different APIs (like InterlockedCompareExchange from Win32 API) does not provide the correct solution either because their semantic allows atomic access to one 32-bit memory address only.

answered 2011-06-26T07:26:12.350

Your Answer