
On Nov 14, 2007, at 5:14 PM, Phil Endecott wrote:
Howard Hinnant wrote:
Andrey Semashev wrote:
Beman Dawes wrote:
I'm not totally enthralled by the condition_variable_any name. If someone has a suggestion for a more meaningful name, now is a good time to speak up.
cond_var would better for my carpal tunnels.... I was also happy with 'condition'. (Very long names should perhap be reserved for bad things. The time that it takes me to type reinterpret_cast is normally long enough to make me reconsider whether it's appropriate!)
<nod> I'm not terribly fond of any of the names and my favorites (least hated) so far have been cond_var and gen_cond_var. However the committee decided otherwise, and I can live with that.
I wonder why not making condition_variable a template with a mutex type in its template parameter. We could specialize it on the boost::mutex type to have the current optimized condition_variable implementation and leave it implemented as condition_variable_any for a general case.
The rationale for the current design (with different names) can be found here:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html#condition...
Thanks for the link. Quote:
"For those platforms which offer a native condition variable (e.g. pthread_cond_t), C++ should offer as thin a wrapper as possible around that OS functionality."
I think this is a mistake. What is the motivation? Portability, perhaps?
By wrapping the existing functionality, we bound the performance that we can achieve: we'll never be faster than C code. High-performance concurrency primitives will be crucial to getting the most from the next generations of multi-core hardware. We should at least be considering building from the most basic building blocks available. (Consider the shared_ptr implementation, for example, which only falls back to pthread_mutex if it doesn't have a better solution using atomics.)
My experience with pthread_mutex is that it's simple to write significantly faster (but less-portable) mutexes, and I think that Boost should be taking that approach, with the wrapped OS functionality offered only as a fallback.
I have not yet tried to benchmark pthread_cond, but I would be surprised to find it faster than the condition variable using mutexes that I posted elsewhere in this thread [though that code may well have some horrible flaw in it.....].
We are approaching this from two different perspectives. The above link refers to a C++ committee paper. I'm representing the path that C ++ should take in C++0X, and not boost. The wording is intended for performance, both in cpu and memory. The wording is not intended to dictate a particular implementation, but to simply allow for the highest performance implementation on any given platform. The condition variable is by now a tried and true multithread primitive. It predates C++ itself. We should have it. How it is implemented is an implementation detail. If pthread semantics can be implemented more efficiently using atomics (which C++0X will have), then that's great. There is no requirement that pthread_cond_t be at the center of std::condition_variable. On the other hand, this is an OS-level functionality. If the semantics of pthread_cond_t can be implemented more efficiently on some platform than is currently done, I imagine that the OS vendor will likely do it, and call it pthread_cond_t.
Apart from performance, another problem with wrapping existing functionality is that the lowest common denominator of all the constraints from the existing implementations has to be passed on to the user. For example, in the condition variable code that I posted, a mutex is locked from one thread and then unlocked from another. I think this works for all of the mutexes that I've written (spinlock, loop-calling-yield, futex) (though I may be missing something - I'm not an expert in any of this). Because it works with futex, I guess that the Linux pthread_mutex may also work in DEFAULT mode, though it's possible that there is something in glibc that breaks it. However, POSIX says that "if a thread attempts to unlock a mutex that it has not locked ... undefined behavior results." So the wording in N2447 also requires that "the current thread of execution shall own the mutex" before it can call unlock().
The Posix committee has considerable experience and expertise in this area. While I do not trust their advice blindly, I also do not dismiss it lightly (quite the contrary). Transferring mutex ownership among threads is not one of the decisions they have made that I've questioned. I've lacked the motivation. If you have strong motivation for relaxing this restriction, coupled with some insight into the posix decision and why it should be relaxed, I am most interested. -Howard