Re: JavaMemoryModel: Idiom for safe, unsynchronized reads

From: Paul Haahr (haahr@jivetech.com)
Date: Mon Jun 28 1999 - 15:17:48 EDT


At the risk of sounding naive, I'll admit to being confused about what
we're discussing here. Bill's original description was:

  Provide a synchronization idiom that provides a safe way for a thread
  to construct an object, perform a series of updates on the object, and
  then publish the object (store a reference to the object in memory
  read by other threads). Other threads should then be able to read that
  reference and see an object that reflects all of the modifications.
  Importantly, the threads reading that reference should be able to do
  so without any synchronization.
  
  Once again, this guarantee only applies to seeing a consistent and
  complete object. Other parts of the world state may be inconsistent.

I *think* this example captures the pattern Bill was talking about:

  class Publisher {
    public static Foo unchangingFoo = null;
    ... { // code that runs once, in one thread
      Foo foo = new Foo(arg, arg, arg);
      foo.someMethod(more, args);
      foo.someField = aValue;

      // publish the object
      unchangingFoo = foo;
    }
  }

  class User {
    ... { // code that runs in many threads
      Foo foo = Publisher.unchangingFoo;
      if (foo != null) {
        // The object named by foo should be correctly formed
        // and usable.
      }
    }
  }

Now, my understanding is that this code is broken for MP machines with
relaxed memory order, because the writes to the foo object by the
constructor, someMethod, or the putfield may not be seen by a processor
running the User code.

This seems all well and good. There was, I thought, a relatively simple
solution to this problem, which required changing the Publisher code to:

      // publish the object
      synchronized (foo) {
        unchangingFoo = foo;
      }

or, perhaps,

      // publish the object
      synchronized (foo) { }
      unchangingFoo = foo;

and that would force a memory barrier between creating the object and
publishing it to the world.

But then I read Bill's note, which included this set of possible
actions:

                                  Processor 2 has cached the
                                  contents of address 0x1234

  Processor 1 allocates a new
  object at address 0x1234

  Processor 1 initializes the
  object at address 0x1234

  Processor 1 does a memory
  barrier

  Processor 1 stores 0x1234
  into address 0x5678

                                  Processor 2 reads address 0x5678,
                                  gets 0x1234

                                  Processor 2 reads contents of object at
                                  address 0x1234 out of stale cache line

This does, unfortunately, make sense. I had assumed that a memory
barrier would (somehow) inform other processors that their cached data
might be stale. But I can believe that there are NUMA architectures
where the stale read could occur.

I am left asking ``Can one actually implement Java, with the usual safety
guarantees, on such an architecture?'' That is, is it possible to ensure
that object headers are initialized properly before objects are seen in
other threads?

(Blue skying for a second, I guess it's possible to envision a GC design
where all processors ensure that newly allocated objects are not cached
in any stale lines. For that to work, it probably prohibits allocation
of two objects from the same cache line.)

Right now, it appears to me that the only feasible answer is memory
barriers around almost all reads. Which scares me a lot, because I have
a customer who wants to ship my technology on SMP Alpha hardware in the
near future, and (1) we haven't done the work to support this yet and
(2) the performance would be much worse than uniprocessor.

Now, please, tell me where I'm wrong.

--p
-------------------------------
This is the JavaMemoryModel mailing list, managed by Majordomo 1.94.4.

To send a message to the list, email JavaMemoryModel@cs.umd.edu
To send a request to the list, email majordomo@cs.umd.edu and put
your request in the body of the message (use the request "help" for help).
For more information, visit http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:13 EDT