diff options
Diffstat (limited to 'nptl/pthread_create.c')
-rw-r--r-- | nptl/pthread_create.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index caaf07c134..92c945b12b 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -427,12 +427,23 @@ START_THREAD_DEFN compilers without that support we do use setjmp. */ struct pthread_unwind_buf unwind_buf; - /* No previous handlers. */ + int not_first_call; + not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf); + + /* No previous handlers. NB: This must be done after setjmp since the + private space in the unwind jump buffer may overlap space used by + setjmp to store extra architecture-specific information which is + never used by the cancellation-specific __libc_unwind_longjmp. + + The private space is allowed to overlap because the unwinder never + has to return through any of the jumped-to call frames, and thus + only a minimum amount of saved data need be stored, and for example, + need not include the process signal mask information. This is all + an optimization to reduce stack usage when pushing cancellation + handlers. */ unwind_buf.priv.data.prev = NULL; unwind_buf.priv.data.cleanup = NULL; - int not_first_call; - not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf); if (__glibc_likely (! not_first_call)) { /* Store the new cleanup handler info. */ |