Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4432655

read or write to long volatile variable is not atomic.

XMLWordPrintable

    • beta2
    • sparc
    • solaris_7



      Name: akR10088 Date: 04/02/2001



      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 demonstartes that the JDK1.4 (release beta-b58)
      does not preform 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 idenital
      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.

      Note that jdk1.3 (build 1.3.0rc3-Z) does not fail the test.

      ----------------------- file thrd05201.java
      // this is a slightly simplified version of the JCK test lang/THRD/thrd05201

      import java.io.PrintStream;

      public class thrd05201 extends Thread {
      public static final long timeout = 30000; // max 1/2 min of work

      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
      System.out.print("after "+(System.currentTimeMillis()-startTime)+" msec: ");
      System.out.println("left="+pl+" right="+pr);
      passed=false;
      break loop;
      }
      }
      if (peer.finished) break loop;
      }
      finished=true;
      }

      public static void main(String args[]) {
      thrd05201 thr1 = new thrd05201();
      thrd05201 thr2 = new thrd05201();
      thr1.peer=thr2;
      thr2.peer=thr1;

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

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

      }
      ----------------------- end of file thrd05201.java
       
      novo64% javac thrd05201.java
      novo64% java -version
      java version "1.4.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b58)
      Java HotSpot(TM) Client VM (build 1.4.0-beta-b58, mixed mode)
      novo64% java thrd05201
      after 1413 msec: left=25130 right=25131
      novo64% java thrd05201
      after 1432 msec: left=11175 right=11176
      novo64% java thrd05201
      after 2386 msec: left=14604 right=64762


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

            smitrovisunw Srdjan Mitrovic (Inactive)
            rfqsunw Rfq Rfq (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: