Skip to content
Snippets Groups Projects
Commit eb7e35d1 authored by Jonas Kastberg Hinrichsen's avatar Jonas Kastberg Hinrichsen
Browse files

Updated specs to logical atomicity.

Generalized buffer CMRA to work for any type.
parent 37857a80
No related branches found
No related tags found
No related merge requests found
...@@ -2,5 +2,6 @@ ...@@ -2,5 +2,6 @@
-arg -w -arg -notation-overridden,-redundant-canonical-projection,-several-object-files -arg -w -arg -notation-overridden,-redundant-canonical-projection,-several-object-files
theories/list.v theories/list.v
theories/buffer.v theories/buffer.v
theories/auth_excl.v
theories/channel.v theories/channel.v
...@@ -4,53 +4,51 @@ From iris.algebra Require Import excl auth. ...@@ -4,53 +4,51 @@ From iris.algebra Require Import excl auth.
From iris.base_logic.lib Require Import auth. From iris.base_logic.lib Require Import auth.
Set Default Proof Using "Type". Set Default Proof Using "Type".
(* Buffer CMRA *) Definition exclUR (A : Type) : ucmraT :=
Definition buff_type := list val. optionUR (exclR (leibnizC A)).
Definition buffUR : ucmraT := Class auth_exclG (A : Type) (Σ :gFunctors) :=
optionUR (exclR (leibnizC (buff_type))). AuthExclG {
exclG_authG :> authG Σ (exclUR A);
}.
Definition to_buff (b : buff_type) : buffUR := Definition auth_exclΣ (A : Type) : gFunctors :=
Excl' (b: leibnizC buff_type). #[GFunctor (authR (exclUR A))].
Class buffG (Σ :gFunctors) := BuffG { Instance subG_auth_exclG (A : Type) {Σ} :
buffG_authG :> authG Σ buffUR; subG (auth_exclΣ A) Σ (auth_exclG A) Σ.
}.
Definition buffΣ : gFunctors :=
#[GFunctor (authR buffUR)].
Instance subG_buffG {Σ} :
subG buffΣ Σ buffG Σ.
Proof. solve_inG. Qed. Proof. solve_inG. Qed.
Section buff. Definition to_auth_excl {A : Type} (a : A) : exclUR A :=
Context `{!buffG Σ} (N : namespace). Excl' (a: leibnizC A).
Section auth_excl.
Context `{!auth_exclG A Σ} (N : namespace).
Lemma excl_eq γ x y : Lemma excl_eq γ x y :
own γ ( to_buff y) -∗ own γ ( to_buff x) -∗ x = y⌝%I. own γ ( to_auth_excl y) -∗ own γ ( to_auth_excl x) -∗ x = y⌝%I.
Proof. Proof.
iIntros "Hauth Hfrag". iIntros "Hauth Hfrag".
iDestruct (own_valid_2 with "Hauth Hfrag") as %Hvalid. iDestruct (own_valid_2 with "Hauth Hfrag") as %Hvalid.
apply auth_valid_discrete_2 in Hvalid. apply auth_valid_discrete_2 in Hvalid.
destruct Hvalid as [Hincl _]. destruct Hvalid as [Hincl _].
apply Excl_included in Hincl. apply Excl_included in Hincl.
unfold to_buff. unfold to_auth_excl.
rewrite Hincl. rewrite Hincl.
iFrame. iFrame.
eauto. eauto.
Qed. Qed.
Lemma excl_update γ x y z : Lemma excl_update γ x y z :
own γ ( to_buff y) -∗ own γ ( to_buff x) -∗ |==> own γ ( to_buff z) own γ ( to_buff z). own γ ( to_auth_excl y) -∗ own γ ( to_auth_excl x) -∗ |==> own γ ( to_auth_excl z) own γ ( to_auth_excl z).
Proof. Proof.
iIntros "Hauth Hfrag". iIntros "Hauth Hfrag".
iDestruct (own_update_2 with "Hauth Hfrag") as "H". iDestruct (own_update_2 with "Hauth Hfrag") as "H".
{ eapply (auth_update _ _ (to_buff z) (to_buff z)). { eapply (auth_update _ _ (to_auth_excl z) (to_auth_excl z)).
eapply option_local_update. eapply option_local_update.
eapply exclusive_local_update. done. } eapply exclusive_local_update. done. }
rewrite own_op. rewrite own_op.
done. done.
Qed. Qed.
End buff. End auth_excl.
...@@ -7,10 +7,9 @@ From iris.base_logic.lib Require Import auth. ...@@ -7,10 +7,9 @@ From iris.base_logic.lib Require Import auth.
From iris.heap_lang.lib Require Import lock. From iris.heap_lang.lib Require Import lock.
From iris.heap_lang.lib Require Import spin_lock. From iris.heap_lang.lib Require Import spin_lock.
From osiris Require Import list. From osiris Require Import list.
From osiris Require Import buffer. From osiris Require Import auth_excl.
Set Default Proof Using "Type". Set Default Proof Using "Type".
Definition new_list : val := Definition new_list : val :=
λ: <>, lnil #(). λ: <>, lnil #().
...@@ -61,7 +60,7 @@ Definition recv : val := ...@@ -61,7 +60,7 @@ Definition recv : val :=
end. end.
Section channel. Section channel.
Context `{!heapG Σ, !lockG Σ, !buffG Σ} (N : namespace). Context `{!heapG Σ, !lockG Σ, !auth_exclG (list val) Σ} (N : namespace).
Definition is_list_ref (l : val) (xs : list val) : iProp Σ := Definition is_list_ref (l : val) (xs : list val) : iProp Σ :=
( l':loc, hd : val, l = #l' l' hd is_list hd xs)%I. ( l':loc, hd : val, l = #l' l' hd is_list hd xs)%I.
...@@ -69,275 +68,208 @@ Section channel. ...@@ -69,275 +68,208 @@ Section channel.
Definition is_side (s : val) : Prop := Definition is_side (s : val) : Prop :=
s = left s = right. s = left s = right.
Definition is_chan (lkγ lsγ rsγ : gname) (c : val) (ls rs : list val) : iProp Σ := Record chan_name := Chan_name {
( l r lk : val, c = ((l, r), lk)%V chan_lock_name : gname;
own lsγ ( to_buff ls) own rsγ ( to_buff rs) chan_l_name : gname;
is_lock N lkγ lk chan_r_name : gname
( ls rs, }.
is_list_ref l ls own lsγ ( to_buff ls)
is_list_ref r rs own rsγ ( to_buff rs)))%I. Definition chan_ctx (γ : chan_name) (c : val) : iProp Σ :=
( l r lk : val,
c = ((l, r), lk)%V
is_lock N (chan_lock_name γ) lk ( ls rs,
is_list_ref l ls own (chan_l_name γ) ( to_auth_excl ls)
is_list_ref r rs own (chan_r_name γ) ( to_auth_excl rs)))%I.
Definition is_chan (γ : chan_name) (c : val) (ls rs : list val) : iProp Σ :=
( l r lk : val,
c = ((l, r), lk)%V
own (chan_l_name γ) ( to_auth_excl ls) own (chan_r_name γ) ( to_auth_excl rs))%I.
Lemma new_chan_spec : Lemma new_chan_spec :
{{{ True }}} {{{ True }}}
new_chan #() new_chan #()
{{{ c lkγ lsγ rsγ, RET c; is_chan lkγ lsγ rsγ c [] [] }}}. {{{ c γ, RET c; is_chan γ c [] [] chan_ctx γ c }}}.
Proof. Proof.
iIntros (Φ) "_ HΦ". rewrite -wp_fupd /newlock /new_list /=. iIntros (Φ) "_ HΦ". rewrite /is_chan /chan_ctx /is_lock.
repeat wp_lam. wp_alloc lk as "Hlk". repeat wp_lam. wp_alloc lk as "Hlk".
iMod (own_alloc (Excl ())) as (lkγ) "Hγlk"; first done.
repeat wp_lam. wp_alloc r as "Hr". repeat wp_lam. wp_alloc r as "Hr".
iMod (own_alloc (Auth (Excl' (to_auth_excl [])) (to_auth_excl []))) as (lsγ) "Hls"; first done.
repeat wp_lam. wp_alloc l as "Hl". repeat wp_lam. wp_alloc l as "Hl".
wp_pures. iMod (own_alloc (Auth (Excl' (to_auth_excl [])) (to_auth_excl []))) as (rsγ) "Hrs"; first done.
iMod (own_alloc (Excl ())) as (lkγ) "Hγlk"; first done. rewrite auth_both_op own_op own_op.
iMod (own_alloc (Auth (Excl' (to_buff [])) (to_buff []))) as (lsγ) "Hls"; first done. pose (Chan_name lkγ lsγ rsγ).
iMod (own_alloc (Auth (Excl' (to_buff [])) (to_buff []))) as (rsγ) "Hrs"; first done.
rewrite auth_both_op.
rewrite own_op. rewrite own_op.
iDestruct "Hls" as "[Hlsa Hlsf]". iDestruct "Hls" as "[Hlsa Hlsf]".
iDestruct "Hrs" as "[Hrsa Hrsf]". iDestruct "Hrs" as "[Hrsa Hrsf]".
iMod (inv_alloc N _ (lock_inv lkγ lk ( (ls rs : list val), is_list_ref #l ls own lsγ ( to_buff ls) is_list_ref #r rs own rsγ ( to_buff rs)))%I with "[Hlk Hγlk Hr Hl Hlsa Hrsa]") as "Hlk". iMod (inv_alloc N _ (lock_inv lkγ lk ( (ls rs : list val), is_list_ref #l ls own lsγ ( to_auth_excl ls) is_list_ref #r rs own rsγ ( to_auth_excl rs)))%I with "[Hlk Hγlk Hr Hl Hlsa Hrsa]") as "Hlk".
{ {
iNext. iExists _. iFrame. iFrame. rewrite /is_list_ref /is_list /lock_inv.
iExists [], []. iFrame. iNext. iExists _.
iSplitL "Hlk"=> //=.
iSplitL "Hγlk"=> //=.
iExists _, _. iFrame.
iSplitL "Hl"=> //; iExists _, _; iSplit=> //; iFrame=> //. iSplitL "Hl"=> //; iExists _, _; iSplit=> //; iFrame=> //.
} }
iModIntro. wp_pures.
iApply "HΦ". iSpecialize ("HΦ" $!(#l, #r, #lk)%V c).
iExists _, _, _. iApply ("HΦ").
iFrame "Hlsf Hrsf". iSplitL "Hlsf Hrsf"=> //;
iSplit=> //. eauto 10 with iFrame.
unfold is_lock. iExists _. iSplit=> //.
Qed. Qed.
Definition send_upd lkγ lsγ rsγ c ls rs s v : iProp Σ := Definition send_upd γ c ls rs s v : iProp Σ :=
match s with match s with
| left => is_chan lkγ lsγ rsγ c (ls ++ [v]) rs | left => is_chan γ c (ls ++ [v]) rs
| right => is_chan lkγ lsγ rsγ c ls (rs ++ [v]) | right => is_chan γ c ls (rs ++ [v])
| _ => False⌝%I | _ => False⌝%I
end. end.
Lemma send_spec (lkγ lsγ rsγ : gname) (c v s : val) (ls rs : list val) : Lemma send_spec Φ E γ (c v s : val) :
{{{ is_chan lkγ lsγ rsγ c ls rs is_side s⌝%I }}} is_side s
send c s v chan_ctx γ c -∗
{{{ RET #(); send_upd lkγ lsγ rsγ c ls rs s v }}}. (|={,E}=> ls rs,
is_chan γ c ls rs
(send_upd γ c ls rs s v ={E,}=∗ Φ #())
) -∗
WP send c s v {{ Φ }}.
Proof. Proof.
iIntros (Φ) "[Hc #Hs] HΦ". iIntros (Hside) "Hc HΦ". wp_lam; wp_pures.
iRevert "Hs". iIntros (Hs). iDestruct "Hc" as (l r lk ->) "#Hlock"; wp_pures.
rewrite -wp_fupd /send /=. wp_apply (acquire_spec with "Hlock"); iIntros "[Hlocked Hinv]".
iDestruct "Hc" as (l r lk Hc) "[Hlsf [Hrsf #Hlk]]". iDestruct "Hinv" as (ls rs) "(Hl & Hls & Hr & Hrs)".
wp_lam. destruct Hside as [-> | ->].
wp_pures. - wp_pures. iDestruct "Hl" as (ll lhd ->) "(Hl & Hll)".
subst. wp_load. wp_apply (lsnoc_spec with "Hll").
wp_bind (Snd _). iIntros (hd') "Hll". wp_store. wp_pures.
wp_pures. iApply fupd_wp. iMod "HΦ" as (ls' rs') "[Hchan HΦ]".
wp_bind (acquire lk). iDestruct "Hchan" as (l' r' lk' [= <- <- <-]) "[Hls' Hrs']".
iApply acquire_spec=> //. iDestruct (excl_eq with "Hls Hls'") as %->.
iNext. iMod (excl_update _ _ _ (ls ++ [v]) with "Hls Hls'") as "[Hls Hls']".
iIntros "[Hlocked Hl]". iMod ("HΦ" with "[Hls' Hrs']") as "HΦ".
iDestruct "Hl" as (ls' rs') "[Hls [Hlsa [Hrs Hrsa]]]". { rewrite /= /is_chan. eauto with iFrame. }
iDestruct (excl_eq with "Hlsa Hlsf") as %Heqls. rewrite -(Heqls).
iDestruct (excl_eq with "Hrsa Hrsf") as %Heqrs. rewrite -(Heqrs).
wp_seq.
wp_pures.
inversion Hs.
- iDestruct "Hls" as (lb Hb bhd) "[Hl #Hbhd]".
iDestruct (excl_update _ _ _ (ls ++ [v]) with "Hlsa Hlsf") as ">[Hlsa Hlsf]".
subst.
wp_pures.
wp_bind (lsnoc (Load #lb) v).
wp_load.
iApply lsnoc_spec=> //.
iIntros (hd' Hhd').
iNext.
wp_store.
wp_pures.
eauto.
iApply (release_spec N lkγ lk with "[Hlocked Hl Hlsa Hrsa Hrs]") => //.
{
iFrame; eauto.
iSplitR. iApply "Hlk".
iFrame. iExists _, _. iFrame.
iExists _, _. iSplit=> //. iFrame. iPureIntro => //.
}
iModIntro.
iIntros (_).
iModIntro.
iApply "HΦ".
iExists _, _, _.
iSplitR=> //.
iSplitL "Hlsf"=> //.
iSplitL "Hrsf"=> //.
- iDestruct "Hrs" as (lb Hb bhd) "[Hr #Hbhd]".
iDestruct (excl_update _ _ _ (rs ++ [v]) with "Hrsa Hrsf") as ">[Hrsa Hrsf]".
subst.
wp_pures.
wp_bind (lsnoc (Load #lb) v).
wp_load.
iApply lsnoc_spec=> //.
iIntros (hd' Hhd').
iNext.
wp_store.
wp_pures.
eauto.
iApply (release_spec N lkγ lk with "[Hlocked Hr Hlsa Hrsa Hls]") => //.
{
iFrame; eauto.
iSplitR. iApply "Hlk".
iFrame. iExists _, _. iFrame.
iExists _, _. iSplit=> //. iFrame. iPureIntro => //.
}
iModIntro. iModIntro.
iIntros (_). wp_apply (release_spec with "[-HΦ $Hlock $Hlocked]").
{ rewrite /is_list_ref. eauto 10 with iFrame. }
iIntros "_ //".
- wp_pures. iDestruct "Hr" as (lr rhd ->) "(Hr & Hlr)".
wp_load. wp_apply (lsnoc_spec with "Hlr").
iIntros (hd') "Hlr". wp_store. wp_pures.
iApply fupd_wp. iMod "HΦ" as (ls' rs') "[Hchan HΦ]".
iDestruct "Hchan" as (l' r' lk' [= <- <- <-]) "[Hls' Hrs']".
iDestruct (excl_eq with "Hrs Hrs'") as %->.
iMod (excl_update _ _ _ (rs ++ [v]) with "Hrs Hrs'") as "[Hrs Hrs']".
iMod ("HΦ" with "[Hls' Hrs']") as "HΦ".
{ rewrite /= /is_chan. eauto with iFrame. }
iModIntro. iModIntro.
iApply "HΦ". wp_apply (release_spec with "[-HΦ $Hlock $Hlocked]").
iExists _, _, _. { rewrite /is_list_ref. eauto 10 with iFrame. }
iSplitR=> //. iIntros "_ //".
iSplitL "Hlsf"=> //.
iSplitL "Hrsf"=> //.
Qed. Qed.
Definition try_recv_upd lkγ lsγ rsγ c ls rs s v : iProp Σ := Definition try_recv_upd γ c ls rs s v : iProp Σ :=
match s with match s with
| left => match v with | left => match v with
| NONEV => (is_chan lkγ lsγ rsγ c ls rs rs = [])%I | NONEV => (is_chan γ c ls rs rs = [])%I
| SOMEV w => ( rs', is_chan lkγ lsγ rsγ c ls rs' rs = w::rs')%I | SOMEV w => ( rs', is_chan γ c ls rs' rs = w::rs')%I
| _ => False⌝%I | _ => False⌝%I
end end
| right => match v with | right => match v with
| NONEV => (is_chan lkγ lsγ rsγ c ls rs ls = [])%I | NONEV => (is_chan γ c ls rs ls = [])%I
| SOMEV w => ( ls', is_chan lkγ lsγ rsγ c ls' rs ls = w::ls')%I | SOMEV w => ( ls', is_chan γ c ls' rs ls = w::ls')%I
| _ => False⌝%I | _ => False⌝%I
end end
| _ => False⌝%I | _ => False⌝%I
end. end.
Lemma try_recv_spec ( lkγ lsγ rsγ : gname) (c v s : val) (ls rs : list val) : Lemma try_recv_spec Φ E γ (c v s : val) :
{{{ is_chan lkγ lsγ rsγ c ls rs is_side s⌝%I }}} is_side s
try_recv c s chan_ctx γ c -∗
{{{ v, RET v; try_recv_upd lkγ lsγ rsγ c ls rs s v }}}. (|={,E}=> ls rs,
is_chan γ c ls rs
( v, try_recv_upd γ c ls rs s v ={E,}=∗ Φ v)
) -∗
WP try_recv c s {{ Φ }}.
Proof. Proof.
iIntros (Φ) "[Hc #Hs] HΦ". iIntros (Hside) "Hc HΦ". wp_lam; wp_pures.
iRevert "Hs". iIntros (Hs). iDestruct "Hc" as (l r lk ->) "#Hlock"; wp_pures.
rewrite -wp_fupd /send /=. wp_apply (acquire_spec with "Hlock"); iIntros "[Hlocked Hinv]".
iDestruct "Hc" as (l r lk Hc) "[Hlsf [Hrsf #Hlk]]". iDestruct "Hinv" as (ls rs) "(Hls & Hlsa & Hrs & Hrsa)".
subst. destruct Hside as [-> | ->].
wp_lam. - iDestruct "Hrs" as (rl rhd ->) "[Hrs #Hrhd]".
wp_pures.
wp_bind (acquire _).
iApply acquire_spec=> //.
iNext.
iIntros "[Hlocked Hl]".
iDestruct "Hl" as (ls' rs') "[Hls [Hlsa [Hrs Hrsa]]]".
iDestruct (excl_eq with "Hlsa Hlsf") as %Heqls. rewrite -(Heqls).
iDestruct (excl_eq with "Hrsa Hrsf") as %Heqrs. rewrite -(Heqrs).
wp_seq.
wp_pures.
inversion Hs; subst.
- wp_pures.
iDestruct "Hrs" as (rl Hr rhd) "[Hrs #Hrhd]".
wp_pures.
subst.
wp_load. wp_load.
iRevert "Hrhd". iIntros (Hrhd). destruct rs.
unfold is_list in Hrhd. + iRevert "Hrhd". rewrite /is_list. iIntros (->).
destruct rs'.
+ subst.
wp_pures.
wp_bind (release _).
wp_pures.
iApply (release_spec N lkγ lk with "[Hlocked Hls Hrs Hlsa Hrsa]") => //.
{
iFrame; eauto.
iSplitR. iApply "Hlk".
iFrame. iExists _, _. iFrame.
iExists _, _. iFrame=> //.
}
iNext. iIntros (_).
wp_pures. wp_pures.
iApply fupd_wp.
iMod "HΦ" as (ls' rs') "[Hchan HΦ]".
iDestruct "Hchan" as (l' r' lk' [= <- <- <-]) "[Hlsf Hrsf]".
iDestruct (excl_eq with "Hlsa Hlsf") as %->.
iDestruct (excl_eq with "Hrsa Hrsf") as %->.
iSpecialize ("HΦ" $!(InjLV #())).
iMod ("HΦ" with "[Hlsf Hrsf]") as "HΦ".
{ rewrite /try_recv_upd /is_chan. eauto 10 with iFrame. }
iModIntro. iModIntro.
iApply "HΦ". wp_apply (release_spec with "[-HΦ $Hlocked $Hlock]").
iSplit=> //. { rewrite /is_list_ref /is_list. eauto 10 with iFrame. }
iExists _, _, _. iIntros (_).
iSplit=> //.
iFrame.
iApply "Hlk".
+ subst.
destruct Hrhd as [hd' [Hrhd Hrhd']].
subst.
wp_pures. wp_pures.
wp_store. wp_pures. by iApply "HΦ".
iDestruct (excl_update _ _ _ (rs') with "Hrsa Hrsf") as ">[Hrsa Hrsf]". + iRevert "Hrhd". rewrite /is_list. iIntros ([hd' [-> Hrhd']]).
wp_bind (release _).
wp_pures. wp_pures.
iApply (release_spec N lkγ lk with "[Hlocked Hls Hrs Hlsa Hrsa]") => //. iApply fupd_wp.
{ iMod "HΦ" as (ls' rs') "[Hchan HΦ]".
iFrame; eauto. iDestruct "Hchan" as (l' r' lk' [= <- <- <-]) "[Hlsf Hrsf]".
iSplitR. iApply "Hlk". iDestruct (excl_eq with "Hlsa Hlsf") as %->.
iFrame. iExists _, _. iFrame. iDestruct (excl_eq with "Hrsa Hrsf") as %->.
iExists _, _. iFrame=> //. iDestruct (excl_update _ _ _ (rs) with "Hrsa Hrsf") as ">[Hrsa Hrsf]".
} iSpecialize ("HΦ" $!(InjRV (v0))).
iNext. iIntros (_). iMod ("HΦ" with "[Hlsf Hrsf]") as "HΦ".
wp_pures. { rewrite /try_recv_upd /is_chan. eauto 10 with iFrame. }
iApply "HΦ".
iExists _.
iModIntro. iModIntro.
iSplit=> //. wp_store.
iExists _, _, _. wp_apply (release_spec with "[-HΦ $Hlocked $Hlock]").
iSplit=> //. { rewrite /is_list_ref /is_list. eauto 10 with iFrame. }
iFrame. iIntros (_).
iApply "Hlk".
- wp_pures.
iDestruct "Hls" as (ls Hl lhd) "[Hls #Hlhd]".
wp_pures.
subst.
wp_load.
iRevert "Hlhd". iIntros (Hlhd).
unfold is_list in Hlhd.
destruct ls'.
+ subst.
wp_pures.
wp_bind (release _).
wp_pures. wp_pures.
iApply (release_spec N lkγ lk with "[Hlocked Hls Hrs Hlsa Hrsa]") => //. by iApply "HΦ".
{ - iDestruct "Hls" as (ll lhd ->) "[Hls #Hlhd]".
iFrame; eauto. wp_load.
iSplitR. iApply "Hlk". destruct ls.
iFrame. iExists _, _. iFrame. + iRevert "Hlhd". rewrite /is_list. iIntros (->).
iExists _, _. iFrame=> //.
}
iNext. iIntros (_).
wp_pures. wp_pures.
iApply fupd_wp.
iMod "HΦ" as (ls' rs') "[Hchan HΦ]".
iDestruct "Hchan" as (l' r' lk' [= <- <- <-]) "[Hlsf Hrsf]".
iDestruct (excl_eq with "Hlsa Hlsf") as %->.
iDestruct (excl_eq with "Hrsa Hrsf") as %->.
iSpecialize ("HΦ" $!(InjLV #())).
iMod ("HΦ" with "[Hlsf Hrsf]") as "HΦ".
{ rewrite /try_recv_upd /is_chan. eauto 10 with iFrame. }
iModIntro. iModIntro.
iApply "HΦ". wp_apply (release_spec with "[-HΦ $Hlocked $Hlock]").
iSplit=> //. { rewrite /is_list_ref /is_list. eauto 10 with iFrame. }
iExists _, _, _. iIntros (_).
iSplit=> //.
iFrame.
iApply "Hlk".
+ subst.
destruct Hlhd as [hd' [Hlhd Hlhd']].
subst.
wp_pures. wp_pures.
wp_store. wp_pures. by iApply "HΦ".
iDestruct (excl_update _ _ _ (ls') with "Hlsa Hlsf") as ">[Hlsa Hlsf]". + iRevert "Hlhd". rewrite /is_list. iIntros ([hd' [-> Hlhd']]).
wp_bind (release _).
wp_pures. wp_pures.
iApply (release_spec N lkγ lk with "[Hlocked Hls Hrs Hlsa Hrsa]") => //. iApply fupd_wp.
{ iMod "HΦ" as (ls' rs') "[Hchan HΦ]".
iFrame; eauto. iDestruct "Hchan" as (l' r' lk' [= <- <- <-]) "[Hlsf Hrsf]".
iSplitR. iApply "Hlk". iDestruct (excl_eq with "Hlsa Hlsf") as %->.
iFrame. iExists _, _. iFrame. iDestruct (excl_eq with "Hrsa Hrsf") as %->.
iExists _, _. iFrame=> //. iDestruct (excl_update _ _ _ (ls) with "Hlsa Hlsf") as ">[Hlsa Hlsf]".
} iSpecialize ("HΦ" $!(InjRV (v0))).
iNext. iIntros (_). iMod ("HΦ" with "[Hlsf Hrsf]") as "HΦ".
wp_pures. { rewrite /try_recv_upd /is_chan. eauto 10 with iFrame. }
iApply "HΦ".
iExists _.
iModIntro. iModIntro.
iSplit=> //. wp_store.
iExists _, _, _. wp_apply (release_spec with "[-HΦ $Hlocked $Hlock]").
iSplit=> //. { rewrite /is_list_ref /is_list. eauto 10 with iFrame. }
iFrame. iIntros (_).
iApply "Hlk". wp_pures.
Qed. by iApply "HΦ".
Qed.
End channel. End channel.
\ No newline at end of file
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