[GD-General] Totally Safe lock-free FIFO for arbitrary-sized items.
Brought to you by:
vexxed72
|
From: Jon W. <hp...@mi...> - 2006-08-09 20:10:56
|
And, to confuse things even more, if you have strict aliasing options
turned on, the compiler may even decide to re-order the stores. Thus,
the Totally Safe lock-free FIFO for arbitrary-sized items looks like this:
/* Lock-free FIFO by Jon Watte.
* Stored can be a type of any size.
* Size must be power of 2.
* This FIFO is correct on systems with strongly consistent
* caches (such as Intel). It may require write barriers on
* systems with weakly consistent caches. Insert such a
* barrier in the inline function barrier() if that's the case.
*/
template<typename Stored, size_t Size>
class LockFreeFifo {
public:
LockFreeFifo() { head = 0; tail = 0; }
/* Get an item from the FIFO.
* Return true if an item was there and was copied,
* false if the FIFO is empty.
*/
bool get(Stored & out) {
if (head - tail > 0) {
out = fifo_[tail & (Size-1)];
++tail;
barrier(); /* make sure writer knows FIFO isn't full */
return true;
}
return false;
}
/* Put an item into the FIFO.
* Return true if it fit and was copied,
* false if the FIFO is full.
*/
bool put(Stored & in) {
if (head - tail < Size) {
fifo_[head & (Size-1)] = in;
barrier(); /* make sure FIFO is updated before head */
++head;
barrier(); /* make sure reader can find the new item */
return true;
}
return false;
}
private:
inline void barrier() {
/* If your platform has a weakly consistent cache (i e,
* not Intel) then you need to insert a barrier instruction
* (such as EIEIO on PPC) here.
*/
#warning "Use the intrinsic specific to your platform, if needed."
}
/* Make these volatile, to avoid strict type aliasing analysis to allow
* the compiler to re-order stores.
*/
volatile unsigned int head;
volatile unsigned int tail;
volatile Stored fifo_[Size];
};
Jon Watte wrote:
> Note that the problem is with weakly _consistent_ cahces, not just
> weakly ordered -- i e, if cache line A can flush before cache line B, it
> doesn't matter, as long as the mutliple CPUs implement cache snooping to
> stay consistent (which is the case on Intel). On PPC, you may end up
> wanting to use the cache line reservations with a spin loop.
>
|