Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion STM criticism from Azul Systems
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Rich Hickey  
View profile  
 More options May 25 2008, 8:47 pm
From: Rich Hickey <richhic...@gmail.com>
Date: Sun, 25 May 2008 17:47:21 -0700 (PDT)
Local: Sun, May 25 2008 8:47 pm
Subject: Re: STM criticism from Azul Systems

On May 25, 11:04 am, cliffc <cli...@acm.org> wrote:

> On May 24, 10:51 am, Rich Hickey <richhic...@gmail.com> wrote:
> > As we add locks, performance of both approaches improves, but a new
> > source of errors comes into play for the manual approach - lock
> > acquisition order and the resultant deadlock risk. At this point STM
> > becomes dramatically less complex than manual locking.

> Not interesting *in practice*.  Because in practice, deadlocks are
> easy to find & fix.

I think you'll find plenty of dissent on that point.

> Actually, I was thinking of the compiler-vs-ASM analogy that took
> place in the 60's & 70's.  But point well taken: I agree that we need
> *some* kind of support here.  Maybe in the very long run STM runtimes
> get better & STM does win.  Meanwhile life sucks.  If you can only
> solve the problem with STM's I'll point out below then I'll agree with
> you, and maybe even try my hand at an STM implementation.

> Ok, the long sought after counter example.: STM's do not compose w/
> correctness.
> Bad Java syntax follows, because I don't 'speak' Clojure.  I'm using
> the classic example.

> class Account {
>   long _money;
>   add( long m ) { atomic { _money = _money + m; } }

> }

> transfer( Account a1, Account a2, long m ) {
>   a1.add( m);
>   a2.add(-m);

> }

> While 'add' alone is STM'd & safe, the two calls to 'add' that need to
> be wrapped in an 'atomic' are not - so there is a race where the
> accounts do not balance.  Deciding at what level to add the next
> 'atomic' (should it be around 'transfer' or at a higher level or not
> at all?) demands the programmer have domain knowledge not already
> encapsulated in the Account class.  THIS is the source of vast numbers
> of bugs.

That's a problem with the Account class and OOP - classes are simply
the wrong granularity for so many program semantics. Yet, programmers
demonstrate they can handle this, and set appropriate transaction
boundaries, because they do so in their database work. There is a
pretty close analogy there, since many DBMSs will treat every
statement in a batch as an independent transaction unless collected in
an explicit transaction. In spite of the same risks, work precisely
like this is getting done correctly, and relatively easily, I think in
no small part due to the simplicity of wrapping a bunch of arbitrary
statements in BEGIN TRANSACTION.

> Less trivial examples quickly spiral out of control.  Sure I know
> Ref's A, B & C are all Ref's and thus only updated in 'dosync' blocks
> - but can I split any collection of Ref updates into more than one
> atomic region?  The ad-absurdum answer is to wrap a dosync around
> *all* Ref's - which means the whole program, and that means a single-
> threaded program.  Imagine the program unrolled in front of you, as an
> endless sequence of actions (all control flow flattened out)...
> interspersed with other actions are updates to Ref's.  Now: dissect
> this list into groups with 'atomic' or 'lock' as you see fit,
> preserving the program meaning as another unrolled thread of execution
> is interspersed.  How do you decide where it's OK to split the stream
> and where it's not OK?

> Why, in the Grand Scheme of things is: "... { read _money ... write
> _money } ... " a correct splitting of the action stream,
> while "... { read _money ... write _money }  ... { read _money ...
> write _money } ..." is broken,
> but "... {{ read _money ... write _money } ... { read _money ... write
> _money }} ..."  is correct again?

What you are asking here is a philosophical question, which computers
may never answer, since the answer depends on the semantics of the
program, and such semantics will probably never be conveyed to the
system more easily than:

(defn transfer [a1 a2 m]
  (dosync
    (add a1 m)
    (sub a2 m)))

or the Java-esque:

transfer( Account a1, Account a2, long m ) {
   atomic{
     a1.add( m);
     a2.add(-m);
     }
 }

Absent some similar declaration of relatedness, the program will have
to understand itself (or one program another), since while it may look
like debit/credit to us, it just looks like foo/bar to it.

I hope you don't wait for an answer to this (hard AI, potentially
impossible) problem before dipping your toes in STM - it's likely you
could make a significant contribution.

Rich


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.