On Wed, Apr 15, 2015 at 4:34 PM, Olivier Tristan <o.tristan@uvi.net> wrote:

Have you tried Boost LockFree ?
http://www.boost.org/doc/libs/1_55_0/doc/html/lockfree.html
which handle multiple producer/Multiple-consumer queue

I know about the lockfree library, I've read the book underlying it (the Art of Multiprocessor Programming), and think I've understood at least 80% of it.  My problem is not multiple producer multiple consumer queue, so it doesn't work for me.  In particular, although there are multiple log producers, there is no consumer.  They log into a ring buffer, and normally nobody would care and the log entries get overwritten by new entries (I want to avoid having to wait when logging).  When the reader wants to read, it simply dumps everything in the ring buffer, and won't change the status of the buffer (i.e., it doesn't "consume").  And I don't care if the reader found a few entries are busy being overwritten, it just has to know about that so as to avoid using the data (which leads to wrong output and could lead to crash).  The problem is in fact a lot easier than any of the queues / stacks that is implemented by lockfree.

I've also inspected the assembly generated by g++ over my code in x86-64, and I think it is okay (i.e., no reordering with non-atomic statement is done by the compiler -- together with the strong consistency guarantee under x86-64 the code should be okay I think).  Of course, "okay for one version of a brand of compiler and library under one platform" does not mean my program is correct: a new version of the compiler / library could break it, which is my main worry.

But I've got something more fundamental to ask: what the memory model really means, and what to do once we (inevitably) move away from Boost and join the C++1x/y/z family.  It seems to me that the C++ standard provides something quite a bit weaker than what Boost promises, and I don't know how to get the Boost promise from the C++ standard.  That's the other reason why I ask.
 
Le 15/04/2015 08:42, Isaac To a ?crit :

> I'd like to write a C++ object where there are many logger threads
> logging to a large global (non-atomic) ring buffer, with an occasional
> reader thread which wants to read as much data in the buffer as
> possible. I ended up having a global atomic counter where loggers get
> locations to write to, and each logger increments the counter
> atomically before writing. The reader tries to read the buffer and
> per-logger local (atomic) variable to know whether particular buffer
> entries are busy being written by some logger, so as to avoid using them.

Regards,
Isaac