Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2007-11-14 21:55:17


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_rationale
>
> 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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk