This is the mail archive of the libc-alpha@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Help: Unwinding the C++ stack...throw, longjmp & threads


Ulrich Drepper wrote:
> 
> "George T. Talbot" <george@moberg.com> writes:
> 
> > What would be an acceptable size increase?  Did the people who
> > complained say what would be acceptable or did they just complain?
> > ;^)
> 
> The latter, of course.

;^)

> > What methods do you guys use now to determine what is and what isn't
> > an acceptable performance hit when, say, you're experimenting with
> > different compiler optimization flags?
> 
> I don't have to run performance data.  If a feature effects everybody
> and is hardly used by anybody it's not worth it.  If the effect is
> minimal (i.e., a handful of additional assembler instruction or a few
> bytes of data where needed) this is ok.  But simply enabling
> fexceptions is not.

OK.  I understand.

> > I'm trying to get an idea of what is and what isn't acceptable.  I
> > have no problem doing the hard work of implementing a fix to
> > pthread_cancel() under Linux, and I have no problem doing the hard
> > work of measurement, but I need some objective criteria for doing
> > the measurement so I don't walk down a dead-end path.
> 
> I like the idea of using the exception mechanism to handle cancelation
> even in C.  So what has to be done is:
> 
> - implement a usable interface to the exception handling in gcc (not g++).
>   It must be possible to define macros named pthread_cleanup_push() and
>   pthread_cleanup_pop() and use them like this:
> 
>         pthread_cleanup_push (func, arg);
> 
>         ... do lots of work ...
> 
>         if (some condition)
>           {
>             ... do what is necessary to leave the frame ...
>             return;
>           }
> 
>         ... more work ...
> 
>         pthread_cleanup_pop (doit);
> 
>   This roughly has to be converted to something like:
> 
>         try
>           {
>             ... do lots of work ...
> 
>             if (some condition)
>               return;
> 
>             ... more work ...
> 
>             if (doit)
>               throw (_posix_cancelation_exception_object);
>               // Alternatively do the call directly:
>               // func (arg);
>           };
>         catch (_POSIX_CANCELATION_EXCEPTION &exc)
>           {
>             func (arg);
>           };

Yup.  This is exactly what I was thinking.

>   I.e.:
> 
>   + leaving the frame must somehow be handled

I asked the author of Programming POSIX Threads (David Butenhof) who
said that the standard doesn't really define that case, but that
programs which use return to avoid pthread_cleanup_pop() aren't
portable.  He said that it was acceptable for an implementation to do an
implicit pthread_cleanup_pop(0), which is what your example would do.

So, in other words, no problem.  ;^)

By the way, won't the current implementation have a problem with this
case?

>   + the function to be called (and it's always only one function) is
>     named in the push call at the beginning (contrary to the C++
>     syntax)

I think what ends up happening is something like this:

	pthread_cleanup_push(blah, arg);
	...
	do_work();
	...
	pthread_cleanup_pop(execute);

		is transformed via macro expansion to:

	{						\
		void	(*__function) (void *)	= blah;	|
		void	*__arg			= arg;	| pthread_cleanup_push()
							|
		__try					|
		{					/
			...
			do_work();
			...
		}					\
		__catch (...)				|
		{					| pthread_cleanup_pop()
			__function(arg);		|
			__throw;			|
		}					|
		if (execute) __function(arg);		|
	}						/

(I'm not sure whether the above should be __catch(...) or
__catch(POSIX_cancel c).  I could argue for either one.)

>   + one must be able to throw an exception (in the example above as
>     well as in the cancelation call of the library)

Yup.  I'd need to be able to throw an exception so that I could do the
re-throw above.  I'm not sure whether the above should be __catch(...)
or __catch(POSIX_cancel c).

> - functions which must be compiled with exception handling enabled must
>   be identified.  These include:
> 
>   + functions which are cancelation points:
> 
>   + functions which use callbacks and those directly or indirectly using
>     functions which use callbacks

Personally, the above __try...__catch stuff, the patch to pthread_exit()
to perform a __throw at the right time, and possibly the patch to the
compiler to add exception support to C I can do.  Identifying the
functions which need -fexceptions starts to get me in water over my
head, as I don't know the C library that well.

I agree that this needs to be done.  I'm just saying that it's a problem
that I don't know that I could get right, as I don't have enough
experience and familiarity with the C library.  Is there an automated
way of doing this?

I also get the feeling from other posts by the compiler guys on this
topic is that this issue has made them think about optimizing the
unwinding information to take up less space.  It sure would be nice to
avoid the issue entirely.  ;^)

> If things are implemented this way I could argue that the new scheme
> should be used since it is probably faster than the current implementation.

I hadn't thought of that.

> If you can come up with a scheme which works for the case above (I
> hope I covered all cases) I'd like to learn about it.

If I (or someone else, but I get the feeling that I'm volunteering ;^)
can come up with a good patch for GCC to add exception support to C,
which seems to be something that the people on the compiler list like,
then I've got no problem with the scheme above.

--
George T. Talbot
<george@moberg.com>

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]