On Saturday, 9 January 2016 at 15:51:51 UTC, Jin wrote:
On Saturday, 9 January 2016 at 14:20:18 UTC, Andy Smith wrote:
I'm a little worried you have no volatile writes or fences
around your code when you 'publish' an event using head/tail
etc. It looks like it's working but how are you ensuring no
compiler/CPU reordering is ocurring. Does x86_64 actually
allow you to get away with this? I know its memory model is
stricter than others...
I just add atomic fence for push and take:
this.messages[ this.tail ] = value;
atomicFence;
this.tail = ( this.tail + 1 ) % this.size;
You need it in the tests.
I haven't used atomics in D, but you have
atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(ref const
shared T val)
atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V1)(ref shared
T val, V1 newval)
The compiler should then be able to ignore it if the CPU handles
it well enough, assuming the D implementation work. Something
along the lines of:
immutable i = atomicLoad!(MemoryOrder.raw)(tail);
immutable n = (i+1)%size;
if( n == atomicLoad!(MemoryOrder.acq)(head) ) return QUEUE_FULL;
buffer[n] = ...;
atomicStore(MemoryOrder.rel, tail, n);
Or something like that.