[concurrency-interest] when is safe publication safe?

Boehm, Hans hans.boehm at hp.com
Mon Apr 26 17:02:26 EDT 2010


To clarify, hopefully:

The core problem here is presumably that getMetaClassOf() reads a field, call it mc, containing a reference to the meta class information, and initialization of that field may race with the access.  The classic solution would be to declare mc "volatile", which avoids the data race and (in the absence of other data races) restores sequential consistency, so you don't have to worry about visibility issues.  (If you do want to worry about happens before ordering, it establishes the right happens before ordering.)

The reason you may not be happy with this is that it's slow on some architectures.  However the performance hit on X86 should be negligible, since an ordinary load is sufficient to implement the volatile load.  The store will be more expensive, but that's rare.  Thus you are presumably concerned about non-X86 architectures?

It's a bit confusing to talk about memory barriers since, as far as I know, the only Java class with "barrier" in the name is CyclicBarrier, which is something very different.

Hans

> -----Original Message-----
> From: concurrency-interest-bounces at cs.oswego.edu 
> [mailto:concurrency-interest-bounces at cs.oswego.edu] On Behalf 
> Of Jochen Theodorou
> Sent: Sunday, April 25, 2010 8:49 AM
> To: concurrency-interest at cs.oswego.edu
> Subject: Re: [concurrency-interest] when is safe publication safe?
> 
> Doug Lea wrote:
> > On 04/25/10 05:31, Jochen Theodorou wrote:
> >>> As a first step, consider exactly what effects/semantics you want 
> >>> here, and the ways you intend people to be able to write 
> >>> conditionally correct Groovy code.
> >>
> >> People wouldn't have to write conditionally correct Groovy 
> code. they 
> >> would write normal code as they would in Java (Groovy and Java are 
> >> very near).
> > 
> > It seems implausible that you could do enough analysis at load/run 
> > time to determine whether you need full locking in the presence of 
> > multithreaded racy initialization vs much cheaper release 
> fences. This 
> > would require at least some high-quality escape analysis. 
> And the code 
> > generated would differ both for the writing and reading callers.
> 
> maybe I did explain it not good. Let us assume I have the Groovy code:
> 
> 1+1
> 
> Then this is really something along the lines of:
> 
> SBA.getMetaClassOf(1).invoke("plus",1)
> 
> and SBA.getMetaClassOf(1) would return the meta class of 
> Integer. Since this is purely a runtime construct, it does 
> not exist until the first time this meta class is requested. 
> So getMetaClassOf would be the place to initialize the meta 
> class, that would register it in a global structure and on 
> subsequent invocation use that cached meta class. If two 
> threads execute the code above, then one would do the 
> initialization, while the other has to wait. The waiting 
> thread would then read the initialized global meta class. On 
> subsequent invocations both threads would just read. Since 
> changes of the meta class are rare, we would in 99% of all 
> cases simply read the existing value. Since we have to be 
> memory aware, these meta class can be unloaded at runtime 
> too. They are SoftReferenced so it is done only if really 
> needed. But rather than the normal change a reinitialization 
> might be needed much more often.
> 
> As you see the user code "1+1" does contain zero 
> synchronization code. 
> The memory barriers are all in the runtime. It is not that 
> this cannot be solved by using what Java already has, it is 
> that this is too expensive.
> 
> > As I mentioned, an alternative is to lay down some rules.
> > If people stick to the rules they get consistent (in the sense of 
> > data-race-free) executions, else they might not. And of 
> such rules, I 
> > think the ones that can apply here amount to saying that 
> other threads 
> > performing initializations cannot trust any of their reads of the 
> > partially initialized object.
> > And further, they cannot leak refs to that object outside 
> of the group 
> > of initializer threads.
> > 
> > This is not hugely different than the Swing threading rules
> > 
> (http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html)
> > but applies only during initialization.
> 
> but unlike what the above may suggest there is no single 
> initialization phase. The meta classes are created on demand. 
> We cannot know beforehand which meta classes are needed and 
> doing them all before starting would increase the startup 
> time big times.
> 
> If there were of course a way to recognize a partially 
> initialized object I could maybe think of something... but is 
> there a reliable one?
> 
> bye blackdrag
> 
> --
> Jochen "blackdrag" Theodorou
> The Groovy Project Tech Lead (http://groovy.codehaus.org) 
> http://blackdragsview.blogspot.com/
> 
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> 


More information about the Concurrency-interest mailing list