This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Interleaving pthread_cleanups in C and C++


Since I resisted try-finally in C, I think I'm on the hook to try to
figure out how to make pthread_cleanups work well with combined C/C++
programs -- or relent on try-finally as a C extension.

Here's my first try:

(1) Augment the C version of pthread_cleanup_push to push the current
    stack pointer as well as the other information it already pushes.

(2) When an exception is being handled, take advantage of the
    two-phase EH stuff as follows:

    - In phase one, figure out what the stack pointer will be after 
      control is transferred to the handler.

    - If that stack pointer is "older" than the stack pointer in the
      topmost pthread_cleanup_push entry, run cleanups until that is
      no longer true.

    - Transfer control to the exception handler.

(3) The function called at thread startup looks like:

    void __thread_start(void* (*fp)(void*), void* arg) {
      void* r;
      try {
        r = (*fp) (arg);
      } catch (...) {
        /* This is here to make sure that there is always an exception
	   handler older than any C pthread_cleanup_push entries.
	   They will have been run by the time we get here.  */
	r = PTHREAD_CANCELED;
      }

      __thread_exit (r);
    }

For this to work, you have to be able to tell whether one stack
pointer is older than another.  I'm not aware of an architecture where
this is very hard; even if you have a segmented stack you just figure
out which segment the pointer is in, and then do a comparison.  I'm
not an expert here, though; it might be that this is tough on some
architecture.

The cost is one word per pthread_cleanup_push and some additional work
during exception-handling -- which is not on the fast path.

The key point is that you do not need to run the C pthread_cleanups
with the stack actually unwound; you just need to make sure they are
run before the stack is unwound past the point at which they are
pushed, since the arg to the cleanup may allow the function to get at
stuff on the stack.

Is this madness?

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com


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