24.4.7.3 Atomic Usage Patterns

Certain patterns of access avoid any problem even if an access is
interrupted. For example, a flag which is set by the handler, and
tested and cleared by the main program from time to time, is always safe
even if access actually requires two instructions. To show that this is
so, we must consider each access that could be interrupted, and show
that there is no problem if it is interrupted.

An interrupt in the middle of testing the flag is safe because either it’s
recognized to be nonzero, in which case the precise value doesn’t
matter, or it will be seen to be nonzero the next time it’s tested.

An interrupt in the middle of clearing the flag is no problem because
either the value ends up zero, which is what happens if a signal comes
in just before the flag is cleared, or the value ends up nonzero, and
subsequent events occur as if the signal had come in just after the flag
was cleared. As long as the code handles both of these cases properly,
it can also handle a signal in the middle of clearing the flag. (This
is an example of the sort of reasoning you need to do to figure out
whether non-atomic usage is safe.)

Sometimes you can ensure uninterrupted access to one object by
protecting its use with another object, perhaps one whose type
guarantees atomicity. See Merged Signals, for an example.