Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I make the following code lock free / atomic?

int val = memLoc[index++];

or better yet

int val = memLoc[index++ & 0xFF];

Trying to do a threadsafe read from a shared ring buffer where each call gets the next value - and I'd love it to be lock free if at all possible as it happens a TON. No Boost / C++ 11 allowed :(

like image 892
Michael Dorgan Avatar asked Apr 13 '12 14:04

Michael Dorgan


2 Answers

The only operation here which needs to be synchronized is the increment of the index value. Since this is just a numeric value it can be done without the use of locks via an atomic increment. The rest of the operations you listed are just reads of a shared location and don't need to be synchronized.

On Win32 making the increment synchronized is done with the InterlockedIncrement function

int oldValue = InterlockedIncrement(&index);
int val = memLoc[oldValue & 0xFF];

There are various synchronized increment functions available on Linux. There is a fairly good discussion about the options on this stackoverflow thread

  • How to perform atomic operations on Linux that work on x86, arm, GCC and icc?
like image 132
JaredPar Avatar answered Sep 30 '22 03:09

JaredPar


You'd need to increment and read back index in an atomic operation. Unfortunately the ++ operator doesn't guarantee any atomicity.

Most processors have some sort of fetch-increment-store instruction that can be used. You can insert inline assembly to do that. http://en.wikipedia.org/wiki/Fetch-and-add

If you're running on Windows, MS provides an API to access this: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684122(v=vs.85).aspx

If you're on another OS, there's likely similar functionality. In any case though, you'll need OS or lower type access to get an atomic fetch-increment-store.

like image 30
dragonx Avatar answered Sep 30 '22 02:09

dragonx