Skip to content
Snippets Groups Projects
Commit b14af24e authored by Ralf Jung's avatar Ralf Jung
Browse files

actually we don't need the meta stuff for cinc

parent ae3400d6
No related branches found
No related tags found
No related merge requests found
Pipeline #17398 passed
...@@ -175,8 +175,6 @@ Section conditional_counter. ...@@ -175,8 +175,6 @@ Section conditional_counter.
Definition own_token γ := (own γ (Excl ()))%I. Definition own_token γ := (own γ (Excl ()))%I.
Definition loc_token (l: loc) := ( γ, meta l N γ own_token γ)%I.
Definition pending_state P (n : Z) (proph_winner : option loc) l_ghost_winner (γ_n : gname) := Definition pending_state P (n : Z) (proph_winner : option loc) l_ghost_winner (γ_n : gname) :=
(P match proph_winner with None => True | Some l => l = l_ghost_winner end own γ_n ( Excl' n))%I. (P match proph_winner with None => True | Some l => l = l_ghost_winner end own γ_n ( Excl' n))%I.
...@@ -193,7 +191,7 @@ Section conditional_counter. ...@@ -193,7 +191,7 @@ Section conditional_counter.
only the CAS winner can transition to here, and [loc_token l] serves as a only the CAS winner can transition to here, and [loc_token l] serves as a
"location" token to ensure there is no ABA going on. *) "location" token to ensure there is no ABA going on. *)
Definition done_state Q (l l_ghost_winner : loc) (γ_t : gname) := Definition done_state Q (l l_ghost_winner : loc) (γ_t : gname) :=
((Q own_token γ_t) l_ghost_winner - loc_token l)%I. ((Q own_token γ_t) l_ghost_winner - l {1/2} -)%I.
(* We always need the [proph] in here so that failing threads coming late can (* We always need the [proph] in here so that failing threads coming late can
always resolve their stuff. always resolve their stuff.
...@@ -212,9 +210,8 @@ Section conditional_counter. ...@@ -212,9 +210,8 @@ Section conditional_counter.
Definition counter_inv γ_b γ_n f c := Definition counter_inv γ_b γ_n f c :=
( (b : bool) (l : loc) (q : Qp) (s : abstract_state), ( (b : bool) (l : loc) (q : Qp) (s : abstract_state),
f #b c {1/2} #l l {q} (state_to_val s) f #b c {1/2} #l l {1/2 + q} (state_to_val s)
own γ_b ( Excl' b) own γ_b ( Excl' b)
loc_token l (* the "location" token for ABA protection; also see [done_state] *)
match s with match s with
| injl n => c {1/2} #l own γ_n ( Excl' n) | injl n => c {1/2} #l own γ_n ( Excl' n)
| injr n p => | injr n p =>
...@@ -256,27 +253,6 @@ Section conditional_counter. ...@@ -256,27 +253,6 @@ Section conditional_counter.
apply (iffLR (frac_valid' _)) in Hv. by apply Qp_not_plus_q_ge_1 in Hv. apply (iffLR (frac_valid' _)) in Hv. by apply Qp_not_plus_q_ge_1 in Hv.
Qed. Qed.
Lemma loc_token_exclusive l :
loc_token l -∗ loc_token l -∗ False.
Proof.
iIntros "Hl1 Hl2".
iDestruct "Hl1" as (γ1) "[Hm1 Ht1]".
iDestruct "Hl2" as (γ2) "[Hm2 Ht2]".
iDestruct (meta_agree with "Hm1 Hm2") as %->.
iDestruct (own_valid_2 with "Ht1 Ht2") as %Hcontra.
by inversion Hcontra.
Qed.
Lemma loc_token_alloc v :
{{{ True }}} ref v {{{ l, RET #l; l v loc_token l }}}.
Proof.
iIntros (Φ) "HT HΦ". iApply wp_fupd.
wp_apply (wp_alloc with "HT"). iIntros (l_new) "[Hl_new Hm_new]".
iMod (own_alloc (Excl ())) as (γ_l) "Htok"; first done.
iMod ((meta_set _ _ γ_l N) with "Hm_new") as "Hm"; first done.
iApply "HΦ". iFrame "Hl_new". iExists _. by iFrame.
Qed.
(** Once a [state] protocol is [done] (as reflected by the [γ_s] token here), (** Once a [state] protocol is [done] (as reflected by the [γ_s] token here),
we can at any later point in time extract the [Q]. *) we can at any later point in time extract the [Q]. *)
Lemma state_done_extract_Q P Q p m c_l l l_ghost γ_n γ_t γ_s : Lemma state_done_extract_Q P Q p m c_l l l_ghost γ_n γ_t γ_s :
...@@ -310,11 +286,10 @@ Section conditional_counter. ...@@ -310,11 +286,10 @@ Section conditional_counter.
((own_token γ_t ={}=∗ Q) -∗ Φ #()) -∗ ((own_token γ_t ={}=∗ Q) -∗ Φ #()) -∗
own γ_n ( Excl' n) -∗ own γ_n ( Excl' n) -∗
l_new InjLV #n -∗ l_new InjLV #n -∗
loc_token l_new -∗
WP Resolve (CAS #c_l #l #l_new) #p #l_ghost ;; #() {{ v, Φ v }}. WP Resolve (CAS #c_l #l #l_new) #p #l_ghost ;; #() {{ v, Φ v }}.
Proof. Proof.
iIntros "#InvC #InvS PAU Hl_ghost HQ Hn● Hlntok Hl_new". wp_bind (Resolve _ _ _)%E. iIntros "#InvC #InvS PAU Hl_ghost HQ Hn● [Hl_new Hl_new']". wp_bind (Resolve _ _ _)%E.
iInv counterN as (b' l' q s) "(>Hf & >Hc & >Hl' & Hb● & Hltok & Hrest)". iInv counterN as (b' l' q s) "(>Hf & >Hc & >[Hl Hl'] & Hb● & Hrest)".
iInv stateN as (vs) "(>Hp & [NotDone | Done])"; last first. iInv stateN as (vs) "(>Hp & [NotDone | Done])"; last first.
{ (* We cannot be [done] yet, as we own the "ghost location" that serves { (* We cannot be [done] yet, as we own the "ghost location" that serves
as token for that transition. *) as token for that transition. *)
...@@ -342,10 +317,10 @@ Section conditional_counter. ...@@ -342,10 +317,10 @@ Section conditional_counter.
iMod (own_update with "Hs") as "Hs". iMod (own_update with "Hs") as "Hs".
{ apply (cmra_update_exclusive (Cinr (to_agree ()))). done. } { apply (cmra_update_exclusive (Cinr (to_agree ()))). done. }
iDestruct "Hs" as "#Hs'". iModIntro. iDestruct "Hs" as "#Hs'". iModIntro.
iSplitL "Hl_ghost_inv Hl_ghost Q Hltok Hp'". iSplitL "Hl_ghost_inv Hl_ghost Q Hp' Hl".
(* Update state to Done. *) (* Update state to Done. *)
{ iNext. iExists _. iFrame "Hp'". iRight. unfold done_state. { iNext. iExists _. iFrame "Hp'". iRight. unfold done_state.
iFrame "#∗". iExists _. done. } iFrame "#∗". iSplitR "Hl"; iExists _; done. }
iModIntro. iSplitR "HQ". iModIntro. iSplitR "HQ".
{ iNext. iDestruct "Hc" as "[Hc1 Hc2]". { iNext. iDestruct "Hc" as "[Hc1 Hc2]".
iExists _, l_new, _, (injl n). iFrame. } iExists _, l_new, _, (injl n). iFrame. }
...@@ -364,7 +339,7 @@ Section conditional_counter. ...@@ -364,7 +339,7 @@ Section conditional_counter.
WP Resolve (CAS #c_l #l #l_new) #p #l_ghost ;; #() {{ v, Φ v }}. WP Resolve (CAS #c_l #l #l_new) #p #l_ghost ;; #() {{ v, Φ v }}.
Proof. Proof.
iIntros (Hnl) "#InvC #InvS PAU HQ Hl_new". wp_bind (Resolve _ _ _)%E. iIntros (Hnl) "#InvC #InvS PAU HQ Hl_new". wp_bind (Resolve _ _ _)%E.
iInv counterN as (b' l' q s) "(>Hf & >Hc & >Hl' & >Hb● & >Hltok & Hrest)". iInv counterN as (b' l' q s) "(>Hf & >Hc & >[Hl Hl'] & >Hb● & Hrest)".
iInv stateN as (vs) "(>Hp & [NotDone | [#Hs Done]])". iInv stateN as (vs) "(>Hp & [NotDone | [#Hs Done]])".
{ (* If the [state] protocol is not done yet, we can show that it { (* If the [state] protocol is not done yet, we can show that it
is the active protocol still (l = l'). But then the CAS would is the active protocol still (l = l'). But then the CAS would
...@@ -381,15 +356,17 @@ Section conditional_counter. ...@@ -381,15 +356,17 @@ Section conditional_counter.
(* It must be that l' ≠ l because we are in the failing thread. *) (* It must be that l' ≠ l because we are in the failing thread. *)
destruct (decide (l' = l)) as [->|Hn]. { destruct (decide (l' = l)) as [->|Hn]. {
(* The [state] protocol is [done] while still being the active protocol (* The [state] protocol is [done] while still being the active protocol
of the [counter]? Impossible, we got the location token for that! *) of the [counter]? Impossible, now we will own more than the whole location! *)
iDestruct "Done" as "(_ & _ & >Hltok')". iDestruct "Done" as "(_ & _ & >Hl'')".
iDestruct (loc_token_exclusive with "Hltok Hltok'") as "[]". iDestruct "Hl''" as (v') "Hl''".
iDestruct (mapsto_combine with "Hl Hl''") as "[Hl _]".
rewrite Qp_half_half. iDestruct (mapsto_valid_3 with "Hl Hl'") as "[]".
} }
(* The CAS fails. *) (* The CAS fails. *)
wp_apply (wp_resolve with "Hp"); first done. wp_cas_fail. wp_apply (wp_resolve with "Hp"); first done. wp_cas_fail.
iIntros (vs' ->) "Hp". iModIntro. iIntros (vs' ->) "Hp". iModIntro.
iSplitL "Done Hp". { iNext. iExists _. iFrame "#∗". } iModIntro. iSplitL "Done Hp". { iNext. iExists _. iFrame "#∗". } iModIntro.
iSplitL "Hf Hc Hb● Hrest Hl' Hltok". { eauto 10 with iFrame. } iSplitL "Hf Hc Hb● Hrest Hl Hl'". { eauto 10 with iFrame. }
wp_seq. iApply "HQ". wp_seq. iApply "HQ".
iApply state_done_extract_Q; done. iApply state_done_extract_Q; done.
Qed. Qed.
...@@ -411,7 +388,7 @@ Section conditional_counter. ...@@ -411,7 +388,7 @@ Section conditional_counter.
iModIntro. iIntros (Φ) "_ HQ". wp_lam. wp_pures. iModIntro. iIntros (Φ) "_ HQ". wp_lam. wp_pures.
wp_alloc l_ghost as "[Hl_ghost' Hl_ghost'2]". wp_bind (! _)%E. simpl. wp_alloc l_ghost as "[Hl_ghost' Hl_ghost'2]". wp_bind (! _)%E. simpl.
(* open outer invariant to read `f` *) (* open outer invariant to read `f` *)
iInv counterN as (b' l' q s) "(>Hf & >Hc & >Hl' & >Hb● & >Hltok & Hrest)". iInv counterN as (b' l' q s) "(>Hf & >Hc & >Hl' & >Hb● & Hrest)".
wp_load. wp_load.
(* two different proofs depending on whether we are succeeding thread *) (* two different proofs depending on whether we are succeeding thread *)
destruct (decide (l_ghost_inv = l_ghost)) as [-> | Hnl]. destruct (decide (l_ghost_inv = l_ghost)) as [-> | Hnl].
...@@ -438,10 +415,9 @@ Section conditional_counter. ...@@ -438,10 +415,9 @@ Section conditional_counter.
iModIntro. iSplitR "Hl_ghost'2 HQ Hn●". iModIntro. iSplitR "Hl_ghost'2 HQ Hn●".
{ eauto 12 with iFrame. } { eauto 12 with iFrame. }
destruct b2; wp_if; [ wp_op | .. ]; destruct b2; wp_if; [ wp_op | .. ];
wp_apply (loc_token_alloc with "[//]"); iIntros (l_new) "[Hl_new Hm_new]"; wp_alloc l_new as "Hl_new"; wp_pures;
wp_pures;
iApply (complete_succeeding_thread_pending iApply (complete_succeeding_thread_pending
with "InvC InvS PAU Hl_ghost'2 HQ Hn● Hl_new Hm_new"). with "InvC InvS PAU Hl_ghost'2 HQ Hn● Hl_new").
+ (* Accepted: contradiction *) + (* Accepted: contradiction *)
iDestruct "Accepted" as "[>Hl_ghost_inv _]". iDestruct "Accepted" as "[>Hl_ghost_inv _]".
iDestruct "Hl_ghost_inv" as (v) "Hlghost". iDestruct "Hl_ghost_inv" as (v) "Hlghost".
...@@ -455,7 +431,7 @@ Section conditional_counter. ...@@ -455,7 +431,7 @@ Section conditional_counter.
- (* we are the failing thread *) - (* we are the failing thread *)
(* close invariant *) (* close invariant *)
iModIntro. iModIntro.
iSplitL "Hf Hc Hrest Hl' Hb● Hltok". { eauto 10 with iFrame. } iSplitL "Hf Hc Hrest Hl' Hb●". { eauto 10 with iFrame. }
(* two equal proofs depending on value of b1 *) (* two equal proofs depending on value of b1 *)
destruct b'; wp_if; [ wp_op | ..]; wp_alloc Hl_new as "Hl_new"; wp_pures; destruct b'; wp_if; [ wp_op | ..]; wp_alloc Hl_new as "Hl_new"; wp_pures;
iApply (complete_failing_thread iApply (complete_failing_thread
...@@ -473,22 +449,22 @@ Section conditional_counter. ...@@ -473,22 +449,22 @@ Section conditional_counter.
iIntros "#InvC". iDestruct "InvC" as (γ_b γ_n f_l c_l) "[Heq InvC]". iIntros "#InvC". iDestruct "InvC" as (γ_b γ_n f_l c_l) "[Heq InvC]".
iDestruct "Heq" as %[-> ->]. iIntros (Φ) "AU". iLöb as "IH". iDestruct "Heq" as %[-> ->]. iIntros (Φ) "AU". iLöb as "IH".
wp_lam. wp_proj. wp_let. wp_proj. wp_let. wp_bind (!_)%E. wp_lam. wp_proj. wp_let. wp_proj. wp_let. wp_bind (!_)%E.
iInv counterN as (b' l' q s) "(>Hf & >Hc & >[Hl Hl'] & >Hb● & >Hltok & Hrest)". iInv counterN as (b' l' q s) "(>Hf & >Hc & >[Hl [Hl' Hl'']] & >Hb● & Hrest)".
wp_load. destruct s as [n|n p]. wp_load. destruct s as [n|n p].
- iDestruct "Hrest" as "(Hc' & Hv)". - iDestruct "Hrest" as "(Hc' & Hv)".
iModIntro. iSplitR "AU Hl". iModIntro. iSplitR "AU Hl'".
{ iModIntro. iExists _, _, (q/2)%Qp, (injl n). iFrame. } { iModIntro. iExists _, _, (q/2)%Qp, (injl n). iFrame. }
wp_let. wp_load. wp_match. wp_apply wp_new_proph; first done. wp_let. wp_load. wp_match. wp_apply wp_new_proph; first done.
iIntros (l_ghost p') "Hp'". iIntros (l_ghost p') "Hp'".
wp_let. wp_apply (loc_token_alloc with "[//]"); iIntros (ly) "[Hly Hmy]". wp_let. wp_alloc ly as "Hly".
wp_let. wp_bind (CAS _ _ _)%E. wp_let. wp_bind (CAS _ _ _)%E.
(* open outer invariant again to CAS c_l *) (* open outer invariant again to CAS c_l *)
iInv counterN as (b2 l'' q2 s) "(>Hf & >Hc & >Hl' & >Hb● & >Hltok & Hrest)". iInv counterN as (b2 l'' q2 s) "(>Hf & >Hc & >Hl & >Hb● & Hrest)".
destruct (decide (l' = l'')) as [<- | Hn]. destruct (decide (l' = l'')) as [<- | Hn].
+ (* CAS succeeds *) + (* CAS succeeds *)
iDestruct (mapsto_agree with "Hl Hl'") as %<-%state_to_val_inj. iDestruct (mapsto_agree with "Hl' Hl") as %<-%state_to_val_inj.
iDestruct "Hrest" as ">[Hc' Hn●]". iCombine "Hc Hc'" as "Hc". iDestruct "Hrest" as ">[Hc' Hn●]". iCombine "Hc Hc'" as "Hc".
wp_cas_suc. iClear "Hltok". wp_cas_suc.
(* Initialize new [state] protocol .*) (* Initialize new [state] protocol .*)
iDestruct (laterable with "AU") as (AU_later) "[AU #AU_back]". iDestruct (laterable with "AU") as (AU_later) "[AU #AU_back]".
iMod (own_alloc (Excl ())) as (γ_t) "Token"; first done. iMod (own_alloc (Excl ())) as (γ_t) "Token"; first done.
...@@ -528,7 +504,7 @@ Section conditional_counter. ...@@ -528,7 +504,7 @@ Section conditional_counter.
{{{ ctr γs, RET ctr ; is_counter γs ctr counter_content γs true 0 }}}. {{{ ctr γs, RET ctr ; is_counter γs ctr counter_content γs true 0 }}}.
Proof. Proof.
iIntros (Φ) "_ HΦ". wp_lam. wp_apply wp_fupd. iIntros (Φ) "_ HΦ". wp_lam. wp_apply wp_fupd.
wp_apply (loc_token_alloc with "[//]"); iIntros (l_n) "[Hl_n Hltok]". wp_alloc l_n as "Hl_n".
wp_alloc l_c as "Hl_c". wp_let. wp_alloc l_c as "Hl_c". wp_let.
wp_alloc l_f as "Hl_f". wp_let. wp_pair. wp_alloc l_f as "Hl_f". wp_let. wp_pair.
iMod (own_alloc ( Excl' true Excl' true)) as (γ_b) "[Hb● Hb◯]". iMod (own_alloc ( Excl' true Excl' true)) as (γ_b) "[Hb● Hb◯]".
...@@ -536,9 +512,10 @@ Section conditional_counter. ...@@ -536,9 +512,10 @@ Section conditional_counter.
iMod (own_alloc ( Excl' 0 Excl' 0)) as (γ_n) "[Hn● Hn◯]". iMod (own_alloc ( Excl' 0 Excl' 0)) as (γ_n) "[Hn● Hn◯]".
{ by apply auth_both_valid. } { by apply auth_both_valid. }
iMod (inv_alloc counterN _ (counter_inv γ_b γ_n l_f l_c) iMod (inv_alloc counterN _ (counter_inv γ_b γ_n l_f l_c)
with "[Hl_f Hl_c Hl_n Hltok Hb● Hn●]") as "#InvC". with "[Hl_f Hl_c Hl_n Hb● Hn●]") as "#InvC".
{ iNext. iDestruct "Hl_c" as "[Hl_c1 Hl_c2]". { iNext. iDestruct "Hl_c" as "[Hl_c1 Hl_c2]".
iExists true, l_n, _, (injl 0). iFrame. } iDestruct "Hl_n" as "[??]".
iExists true, l_n, (1/2)%Qp, (injl 0). iFrame. }
iModIntro. iModIntro.
iApply ("HΦ" $! (#l_f, #l_c)%V (γ_b, γ_n)). iApply ("HΦ" $! (#l_f, #l_c)%V (γ_b, γ_n)).
iSplitR; last by iFrame. iExists γ_b, γ_n, l_f, l_c. iSplit; done. iSplitR; last by iFrame. iExists γ_b, γ_n, l_f, l_c. iSplit; done.
...@@ -552,7 +529,7 @@ Section conditional_counter. ...@@ -552,7 +529,7 @@ Section conditional_counter.
Proof. Proof.
iIntros "#InvC" (Φ) "AU". iDestruct "InvC" as (γ_b γ_n f_l c_l) "[Heq InvC]". iIntros "#InvC" (Φ) "AU". iDestruct "InvC" as (γ_b γ_n f_l c_l) "[Heq InvC]".
iDestruct "Heq" as %[-> ->]. wp_lam. wp_let. wp_proj. iDestruct "Heq" as %[-> ->]. wp_lam. wp_let. wp_proj.
iInv counterN as (b c q s) "(>Hf & >Hc & >[Hl Hl'] & >Hb● & >Hltok & Hrest)". iInv counterN as (b c q s) "(>Hf & >Hc & >[Hl Hl'] & >Hb● & Hrest)".
iMod "AU" as (b' n') "[[Hb◯ Hn◯] [_ Hclose]]"; simpl. iMod "AU" as (b' n') "[[Hb◯ Hn◯] [_ Hclose]]"; simpl.
wp_store. wp_store.
iDestruct (sync_flag_values with "Hb● Hb◯") as %HEq; subst b. iDestruct (sync_flag_values with "Hb● Hb◯") as %HEq; subst b.
...@@ -570,7 +547,7 @@ Section conditional_counter. ...@@ -570,7 +547,7 @@ Section conditional_counter.
Proof. Proof.
iIntros "#InvC" (Φ) "AU". iDestruct "InvC" as (γ_b γ_n f_l c_l) "[Heq InvC]". iIntros "#InvC" (Φ) "AU". iDestruct "InvC" as (γ_b γ_n f_l c_l) "[Heq InvC]".
iDestruct "Heq" as %[-> ->]. iLöb as "IH". wp_lam. repeat (wp_proj; wp_let). wp_bind (! _)%E. iDestruct "Heq" as %[-> ->]. iLöb as "IH". wp_lam. repeat (wp_proj; wp_let). wp_bind (! _)%E.
iInv counterN as (b c q s) "(>Hf & >Hc & >[Hl Hl'] & >Hb● & >Hltok & Hrest)". iInv counterN as (b c q s) "(>Hf & >Hc & >[Hl [Hl' Hl'']] & >Hb● & Hrest)".
wp_load. wp_load.
destruct s as [n|n p]. destruct s as [n|n p].
- iMod "AU" as (au_b au_n) "[[Hb◯ Hn◯] [_ Hclose]]"; simpl. - iMod "AU" as (au_b au_n) "[[Hb◯ Hn◯] [_ Hclose]]"; simpl.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment