From 548a5de9301de732bb11bd7d812fa3bb011b13ba Mon Sep 17 00:00:00 2001
From: Zhen Zhang <zhangz@mpi-sws.org>
Date: Tue, 9 Aug 2016 11:53:30 +0200
Subject: [PATCH] use pair of ref in ticket lock

---
 heap_lang/lib/ticket_lock.v | 137 ++++++++++++++++++------------------
 1 file changed, 69 insertions(+), 68 deletions(-)

diff --git a/heap_lang/lib/ticket_lock.v b/heap_lang/lib/ticket_lock.v
index d2569159f..fdcf90bd0 100644
--- a/heap_lang/lib/ticket_lock.v
+++ b/heap_lang/lib/ticket_lock.v
@@ -7,26 +7,27 @@ From iris.algebra Require Import gset.
 Import uPred.
 
 Definition wait_loop: val :=
-  rec: "wait_loop" "x" "l" :=
-    let: "o" := Fst !"l" in
+  rec: "wait_loop" "x" "lock" :=
+    let: "o" := !(Fst "lock") in
     if: "x" = "o"
       then #() (* my turn *)
-      else "wait_loop" "x" "l".
+      else "wait_loop" "x" "lock".
+
+Definition newlock : val := λ: <>, ((* owner *) ref #0, (* next *) ref #0).
 
-Definition newlock : val := λ: <>, ref((* owner *) #0, (* next *) #0).
 Definition acquire : val :=
-  rec: "acquire" "l" :=
-    let: "oldl" := !"l" in
-    if: CAS "l" "oldl" (Fst "oldl", Snd "oldl" + #1)
-      then wait_loop (Snd "oldl") "l"
-      else "acquire" "l".
+  rec: "acquire" "lock" :=
+    let: "n" := !(Snd "lock") in
+    if: CAS (Snd "lock") "n" ("n" + #1)
+      then wait_loop "n" "lock"
+      else "acquire" "lock".
 
 Definition release : val :=
-  rec: "release" "l" :=
-    let: "oldl" := !"l" in
-    if: CAS "l" "oldl" (Fst "oldl" + #1, Snd "oldl")
+  rec: "release" "lock" :=
+    let: "o" := !(Fst "lock") in
+    if: CAS (Fst "lock") "o" ("o" + #1)
       then #()
-      else "release" "l".
+      else "release" "lock".
 
 Global Opaque newlock acquire release wait_loop.
 
@@ -42,28 +43,29 @@ Instance subG_tlockΣ {Σ} : subG tlockΣ Σ → tlockG Σ.
 Proof. intros [? [?%subG_inG _]%subG_inv]%subG_inv. split; apply _. Qed.
 
 Section proof.
-Context `{!heapG Σ, !tlockG Σ} (N : namespace).
+Context `{!heapG Σ, !tlockG Σ} (N : namespace) (HN: heapN ⊥ N).
 
 Definition tickets_inv (n: nat) (gs: gset_disjUR nat) : iProp Σ :=
   (gs = GSet (seq_set 0 n))%I.
 
-Definition lock_inv (γ1 γ2: gname) (l : loc) (R : iProp Σ) : iProp Σ :=
-  (∃ o n: nat, l ↦ (#o, #n) ★
-               auth_inv γ1 (tickets_inv n) ★
-               ((own γ2 (Excl ()) ★  R) ∨ auth_own γ1 (GSet {[ o ]})))%I.
+Definition lock_inv (γ1 γ2: gname) (lo ln: loc) (R : iProp Σ) : iProp Σ :=
+  (∃ (o n: nat),
+       lo ↦ #o ★ ln ↦ #n ★
+       auth_inv γ1 (tickets_inv n) ★
+       ((own γ2 (Excl ()) ★  R) ∨ auth_own γ1 (GSet {[ o ]})))%I.
 
-Definition is_lock (l: loc) (R: iProp Σ) : iProp Σ :=
-  (∃ γ1 γ2, heapN ⊥ N ∧ heap_ctx ∧ inv N (lock_inv γ1 γ2 l R))%I.
+Definition is_lock (l: val) (R: iProp Σ) : iProp Σ :=
+  (∃ γ1 γ2 (lo ln: loc), heap_ctx ∧ l = (#lo, #ln)%V ∧ inv N (lock_inv γ1 γ2 lo ln R))%I.
 
-Definition issued (l : loc) (x: nat) (R : iProp Σ) : iProp Σ :=
-  (∃ γ1 γ2, heapN ⊥ N ∧ heap_ctx ∧ inv N (lock_inv γ1 γ2 l R) ∧
-            auth_own γ1 (GSet {[ x ]}))%I.
+Definition issued (l : val) (x: nat) (R : iProp Σ) : iProp Σ :=
+  (∃ γ1 γ2 (lo ln: loc), heap_ctx ∧ l = (#lo, #ln)%V ∧ inv N (lock_inv γ1 γ2 lo ln R) ∧
+                         auth_own γ1 (GSet {[ x ]}))%I.
 
-Definition locked (l : loc) (R : iProp Σ) : iProp Σ :=
-  (∃ γ1 γ2, heapN ⊥ N ∧ heap_ctx ∧ inv N (lock_inv γ1 γ2 l R) ∧
-            own γ2 (Excl ()))%I.
+Definition locked (l : val) (R : iProp Σ) : iProp Σ :=
+  (∃ γ1 γ2 (lo ln: loc), heap_ctx ∧ l = (#lo, #ln)%V ∧ inv N (lock_inv γ1 γ2 lo ln R) ∧
+                         own γ2 (Excl ()))%I.
 
-Global Instance lock_inv_ne n γ1 γ2 l : Proper (dist n ==> dist n) (lock_inv γ1 γ2 l).
+Global Instance lock_inv_ne n γ1 γ2 lo ln: Proper (dist n ==> dist n) (lock_inv γ1 γ2 lo ln).
 Proof. solve_proper. Qed.
 Global Instance is_lock_ne n l: Proper (dist n ==> dist n) (is_lock l).
 Proof. solve_proper. Qed.
@@ -74,14 +76,13 @@ Global Instance is_lock_persistent l R : PersistentP (is_lock l R).
 Proof. apply _. Qed.
 
 Lemma newlock_spec (R : iProp Σ) Φ :
-  heapN ⊥ N →
-  heap_ctx ★ R ★ (∀ l, is_lock l R -★ Φ #l) ⊢ WP newlock #() {{ Φ }}.
+  heap_ctx ★ R ★ (∀ l, is_lock l R -★ Φ l) ⊢ WP newlock #() {{ Φ }}.
 Proof.
-  iIntros (?) "(#Hh & HR & HΦ)". rewrite /newlock.
-  wp_seq. wp_alloc l as "Hl".
+  iIntros "(#Hh & HR & HΦ)". rewrite /newlock.
+  wp_seq. wp_alloc lo as "Hlo". wp_alloc ln as "Hln".
   iVs (own_alloc (Excl ())) as (γ2) "Hγ2"; first done.
   iVs (own_alloc_strong (Auth (Excl' ∅) ∅) {[ γ2 ]}) as (γ1) "[% Hγ1]"; first done.
-  iVs (inv_alloc N _ (lock_inv γ1 γ2 l R) with "[-HΦ]").
+  iVs (inv_alloc N _ (lock_inv γ1 γ2 lo ln R) with "[-HΦ]").
   { iNext. rewrite /lock_inv.
     iExists 0%nat, 0%nat.
     iFrame.
@@ -93,90 +94,90 @@ Proof.
     by iFrame. }
   iVsIntro.
   iApply "HΦ".
-  iExists γ1, γ2.
+  iExists γ1, γ2, lo, ln.
   iSplit; by auto.
 Qed.
 
 Lemma wait_loop_spec l x R (Φ : val → iProp Σ) :
-  issued l x R ★ (∀ l, locked l R -★ R -★ Φ #()) ⊢ WP wait_loop #x #l {{ Φ }}.
+  issued l x R ★ (∀ l, locked l R -★ R -★ Φ #()) ⊢ WP wait_loop #x l {{ Φ }}.
 Proof.
-  iIntros "[Hl HΦ]". iDestruct "Hl" as (γ1 γ2) "(% & #? & #? & Ht)".
-  iLöb as "IH". wp_rec. wp_let. wp_bind (! _)%E.
-  iInv N as (o n) "[Hl Ha]" "Hclose".
+  iIntros "[Hl HΦ]". iDestruct "Hl" as (γ1 γ2 lo ln) "(#? & % & #? & Ht)".
+  iLöb as "IH". wp_rec. subst. wp_let. wp_proj. wp_bind (! _)%E.
+  iInv N as (o n) "[Hlo [Hln Ha]]" "Hclose".
   wp_load. destruct (decide (x = o)) as [->|Hneq].
   - iDestruct "Ha" as "[Hainv [[Ho HR] | Haown]]".
-    + iVs ("Hclose" with "[Hl Hainv Ht]").
+    + iVs ("Hclose" with "[Hlo Hln Hainv Ht]").
       { iNext. iExists o, n. iFrame. eauto. }
-      iVsIntro. wp_proj. wp_let. wp_op=>[_|[]] //.
+      iVsIntro. wp_let. wp_op=>[_|[]] //.
       wp_if. iVsIntro.
-      iApply ("HΦ" with "[-HR] HR"). iExists γ1, γ2; eauto.
+      iApply ("HΦ" with "[-HR] HR"). iExists γ1, γ2, lo, ln; eauto.
     + iExFalso. iCombine "Ht" "Haown" as "Haown".
       iDestruct (auth_own_valid with "Haown") as % ?%gset_disj_valid_op.
       set_solver.
-  - iVs ("Hclose" with "[Hl Ha]").
+  - iVs ("Hclose" with "[Hlo Hln Ha]").
     { iNext. iExists o, n. by iFrame. }
-    iVsIntro. wp_proj. wp_let. wp_op=>?; first omega.
+    iVsIntro. wp_let. wp_op=>?; first omega.
     wp_if. by iApply ("IH" with "Ht").
 Qed.
 
 Lemma acquire_spec l R (Φ : val → iProp Σ) :
-  is_lock l R ★ (∀ l, locked l R -★ R -★ Φ #()) ⊢ WP acquire #l {{ Φ }}.
+  is_lock l R ★ (∀ l, locked l R -★ R -★ Φ #()) ⊢ WP acquire l {{ Φ }}.
 Proof.
-  iIntros "[Hl HΦ]". iDestruct "Hl" as (γ1 γ2) "(% & #? & #?)".
-  iLöb as "IH". wp_rec. wp_bind (! _)%E.
-  iInv N as (o n) "[Hl Ha]" "Hclose".
-  wp_load. iVs ("Hclose" with "[Hl Ha]").
+  iIntros "[Hl HΦ]". iDestruct "Hl" as (γ1 γ2 lo ln) "(#? & % & #?)".
+  iLöb as "IH". wp_rec. wp_bind (! _)%E. subst. wp_proj.
+  iInv N as (o n) "[Hlo [Hln Ha]]" "Hclose".
+  wp_load. iVs ("Hclose" with "[Hlo Hln Ha]").
   { iNext. iExists o, n. by iFrame. }
-  iVsIntro. wp_let. wp_proj. wp_proj. wp_op.
+  iVsIntro. wp_let. wp_proj. wp_op.
   wp_bind (CAS _ _ _).
-  iInv N as (o' n') "[Hl [Hainv Haown]]" "Hclose".
-  destruct (decide ((#o', #n') = (#o, #n)))%V
-    as [[= ->%Nat2Z.inj ->%Nat2Z.inj] | Hneq].
+  iInv N as (o' n') "[Hlo' [Hln' [Hainv Haown]]]" "Hclose".
+  destruct (decide (#n' = #n))%V
+    as [[= ->%Nat2Z.inj] | Hneq].
   - wp_cas_suc.
     iDestruct "Hainv" as (s) "[Ho %]"; subst.
     iVs (own_update with "Ho") as "Ho".
     { eapply auth_update_no_frag, (gset_alloc_empty_local_update n).
       rewrite elem_of_seq_set; omega. }
     iDestruct "Ho" as "[Hofull Hofrag]".
-    iVs ("Hclose" with "[Hl Haown Hofull]").
+    iVs ("Hclose" with "[Hlo' Hln' Haown Hofull]").
     { rewrite gset_disj_union; last by apply (seq_set_S_disjoint 0).
       rewrite -(seq_set_S_union_L 0).
-      iNext. iExists o, (S n)%nat.
+      iNext. iExists o', (S n)%nat.
       rewrite Nat2Z.inj_succ -Z.add_1_r.
       iFrame. iExists (GSet (seq_set 0 (S n))). by iFrame. }
-    iVsIntro. wp_if. wp_proj.
-    iApply wait_loop_spec.
+    iVsIntro. wp_if.
+    iApply (wait_loop_spec (#lo, #ln)).
     iSplitR "HΦ"; last by done.
     rewrite /issued /auth_own; eauto 10.
   - wp_cas_fail.
-    iVs ("Hclose" with "[Hl Hainv Haown]").
+    iVs ("Hclose" with "[Hlo' Hln' Hainv Haown]").
     { iNext. iExists o', n'. by iFrame. }
     iVsIntro. wp_if. by iApply "IH".
 Qed.
 
 Lemma release_spec R l (Φ : val → iProp Σ):
-  locked l R ★ R ★ Φ #() ⊢ WP release #l {{ Φ }}.
+  locked l R ★ R ★ Φ #() ⊢ WP release l {{ Φ }}.
 Proof.
-  iIntros "(Hl & HR & HΦ)"; iDestruct "Hl" as (γ1 γ2) "(% & #? & #? & Hγ)".
-  iLöb as "IH". wp_rec. wp_bind (! _)%E.
-  iInv N as (o n) "[Hl Hr]" "Hclose".
-  wp_load. iVs ("Hclose" with "[Hl Hr]").
+  iIntros "(Hl & HR & HΦ)"; iDestruct "Hl" as (γ1 γ2 lo ln) "(#? & % & #? & Hγ)".
+  iLöb as "IH". wp_rec. subst. wp_proj. wp_bind (! _)%E.
+  iInv N as (o n) "[Hlo [Hln Hr]]" "Hclose".
+  wp_load. iVs ("Hclose" with "[Hlo Hln Hr]").
   { iNext. iExists o, n. by iFrame. }
   iVsIntro. wp_let. wp_bind (CAS _ _ _ ).
-  wp_proj. wp_op. wp_proj.
-  iInv N as (o' n') "[Hl Hr]" "Hclose".
-  destruct (decide ((#o', #n') = (#o, #n)))%V
-    as [[= ->%Nat2Z.inj ->%Nat2Z.inj] | Hneq].
+  wp_proj. wp_op.
+  iInv N as (o' n') "[Hlo' [Hln' Hr]]" "Hclose".
+  destruct (decide (#o' = #o))%V
+    as [[= ->%Nat2Z.inj ] | Hneq].
   - wp_cas_suc.
     iDestruct "Hr" as "[Hainv [[Ho _] | Hown]]".
     + iExFalso. iCombine "Hγ" "Ho" as "Ho".
       iDestruct (own_valid with "#Ho") as %[].
-    + iVs ("Hclose" with "[Hl HR Hγ Hainv]").
-      { iNext. iExists (o + 1)%nat, n%nat.
+    + iVs ("Hclose" with "[Hlo' Hln' HR Hγ Hainv]").
+      { iNext. iExists (o + 1)%nat, n'%nat.
         iFrame. rewrite Nat2Z.inj_add.
         iFrame. iLeft; by iFrame. }
       iVsIntro. by wp_if.
-  - wp_cas_fail. iVs ("Hclose" with "[Hl Hr]").
+  - wp_cas_fail. iVs ("Hclose" with "[Hlo' Hln' Hr]").
     { iNext. iExists o', n'. by iFrame. }
     iVsIntro. wp_if. by iApply ("IH" with "Hγ HR").
 Qed.
-- 
GitLab