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

Re: Is it safe to implement a mutex using sig_atomic_t.


On Fri, 1 Jul 2005, mishabear wrote:

> I have modified the "Non-atomic example" of Atomic Data Access. The
> result seems fine. But I'm not sure whether it is safe to implement a
> mutex using sig_atomic_t.

The purpose of sig_atomic_t is to have a type which can be read and
written atomically, with respect to the main program and signal
handlers.

> #include <signal.h>
> #include <stdio.h>
> 
> sig_atomic_t mtx;
> 
> struct two_words { int a, b; } memory; 
> 
> void handler(int signum) 
> {
>     if(++mtx == 1)

The sig_atomic_t type doesn't provide atomic updates. The ++ operator
reads the object, and then stores a new value. That two-access
transaction isn't atomic. A signal handler may be invoked between the
read and write, and that signal handler may read the old value and act
on it or it may store a new value which is about to be overwritten.

You can't implement mutexes between signal handlers anyway; the very
concept doesn't make sense. Suppose the program is holding a mutex and
a signal handler wants to acquire it. Since you don't actually have
more than one thread, you can't block the signal handler to wait on the
mutex. You're blocking the one and only thread you have.

The way mutual exclusion is achieved under signals (or interrupts, in
general) is that interrupts are disabled over critical sections of
code. The programmer is then certain that a given signal cannot be
delivered while the instruction pointer is in certain sections of code,
and therefore the data manipulations done by the signal handler cannot
occur. Conversely, the signal handler code is known to have mutual
exclusion with respect to the main program, because it has interrupted
that program only in some situation where it was permitted to do so,
and the main program won't resume until that handler returns.

Under POSIX, you can block and unblock individual signals. When a
blocked signal is raised, it remains pending: its processing is delayed
until it is unblocked. You can also arrange to have a signal
automatically be blocked and unblocked around the call to its handler,
so that the handler won't be re-entered by another delivery of that
signal.

-- 
Meta-CVS: the working replacement for CVS that has been stable since
2002.  It versions the directory structure, symbolic links and execute
permissions. It figures out renaming on import. Plus it babysits the kids
and does light housekeeping! http://freshmeat.net/projects/mcvs


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