Re: [boost] Boost.Threads, N2178, N2184, et al

Peter Dimov wrote:> > Howard Hinnant wrote:> > > >> N2184 takes the minimalist approach. It is easier to add> >> functionality (and the associated expense) than to subtract it. There> >> are many things the N2184::thread does not directly support. I> >> believe this is a feature, not a bug.> > > > This is true under the assumption that we need to target the least common > > denominator. Try/timed joins for example come for free on Windows. So you > > are imposing an unnecessary mutex+cv overhead for everyone wanting to use > > try/timed joins there.> > > > I've decided to adopt a different approach and suggest a way to equalize > > ('harmonise' in EU terms :-) ) the platforms via the join2 extensions. In a > > perfect world, this would lead to everyone enjoying _zero overhead_ > > try/timed joins in a few years once pthread implementors adopt the > > extensions.> > > > Yes, I agree that this can be considered idealistic; but the other option is > > to not even give them a chance to offer the functionality as there would be > > no portable C++ way to take advantage of it. > > I'm far from being an expert on the Windows internals, but maybe what > seems to "zero overhead" try/timed join is not really zero overhead, and > the overhead is there, just hidden somewhere inside. If that's the case, > then the "idealistic" way to go is to get Windows to supply a true zero > overhead join. I am also not an expert, but my understanding is that there are no technical problems to extend the pthread interface to support try/timed joins, and that this does not introduce overhead.
If this is correct, and if N2178 is accepted, then zero-overhead try/timed join becomes available across the the board. If N2184 is accepted, then zero-overhead try/timed join becomes unavailable across the board, regardless of whether it is possible from a technical point of view. Emil Dotchevski _________________________________________________________________ Take a break and play crossword puzzles - FREE! http://games.msn.com/en/flexicon/default.htm?icid=flexicon_ wlmemailtaglinemarch07

On Mar 25, 2007, at 5:53 PM, Emil Dotchevski wrote:
If this is correct, and if N2178 is accepted, then zero-overhead try/ timed join becomes available across the the board. If N2184 is accepted, then zero-overhead try/timed join becomes unavailable across the board, regardless of whether it is possible from a technical point of view.
I've been hesitant to say this, but it may be possible to add try/ timed_join to N2184. I know that it definitely could be added to my pthreads-based implementation of N2184 (well, I haven't actually done it so maybe definitely is too strong - 98% sure). And by added here, I mean at no extra cost. What has me worried about adding try/timed_join to N2184 is actually N2178! :-) I implemented N2184 for one of the "problem platforms" that I mentioned in my post concerning C/C++ cancellation interoperability: Mac OS X. I can not currently implement a pthread_cancel on this platform that will work in C++. This is both good and bad. The bad is obvious: no C/C++ interoperability. The good is that it forced me to not implement std::thread::join in terms of pthread_join. Because thread::join must be a C++ cancellation point, and pthread_join isn't a C++ cancellation point (if you can't use pthread_cancel), then one must implement thread::join in terms of a mutex/cv stored in thread local data (and thread local data is hopefully coming via N2147). The reason for this is that condition is the only trigger I have in the tool box to wake a sleeping thread so it can be canceled. That makes it zero cost to add siblings of thread::join which do try_join (just check the done flag in thread local data), and timed_join (use cv/timed_wait). However if thread::cancel is implemented in terms of pthread_cancel, that means that there is pressure to implement thread::join in terms of pthread_join (because cancellation then works). And there is no pthread_try_join or pthread_timed_join so if these were required at the C++ level, then you've added a feature that adds cost. The other, extremely remote, possibility is to ask the posix group to add pthread_try_join and pthread_timed_join. They might even be willing to do this. However there is just no way we're going to get that committee to mandate that pthread_cancel emits a catchable C++ exception. And in that case pthread_try_join and pthread_timed_join are useless to us anyway. Thread cancellation is at the heart of a lot of these issues! :-\ -Howard

Howard Hinnant wrote:
What has me worried about adding try/timed_join to N2184 is actually N2178! :-)
:-) But that is why N2178 also has pthread_*join2_np. The amount of work that is required from a pthread implementation to make pthread_cancel C++ friendly is much more than what's needed to provide the extensions.
The other, extremely remote, possibility is to ask the posix group to add pthread_try_join and pthread_timed_join. They might even be willing to do this. However there is just no way we're going to get that committee to mandate that pthread_cancel emits a catchable C++ exception.
I just got permission to quote Hans Boehm here, since he put it much better than I could in a post to POSIX-C++: "To me, this reaction makes perfect sense in many contexts, but I'm not sure it makes sense here. I do not work with the people at HP who would have to fix this. But what I've heard in the past is that there is enough dissatisfaction with the fact that cancellation & C++ basically doesn't work that most people would like to see this fixed. The hassle involved in doing the work is probably less than that of listening to the continuous complaints. My impression is that this is probably one of the more superficial problems with C++ & pthreads, but it seems to be the one that draws the most complaints. And implementers would like guidance as to the correct solution." It seems very likely to me that once threads are officially recognized by the C++ standard, the customers will demand unified C/C++ cancelation, and do that loudly. So regardless of what the POSIX committee says, pthread_cancel will start throwing something that looks like an exception to C++ code, earlier or later. We should be prepared for that.

On Mar 25, 2007, at 7:54 PM, Peter Dimov wrote:
Howard Hinnant wrote:
What has me worried about adding try/timed_join to N2184 is actually N2178! :-)
:-)
But that is why N2178 also has pthread_*join2_np. The amount of work that is required from a pthread implementation to make pthread_cancel C++ friendly is much more than what's needed to provide the extensions.
The other, extremely remote, possibility is to ask the posix group to add pthread_try_join and pthread_timed_join. They might even be willing to do this. However there is just no way we're going to get that committee to mandate that pthread_cancel emits a catchable C++ exception.
I just got permission to quote Hans Boehm here, since he put it much better than I could in a post to POSIX-C++:
"To me, this reaction makes perfect sense in many contexts, but I'm not sure it makes sense here. I do not work with the people at HP who would have to fix this. But what I've heard in the past is that there is enough dissatisfaction with the fact that cancellation & C++ basically doesn't work that most people would like to see this fixed. The hassle involved in doing the work is probably less than that of listening to the continuous complaints.
My impression is that this is probably one of the more superficial problems with C++ & pthreads, but it seems to be the one that draws the most complaints. And implementers would like guidance as to the correct solution."
It seems very likely to me that once threads are officially recognized by the C++ standard, the customers will demand unified C/C++ cancelation, and do that loudly. So regardless of what the POSIX committee says, pthread_cancel will start throwing something that looks like an exception to C++ code, earlier or later. We should be prepared for that.
<grin> Yeah, glad you're listening to POSIX-C++. Hans speaks quite elegantly. I definitely would like to allow pthread_cancel to throw an exception. I suspect this will even become the norm on 64 bit platforms. But I'm still very worried about 32 bit platforms and I don't think it will be the norm there. There's so many backwards compatibility problems. I agree with you that there are good use cases for try/timed_join. And for the 32 bit systems I'm worried about, they can be added no cost to the N2184 model. For the 64 bit systems, your pthread extension functions look like a good route to pursue for keeping these zero-cost. Note that simply allowing pthread_cancel to throw an exception doesn't make C and C++ cancellation portably interoperable. So we've still got a problem there. Indeed maybe even a bigger one: fclose is allowed to throw! :-\ -Howard

Howard Hinnant wrote: [...]
got a problem there. Indeed maybe even a bigger one: fclose is allowed to throw! :-\
That just means that you'd either have to deal with it (disable cancel at places where you don't want it to throw, or catch and self-re-cancel, or whatever) or just declare your code cancel unsafe (your clients will either disable cancel or simply won't cancel at all) and be done with it. Given that the later is the current state of affairs in today's (p)thread/C++ world, what the heck is the problem? regards, alexander.

On Mar 26, 2007, at 1:32 AM, Alexander Terekhov wrote:
Howard Hinnant wrote: [...]
got a problem there. Indeed maybe even a bigger one: fclose is allowed to throw! :-\
That just means that you'd either have to deal with it (disable cancel at places where you don't want it to throw, or catch and self-re- cancel, or whatever) or just declare your code cancel unsafe (your clients will either disable cancel or simply won't cancel at all) and be done with it. Given that the later is the current state of affairs in today's (p)thread/C++ world, what the heck is the problem?
Perhaps just one of education. I'm a cautious person and strive to fully consider the ramifications of all the decisions we're making. It seems to me that the more cancellation points we introduce, the more complicated the interface becomes that we're introducing. We tentatively have cancellation points to introduce in two categories: 1. New functions that haven't before appeared in the standard: thread::join this_thread::sleep etc. 2. Existing functions that acquire this new functionality of cancellation point: fclose fflush fgetc fopen fprintf etc. Set 2 worries me more than set 1. If no one else sees any problems I might be tempted to write it off as me being overly cautious (again). But the last time I got LWG direction on this very subject, they were much more agreeable to set 1 than set 2. That could change of course. Perhaps we all just need a little more thought and education. Or perhaps our caution is warranted. -Howard
participants (4)
-
Alexander Terekhov
-
Emil Dotchevski
-
Howard Hinnant
-
Peter Dimov