RE: JavaMemoryModel: Question about _current_ semantics of start

From: Paul Jakubik (pjakubik@dallas.objectspace.com)
Date: Tue Jun 13 2000 - 16:55:38 EDT


Bill Pugh Wrote:
> At 11:03 AM -0500 6/12/00, Paul Jakubik wrote:
> >Why is the only reasonable answer that both writes are visible?
> >
> >As long as the Java Threads are implemented over pthreads,
> >then both writes
> >should be visible since t2.start would probably call
> >pthread_create or
> >possible pthread_cond_signal. Both of these are supposed to have the
> >behavior that you want.
>
> But if compiler memory actions from before the call to start() to
> after the call to start(), you are still screwed.
>
> This point is important to mention because all of these memory model
> issues involve the interaction of the compiler, native libraries and
> processor architecture.

I think we agree that different interactions could cause one or more of the
writes to not be visible. My point was not to question why a specification
is needed. My question is why should we assume that both writes should be
visible, and not just the first write.

In Butenhof's list of rules, he talks about thread creation implying a
memory barrier, but says nothing about thread starting implying anything. So
the most literal translation of this is that an OS thread would be created
at the "new Thread" and imply nothing about starting the thread (Gordon
Hutchison mentioned this as well).

When I discussed what a pthreads implementation would involve, this was from
the point of view of why it would be tempting to say that there should be a
memory barrier there that guarantees that the started thread can see
everything that was inside the thread that started it at the time it is
started. If an implementation calls pthread_create when a Thread is
constructed, the new thread starts immediately.

An easy way to separate pthread creation from pthread starting is to have
the started thread immediately call pthread_cond_wait. Then Thread.start
could call pthread_cond_signal to start the thread up.

Regardless of whether Thread.start calls pthread_create or
pthread_cond_signal, a memory barrier is generated by Thread.start ensuring
both writes are visible. I thought that this was the justification for
assuming that is was desirable to go ahead and require both writes to be
visible. If it is difficult for a JVM to not provide this behavior, then it
might as well show up as a requirement since then everyone could depend on
it.

The question I had was how convenient would this rule be for non-native
thread libraries. While a non-native thread library (e.g. green threads)
probably has no reason to actually implement per-thread memory caches, it
certainly is allowed by the current memory model. If this is the case, the
new thread may initialize its cache at the time it is created, and so only
guarantee that the first write is visible.

This is just an example of a potential JVM implementation where making both
writes visible may not be convenient. So if the assumption that both writes
should be made visible was based on that generally being a convenient thing
to do, then that might not be a good enough reason.

Are there stronger reasons for wanting both writes to be visible. It
certainly did not seem obvious to me that I should expect this after reading
Butenhof's rules. Only deeper inspection of how to create a pthread without
starting it made me think that Butenhof's rules really would make both
writes visible.

So why should the memory barrier be at thread.Start instead of at new
Thread? Why should both writes be visible? Would it be easier to limit code
motion with respect to calls to "new" instead of trying to restrict calls to
"Thread.start"? Is it possibly more natural to only assume that the first
write is visible?

--Paul

-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



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