[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: TechEd 2006 -- "parallelism is the new OO"



Hi,

> > I'd be interested to hear from JCSP people on this -- is the
> > implementation clean, or does it have similar problems described above?
> 
> Depends what you mean by clean.  You can get hold of the source code
> from www.jcsp.org <http://www.jcsp.org/>  and take a look at it and see.
> As an example, the One2OneChannel only has one monitor lock so is fairly
> clean, whereas the Alternative is a bit messier.  This is not really a
> problem with the design of JCSP, but Java's shortcomings.  The problem
> with Alternative has something to do with timers in Java returning
> early, you'd have to check with someone more in the know on the
> specifics.

The JCSP implementation should have no problems from multi-core processors
and processors with out-of-order code execution!  We took considerable
care to get all the monitor/condition-variable stuff *right* - so that
users don't have to, :).  All shared structures needed for implementation
are protected - we rely on no `volatile' semantics (which cause such
counter-intuitive headaches when wrestling with the memory model in the
presence of code re-ordereings) and, of course, no broken tricks (such
as the double-check idiom).

Recently, I've finally added protection against "spurious wakeups",
although I've never ever ever ever seen one!  This is in the (not yet
released) "core" JCSP 1.0-rc6 - which will be merged with Quickstone's
JCSP Network Edition (www.jcsp.org).

For anyone not knowing about spurious wakeups, this is fun!  When a
Java thread executes a "wait()", it releases the monitor lock (it
must be holding on the object to which the "wait()" belongs) and
blocks until:

  (a) either some other thread acquires the relevant monitor lock,
      issues a "notify()" and the waiting thread is chosen for
      release (and, then, has to re-acquire the monitor) ...
  
  (b) or some other thread acquires the relevant monitor lock and
      issues a "notifyAll()", whereupon the waiting thread competes
      with everyone to re-acquire the monitor ...
  
  (c) or some other thread has reference to the waiting "Thread"
      and invokes "interrupt()" ...
  
  (d) or for no reason at all.

The last clause above is the spurious wakeup.  The Java people swear
blind that this is a *deliberate* design decision - not a bug resulting
from broken OS threading support that they didn't fix for some reason.
We can imagine the discussion amongst the Java threading designers:

  "OK - that's decided then, a thread blocks until it's notified ..."

  "Hang on, nobody expects the Spanish Inquisition - better make that:
   a thread blocks until it's notified or interrupted ..."
  
  "Hey, here's a really cool idea - why don't we make that: a thread
   blocks until it's notified or interrupted ... or let's just release
   it sometimes for no reason whatsoever ... ???"

  "Yeah - what a great idea - that'll keep them on their toes.  Let's
   do it!"

The timer problem Kevin refers to above is the icing on the cake.  For
a wait-with-timeout, "wait(timeout)", clauses (a)..(d) all apply plus
one more:

  (e) the specified amount of real time has elapsed, more or less.

where the above is a quote from the JDK documentation.  Interpreting
this, the timeout (from the wait) is allowed to happen at any time
after (or equal to) the timeout period set ... and also any time
before.  Now, that really is cool!

Telling the difference between an early wakeup (e) and a spurious one
(d) is, I think, impossible - although we can guess.  Early wakeups
happen all the time (unlike the spurious ones).  I suspect it may be
to do with clock interrupts (on many JVMs) happening with only 10 ms
granularity ... so that it rounds the actual release to the nearest
10 ms, even if that's early?

Dealing with this does complicate the JCSP implementation ... but this
is a different matter to fragility due to out-of-order code execution
and multicore processors (against which JCSP should be robust).

Cheers,

Peter.

PS. do .NET/c# have semantic quirks like (d) and (e) above?