Volatile keyword

R

raphfrk

Does this make all read/writes happen in full.

For example, if one thread had

volatile long a = 0xFFFFFFFF00000000L;

<do stuff>

a = ~a;

If another thread read a, would it always give 0xFFFFFFFF00000000 or
0x00000000FFFFFFFF and not partial writes (say it updates 32 bits and
then the next 32 bits).

I understand that if two threads do a++, it might only increment
twice, if they both read the old value at the same time.

Effectively, does the CPU lock the entire 64-bits for the long when
doing the write update, and so other threads either seen the updated
value or the old value?
 
A

Andreas Leitgeb

Does this make all read/writes happen in full.

That's how it is specified.
For example, if one thread had
volatile long a = 0xFFFFFFFF00000000L;
<do stuff>
a = ~a;
If another thread read a, would it always give 0xFFFFFFFF00000000 or
0x00000000FFFFFFFF and not partial writes (say it updates 32 bits and
then the next 32 bits).

That's how it is specified. :)
I understand that if two threads do a++, it might only increment
twice, if they both read the old value at the same time.

"once," but I think you meant "once," anyway, with "only" in the
context.

Even if more processes did "a = ~a;" concurrently on a volatile long a
with given initialization, then the assumption of always reading either
0xFFFFFFFF00000000 or 0x00000000FFFFFFFF but nothing else would still
be a rather safe bet. (i.e. betting only against hardware-flaws, or
severe bugs in the JVM implementation) Of course, *which* one of these
values you'd see is not necessarily related to the total number of these
manipulations performed by all threads together (as in the a++ case).
Effectively, does the CPU lock the entire 64-bits for the long when
doing the write update, and so other threads either seen the updated
value or the old value?

That's how it is specified. :)
 
L

Lew

Does this make all read/writes happen in full.

For example, if one thread had

volatile long a = 0xFFFFFFFF00000000L;

<do stuff>

a = ~a;

If another thread read a, would it always give 0xFFFFFFFF00000000 or
0x00000000FFFFFFFF and not partial writes (say it updates 32 bits and
then the next 32 bits).

I understand that if two threads do a++, it might only increment
twice, if they both read the old value at the same time.

Effectively, does the CPU lock the entire 64-bits for the long when
doing the write update, and so other threads either seen the updated
value or the old value?

http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.4
http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.3.1.4
 
M

markspace

Effectively, does the CPU lock the entire 64-bits for the long when
doing the write update, and so other threads either seen the updated
value or the old value?


I don't like the word "lock" here because it implies something that
probably isn't happening. I think that volatile, even for long and
double, is specified to be much lighter weight than a lock.

The spec that Lew referred to says they are "atomic" and doesn't mention
"lock." I think of them that way, myself, in addition to "light weight"
as opposed to the more heavy actual lock.

volatile long === light weight & atomic.

(=== here meant to mean "defined to be.")
 
T

Tom Anderson

I don't like the word "lock" here because it implies something that probably
isn't happening. I think that volatile, even for long and double, is
specified to be much lighter weight than a lock.

The spec that Lew referred to says they are "atomic" and doesn't mention
"lock." I think of them that way, myself, in addition to "light weight" as
opposed to the more heavy actual lock.

volatile long === light weight & atomic.

(=== here meant to mean "defined to be.")

I don't think it's *defined to be* lightweight. A sadistic JVM implementor
could make it heavyweight without violating the spec. However, it is
indeed *defined in such a way as that it can be implemented as*
lightweight, which is what i think you were getting at.

I would imagine that on the x86, volatile writes to longs are implemented
by issuing the store instruction with the LOCK prefix, which prevents
other cores from using the bus until the instruction completes - it's a
sort of micro-lock, much lighter-weight than a monitor entry. Although
here is an interesting thread:

http://stackoverflow.com/questions/78277/how-to-guarantee-64-bit-writes-are-atomic

which indicates that my imagination is completely wrong! Suggestions are
that (a) aligned 64-bit stores are atomic on Pentiums and later anyway,
and that (b) you can use FISTP to do an intrinsically atomic 64-bit store
(although that's a FPU instruction - such is the x86 way).

On the PowerPC, if there isn't an atomic 64-bit store, i think you can use
the load linked/store conditional instructions: LL the second word, do a
normal store to the first word, then SC to the second word. Oh no, hang
on, you can still get a race on the first word. Oh well, i suspect that
the PowerPC has an atomic 64-bit store anyway.

I have no idea what you'd do on a SPARC. I can't think of any other
interesting chips for JVMs. ARM, maybe? Even less idea there! Ooh, or the
ShenWei SW-3? Apparently that uses the MIPS instruction set.

tom
 
R

Roedy Green

Does this make all read/writes happen in full.

for the short answer see http://mindprod.com/jgloss/volatile.html

for the long answer see
http://mindprod.com/jgloss/thread.html
and click the link to Goetz's book with the three high speed trains on
the cover.
--
Roedy Green Canadian Mind Products
http://mindprod.com
For me, the appeal of computer programming is that
even though I am quite a klutz,
I can still produce something, in a sense
perfect, because the computer gives me as many
chances as I please to get it right.
 
R

Roedy Green

I don't like the word "lock" here because it implies something that
probably isn't happening. I think that volatile, even for long and
double, is specified to be much lighter weight than a lock.

In a 64-bit java, there is nothing to do. 64-bit reads are atomic
because the hardware is atomic.

In 32 bit, there is an assembler instruction cmpxchg8b designed to let
you implement a light weight atomic 64-bit read.

--
Roedy Green Canadian Mind Products
http://mindprod.com
For me, the appeal of computer programming is that
even though I am quite a klutz,
I can still produce something, in a sense
perfect, because the computer gives me as many
chances as I please to get it right.
 
R

Robert Klemme

Right, there is no lock, just a memory barrier.
In a 64-bit java, there is nothing to do. 64-bit reads are atomic
because the hardware is atomic.

I would be unsure whether that can be generalized. I can imagine a 64
bit system which externally uses 32 bit - even though that this would
not be very likely these days. But in the past there have been 32 bit
processors with 16 bit data bus. So you would need two write operations
on the bus. And in a SMP scenario these need not be atomic. Again, not
very likely but possible. Bottom line is that the JVM spec does not
make any guarantees here (§17.7 see Lew's reference).
In 32 bit, there is an assembler instruction cmpxchg8b designed to let
you implement a light weight atomic 64-bit read.

Since you do not know on what JVM your Java program will run when you
write it (or at least someone can choose to use a different JVM model)
it is safer to code under the assumption that a long and double write is
two operations i.e. not atomic. To remedy that there is AtomicLong.
For double handling see the end of the JavaDoc at
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/package-summary.html

Kind regards

robert
 
R

Robert Klemme

[...]Bottom line is that the JVM spec does not make
any guarantees here (§17.7 see Lew's reference).

I think it's worth being careful about "does not make any guarantees
here". The implication of 17.7 is that there _is_ in fact a guarantee,
for certain 64-bit fields marked as "volatile". Specifically, those
which are of the type "double" or "long". This is true even on 32-bit
systems.

And what guarantee is there? Can you unambiguously formulate that and
provide reference to the JLS so everybody can check it?
There is no need to make that assumption provided the field involved is
marked "volatile".

I beg to differ - but I am eagerly waiting to be convinced otherwise.

Cheers

robert
 
D

Daniel Pitts

[...]Bottom line is that the JVM spec does not make
any guarantees here (§17.7 see Lew's reference).

I think it's worth being careful about "does not make any guarantees
here". The implication of 17.7 is that there _is_ in fact a guarantee,
for certain 64-bit fields marked as "volatile". Specifically, those
which are of the type "double" or "long". This is true even on 32-bit
systems.

And what guarantee is there? Can you unambiguously formulate that and
provide reference to the JLS so everybody can check it?
There is no need to make that assumption provided the field involved is
marked "volatile".

I beg to differ - but I am eagerly waiting to be convinced otherwise.'
The JLS does specifically say that volatile will ensure atomic
operations on long and double.

The last paragraph of section 17.7:

"The load, store, read, and write actions on volatile variables are
atomic, even if the type of the variable is double or long."

<http://java.sun.com/docs/books/jls/second_edition/html/memory.doc.html#28330>

So unless you use a non-conforming "JVM" implementation (which by
definition isn't really a JVM), then you will *always* have atomic reads
and atomic writes for volatile doubles and volatile longs.
 
R

Robert Klemme

On 12/12/11 11:37 PM, Robert Klemme wrote:
[...]Bottom line is that the JVM spec does not make
any guarantees here (§17.7 see Lew's reference).

I think it's worth being careful about "does not make any guarantees
here". The implication of 17.7 is that there _is_ in fact a guarantee,
for certain 64-bit fields marked as "volatile". Specifically, those
which are of the type "double" or "long". This is true even on 32-bit
systems.

And what guarantee is there? Can you unambiguously formulate that and
provide reference to the JLS so everybody can check it?

As indicated in the quoted material, the relevant section is
"17.7 Non-atomic Treatment of double and long"
http://java.sun.com/docs/books/jls/third_edition/html/memory.html#61803

Thank you Patricia and Daniel for helping my feeble eyes!

Kind regards

robert
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top