JDK-4519234 : read or write to long volatile variable is not atomic.
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: windows_nt
  • CPU: x86
  • Submitted: 2001-10-25
  • Updated: 2004-03-20
  • Resolved: 2003-11-24
Related Reports
Relates :  
Relates :  
Description

Name: ngR10089			Date: 10/25/2001



Similar bug 4432655 was filed against solaris implementation and was fixed 
in merlin-beta2.
This bug is reproduced on WindowsNT.

The Java Language Specification, 2nd Edition, reads:

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

However, the following test demonstrates that the JDK1.4 (build beta-b84)
does not perform read or write as an atomic action even on a single processor 
computer.
In the test, one thread writes to a long variable a value with identical
high and low 32-bit halves, while another thread reads this variable and checks
if the halves are identical. If they are not identical, the test fails.

----------------------- file thrd05201.java
package javasoft.sqe.tests.lang.thrd052.thrd05201;
import java.io.PrintStream;

public class thrd05201 extends Thread {
	public static final long timeout = 30000; // max 1/2 min of work
	PrintStream out;
	volatile long vvar=0;
	thrd05201 peer;
	volatile boolean finished=false;
	volatile boolean passed=true;
	long startTime=System.currentTimeMillis();

	public synchronized void run() {
		long startTime=System.currentTimeMillis();
		loop:
		for (int cnt1=0; cnt1<0x7FFF; ) {
			long time=System.currentTimeMillis()-startTime;
			if (time>=timeout) break loop;
			for (int cnt2=0; cnt2<0xFFFF; cnt2++ ) {
				long cnt=(cnt1<<16)|cnt2;
// assign our own vvar with a long value composed of two identical halves
				vvar=(cnt<<32)|cnt;
// read peer's vvar to see if it consists of two identical halves
				long pvvar=peer.vvar;
				int pl=(int)(pvvar>>32);
				int pr=(int)(pvvar&0xFFFFFFFF);
				if (pl!=pr) {
// error: halves are not identical
					out.print("after 
"+(System.currentTimeMillis()-startTime)+" msec: ");
					out.println("left="+pl+" right="+pr);
					passed=false;
					break loop;
				}
			}
			if (peer.finished) break loop;
		}
		finished=true;
	}

	thrd05201(PrintStream out) {
		this.out=out;
	}

	public static int run(String args[], PrintStream out) {
		thrd05201 thr1 = new thrd05201(out);
		thrd05201 thr2 = new thrd05201(out);
		thr1.peer=thr2;
		thr2.peer=thr1;

		thr1.start();
		thr2.start();
		try {
			thr1.join();
			thr2.join();
		} catch (InterruptedException e) {
			out.println("InterruptedException");

		}
		if (thr1.passed && thr2.passed) {
			return 0/*STATUS_PASSED*/;
		} else {
			return 2/*STATUS_FAILED*/;
		}
	}

	public static void main(String args[]) {
		System.exit(run(args, System.out) + 95/*STATUS_TEMP*/); 
	} 
 
}
----------------------- end of file thrd05201.java
 
> javac -d . thrd05201.java

> java -version
java version "1.4.0-beta3"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta3-b84)
Java HotSpot(TM) Client VM (build 1.4.0-beta3-b84, mixed mode)

> java -cp . -Xfuture javasoft.sqe.tests.lang.thrd052.thrd05201.thrd05201
after 0 msec: left=220 right=221

> java -cp . -Xfuture javasoft.sqe.tests.lang.thrd052.thrd05201.thrd05201
after 0 msec: left=272 right=273

> java -cp . -Xfuture javasoft.sqe.tests.lang.thrd052.thrd05201.thrd05201
after 0 msec: left=268 right=267

> java -cp . -Xfuture javasoft.sqe.tests.lang.thrd052.thrd05201.thrd05201
after 0 msec: left=264 right=263

----------------------------------------------------

======================================================================

Comments
EVALUATION Tiger bug. ###@###.### 2003-11-14 NR in tiger b29 on both dual and single cpu boxes. I suspect this bug was fixed when the fix for 4526490 aligned heap objects on 8-byte boundaries on all platforms, not just sparc and ia64. If a heap object was aligned on a 4-byte boundary, there was no way to guarantee that a long or double field would be 8-byte aligned. ###@###.### 2003-11-24
24-11-2003