Practical Lock-Free Buffers
ddj.com
ddj.com
The TransferString function he proposes seems overly complex to me, using locks would make it more simple and even faster. It would almost make the code look like "lock(); memcpy(); unlock();" which is not prone to deadlocking.
I even downloaded the source code to the article, but he uses threads to test it. Anyone care to explain this thing to me?
He essentially packs 4 byte strings into integers (assuming 32 bit integers) in an atomic manner. In the strictest sense there are no locks here, but at the end of the day he treats each memory location as its own lock. He also does some busy waiting, which is just a good old spin lock:
while(!InsertAt(data,insertedAt));
Interesting concept but nothing too new. I would also caution against using this code without understanding it first. I don't see much error checking in there.GCC, for example has __sync_val_compare_and_swap(...) function that give you access to the hardware compare and swap.
FreeBSD has atomic.h providing a bunch of different atomic ops, e.g: http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/amd64/include/...
I believe FreeBSD also uses this style of buffer for dmesg, which sadly also results in a lot of interlacing if two kernel threads are trying to write to the buffer at once.
One case I don't think he handles is if a user does a Lookup() for some value in a slot, then tries to delete that slot. In this case, the wrong value might be deleted if an InsertAt() happens in the meanwhile.
You can use them between processes if you use shared memory.
This is useful in realtime or any other low latency applications where one reader or writer cannot be blocked for more than a couple of hundred microseconds.
It is basically reimplementing the semaphore but it is controlled by the application. There are no system calls, no threads being suspended. Instead of the busy while loop it might be possible to use a fixed count of iterations or a specific timeout value.
This is useful but in a very narrow context.
Still I think the implementation in the article is bad, and you should avoid using it in production, because it uses too much busy waits and there is no error handling.
And if one don't use shared memory, just threads (as in the example code) you gain nothing from this solution. You'd better use a simple lock-based implementation, or if you need low latency a correct lock-free or even better, a wait-free queue.