This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Interleaving pthread_cleanups in C and C++
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc at gcc dot gnu dot org
- Cc: rth at redhat dot com
- Date: Fri, 2 May 2003 18:38:40 -0700
- Subject: Interleaving pthread_cleanups in C and C++
- Reply-to: mark at codesourcery dot com
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