Communication deadlocks


Concurrency is hard

Shared-memory concurrency is ridiculously hard

+ concurrency?

+ concurrency?


🀷?

Choreographies


Message passing concurrency

Choreographies are a way of describing communicating systems as global programs

A

💃

B

🕺🏜

A

💃

B

🕺🏜

        A.x -> B.x
      

        A.x -> B.x
      

A


        Send("B",x)
      

B


        x = Receive("A")
      

        A.x -> B.x
        let y@A = foo()
        let w@B = bar()
      

A


        Send("B",x)
        y = foo()
      

B


        x = Receive("A")
        w = bar()
      

        A.x -> B.x
        let y@A = foo()
        let w@B = bar()
      

        A.x -> B.x
        let y@A = foo()
        let w@B = bar()
        if y@A
          A->B[T]
          ...
        else
          A->B[F]
          ...
      

        A.x -> B.x
        let y@A = crunch()
        let w@B = crunch()
        if y@A
          A->B[T]
          ...
        else
          A->B[F]
          ...
      

A


        if y
          Choose("B",T)
          ...
        else
          Choose("B",F)
          ...
      

B


        if Choice("A")
          ...
        else
          ...
      

Features


+ concurrency?


        A.x -> B.x
        B.y -> C.y
        ...
      


      A.x -> B.x
      B.y -> C.y
      ...
    

A
B
C
G::= A.x -> B.y; G(com)
| A -> B[b]; G(sel)
| Let x@A = foo(..); G(let)
| If x@A Then G Else G(if)
| Fix fn G(fix)
| Call fn(call)
| End(end)

$(s,c) \xrightarrow{(\tau,l)} (s',c')$


Where:

Communication


A.x -> B.y;C

Communication


S
A.x -> B.y;C

Communication


S(A,x) = d
A.x -> B.y;C

Communication


A.x -> B.y;C
S[(B,y)|->d]

Communication


S[(B,y)|->d]
C

Deadlock-freedom

$\text{fv}(c) \subseteq \text{fv}(s)$
$c\equiv end \lor \exists{s' c'.}{(s,c) \rightarrow (s',c')}$

        A.x -> B.x
        B.y -> C.y
        ...
      


        A.x -> B.x
        B.y -> C.y
        ...
      

EPN


        let x@A = [1,2,3]
        A.x -> B.y
        let y@B = sort x
        B.y -> A.y
        ...
      

A


        Let x = [1,2,3]
        Send B x
        Receive A y
        ...
      

B


        Receive A x
        Let y = sort x
        Send A y
        ...
      

A


        Let x = [1,2,3]
        Send B x
        Receive A y
        ...
      

B


        Receive A x
        Let y = sort x
        Send A y
        ...
      

A


        let x = [1,2,3]
        let _ = #send B x
        let x = #receive A
        ...
      

B


        let x = #receive A
        let y = sort x
        let _ = #send A y
        ...
      

Semantic preservation

$(s,c)\xrightarrow{}(s',c')$
$\exists{c'',s''.\;}(s',c')\rightarrow^{\ast}(s'',c'')\,\land\, [\![s,c]\!]\rightarrow^{\ast}[\![s'',c'']\!]$

Semantic reflection

$[\![s,c]\!]\xrightarrow{}epn$
$\exists{c',s'.\;}epn\rightarrow^{\ast}[\![s',c']\!]\,\land\, (s,c)\rightarrow^{\ast}(s',c')$

        A.x -> B.x
        B.y -> C.y
        ...
      

EPN

EPN

EPN

Selection

Payload

Closure


        A.x -> B.x
        B.y -> A.y
        ...
      


        A.x -> B.x
        B.y -> A.y
        ...
      


😮‍💚

EPN

<-

->

Selection

<-

->

Payload

<-

->

Closure

<-

->

* Cumbersome and repetitive

🌎 Interaction trees

        'a 'e 'r itree =
           Ret 'r
         | Tau ('a 'e 'r itree)
         | Vis 'e ('a -> 'a 'e 'r itree)
      

A


        x = foo()
        Send("B",x)
        y = Receive("B")
        return y
      
Itree A

A


        x = foo()
        Send("B",x)
        y = Receive("B")
        return y
      
Tau
(
Itree A
)

A


        x = foo()
        Send("B",x)
        y = Receive("B")
        return y
      
Tau
(
Vis (Send B x)
(
λ_->
Itree A
) )

A


        x = foo()
        Send("B",x)
        y = Receive("B")
        return y
      
Tau
(
Vis (Send B x)
(
λ_->
Itree A
) )

A


        x = foo()
        Send("B",x)
        y = Receive("B")
        return y
      
(
λ_->
Itree A
)
0

A


        x = foo()
        Send("B",x)
        y = Receive("B")
        return y
      
(
λ_->
Itree A
)
0

Vis (Receive B)
(λy-> Ret y)

A


        x = foo()
        Send("B",x)
        y = Receive("B")
        return y
      
Vis (Receive B)
(λy-> Ret y)
(λy-> Ret y)
(λy-> Ret y)

5

10

100
(λy-> Ret y)

5

Ret 5

10

Ret 10

100

Ret 100
interp : ('a 'e 'r) itree
->
'r
interp : ('a 'e 'r) itree
->
'i

    interp (Ret n)             = n
    interp (Tau t)             = interp t
    interp (Vis (Send p x) f)  = interp (f 0)
    interp (Vis (Receive p) f) = interp (f 5)
  

💃🕺🏜 -> 🌎?

🌲

🎄


        A.x -> B.x
        B.y -> C.y
        ...
      

A

🌎

B

🌲

C

🎄

Interaction forest


🌎A

Vis (Send "B" 5) fa

🌲B

...

🌎A

fa Ok
(B,A) |-> x

🌲B

...
(B,A) |-> x

🌲B

Vis (Receive A) fb

🌲B

fb x

          iforest =
            <| forest : 'p |-> ('a,'e,'r) itree
               st     : 's
               act    : 's -> 'p -> 'e -> 'a option;
               upd    : 's -> 'p -> 'e -> 's;
            |>
        

        s : 'p ⚯ 'p |-> 'a
      

        chor_act s p (Send q x)  = SOME Ok
        chor act s p (Receive q) = lookup s (p,q)
        ...
      

        chor_upd s p (Send q x)  =
          s with queue := update s (q,p) (Msg x)
        ...
      

An interaction forest interpreter



      [
       ("A",Int),
       ("B",Int),
       ("A",Ext (Send "B" x)),
       ("C",Int),
       ("B",Ext (Receive "A"))

       ...
      ]
    

🌲

Kalas

🌲

EPN

🌲 🌲 🌲

Kalas

🌲 🌲 🌲

EPN