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). – Woodsonstd::atomic<int>
for the port? Considering thatlong
has different sizes on Windows and OSX, you will probably have to do something OS specific anyway. – Forebodingstd::atomic<int>
orstd::atomic<long>
you could useatomic_fetch_add
operation to increment variables. Take a look at my answer. – Barny