views:

248

answers:

3

I fully appreciate the atomicity that the Threading.Interlocked class provides; I don't understand, though, why the Add function only offers two overloads: one for Integers, another for Longs. Why not Doubles, or any other numeric type for that matter?

Clearly, the intended method for changing a Double is CompareExchange; I am GUESSING this is because modifying a Double is a more complex operation than modifying an Integer. Still it isn't clear to me why, if CompareExchange and Add can both accept Integers, they can't also both accept Doubles.

A: 

As Adam Robinson pointed out, there IS an overload for Interlocked.Increment that takes an Int64, but note:

The Read method and the 64-bit overloads of the Increment, Decrement, and Add methods are truly atomic only on systems where a System.IntPtr is 64 bits long. On other systems, these methods are atomic with respect to each other, but not with respect to other means of accessing the data. Thus, to be thread safe on 32-bit systems, any access to a 64-bit value must be made through the members of the Interlocked class.

Mitch Wheat
+1  A: 

I suspect that there are two reasons.

  1. The processors targeted by .Net support interlocked increment only for integer types. I believe this is the LOCK prefix on x86, probably similar instructions exist for other processors.
  2. Adding one to a floating point number can result in the same number if it is big enough, so I'm not sure if you can call that an increment. Perhaps the framework designers are trying to avoid nonintuitive behavior in this case.
dsolimano
Regarding your second point: yes, but I am asking about Interlocked.Add, not Interlocked.Increment.
Dan Tao
+2  A: 

The Interlocked class wraps around the Windows API Interlocked** functions.

These are, in turn, wrapping around the native processor API, using the LOCK instruction prefix for x86. It only supports prefixing the following instructions:

BT, BTS, BTR, BTC, XCHG, XADD, ADD, OR, ADC, SBB, AND, SUB, XOR, NOT, NEG, INC, DEC

You'll note that these, in turn, pretty much map to the interlocked methods. Unfortunately, the ADD functions for non-integer types are not supported here. Add for 64bit longs is supported on 64bit platforms.

Here's a great article discussing lock semantics on the instruction level.

Reed Copsey