While porting some Windows C++ code to iOS, I need to provide an implementation of Win32's long InterlockedIncrement(long *p) call. This is easy enough using the functions defined in <libkern/OSAtomic.h>.
However, I am wondering whether it's possible to write it in a OS-agnostic way using just the C++11 facility, mainly <atomic>. I came up with this, which I am not sure accomplishes what I want:
inline long InterlockedIncrement(long* p) { std::atomic<long&> atomicP(*p); return ++atomicP; } Does this work? Is that good enough? The two lines are not atomic, but the increment should be atomic, which is the key here.
All the examples of use for <atomic> that I found are different, where a std::atomic<T> is defined and used directly. Here I want to use an existing long variable that the callers passes to me by address. I couldn't find such an example.
Edit: Clang 3.2 (in Xcode 4.x) fails to compile ++atomicP with the error "cannot increment value of type std::atomic<long&>" (nor atomicP += 1 either).
What would be the correct way?
Edit again: a pointer implementation compiles...
inline long InterlockedIncrement(long* p) { std::atomic<long*> atomicP(p); return ++(*atomicP); } But I'm afraid this doesn't work, since I don't increment an atomic type, but the value pointed by the pointer, which is not atomic.
atomic<T&>. And the pointer version is wrong (the stored pointer itself will be atomic, not the pointed-to value).std::atomic<int>for the port? Considering thatlonghas different sizes on Windows and OSX, you will probably have to do something OS specific anyway.std::atomic<int>orstd::atomic<long>you could useatomic_fetch_addoperation to increment variables. Take a look at my answer.