typdef'ing from sig_atomic_t valid?

Discussion in 'C Programming' started by Mark Piffer, Apr 22, 2004.

  1. Mark Piffer

    Mark Piffer Guest

    Does a typedef like
    typedef sig_atomic_t atomic_int;
    produce an atomically write/readable type? From what I read in the
    standard I would guess yes, as sig_atomic_t itself is produced by a
    typedef and typedefs don't really introduce new types. For another
    question though, how to define an unsigned atomic type? I can't find
    anything in the standard that would justify it, if sig_atomic_t is
    signed, not even looking into signal.h and using the unsigned type
    from which sig_atomic_t is constructed, as it could well have a
    different width/object representation.

    Mark
     
    Mark Piffer, Apr 22, 2004
    #1
    1. Advertising

  2. Mark Piffer

    Ian Woods Guest

    (Mark Piffer) wrote in
    news::

    > Does a typedef like
    > typedef sig_atomic_t atomic_int;
    > produce an atomically write/readable type? From what I read in the
    > standard I would guess yes, as sig_atomic_t itself is produced by a
    > typedef and typedefs don't really introduce new types. For another
    > question though, how to define an unsigned atomic type? I can't find
    > anything in the standard that would justify it, if sig_atomic_t is
    > signed, not even looking into signal.h and using the unsigned type
    > from which sig_atomic_t is constructed, as it could well have a
    > different width/object representation.
    >
    > Mark


    sig_atomic_t has a range of SIG_ATOMIC_MIN to SIG_ATOMIC_MAX and may be
    either signed or unsigned. Signed, the minimum range is -127 to 127.
    Unsigned, the minimum range is 0 to 255. Or, in other words... you know for
    definate that sig_atomic_t can hold values from 0 to 127 whether it's
    signed or unsigned. (All from C99). Either way, I can't see any way of
    making a "signed" or "unsigned" version of sig_atomic_t.

    sig_atomic_t is best treated IMO as a completely seperate type from all the
    other integer types rather than thinking of it as "typedef"ed from some
    other type. The fact that the compiler has to make operations on it atomic
    means that the compiler at some level has to know that isn't just a plain
    old integer type.

    Ian Woods

    --
    "I'm a paranoid schizophrenic sado-masochist.
    My other half's out to get me and I can't wait."
    Richard Heathfield
     
    Ian Woods, Apr 22, 2004
    #2
    1. Advertising

  3. Mark Piffer

    Dan Pop Guest

    In <Xns94D3A4ABCE75Cnewspubwuggyorg@217.32.252.50> Ian Woods <> writes:

    >sig_atomic_t is best treated IMO as a completely seperate type from all the
    >other integer types rather than thinking of it as "typedef"ed from some
    >other type. The fact that the compiler has to make operations on it atomic
    >means that the compiler at some level has to know that isn't just a plain
    >old integer type.


    If the compiler *naturally* handles integer type T atomically, then
    it couldn't care less whether the object was defined as having type
    T directly or via sig_atomic_t.

    It would take a less than 8-bit processor so that none of the integer
    types can be handled atomically, requiring the additional information
    you're talking about. But I have yet to hear about standard C
    implementations for such processors...

    I agree that maximally portable code can only rely on the 0..127 range
    for sig_atomic_t, but this range should be more than enough for most
    applications. Keep in mind that only *accesses* to sig_atomic_t are
    guaranteed to be performed atomically, so the only meaningful operations
    on this type are assigning a value and reading the current value.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Apr 22, 2004
    #3
  4. On 22 Apr 2004 16:28:18 GMT, (Dan Pop) wrote:
    >Keep in mind that only *accesses* to sig_atomic_t are
    >guaranteed to be performed atomically, so the only meaningful operations
    >on this type are assigning a value and reading the current value.


    Does this mean that atomic read-modify-write is not supported? If not, of
    what use is 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
     
    Kevin D. Quitt, Apr 22, 2004
    #4
  5. in comp.lang.c i read:
    >On 22 Apr 2004 16:28:18 GMT, (Dan Pop) wrote:


    >>Keep in mind that only *accesses* to sig_atomic_t are
    >>guaranteed to be performed atomically, so the only meaningful operations
    >>on this type are assigning a value and reading the current value.

    >
    >Does this mean that atomic read-modify-write is not supported? If not, of
    >what use is sig_atomic_t?


    correct, read-modify-write is not required to be atomic. it's typical use
    is as a flag, not as a counter, e.g.,

    #include <stdio.h>
    #include <signal.h>

    volatile sig_atomic_t attention;

    void attention_handler(int sig)
    {
    attention = 1;
    if (SIG_ERR == signal(sig, SIG_DFL)) abort();
    }

    int main(void)
    {
    if (SIG_ERR == signal(SIGINT, attention_handler)) abort();
    for (long i=0; i<LONG_MAX; i++)
    {
    /* ... */
    if (attention)
    {
    fprintf(stderr, "interrupted at %ld\n", i);
    break;
    }
    /* ... */
    }
    }

    signal handling and atomic types and operations in standard c are very
    limited, else it would be too hard to have hosted implementations on a
    significant number of diverse platforms. typically there are other
    standards or extensions which enhance an environment so much more can be
    done, but you lose some portability (perhaps quite a lot) in the bargain.

    --
    a signature
     
    those who know me have no need of my name, Apr 23, 2004
    #5
  6. On 23 Apr 2004 09:57:05 GMT, those who know me have no need of my name
    <> wrote:

    >correct, read-modify-write is not required to be atomic. it's typical use
    >is as a flag, not as a counter, e.g.,


    Clearly this is a meaning of atomic with which I'm not familiar (i.e.,
    bus-atomic). There is insufficient information in the Standard to define
    what it means by atomic. 7.14 p2 says:

    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.

    At first that sounds interesting, since that would be very useful for
    structs, especially linked lists. But that's clearly not the case; 7.18.3
    says:

    If sig_atomic_t (see 7.14) is defined as a signed integer type, the value
    of SIG_ATOMIC_MIN shall be no greater than -127 and the value of
    SIG_ATOMIC_MAX shall be no less than 127; otherwise, sig_atomic_t is
    defined as an unsigned integer type, and the value of SIG_ATOMIC_MIN shall
    be 0 and the value of SIG_ATOMIC_MAX shall be no less than 255.

    So it isn't necessarily more than a byte. How can access to a byte not be
    atomic? With an 8-bit processor and bus, it's conceivable that 16- or
    32-bit fetches might not be atomic, but 8-bit must be.

    And if it must also be declared as volatile, I can't see *any* use for
    sig_atomic_t. Please help me cure my ignorance. Point me at the detailed
    definition of 'atomic' according to C, or show me code where an object of
    type volatile sig_atomic_t acts differently that an object of type
    volatile.


    --
    #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
     
    Kevin D. Quitt, Apr 23, 2004
    #6
  7. Mark Piffer

    Eric Sosman Guest

    "Kevin D. Quitt" wrote:
    > [...]
    > So it isn't necessarily more than a byte. How can access to a byte not be
    > atomic? With an 8-bit processor and bus, it's conceivable that 16- or
    > 32-bit fetches might not be atomic, but 8-bit must be.


    On the original Alpha processors, the memory subsystem
    supported only 64- and 32-bit accesses. If you wanted to
    store a byte, you had to fetch the entire containing region,
    do some shifting and masking, and store the whole thing
    back again. So much for the atomicity of bytes.

    --
     
    Eric Sosman, Apr 23, 2004
    #7
  8. Mark Piffer

    Ben Pfaff Guest

    Kevin D. Quitt <> writes:

    > So it isn't necessarily more than a byte. How can access to a byte not be
    > atomic? With an 8-bit processor and bus, it's conceivable that 16- or
    > 32-bit fetches might not be atomic, but 8-bit must be.


    What about using a 1-bit bus? Or a 32-bit bus? Access to a byte
    can easily be non-atomic.
    --
    "To get the best out of this book, I strongly recommend that you read it."
    --Richard Heathfield
     
    Ben Pfaff, Apr 23, 2004
    #8
  9. Mark Piffer

    Dan Pop Guest

    In <> Kevin D. Quitt <> writes:

    >On 22 Apr 2004 16:28:18 GMT, (Dan Pop) wrote:
    >>Keep in mind that only *accesses* to sig_atomic_t are
    >>guaranteed to be performed atomically, so the only meaningful operations
    >>on this type are assigning a value and reading the current value.

    >
    >Does this mean that atomic read-modify-write is not supported?


    The type defined is

    sig_atomic_t

    which is the integral type of an object that can be accessed as an
    atomic entity, even in the presence of asynchronous interrupts.
    ....
    If the signal occurs other than as the result of calling the abort
    or raise function, the behavior is undefined if the signal handler
    ^^^^^^^^^^^^^^^^^^^^^^^^^
    calls any function in the standard library other than the signal
    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.
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

    Typical example:

    #include <stdio.h>
    #include <signal.h>

    volatile sig_atomic_t gotsig = 0;

    void handler(int signo)
    {
    gotsig = signo;
    }

    int main()
    {
    signal(SIGINT, handler);
    puts("Press the interrupt key to exit.");
    while (gotsig == 0) ;
    printf ("The program received signal %d.\n", (int)gotsig);
    return 0;
    }

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

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Apr 23, 2004
    #9
  10. OK, thanks to the both of your for removing one set of my (many, I'm sure)
    blinders.

    (Except, of course, you invoked a read-modify-write, which would have been
    a really useful thing to have been in the standard. But never mind.)


    --
    #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
     
    Kevin D. Quitt, Apr 24, 2004
    #10
  11. On 23 Apr 2004 18:19:04 GMT, (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
     
    Kevin D. Quitt, Apr 24, 2004
    #11
  12. in comp.lang.c i read:
    >On 23 Apr 2004 18:19:04 GMT, (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
     
    those who know me have no need of my name, Apr 24, 2004
    #12
  13. On 24 Apr 2004 00:55:27 GMT, those who know me have no need of my name
    <> 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
     
    Kevin D. Quitt, Apr 24, 2004
    #13
  14. In article <>, Kevin D. Quitt <> 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 8) 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

    How can I sing with love in my bosom?
    Unclean, immature and unseasonable salmon. -- Basil Bunting
     
    Michael Wojcik, Apr 26, 2004
    #14
  15. Mark Piffer

    Dan Pop Guest

    In <> Kevin D. Quitt <> writes:

    >On 23 Apr 2004 18:19:04 GMT, (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:
     
    Dan Pop, Apr 26, 2004
    #15
  16. Mark Piffer

    Dan Pop Guest

    In <> (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:
     
    Dan Pop, Apr 27, 2004
    #16
  17. On 26 Apr 2004 18:14:03 GMT, (Dan Pop) wrote:


    >In <> Kevin D. Quitt <> 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
     
    Kevin D. Quitt, Apr 27, 2004
    #17
  18. Mark Piffer

    Dan Pop Guest

    You seem to be MUCH denser than usual.

    In <> Kevin D. Quitt <> writes:

    >On 26 Apr 2004 18:14:03 GMT, (Dan Pop) wrote:
    >
    >
    >>In <> Kevin D. Quitt <> 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:
     
    Dan Pop, Apr 27, 2004
    #18
  19. in comp.lang.c i read:
    >On 26 Apr 2004 18:14:03 GMT, (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
     
    those who know me have no need of my name, Apr 27, 2004
    #19
  20. Mark Piffer

    Mark Piffer Guest

    Kevin D. Quitt <> wrote in message news:<>...
    > On 26 Apr 2004 18:14:03 GMT, (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
     
    Mark Piffer, Apr 28, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Vijay Kumar R Zanvar

    sig_atomic_t

    Vijay Kumar R Zanvar, Nov 24, 2003, in forum: C Programming
    Replies:
    6
    Views:
    1,042
    Chris Torek
    Nov 29, 2003
  2. j0mbolar

    sig_atomic_t

    j0mbolar, Nov 6, 2004, in forum: C Programming
    Replies:
    6
    Views:
    1,342
    Dan Pop
    Nov 10, 2004
  3. Ian Pilcher

    Is "volatile sig_atomic_t" redundant?

    Ian Pilcher, Mar 24, 2005, in forum: C Programming
    Replies:
    14
    Views:
    1,223
    Tor Rustad
    Mar 29, 2005
  4. Dave
    Replies:
    1
    Views:
    328
    Ron Natalie
    Nov 9, 2005
  5. Ben Pfaff

    Re: Minimum width of sig_atomic_t?

    Ben Pfaff, Jan 28, 2010, in forum: C Programming
    Replies:
    0
    Views:
    384
    Ben Pfaff
    Jan 28, 2010
Loading...

Share This Page