In article <11************ **********@e3g2 000cwe.googlegr oups.com>
<ch**********@m erck.comwrote:
>... I have a followup as well. Is there any
guarentee that when an lvalue is accessed for a read, that the
resultant machine code will be loads and no stores.
Not in general, no.
In general, the "volatile" qualifier is necessary but not sufficient
to obtain such a guarantee. It is up to each implementation to
define an "access" for a volatile-qualified type, so -- at least
in theory -- you simply read your implementation document(s) to
see what it/they say, and use that information to select whatever
it is that is both necessary *and* sufficient. This may include
restricting the base type(s) of the volatile-qualified types:
e.g., perhaps "volatile int" is atomic while "volatile long long"
and/or "volatile double" is not.
>I ask as I am trying to verify the validity of statements
regarding threads (specifically pthreads, and I understand
outside the scope of this newsgroup) that they can access global
shared memory without mutex or locks as long as the accesses are
only reads, since the threads maintain thread local stacks and
registers.
C does not make such a guarantee, but some other, more restrictive
standard could. Suppose (for instance) that the Zorblatt 25 computer
has a problem with *all* memory-read operations, such that every
load is followed by a store in the generated code (because "load"
means "load and clear", because the Zorblatt has actual "core"
memory with its destructive-read system, and no auto-rewrite).
This machine can support ISO C, but not the other, more-restrictive
standard: any valid, strictly conforming C program runs fine on
the Zorblatt 25, but code that uses thread extensions does not.
In general, the more constraints some programming language or
standard makes, the fewer machines it can run on, but the easier
it is to use. If C had less "undefined behavior", we might be
able to say what "i++ * i++" means, but we might not be able
to implement C on every new machine that comes along (or at least,
not efficiently) -- consider VLIW machines, for instance, with
their multiple functional units. (See the Wikipedia entry at
<http://en.wikipedia.or g/wiki/VLIW>.)
>However, if in some
strange implementation, everytime you read a variables value, the
resultant machine code also contained some STOR to shared memory (I
don't know why that'd ever be the case, but regardless) ...
The above example (magnetic core memory) suggests a possible reason.
Reads are performed by writing a value (normally 0) to the location
whose value is to be read. If writing a zero requires *changing*
the state, the magnetic field flips. This flip is tested-for. If
nothing is sensed, the previous value must have been 0; if something
is sensed, the previous value must have been 1. (For more detail,
see <http://en.wikipedia.or g/wiki/Magnetic_core_m emory>.)
Interestingly, conventional DRAM actually has the same problem as
old-style magnetic core memory: reads are destructive, because they
discharge the capacitor at the heart of each DRAM cell. In this
case, however, it is necessary for the chip itself to rewrite the
cell contents, as an entire row (or column, in CAS-before-RAS) is
dumped into the row-wide sense amplifiers. This internal rewrite
is harnessed for DRAM refresh. (I am deliberately skipping over
all kinds of detail; again, there is more in Wikipedia at
<http://en.wikipedia.or g/wiki/DRAM>.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it
http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.