473,396 Members | 2,147 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

typdef'ing from sig_atomic_t valid?

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
Nov 14 '05 #1
21 2094
so************@yahoo.com (Mark Piffer) wrote in
news:cc*************************@posting.google.co m:
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
Nov 14 '05 #2
In <Xn*****************************@217.32.252.50> Ian Woods <ne******@wuggyNOCAPS.org> 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: Da*****@ifh.de
Nov 14 '05 #3
On 22 Apr 2004 16:28:18 GMT, Da*****@cern.ch (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
Nov 14 '05 #4
in comp.lang.c i read:
On 22 Apr 2004 16:28:18 GMT, Da*****@cern.ch (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
Nov 14 '05 #5
On 23 Apr 2004 09:57:05 GMT, those who know me have no need of my name
<no****************@usa.net> 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
Nov 14 '05 #6
"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.

--
Er*********@sun.com
Nov 14 '05 #7
Kevin D. Quitt <KQ**********@IEEIncUNMUNG.com> 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
Nov 14 '05 #8
In <qn********************************@4ax.com> Kevin D. Quitt <KQ**********@IEEIncUNMUNG.com> writes:
On 22 Apr 2004 16:28:18 GMT, Da*****@cern.ch (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: Da*****@ifh.de
Nov 14 '05 #9
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
Nov 14 '05 #10
On 23 Apr 2004 18:19:04 GMT, Da*****@cern.ch (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
Nov 14 '05 #11
in comp.lang.c i read:
On 23 Apr 2004 18:19:04 GMT, Da*****@cern.ch (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
Nov 14 '05 #12
On 24 Apr 2004 00:55:27 GMT, those who know me have no need of my name
<no****************@usa.net> 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
Nov 14 '05 #13

In article <66********************************@4ax.com>, Kevin D. Quitt <KQ**********@IEEIncUNMUNG.com> 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 mi************@microfocus.com

How can I sing with love in my bosom?
Unclean, immature and unseasonable salmon. -- Basil Bunting
Nov 14 '05 #14
In <ob********************************@4ax.com> Kevin D. Quitt <KQ**********@IEEIncUNMUNG.com> writes:
On 23 Apr 2004 18:19:04 GMT, Da*****@cern.ch (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: Da*****@ifh.de
Nov 14 '05 #15
In <c6********@news3.newsguy.com> mw*****@newsguy.com (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: Da*****@ifh.de
Nov 14 '05 #16
On 26 Apr 2004 18:14:03 GMT, Da*****@cern.ch (Dan Pop) wrote:

In <ob********************************@4ax.com> Kevin D. Quitt <KQ**********@IEEIncUNMUNG.com> 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
Nov 14 '05 #17
You seem to be MUCH denser than usual.

In <6l********************************@4ax.com> Kevin D. Quitt <KQ**********@IEEIncUNMUNG.com> writes:
On 26 Apr 2004 18:14:03 GMT, Da*****@cern.ch (Dan Pop) wrote:

In <ob********************************@4ax.com> Kevin D. Quitt <KQ**********@IEEIncUNMUNG.com> 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: Da*****@ifh.de
Nov 14 '05 #18
in comp.lang.c i read:
On 26 Apr 2004 18:14:03 GMT, Da*****@cern.ch (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
Nov 14 '05 #19
Kevin D. Quitt <KQ**********@IEEIncUNMUNG.com> wrote in message news:<6l********************************@4ax.com>. ..
On 26 Apr 2004 18:14:03 GMT, Da*****@cern.ch (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
Nov 14 '05 #20
On 27 Apr 2004 17:44:31 GMT, Da*****@cern.ch (Dan Pop) wrote:
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.
OK. It's strictly for portability. I have to revise my view of it, then;
it does have a real (meta) use.

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.


Nah - the client read the value into another variable, or uses the
variable in a switch or if. It's another line of code before it can get
around to setting it to zero. The interrupt can happen in between, so you
can still lose the information.

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!


Except for portability, I stand by the comment. If you use a volatile
variable that's the right size for the hardware in question, adding
sig_atomic_t to it gets you no more protection.

You're the only who failed to really engage his brain on this issue,
despite the detailed explanations you have already gotten.
Apparently so. Your immediately previous post is the only one that
specifically said it was to guarantee portability. I guess I was still
thinking down in the hardware details and not an abstract enough.

You're behaving like an idiot in this thread.


I was behaving ignorantly in this thread, trying to cure my ignorance.
With your (and others') help, I've cured it. I thank you.

--
#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
Nov 14 '05 #21
In <58********************************@4ax.com> Kevin D. Quitt <KQ**********@IEEIncUNMUNG.com> writes:
On 27 Apr 2004 17:44:31 GMT, Da*****@cern.ch (Dan Pop) wrote:
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.


OK. It's strictly for portability. I have to revise my view of it, then;
it does have a real (meta) use.


Try to write a portable signal handler, according to the standard
specification, and you'll see that there is no place for "meta"
in your statement above.
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.


Nah - the client read the value into another variable, or uses the
variable in a switch or if. It's another line of code before it can get
around to setting it to zero. The interrupt can happen in between, so you
can still lose the information.


If you want to shoot yourself in the foot, C is not going to prevent you
from doing it. The point is that sig_atomic_t *can* be safely used in
portable C code. Look again at the demo code I've posted. There is no
danger to lose any information there.

There is one genuine problem with signal handling in standard C and it
was recently discussed in comp.std.c, so I'm not going to rehash it here
(the standard specification allows race conditions).
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!


Except for portability, I stand by the comment.


The only reason to pay any attention to the C standard is portability.
Otherwise, the documentation of your compiler is much better and provides
lots of extra functionality. So, I miss your point: *everything* in the
C standard is about portability and sig_atomic_t is no exception.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #22

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: Mark Snelling | last post by:
I wish to typedef a templated function for readability but cannot find the correct syntax to do so. For example: #include <iostream> template< int I > void foo() { std::cout << I <<...
1
by: Dave | last post by:
I have several enums that are generated by a code generator (and I have no control over the code generator), the problem is that the names are pretty long enum VeryLoooooooongEnumName {...
22
by: Richard | last post by:
I've really tried searching for this before I thought of bother you guys with this question. It's such a simple thing, but it's driving me nuts! Is it possible to check if an int (or any other...
4
by: TGOS | last post by:
I was thinking about it for a while, a mutex written in C and without disabling any interrupts. Is it possible? typdef struct mutex { unsigned int owner1; unsigend int owner2; } *mutex; ...
42
by: baumann | last post by:
hi all, typedef int (*pfunc)(int , int); pfunc a_func; i know it's ok, but how can define a_func without typedef statement? thanks .
30
by: junky_fellow | last post by:
I was looking at the source code of linux or open BSD. What I found that lots of typedefs were used. For example, consider the offset in a file. It was declared as off_t offset; and off_t is...
3
by: gorbulastic | last post by:
ok, i've created a typedef of somthing, and I put it through a for loop to put the entries into it. They are stored as an array of the typedef''s, with memory allocated via malloc command. For...
18
by: Philluminati | last post by:
I am writing a poker game which needs to work with cash. I am aware that there are problems with floats that make them unsuitable for storing money values. On top of this I may be expected to do...
3
by: Markus Dehmann | last post by:
I have an abstract base class which contains a function that I would like to template, but virtual template functions are illegal. I put a mini code example below, which doesn't do anything great,...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.