
Alexander Terekhov <terekhov@web.de> wrote:
Matt Hurd wrote: [...]
But why is a concurrent-aware setter useful if its effects aren't visible to the other threads?
In what way do you mean they not visible?
Such aligned memory operations are guaranteed to be atomic on ia32 at a system wide level AFAIK.
On IA32, sure, but not on other architectures.
Yup. Which gets back to the subject line...
On IA32,
- stores have release semantics (sink-load/store mbar for preceding loads/stores in the program order);
- loads have acquire semantics (hoist-load/store mbar for subsequent loads/stores in the program order);
- lock instructions have compound release and acquire semantics (fully fenced).
See Plan9 story for an illustration of lockless stuff that needs store-load fence (compound sink-store and hoist-load mbar) on IA32.
http://groups.google.com/groups?selm=414E9E40.A66D4F48%40web.de (Subject: std::msync)
regards, alexander.
Always insightful, thanks Alexander. However, I'm not talking about guarantees of ordering or timing, just "eventual" visibility. Avoiding a lock/fence where possible is a good thing if appropriate, though as you show the subtleties are not to be underestimated. The type trait needs_lock<T> would provide you with a cue to memory transaction atomicity. Timely availability and ordering, as you show, are different beasts. Perhaps a better name would be boost::memory_atomic<T> as needs_lock is almost as misleading as stl::set? By the way, when you say ia32 which architectures are you referring to, as they have varied quite a bit on their capabilities from 386 to P4 & Xeon? Do you have a view on the original question about how to structure code regarding architecture specific specializations? Regards, Matt Hurd matthurd@acm.org www.hurd.com.au