/**
 * Test if access to volatile long (64 bit) valuies is atomic.
 *
 * From an example in Dr. Dobb's Journal june 2002, page 93.
 *
 * @author Peter Haggar
 */
public class AtomicLong extends Thread
{

    static volatile long val;
    static int count = 10000000;
    long key;

    AtomicLong(int k)
    {
	long temp = k;
	// key = 00000001 00000001 for thread 1
	// key = 00000002 00000002 for thread 2
	key = (temp << 32) | temp;
    }

    public void run()
    {
	for (int i = 0; i < count; i++)
	{
	    // This 64 bit assignment is supposed to be atomic since
	    // val is declared atomic
	    long temp = val; // temp = 00000001 00000001
	    long temp1 = temp >>> 32; // temp1 = 00000000 00000001
	    long temp2 = temp << 32; // temp2 = 00000001 00000000
	    temp2 = temp2 >>> 32; // temp2 = 00000000 00000001

	    if (temp1 != temp2)
	    {
		failed("atomic access to volatile long is not atomic ("+
				temp1 + " != " + temp2 + ").");
		System.exit(1);
	    }
	    // This 64-bit assigment is supposed to be atomic since
	    // val is declared volatile.  temp1 should always equal
	    // temp2.
	    val = key; // val should always = 00000001 00000001 for thread 1
	}
	// XXX This should be rewritten to only print one 'passed' message.
	passed("Thread " + key + " terminated successfully.");
    }
	    

    public static void main(String[] args)
    {
	for (int t = 1; t < 10; t++)
	    new AtomicLong(t).start();
    }

    public void failed(String s)
    {
      if (s != null)
	System.out.println("FAILED: " + s);
      else
	System.out.println("FAILED: ");
    }

    public void passed(String s)
    {
      if (s != null)
	System.out.println("PASSED: " + s);
      else
	System.out.println("PASSED: ");
    }
}
