This is the mail archive of the libc-alpha@sourceware.org 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]
Other format: [Raw text]

Should pthread_kill be marked __THROW?


In glibc we mark pthread_kill as __THROW.

/* Send signal SIGNO to the given thread. */
extern int pthread_kill (pthread_t __threadid, int __signo) __THROW;

Which imparts the 'leaf' attribute on the declaration.

Should it be __THROWNL to avoid problems with compiler optimizations
and signal handlers?

In this case the function is going to deliver a signal to the process
and this is exactly one of the complicated use cases described in the
GCC manual:

~~~
Note that leaf functions might invoke signals and signal handlers might be
defined in the current compilation unit and use static variables.  The only
compliant way to write such a signal handler is to declare such variables
@code{volatile}.
~~~

I sent a gcc doc patch upstream to clarify the text a bit more:
https://gcc.gnu.org/ml/gcc-patches/2016-03/msg00788.html

There I show an example C program that might expect exit with code 0.
When compiled at -O3 it exists with code 1, when compiled at -O0 it
exits with code 0. The problem is that the compiler elides several
stores which it thinks are not observable. The recommendation is that
you use volatile in this case for the variable tst.

One might argue that volatile is heavy handed, and that until and unless
you wait for the signal delivery you can't assume the signal is
ever delivered or that the signal handler observes the effect before
you decrement tst again. Adding sem_post/sem_wait to the example does
fix the issue, as does using C11 atomics. That doesn't mean that the
C or C++ or POSIX standard have anything to say about this particular
case and memory synchronization with signal handlers.

I'm looking at this from a developer perspective and trying to apply
the principle of least surprise. It's suprising that pthread_kill is
not a memory synchronization point. It's surprising when the compiler
elides the store to the global static.

What should we do?

Florian Weimer also allerted me to the fact that there are other
functions which have __THROW and that such markup might be questionable.
I suggest we start another thread for those.

-- 
Cheers,
Carlos.


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