Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2007-11-15 12:36:41


On Nov 15, 2007, at 7:37 AM, Phil Endecott wrote:

> The semantics of pthread_mutex&cond_t are more complex than are needed
> for std::mutex&cond_var. Slightly more efficient pthread functions
> could be implemented by inlining (maybe some implementations already
> do
> this). But the overhead of using a single type for all kinds of mutex
> (recursive, non-recursive, checking etc), with run-time look up of the
> kind, is unavoidable. Since the optimal uncontended mutex locking
> code
> is just two inline instructions, even adding one additional 'if
> kind==x' will measurably reduce performance.

Your argument above addresses pthread_mutex_t but not pthread_cond_t.
I too find it unfortunate that so much functionality got stuffed into
pthread_mutex_t. And that is precisely why boost::mutex, and the
proposed std::mutex separate out functionality into different types.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html#mutex_rationale

> Like boost, and unlike POSIX, this design separates these
> functionalities into several distinct types which form a hierarchy
> of concepts. The rationale for the different types is to keep the
> most common, and simplest mutex type as small and efficient as
> possible. Each successive concept adds both functionality, and
> potentially expense.

That being said, the posix rationale includes the following statement
on this issue:

> Since most attributes only need to be checked when a thread is going
> to be blocked, the use of attributes does not slow the (common)
> mutex-locking case.

>>> 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.
>
> You are not the only one to have argued in this thread that the
> status-quo has been arrived at as a result of much deliberation by
> experts whose conclusions we should trust. While I don't exactly
> disagree with that attitude, I suggest that the level of deference
> might perhaps be dropped back one notch.
>
> The rationale section in the pthread_mutex documentation says nothing
> about the restriction on locking in one thread and unlocking in
> another. Maybe some readers can propose an explanation? My guess is
> that someone, long ago, decided to prohibit behaviour that they
> couldn't think of a use for, and that this has simply been carried
> forward.
>
>
> My motivation for relaxation is simply that it's useful (essential?)
> in
> the algorithm that I presented for a condition variable. (I'm curious
> to know if anyone has spotted any fundamental problems with that
> algorithm, by the way.)

David Butenhof (Programming with POSIX Threads) recommends semaphores
for use cases where you want to lock in one thread and unlock in
another.

-Howard


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