
On Mon, 21 Dec 2009, Chris M. Thomasson wrote:
Of course you are right. For some reason, I was thinking that `memory_order_consume' would boil down to a:
MEMBAR #LoadLoad
on a SPARC. The name was confusing me. Perhaps it should be named `memory_order_depends' or something...
I think it was named exactly that way in some earlier proposals, and I also liked it better.
I don't think I can use C++0x memory ordering to achieve simple #LoadLoad and #StoreStore barriers without the #LoadStore constraint. Am I right?
If a hypothetical C++0x compiler were extremely clever and knew that the only operations on shared data before a given "release" fence were stores, it could translate this as "MEMBAR #StoreStore" (similar for "acquire" with loads). I don't know if the required code analysis is feasible or worthwhile, but there is certainly no way to force the compiler to generate these exact barriers. It's a pity that something like the below algorithm is therefore not possible: template<typename X> class atomic_readmostly_state { public: X read() { for(;;) { unsigned int g=generation.load(memory_order_relaxed); load_load_mb(); X tmp=state[g&1]; load_load_mb(); if (g==generation.load(memory_order_relaxed)) return tmp; } } void write(X tmp) { mutex::scoped_lock g(write_lock); unsigned int next=generation.load(memory_order_relaxed)+1; state[next&1]=tmp; generation.store(next, memory_order_release); } private: X state[2]; atomic<unsigned int> generation; mutex write_lock; }; which provides a nice, contention-free (no stores by readers!) mechanism to share read-mostly state. Helge