[jmm-dev] DRF theorem for event structures model of relaxed memory

Doug Lea dl at cs.oswego.edu
Fri Mar 28 13:07:57 UTC 2014


On 03/26/2014 01:41 PM, Alan Jeffrey wrote:
> Another update on where we are with modeling relaxed memory...

A couple of questions about decoding it ...

>
>  From Winskel, a prime event structure with labels Sigma is a quadruple
> (E,<=,#,l) where:
>
> * E is a set of events
> * <= is a partial order
> * # is a down-closed symmetric binary relation
> * l is a function from E to Sigma
>
> We will write e in HB(d) for e < d and e in HA(d) for e > d.
>
> An event structure is pointed when E has a least element init.
>
> New here, a memory model alphabet is a set Sigma together with:
>
> * An element initialize of Sigma
> * A subset Sync of Sigma

("Sync" is not used below? I can guess intent, but it would
be more comforting to know.)

> * Binary relations RWJ subseteq RWC on Sigma such that
> * RWC is transitive
> * For any a, (initialize,a) in RWC
>
> [The idea is that RWJ is the "read-write justification" relation, for example (R
> x=v, W x=v) in RWJ, and RWC is the "read-write conflict" relation, for example
> (R x=v, W x=w) in RWC.]
>
>  From RWC we can define WWC and DC (data conflict):
>
>    (a,b) in WWC whenever there exists (c,a) in RWC and (c,b) in RWC
>    (a,b) in DC whenever (a,b) in RWC or (b,a) in RWC or (a,b) in WWC
>
> A memory model event structure is a pointed event structure whose labels form a
> memory model alphabet, such that l(init) = initialize.
>
> For any MMES, we can lift RWJ, RWC, WWC and DC from Sigma to E, for example:
>
>    (d,e) in RWJ whenever (d,e) not in # and (l(d),l(e)) in RWJ
>
> Define past-time LTL over E* as per usual, in particular (writing <= on strings
> for prefix order):

Is there a good tutorial reference on the "per usual" techniques?

>
>    epsilon in wkprev(phi) always
>    se in wkprev(phi) whenever s in phi

My reading was that this ("weak previous"?) allows binary relations
to apply to the first event, by giving it an artificial empty predecessor?
But I'm not so sure because I can't decode its use in "Relaxed" below.

>
>    s in always phi whenever for all t <= s we have t in phi
>
>    s in eventually phi whenever there exists t <= s s.t. t in phi
>
>    s in phi since psi whenever there exists u <= s s.t. u in psi
>      and for all u < t <= s we have t in phi
>
> and one extra modality (writing <~ for non-contiguous substring order):
>
>    s in extended(phi) whenever there exists t ~> s s.t. t in phi
>
> For example, propositional LTL is enough to define being a configuration of an
> ES (as per Winskel though on sequences rather than sets):
>
>    HBClosed = forall e . forall d < e . (e => eventually(d))
>
>    ConflictFree = forall e . (e => always(not(#(e))))
>
>    RepeatFree = forall e . (e => always(not(e)))
>
>    Configuration = HBClosed and ConflictFree and RepeatFree
>
> and the memory model:
>
>    DRF = always (forall e . e => always(DC(e) => HB(e)))
>
>    Sequential = always (forall e . exists d in RWJ(e) .
>      e => wkprev(not RWC(e) since d)
>
>    SConfiguration = Configuration and Sequential
>
>    Relaxed = always (forall e . exists d in RWJ(e) .
>      e => wkprev(not (HB(e) and HA(d) and RWC(e)) since d)
>
>    RConfiguration = Configuration and
>      extended (HBClosed and RepeatFree and Relaxed)
>
> The idea is that a configuration is an rconfiguration (that is, allowed by the
> relaxed memory model) when it can be embedded in a <-closed, repeat-free (but
> *not* conflict-free) sequence of actions such that every event has a visible
> read-write justifier.) For example the program:
>
>    thread 1: r=x; y=r
>    thread 2: r=y; x=1
>
> has event structure with order:
>
>    init <= (R x=1) <= (W y=1)
>    init <= (R x=0) <= (W y=0)
>    init <= (R y=1) <= (W x=1)
>    init <= (R y=0) <= (W x=1)
>
> and conflict relation generated by:
>
>    (R x=1) # (R x=0)
>    (R y=1) # (R y=0)
>
> The configuration:
>
>    (init) (R y=1) (W x=1) (R x=1) (W x=1)
>
> is an rconfiguration because it can be embedded in:
>
>    (init) (R x=0) (W x=1) (R y=1) (W x=1) (R x=1) (W x=1)
>
> which is relaxed (but note, not conflict-free as it contains (R x=0) as well as
> (R x=1)).
>
> The model doesn't admit the canonical OOTA execution, since the program:
>
>    thread 1: r=x; y=r
>    thread 2: r=y; x=r
>
> has event structure with order:
>
>    init <= (R x=1) <= (W y=1)
>    init <= (R x=0) <= (W y=0)
>    init <= (R y=1) <= (W x=1)
>    init <= (R y=0) <= (W x=0)
>
> and conflict relation generated by:
>
>    (R x=1) # (R x=0)
>    (R y=1) # (R y=0)
>
> but there is no extension of the configuration:
>
>    (init) (R y=1) (W x=1) (R x=1) (W x=1)
>
> which makes it an rconfiguration, for example the candidate:
>
>    (init) (R x=0) (W x=0) (R y=1) (W x=1) (R x=1) (W x=1)
>
> has an unjustified (R y=1) event.
>
> To state the DRF theorem, we need one more thing which is the concept of a
> "read-write-enabled" event structure. Informally the idea is that if a program
> can perform (R x=1) then it can also perform (R x=0). Formalizing this, we
> define an equivalence class ~ on events such that if (d ~ e) then:
>
>    (c,d) in RWC iff (c,e) in RWC
>    (d,c) in RWC iff (e,c) in RWC
>    (c,d) in HB  iff (c,e) in HB
>    either d=e or d#e
>    if d#c then either e<=c or e#c
>    if e#c then either d<=c or d#c
>
> The read-write-enabled events are the ones
>
>    (d,e) in RWE iff there exists c~d s.t. (c,e) in RWJ
>
> For example (R x=1, W x=0) in RWE whenever we can find (R x=0)~(R x=1) such that
> (R x=0, W x=0) in RWJ. The additional requirement it then that every
> read-write-conflict is read-write-enabled, and the DRF theorem is then:
>
>    If (RWC subseteq RWE)
>    and (SConfiguration subseteq DRF)
>    then (RConfiguration subseteq SConfiguration)
>



More information about the jmm-dev mailing list