On my Linux box,
sig_atomic_t is a plain old
ints posses a special atomic quality?
$ gcc -v Using built-in specs. Target: x86_64-linux-gnu ... Thread model: posix gcc version 4.3.2 (Debian 4.3.2-1.1) $ echo '#include <signal.h>' | gcc -E - | grep atomic typedef int __sig_atomic_t; typedef __sig_atomic_t sig_atomic_t;
sig_atomic_t conforms only to a very weak definition of “atomicity”, because C99 has no concept of concurrency, only interruptibility. (C2011 adds a concurrency model, and with it the
_Atomic types that make stronger guarantees; however, AFAIK
sig_atomic_t is unchanged, since its raison d’être is still communication with signal handlers, not across threads.)
This is everything C99 says about
<signal.h>, paragraph 2) The type defined is
sig_atomic_t, which is the (possibly volatile-qualified) integer type of an object that can be accessed as an atomic entity, even in the presence of asynchronous interrupts. (§7.14
<signal.h>, paragraph 2)
(§7.14p5) If [a] signal occurs other than as the result of calling the
raisefunction, the behavior is undefined if the signal handler refers to any object with static storage duration other than by assigning a value to an object declared as
(§7.18.3 Limits of other integer types, paragraph 3) If
sig_atomic_t(see 7.14) is defined as a signed integer type, the value of
SIG_ATOMIC_MINshall be no greater than −127 and the value of
SIG_ATOMIC_MAXshall be no less than 127; otherwise, sig_atomic_t is defined as an unsigned integer type, and the value of
SIG_ATOMIC_MINshall be 0 and the value of
SIG_ATOMIC_MAXshall be no less than 255.
The term “atomic entity” is not defined anywhere in the standard. Translating from standards-ese, the intent is that the CPU can completely update a variable of type
sig_atomic_t in memory (“static storage duration”) with one machine instruction. Thus, in the concurrency-free, precisely interruptible C99 abstract machine, it is impossible for a signal handler to observe a variable of type
sig_atomic_t halfway through an update. The §7.18.3p3 language licenses this type to be as small as
char if necessary. Note please the complete absence of any language relating to cross-processor consistency.
There are real CPUs which require more than one instruction to write a value larger than
char to memory. There are also real CPUs which require more than one instruction to write values smaller than a machine word (often, but not necessarily, the same as
int) to memory. The language in the GNU C Library manual is now inaccurate. It represents a desire on the part of the original authors to eliminate what they saw as unnecessary license for C implementations to do weird shit that made life harder for application programmers. Unfortunately, that very license is what makes it possible to have C at all on some real machines. There is at least one embedded Linux port (to the AVR) for which neither
int nor pointers can be written to memory in one instruction. (People are working on making the manual more accurate, see e.g. http://sourceware.org/ml/libc-alpha/2012-02/msg00651.html —
sig_atomic_t seems to have been missed in that one, though.)
Certain types may require multiple instruction to read/write.
int type is always read/written atomically.
Data Type: sig_atomic_t
This is an integer data type. Objects of this type are always accessed
In practice, you can assume that int and other integer types no longer
than int are atomic. You can also assume that pointer types are
atomic; that is very convenient. Both of these are true on all of the
machines that the GNU C library supports, and on all POSIX systems we