Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > typdef'ing from sig_atomic_t valid?

Reply
Thread Tools

typdef'ing from sig_atomic_t valid?

 
 
Kevin D. Quitt
Guest
Posts: n/a
 
      04-24-2004
On 23 Apr 2004 18:19:04 GMT, http://www.velocityreviews.com/forums/(E-Mail Removed) (Dan Pop) wrote:
> function itself or refers to any object with static storage duration
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^
> other than by assigning a value to a static storage duration variable
> ^^^^^^^^^^^====================^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
> of type volatile sig_atomic_t.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


OK, so by definition, the only thing a signal handler can write to that's
available to the rest of the world is a sig_atomic_t. And it has to be
volatile to the rest of the world to make access correct. So the only
thing that makes sig_atomic_t useful is the fact that it's defined to be
useful.


>>If not, of what use is sig_atomic_t?

>
>A volatile sig_atomic_t object can be used as a flag that the signal
>handler has been executed.


Simply declaring that byte volatile would have the same effect under any
set of circumstances I can imagine. Clearly I'm having trouble with my
imagination.


>Some people object to the fact that the signal number cannot be
>represented by a sig_atomic_t object. I ignore them.


Me, too. It's meaningless in light of the definition of sig_atomic_t.


--
#include <standard.disclaimer>
_
Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
Per the FCA, this address may not be added to any commercial mail list
 
Reply With Quote
 
 
 
 
those who know me have no need of my name
Guest
Posts: n/a
 
      04-24-2004
in comp.lang.c i read:
>On 23 Apr 2004 18:19:04 GMT, (E-Mail Removed) (Dan Pop) wrote:


>>Some people object to the fact that the signal number cannot be
>>represented by a sig_atomic_t object. I ignore them.

>
>Me, too. It's meaningless in light of the definition of sig_atomic_t.


i think the point is that it is possible for SIGINT to have a value outside
the range of sig_atomic_t. i've never seen it in the wild, but if one is
usually pedantic about the standard, especially having just quoted it, it's
not entirely misplaced to expect mention of the possibility -- even a left-
handed mention.

--
a signature
 
Reply With Quote
 
 
 
 
Kevin D. Quitt
Guest
Posts: n/a
 
      04-24-2004
On 24 Apr 2004 00:55:27 GMT, those who know me have no need of my name
<(E-Mail Removed)> wrote:
>i think the point is that it is possible for SIGINT to have a value outside
>the range of sig_atomic_t.


I was only saying that *that* problem is a small one compared to the
problematic utility of sig_atomic_t as defined.


> i've never seen it in the wild, but if one is
>usually pedantic about the standard, especially having just quoted it, it's
>not entirely misplaced to expect mention of the possibility -- even a left-
>handed mention.


Completely fair of course. I'm really just trying to cure my ignorance,
but I'm beginning to think that I do understand C's idea of "atomic" - and
that it isn't what "atomic" means to most everybody else.


--
#include <standard.disclaimer>
_
Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
Per the FCA, this address may not be added to any commercial mail list
 
Reply With Quote
 
Michael Wojcik
Guest
Posts: n/a
 
      04-26-2004

In article <(E-Mail Removed)>, Kevin D. Quitt <(E-Mail Removed)> writes:
>
> ... I'm beginning to think that I do understand C's idea of "atomic" - and
> that it isn't what "atomic" means to most everybody else.


I can't speak for "most everybody else", but I've never thought
"atomic" implied "atomic read-and-update" in the context of the C
standard. Obviously "atomic" in computer science usually means that
some operation will either be performed completely or not at all, but
what that operation is can vary widely depending on context.

In the case of sig_atomic_t ISTM that the intent of the standard is
clear: assigning to a sig_atomic_t variable, or referencing one,
will be an atomic operation. The assignment, or reference, will
occur completely or not at all.

Consider a hypothetical conforming implementation on a processor with
an 8-bit bus, where a 16-bit store requires two instructions. An
asynchronous signal could interrupt that sequence between the two
instructions and leave a 16-bit value partially updated. On such an
implementation, sig_atomic_t would have to be an 8-bit integer
(signed or unsigned char, where CHAR_BIT was so that no
sig_atomic_t variable could ever have a partially-updated value.

That said, sig_atomic_t as defined in the standard adds relatively
little value, because there are few cases where strictly-conforming
code could read a partially-updated value from any object. In
particular, a signal handler for an asynchronous signal cannot read
such a value, since it cannot refer to any object with static storage
duration except to assign to a volatile sig_atomic_t.

Footnote 109 (C90) states that another signal while in a handler for
an asynchronous signal causes undefined behavior. Footnotes aren't
normative, but clearly the standard doesn't intend to cover this case
(where a handler's assignment to a variable is interrupted by another
signal) with sig_atomic_t either.

The only other case I can think of is one where:

- Function A establishes a jmp_buf with setjmp.
- Function B assigns a value to a file-scope object X.
- Signal handler H longjmps back to A.
- A, when returning from setjmp via longjmp, refers to X.
- An asynchronous signal occurs while B is assigning to X.

However, it appears to me that this is not guaranteed to work by
the standard (I'm looking at C90), because while it says that a
signal handler may exit by calling longjmp, it also says it's not
allowed to "refer[] to any object with static storage duration"
except for the aforementioned assignment to a volatile sig_atomic_t.
Does calling longjmp constitute referring to the jmp_buf? Also,
in the case of asynchronous signals (ie ones not caused by abort or
raise), handlers are prohibited from calling any library function
other than signal. So as far as I can tell, there are no circum-
stances where a partial assignment could be detected (by strictly-
conforming code) anyway.

I suspect sig_atomic_t is one of those things which has semantics
that are not actually useful for strictly-conforming code, but are
plausibly useful in a variety of implementations as a common
extension. Specifically, I suspect that in most implementations
an asynchronous handler can safely refer to the value of a volatile
sig_atomic_t (as well as assigning to it), and in this case its
atomicity is important (as it guarantees that the handler will not
see a partial value).


--
Michael Wojcik (E-Mail Removed)

How can I sing with love in my bosom?
Unclean, immature and unseasonable salmon. -- Basil Bunting
 
Reply With Quote
 
Dan Pop
Guest
Posts: n/a
 
      04-26-2004
In <(E-Mail Removed)> Kevin D. Quitt <(E-Mail Removed)> writes:

>On 23 Apr 2004 18:19:04 GMT, (E-Mail Removed) (Dan Pop) wrote:
>>
>>A volatile sig_atomic_t object can be used as a flag that the signal
>>handler has been executed.

>
>Simply declaring that byte volatile would have the same effect under any
>set of circumstances I can imagine. Clearly I'm having trouble with my
>imagination.


Clearly. Imagine a traditional Cray processor, that can only access
64-bit words, but whose C implementation uses 8-bit bytes. How do you
write something to one *byte* atomically?

At the other range of the spectre, imagine a 4-bit processor.
This is a pathological case, where sig_atomic_t is different
from normal C types: the compiler has to disable interrupts (errr,
delivery of asynchronous signals) while writing or reading all the 8+
bits composing the sig_atomic_t type, while such precautions are not
necessary for ordinary byte accesses.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: (E-Mail Removed)
 
Reply With Quote
 
Dan Pop
Guest
Posts: n/a
 
      04-27-2004
In <(E-Mail Removed)> (E-Mail Removed) (Michael Wojcik) writes:


>That said, sig_atomic_t as defined in the standard adds relatively
>little value, because there are few cases where strictly-conforming
>code could read a partially-updated value from any object. In
>particular, a signal handler for an asynchronous signal cannot read
>such a value, since it cannot refer to any object with static storage
>duration except to assign to a volatile sig_atomic_t.


It's the ordinary code that is exposed to this problem, not the signal
handler. Imagine that this code has read half of the flag, the signal
handler has been executed, than the interrupted code resumed its
execution by reading the other half of the flag, that has been updated
in the meantine, ending up with half of the old value and half of the
new value. It is precisely this problem that sig_atomic_t solves.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: (E-Mail Removed)
 
Reply With Quote
 
Kevin D. Quitt
Guest
Posts: n/a
 
      04-27-2004
On 26 Apr 2004 18:14:03 GMT, (E-Mail Removed) (Dan Pop) wrote:


>In <(E-Mail Removed)> Kevin D. Quitt <(E-Mail Removed)> writes:
>>Clearly I'm having trouble with my
>>imagination.

>
>Clearly. Imagine a traditional Cray processor, that can only access
>64-bit words, but whose C implementation uses 8-bit bytes. How do you
>write something to one *byte* atomically?


Trivially. One either uses a single instruction that is read-modify-write
bus atomic, or three instructions to do the same. No danger of a
partial-read by anybody.

On any machine that can write (at least) a byte in a single
uninterruptable instruction, there is no meaning to, or protection
provided by sig_atomic_t. sig_atomic_t specifically does *not* provide
protection against the following sequence:

Client task reads sig_atomic_t flag and starts to clear that flag.

Signal handler activates and writes new (different) value to sig_atomic_t
flag.

Client task completes clearing the flag.

Information has now been lost. There is no more protection using volatile
sig_atomic_t than there is just using a volatile. In this case,
sig_atomic_t is meaningless.

Compare this to the operation of a truly bus-atomic test-and-set
instruction, coupled with a bus-atomic test-and-clear, where one can be
guaranteed that information can never be lost. Even more powerful are
instructions like those on the 68K family that can link and unlink
doubly-linked list entries atomically.


>At the other range of the spectre, imagine a 4-bit processor.


This is another case completely, but only because the size of sig_atomic_t
is defined so as to force the loss of information by requiring a data size
that requires multiple instructions for access. On the C compiler I wrote
for the 6502, all accesses to volatile variables of any size were
protected by blocking int^W asynchronous signals; again, sig_atomic_t
would have made no difference.


It seems to me that this is one of those *very( rare cases where somebody
had an idea and an agenda, and forced it through the committee, without
anybody really thinking about it overly much.

Truly, I'm very surprised it got through - I have a great deal of respect
for the members. People around me consider me to be a C guru; I consider
myself (just barely) an expert and certainly not in the league of those on
the committee (those with whom I am familiar).

So basically, it boils down to: sig_atomic_t is useful because the use on
anything else is forbidden.


--
#include <standard.disclaimer>
_
Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
Per the FCA, this address may not be added to any commercial mail list
 
Reply With Quote
 
Dan Pop
Guest
Posts: n/a
 
      04-27-2004
You seem to be MUCH denser than usual.

In <(E-Mail Removed)> Kevin D. Quitt <(E-Mail Removed)> writes:

>On 26 Apr 2004 18:14:03 GMT, (E-Mail Removed) (Dan Pop) wrote:
>
>
>>In <(E-Mail Removed)> Kevin D. Quitt <(E-Mail Removed)> writes:
>>>Clearly I'm having trouble with my
>>>imagination.

>>
>>Clearly. Imagine a traditional Cray processor, that can only access
>>64-bit words, but whose C implementation uses 8-bit bytes. How do you
>>write something to one *byte* atomically?

>
>Trivially. One either uses a single instruction that is read-modify-write
>bus atomic,


It's not enough, even if such an instruction actually exist. Think about
the complete sequence of operations needed for the job:

read word
AND operation to clear old byte
OR operation to insert new byte
write word

>or three instructions to do the same. No danger of a
>partial-read by anybody.


Huh?!? What is preventing an interrupt from occurring in the middle of
the sequence?

>On any machine that can write (at least) a byte in a single
>uninterruptable instruction, there is no meaning to, or protection
>provided by sig_atomic_t.


The point is that you don't know what is the type that can be atomically
written to, even if it exists. On the Cray it is int, on an 8-bit micro
it is char. Hence the need for sig_atomic_t.

>sig_atomic_t specifically does *not* provide
>protection against the following sequence:
>
>Client task reads sig_atomic_t flag and starts to clear that flag.
>
>Signal handler activates and writes new (different) value to sig_atomic_t
>flag.
>
>Client task completes clearing the flag.


You're forgetting that clearing the sig_atomic_t flag is an atomic
operation *by definition*, therefore your scenario cannot happen.

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. ^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

>Information has now been lost.


No information has been lost.

>There is no more protection using volatile
>sig_atomic_t than there is just using a volatile. In this case,
>sig_atomic_t is meaningless.


Bullshit!

>Compare this to the operation of a truly bus-atomic test-and-set
>instruction, coupled with a bus-atomic test-and-clear, where one can be
>guaranteed that information can never be lost. Even more powerful are
>instructions like those on the 68K family that can link and unlink
>doubly-linked list entries atomically.


They are entirely irrelevant in the context of sig_atomic_t and
signal handlers, as specified by the C standard.

>It seems to me that this is one of those *very( rare cases where somebody
>had an idea and an agenda, and forced it through the committee, without
>anybody really thinking about it overly much.


You're the only who failed to really engage his brain on this issue,
despite the detailed explanations you have already gotten.

>Truly, I'm very surprised it got through - I have a great deal of respect
>for the members. People around me consider me to be a C guru; I consider
>myself (just barely) an expert and certainly not in the league of those on
>the committee (those with whom I am familiar).


You're behaving like an idiot in this thread.

>So basically, it boils down to: sig_atomic_t is useful because the use on
>anything else is forbidden.


And there is a *good* reason for forbidding the use of anything else,
as already explained: char doesn't work on the Cray (and the 21064 Alpha),
anything wider than a char doesn't work on the 8-bit micro. No standard
integer type at all works on the less than 8-bit micro.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: (E-Mail Removed)
 
Reply With Quote
 
those who know me have no need of my name
Guest
Posts: n/a
 
      04-27-2004
in comp.lang.c i read:
>On 26 Apr 2004 18:14:03 GMT, (E-Mail Removed) (Dan Pop) wrote:


>>Clearly. Imagine a traditional Cray processor, that can only access
>>64-bit words, but whose C implementation uses 8-bit bytes. How do you
>>write something to one *byte* atomically?

>
>Trivially. One either uses a single instruction that is read-modify-write
>bus atomic, or three instructions to do the same. No danger of a
>partial-read by anybody.


volatile sig_atomic_t is the clue to the compiler that this effort is
needed. a vast speed improvement is typically available when a `bus
atomic' transaction is avoided.

>On any machine that can write (at least) a byte in a single
>uninterruptable instruction, there is no meaning to, or protection
>provided by sig_atomic_t.


portability. one cannot know that any particular system will have this
property.

>Client task reads sig_atomic_t flag and starts to clear that flag.
>
>Signal handler activates and writes new (different) value to sig_atomic_t
>flag.
>
>Client task completes clearing the flag.


indeed, which is why it must also be qualified volatile as well. the
combination (causes the compiler to emit code which) prevents this from
occurring.

>Information has now been lost. There is no more protection using volatile
>sig_atomic_t than there is just using a volatile.


only on specific platforms -- hence non-portable code.

--
a signature
 
Reply With Quote
 
Mark Piffer
Guest
Posts: n/a
 
      04-28-2004
Kevin D. Quitt <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>. ..
> On 26 Apr 2004 18:14:03 GMT, (E-Mail Removed) (Dan Pop) wrote:
> >Clearly. Imagine a traditional Cray processor, that can only access
> >64-bit words, but whose C implementation uses 8-bit bytes. How do you
> >write something to one *byte* atomically?

>
> Trivially. One either uses a single instruction that is read-modify-write
> bus atomic, or three instructions to do the same. No danger of a
> partial-read by anybody.


But there is no such thing as a read-modify-write access in the
semantics of C. Not in the Standard and I highly doubt in any real
implementation either. Read-modify-write is what happens to come out
of an optimizing stage.


> On any machine that can write (at least) a byte in a single
> uninterruptable instruction, there is no meaning to, or protection
> provided by sig_atomic_t.


Exactly. Thats just restating the standard's definiton of sig_atomic_t
in another way: it is a typedef from an existing type, so the compiler
gains _no_ information whatsoever about integers of that type - it
just can be assumed to always generate atomic writes or reads to them.
You could use the implementation defined underlying type and produce
equivalent code (on one platform), with the same semantics of atomic
access, this time just hidden in the compiler handbooks.


> This is another case completely, but only because the size of sig_atomic_t
> is defined so as to force the loss of information by requiring a data size
> that requires multiple instructions for access. On the C compiler I wrote
> for the 6502, all accesses to volatile variables of any size were
> protected by blocking int^W asynchronous signals; again, sig_atomic_t
> would have made no difference.


IOW you implemented your special flavour of C, which in the case of
volatiles takes another (safer, I admit) approach than standard C.
Unluckily I don't expect to become a user of the 6502 or your compiler
any time soon, so my question was directed towards the standard atomic
types. Keep in mind also, that with this policy you prohibit certain
optimizations which contradicts the C design principles.


> Truly, I'm very surprised it got through - I have a great deal of respect
> for the members. People around me consider me to be a C guru; I consider
> myself (just barely) an expert and certainly not in the league of those on
> the committee (those with whom I am familiar).
>
> So basically, it boils down to: sig_atomic_t is useful because the use on
> anything else is forbidden.


Yes, also IMHO sig_atomic_t is one of the dirty corners where your
only lucky escape is to leave the paths of portability to do anything
real-world-ish, with the risk of adapting to this bad practice and
being beaten up on c.l.c

Mark
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Minimum width of sig_atomic_t? Ersek, Laszlo C Programming 0 01-28-2010 09:36 PM
Re: Minimum width of sig_atomic_t? Ben Pfaff C Programming 0 01-28-2010 09:16 PM
Is "volatile sig_atomic_t" redundant? Ian Pilcher C Programming 14 03-29-2005 06:46 PM
sig_atomic_t j0mbolar C Programming 6 11-10-2004 05:19 PM
sig_atomic_t Vijay Kumar R Zanvar C Programming 6 11-29-2003 08:58 PM



Advertisments