From b6760d1c4c8e4f7eae69e6e2fce5bf2e7f5b2bf4 Mon Sep 17 00:00:00 2001 From: Hoang-Hai Dang <haidang@mpi-sws.org> Date: Wed, 6 Jun 2018 01:17:48 +0200 Subject: [PATCH] bump gpfsl and WIP rwlock code --- _CoqProject | 2 - opam | 2 +- theories/lang/spawn.v | 13 +- theories/typing/lib/rwlock/rwlock.v | 214 ++++++------------ theories/typing/lib/rwlock/rwlockreadguard.v | 9 +- .../typing/lib/rwlock/rwlockreadguard_code.v | 45 ++-- theories/typing/lib/rwlock/rwlockwriteguard.v | 15 +- 7 files changed, 115 insertions(+), 185 deletions(-) diff --git a/_CoqProject b/_CoqProject index 75aca45b..c03b2e2b 100644 --- a/_CoqProject +++ b/_CoqProject @@ -66,8 +66,6 @@ theories/typing/lib/refcell/ref.v theories/typing/lib/rwlock/rwlock.v theories/typing/lib/rwlock/rwlockreadguard.v theories/typing/lib/rwlock/rwlockwriteguard.v -theories/typing/lib/rwlock/rwlock_code.v -theories/typing/lib/rwlock/rwlockwriteguard_code.v theories/typing/examples/get_x.v theories/typing/examples/rebor.v theories/typing/examples/unbox.v diff --git a/opam b/opam index f11f39ad..96ec01e2 100644 --- a/opam +++ b/opam @@ -10,5 +10,5 @@ build: [make "-j%{jobs}%"] install: [make "install"] remove: [ "sh" "-c" "rm -rf '%{lib}%/coq/user-contrib/lrust'" ] depends: [ - "coq-gpfsl" { (= "dev.2018-06-04.0.f12ff24c") | (= "dev") } + "coq-gpfsl" { (= "dev.2018-06-05.0.a660e9c0") | (= "dev") } ] diff --git a/theories/lang/spawn.v b/theories/lang/spawn.v index 5a3db296..1b51e66b 100644 --- a/theories/lang/spawn.v +++ b/theories/lang/spawn.v @@ -61,7 +61,8 @@ Definition spawn_interp γe γf Ψ : interpC Σ unitProtocol := (* Accessor content for the GPS invariant *) Definition spawn_inv γc γe γf γj c Ψ := - (tok γf ∗ tok γj ∨ (∃ V, GPS_INV (spawn_interp γe γf Ψ) c γc V))%I. + (tok γf ∗ tok γj + ∨ (∃ V, GPS_INV (spawn_interp γe γf Ψ) c (λ _ _ _, True : Prop) γc V))%I. Definition finish_handle γc γe c Ψ : vProp := (∃ γf γj v, (c >> 1) ↦ v ∗ GPS_SWRawWriter c () #0 γc @@ -111,7 +112,7 @@ Proof. iMod (own_alloc (Excl ())) as (γe) "Hγe"; first done. rewrite own_loc_na_vec_cons own_loc_na_vec_singleton. iDestruct "Hl" as "[Hc Hd]". wp_write. - iMod (GPS_SWRaw_Init_vs (spawn_interp γe γf Ψ) _ false _ () with "Hc []") + iMod (GPS_SWRaw_Init_vs (spawn_interp γe γf Ψ) _ _ false _ () with "Hc []") as (γc) "[SW gpsI]". { iIntros (?). rewrite /spawn_interp /=. by iSplit; iExists false. } iDestruct (GPS_SWRawWriter_RawReader with "SW") as "#R". simpl. @@ -138,8 +139,8 @@ Proof. auto. } iDestruct "Hinv" as (Vb) "HInv". iApply (GPS_SWRawWriter_rel_write (spawn_interp γe γf Ψ) - _ True%I () () _ #1 _ _ Vb - with "[$SW HInv Hf HΨ Hd]"); [done|solve_ndisj|..]. + _ (λ _ _ _, True : Prop) True%I () () _ #1 _ _ Vb + with "[$SW HInv Hf HΨ Hd]"); [done|solve_ndisj|done|..]. { iSplitL "HInv". - iIntros "mb". iNext. by iApply (monPred_in_elim with "mb HInv"). - iNext. iIntros "_ SW". iSplitL ""; [done|]. @@ -163,7 +164,7 @@ Proof. { iExFalso. iCombine "Hj" "Hj'" as "Hj". iDestruct (own_valid with "Hj") as "%". auto. } iDestruct "Hinv" as (Vb) "HInv". - iApply (GPS_SWRawReader_read (spawn_interp γe γf Ψ') _ _ () _ _ _ Vb + iApply (GPS_SWRawReader_read (spawn_interp γe γf Ψ') _ _ _ () _ _ _ Vb with "[$R HInv]"); [solve_ndisj|by right|..]. { iSplitL "HInv". - iIntros "mb". iNext. by iApply (monPred_in_elim with "mb HInv"). @@ -181,7 +182,7 @@ Proof. iMod ("Hclose" with "[Hj Hf]") as "_". { iNext. iLeft. iFrame. } iModIntro. wp_if. wp_op. wp_read. wp_let. iApply (wp_hist_inv); [done|]. iIntros "Hist". - iMod (GPS_SWRawWriter_dealloc _ _ true with "Hist HInv SW") as "[Hc _]"; + iMod (GPS_SWRawWriter_dealloc _ _ _ true with "Hist HInv SW") as "[Hc _]"; [done|]. iAssert (c ↦∗ [ #1 ; v])%I with "[Hc Hd]" as "Hc". { rewrite own_loc_na_vec_cons own_loc_na_vec_singleton. iFrame. } diff --git a/theories/typing/lib/rwlock/rwlock.v b/theories/typing/lib/rwlock/rwlock.v index d36f06a2..462e7ed3 100644 --- a/theories/typing/lib/rwlock/rwlock.v +++ b/theories/typing/lib/rwlock/rwlock.v @@ -10,18 +10,13 @@ Definition rwlock_st := option (() + lft * frac * positive). Definition rwlock_stR := optionUR (csumR (exclR unitC) (prodR (prodR (agreeR lftC) fracR) positiveR)). -Definition rwlock_stAgreeR := - optionUR (prodR (exclR unitC) (agreeR (leibnizC rwlock_st))). -Definition rwlockR := - prodR (authR rwlock_stR) (authR rwlock_stAgreeR). +Definition rwlockR := authR rwlock_stR. Class rwlockG Σ := RwLockG { rwlock_stateG :> inG Σ rwlockR ; rwlock_gpsG :> gpsG Σ unitProtocol; - rwlock_gpsExAgG :> gpsExAgG Σ; }. -Definition rwlockΣ : gFunctors := - #[GFunctor rwlockR; gpsΣ unitProtocol; GFunctor (agreeR (leibnizC Qp))]. +Definition rwlockΣ : gFunctors := #[GFunctor rwlockR; gpsΣ unitProtocol]. Instance subG_rwlockΣ {Σ} : subG rwlockΣ Σ → rwlockG Σ. Proof. solve_inG. Qed. @@ -42,12 +37,9 @@ Definition Z_of_rwlock_st (st : rwlock_st) : Z := Definition rwlockN := lrustN .@ "rwlock". Notation rwown γs st := (⎡ own γs (st : rwlockR) ⎤ : vProp _)%I. -Notation st_agree st := (Some (Excl (), to_agree st)). -Notation st_full st := (● rwlock_to_st st ⋅ ◯ rwlock_to_st st, - ● st_agree st ⋅ ◯ st_agree st). -Notation st_global st:= (● rwlock_to_st st, - ● st_agree st ⋅ ◯ st_agree st). -Notation st_local st := (◯ (rwlock_to_st st), ε). +Notation st_full st := (● rwlock_to_st st ⋅ ◯ rwlock_to_st st). +Notation st_global st:= (● rwlock_to_st st). +Notation st_local st := (◯ rwlock_to_st st). Section rwlock_inv. Context `{typeG Σ, rwlockG Σ}. @@ -56,78 +48,28 @@ Section rwlock_inv. (* Cmra operations *) Definition reading_st (q : frac) (ν : lft) : rwlockR := st_local (Some $ inr (ν, q, xH)). - Definition writing_st : rwlockR := st_local (Some $ inl ()). - Definition main_st (st: rwlock_st): rwlockR := (● rwlock_to_st st, ● st_agree st). - Definition sub_st (st: rwlock_st) : rwlockR := (ε, ◯ st_agree st). - - Lemma rwown_main_sub_agree st1 st2 γs : - rwown γs (main_st st1) -∗ rwown γs (sub_st st2) -∗ ⌜st1 = st2⌝. - Proof. - iIntros "m s". iCombine "m" "s" as "ms". - rewrite pair_op right_id. - iDestruct (own_valid with "ms") - as %[_ [INCL VAL]%(auth_valid_discrete_2 (A:= rwlock_stAgreeR))]. - iPureIntro. - destruct (@Some_included_exclusive _ _ - (pair_exclusive_l _ _ (excl_exclusive _)) _ INCL VAL) - as [_ Eq2%(to_agree_inj (A:= leibnizC _))]. done. - Qed. - - Lemma rwown_st_global_main_sub st γs : - rwown γs (st_global st) ⊣⊢ rwown γs (main_st st) ∗ rwown γs (sub_st st). - Proof. - by rewrite /main_st /sub_st -embed_sep -own_op pair_op right_id. - Qed. - - Lemma rwown_full_global_local st γs : - rwown γs (st_full st) ⊣⊢ rwown γs (st_local st) ∗ rwown γs (st_global st). - Proof. - by rewrite -embed_sep -own_op pair_op left_id. - Qed. - - Lemma rwown_full_split st γs : - rwown γs (st_full st) - ⊣⊢ rwown γs (st_local st) ∗ rwown γs (main_st st) ∗ rwown γs (sub_st st). - Proof. by rewrite rwown_full_global_local rwown_st_global_main_sub. Qed. - - Lemma rwown_agree_update (st st': rwlock_st) : - ● (st_agree st : rwlock_stAgreeR) ⋅ ◯ st_agree st - ~~> ● st_agree st' ⋅ ◯ st_agree st'. - Proof. - apply (auth_update (A:=rwlock_stAgreeR)). - apply (option_local_update (A:= prodR _ (agreeR (leibnizC _)))). - eapply (exclusive_local_update (A:= prodR _ (agreeR (leibnizC _)))). done. - Unshelve. by apply (pair_exclusive_l(B:=agreeR (leibnizC _))), excl_exclusive. - Qed. + Definition writing_st : rwlockR := st_local (Some $ inl ()). Lemma rwown_update_write_read ν γs : let st' : rwlock_st := Some (inr (ν, (1/2)%Qp, 1%positive)) in - rwown γs (main_st None) -∗ rwown γs (sub_st None) - ==∗ rwown γs (main_st st') ∗ rwown γs (sub_st st') ∗ rwown γs (reading_st (1/2)%Qp ν). + rwown γs (st_global None) + ==∗ rwown γs (st_global st') ∗ rwown γs (reading_st (1/2)%Qp ν). Proof. - iIntros (st') "m s". - rewrite bi.sep_assoc -rwown_st_global_main_sub -embed_sep -own_op pair_op right_id. - iDestruct (rwown_st_global_main_sub with "[$m $s]") as "ms". - iMod (own_update (A:=rwlockR) with "ms") as "$"; [|done]. - apply prod_update; simpl; [|by apply rwown_agree_update]. - apply auth_update_alloc. - rewrite -(right_id None op (Some _)). by apply op_local_update_discrete. + iIntros (st') "g". rewrite -embed_sep -own_op. + iMod (own_update with "g") as "$"; [|done]. apply auth_update_alloc. + rewrite /= -(right_id None op (Some _)). by apply op_local_update_discrete. Qed. Lemma rwown_update_read ν (n: positive) (q q': frac) γs (Hqq' : (q + q')%Qp = 1%Qp) : let st : rwlock_st := (Some (inr (ν, q, n))) in let st': rwlock_st := Some (inr (ν, (q + (q'/2)%Qp)%Qp, (n + 1)%positive)) in - rwown γs (main_st st) -∗ rwown γs (sub_st st) - ==∗ rwown γs (main_st st') ∗ rwown γs (sub_st st') ∗ rwown γs (reading_st (q'/2)%Qp ν). + rwown γs (st_global st) + ==∗ rwown γs (st_global st') ∗ rwown γs (reading_st (q'/2)%Qp ν). Proof. - iIntros (st') "m s". - rewrite bi.sep_assoc -rwown_st_global_main_sub -embed_sep -own_op pair_op right_id. - iDestruct (rwown_st_global_main_sub with "[$m $s]") as "ms". - iMod (own_update (A:=rwlockR) with "ms") as "$"; [|done]. - apply prod_update; simpl; [|by apply rwown_agree_update]. - apply auth_update_alloc. - rewrite Pos.add_comm Qp_plus_comm -pos_op_plus + iIntros (st') "g". rewrite -embed_sep -own_op. + iMod (own_update with "g") as "$"; [|done]. apply auth_update_alloc. + rewrite Pos.add_comm Qp_plus_comm -pos_op_plus /= -{2}(agree_idemp (to_agree _)) -frac_op' -2!pair_op -Cinr_op Some_op. rewrite -{2}(right_id None op (Some (Cinr (_, (q' /2)%Qp, _)))). @@ -140,39 +82,28 @@ Section rwlock_inv. Lemma rwown_update_write γs : let st' : rwlock_st := Some (inl ()) in - rwown γs (main_st None) -∗ rwown γs (sub_st None) - ==∗ rwown γs (main_st st') ∗ rwown γs (sub_st st') ∗ rwown γs writing_st. + rwown γs (st_global None) ==∗ rwown γs (st_global st') ∗ rwown γs writing_st. Proof. - iIntros (st') "m s". - rewrite bi.sep_assoc -rwown_st_global_main_sub -embed_sep -own_op pair_op right_id. - iDestruct (rwown_st_global_main_sub with "[$m $s]") as "ms". - iMod (own_update (A:=rwlockR) with "ms") as "$"; [|done]. - apply prod_update; simpl; [|by apply rwown_agree_update]. - apply auth_update_alloc. - rewrite -(right_id None op (Some _)). by apply op_local_update_discrete. + iIntros (st') "g". rewrite -embed_sep -own_op. + iMod (own_update with "g") as "$"; [|done]. apply auth_update_alloc. + rewrite /= -(right_id None op (Some _)). by apply op_local_update_discrete. Qed. Lemma rwown_update_write_dealloc γs : let st : rwlock_st := Some (inl ()) in - rwown γs (main_st st) -∗ rwown γs (sub_st st) -∗ rwown γs writing_st - ==∗ rwown γs (main_st None) ∗ rwown γs (sub_st None). + rwown γs (st_global st) -∗ rwown γs writing_st ==∗ rwown γs (st_global None). Proof. - iIntros (st) "m s w". - rewrite -rwown_st_global_main_sub. - iDestruct (rwown_st_global_main_sub with "[$m $s]") as "ms". - iCombine "ms" "w" as "msw". - iMod (own_update (A:=rwlockR) with "msw") as "$"; [|done]. - apply prod_update; simpl; [|by apply rwown_agree_update]. - apply auth_update_dealloc. - rewrite -(right_id None op (Some _)). by apply cancel_local_update_unit, _. + iIntros (st) "g w". iCombine "g" "w" as "gw". + iMod (own_update with "gw") as "$"; [|done]. apply auth_update_dealloc. + rewrite /= -(right_id None op (Some _)). by apply cancel_local_update_unit, _. Qed. - Lemma rown_main_reading_st st q ν γs: - rwown γs (main_st st) -∗ rwown γs (reading_st q ν) -∗ + Lemma rown_global_reading_st st q ν γs: + rwown γs (st_global st) -∗ rwown γs (reading_st q ν) -∗ ⌜∃ q' n, st = Some (inr (ν,q',n))⌝. Proof. iIntros "m r". iCombine "m" "r" as "mr". - iDestruct (own_valid with "mr") as %[[INCL VAL]%auth_valid_discrete_2 ?]. + iDestruct (own_valid with "mr") as %[INCL VAL]%auth_valid_discrete_2. iPureIntro. destruct st as [[[]|[[]]]|]. - move : INCL => /Some_included [Eq|/csum_included [//|[[?[?[??//]]]|[?[?[?[??//]]]]]]]. @@ -192,26 +123,31 @@ Section rwlock_inv. Definition rwlock_interp (γs: gname) (α : lft) (tyO: vProp) (tyS: lft → vProp) : interpC Σ unitProtocol := - (λ pb l _ _ vs, ∃ st, ⌜vs = #(Z_of_rwlock_st st)⌝ ∗ + (λ pb l γ _ vs, ∃ st, ⌜vs = #(Z_of_rwlock_st st)⌝ ∗ if pb - then match st return _ with + then rwown γs (st_global st) ∗ + match st return _ with | None => (* Not locked. *) - rwown γs (sub_st st) ∗ &{α}tyO + &{α}tyO ∗ + GPS_SWSharedWriter l () #0 γ ∗ + GPS_SWSharedReader l () #0 1%Qp γ | Some (inr (ν, q, n)) => (* Locked for read. *) - rwown γs (sub_st st) ∗ ∃ q', □ (1.[ν] ={↑lftN ∪ ↑histN,↑histN}▷=∗ [†ν]) ∗ ([†ν] ={↑lftN ∪ ↑histN}=∗ &{α}tyO) ∗ - (□ tyS (α ⊓ ν)) ∗ ⌜(q + q')%Qp = 1%Qp⌝ ∗ q'.[ν] + (□ tyS (α ⊓ ν)) ∗ ⌜(q + q')%Qp = 1%Qp⌝ ∗ q'.[ν] ∗ + GPS_SWSharedWriter l () #(Z.pos n) γ ∗ + GPS_SWSharedReader l () #(Z.pos n) q' γ | _ => (* Locked for write. *) True end else □ (∀ κ q E, ⌜lftE ⊆ E⌝ -∗ &{κ}tyO -∗ q.[κ] ={E}=∗ (□ tyS κ) ∗ q.[κ]))%I. + Definition rwlock_noCAS (l: loc) (s : unitProtocol) (v: val) : Prop := v = #(-1). Definition rwlock_proto_inv l γ γs α tyO tyS : vProp := - ((∃ st, rwown γs (main_st st)) ∗ GPS_PPInv (rwlock_interp γs α tyO tyS) l γ)%I. + GPS_INV (rwlock_interp γs α tyO tyS) l rwlock_noCAS γ. Definition rwlock_proto_lc l γ (tyO: vProp) (tyS: lft → vProp) tid ty: vProp := ((▷ □ (tyO ↔ (l +ₗ 1) ↦∗: ty.(ty_own) tid)) ∗ (▷ □ (∀ α, tyS α ↔ ty.(ty_shr) α tid (l +ₗ 1))) ∗ - (∃ v, GPS_PPRaw l () v γ))%I. + (∃ v, GPS_SWRawReader l () v γ))%I. Lemma rwlock_interp_comparable γs α tyO tyS l γ s v (n: Z): rwlock_interp γs α tyO tyS false l γ s v @@ -291,47 +227,51 @@ Section rwlock_inv. { iIntros "!#" (????) "tyO tok". by iMod (ty_share with "LFT tyO tok") as "[#? $]". } iDestruct "H" as ([|n|[]]) "[>Hn >%]"; try lia. - iFrame "Htok". - iMod (own_alloc (st_full None : rwlockR)) as (γs) "Hst". done. - iDestruct (rwown_full_split with "Hst") as "(lst & mst & sst)". - iMod (GPS_PPRaw_Init_vs (rwlock_interp γs α tyO tyS) _ true _ () - with "Hn [Hvl sst]") as (γ) "[R inv]". - { iIntros (?). iSplitR ""; iExists None; by [iFrame "Hvl sst"|iFrame "Share"]. } - iExists γ, γs, tyO, tyS. - iModIntro. iFrame "inv EqO EqS". iSplitL "R"; by iExists _. + iMod (own_alloc (st_global None : rwlockR)) as (γs) "Hst". done. + iMod (GPS_SWRaw_Init_vs_strong (rwlock_interp γs α tyO tyS) _ rwlock_noCAS + true _ () (GPS_SWRawReader l ((): unitProtocol) #0)%I + with "Hn [Hvl Hst]") as (γ) "[inv R]". + { iIntros (?) "W". iDestruct (GPS_SWRawWriter_RawReader with "W") as "#$". + iSplitR ""; iExists None; [|by iFrame "Share"]. iModIntro. iSplit; [done|]. + iFrame "Hvl Hst". by iDestruct (GPS_SWRawWriter_shared with "W") as "[$$]". } + iExists γ, γs, tyO, tyS. iModIntro. iFrame "inv EqO EqS". by iExists _. - iMod (lft_create with "LFT") as (ν) "[[Htok1 Htok2] #Hhν]". done. - iMod (own_alloc (st_full (Some $ inr (ν, (1/2)%Qp, n)) : rwlockR)) - as (γs) "Hst". done. - iDestruct (rwown_full_split with "Hst") as "(lst & mst & sst)". + iMod (own_alloc (st_global (Some $ inr (ν, (1/2)%Qp, n)))) as (γs) "Hst". + { by apply auth_auth_valid. } iMod (rebor _ _ (α ⊓ ν) with "LFT [] Hvl") as "[Hvl Hh]". done. { iApply lft_intersect_incl_l. } iDestruct (lft_intersect_acc with "Htok Htok1") as (q') "[Htok Hclose]". iMod (ty_share with "LFT Hvl Htok") as "[#Hshr Htok]". done. iDestruct ("Hclose" with "Htok") as "[$ Htok]". - iMod (GPS_PPRaw_Init_vs (rwlock_interp γs α tyO tyS) _ true _ () - with "Hn [-mst]") as (γ) "[R inv]". - { iIntros (?). + iMod (GPS_SWRaw_Init_vs_strong (rwlock_interp γs α tyO tyS) _ rwlock_noCAS + true _ () (GPS_SWRawReader l (() : unitProtocol) #(Z.pos n))%I + with "Hn [-]") as (γ) "[inv R]". + { iIntros (?) "W". iDestruct (GPS_SWRawWriter_RawReader with "W") as "#$". iSplitR ""; iExists (Some $ inr (ν, (1/2)%Qp, n)); [|by iFrame "Share"]. - iSplitL ""; [done|]. iFrame "sst". - iExists _. iFrame "Hshr Htok2 Hhν". iSplitR ""; [|by rewrite Qp_div_2]. + iModIntro. iSplitL ""; [done|]. iFrame "Hst". + iExists _. iFrame "Hshr Htok2 Hhν". + iDestruct (GPS_SWRawWriter_shared with "W") as "[$ [$ ?]]". + iSplitR ""; [|by rewrite Qp_div_2]. iIntros "!> Hν". iDestruct (lft_tok_dead with "Htok Hν") as "[]". } - iExists γ, γs, tyO, tyS. - iModIntro. iFrame "inv EqO EqS". iSplitL "R"; by iExists _. - - iMod (own_alloc (st_full (Some $ inl ()) : rwlockR)) as (γs) "Hst". done. + iExists γ, γs, tyO, tyS. iModIntro. iFrame "inv EqO EqS". by iExists _. + - iMod (own_alloc (st_global (Some $ inl ()))) as (γs) "Hst". + { by apply auth_auth_valid. } iFrame "Htok". - iDestruct (rwown_full_split with "Hst") as "(lst & mst & sst)". - iMod (GPS_PPRaw_Init_vs (rwlock_interp γs α tyO tyS) _ true _ () - with "Hn [Hvl]") as (γ) "[R inv]". - { iIntros (?). iSplitR ""; iExists (Some $ inl ()); by [|iFrame "Share"]. } - iExists γ, γs, tyO, tyS. - iModIntro. iFrame "inv EqO EqS". iSplitL "R"; by iExists _. + iMod (GPS_SWRaw_Init_vs_strong (rwlock_interp γs α tyO tyS) _ rwlock_noCAS + true _ () (GPS_SWRawWriter l (() : unitProtocol) #(-1))%I + with "Hn [Hvl Hst]") as (γ) "[inv W]". + { iIntros (?) "$". iModIntro. iSplitR ""; iExists (Some $ inl ()); + by [iFrame "Hst"|iFrame "Share"]. } + iExists γ, γs, tyO, tyS. iModIntro. iFrame "inv EqO EqS". iExists _. + by iDestruct (GPS_SWRawWriter_RawReader with "W") as "#$". Qed. Lemma rwlock_proto_destroy b l γ γs α tyO tyS : ⎡ hist_inv ⎤ -∗ ▷?b rwlock_proto_inv l γ γs α tyO tyS ={↑histN}=∗ ∃ (z : Z), l ↦ #z ∗ ⌜-1 ≤ z⌝. Proof. - iIntros "#hInv [mst inv]". - iMod (GPS_PPInv_dealloc with "hInv inv") as (s v) "(Hl & F & _)"; [done|]. + iIntros "#hInv inv". + iMod (GPS_INV_dealloc with "hInv inv") as (s v) "(Hl & F & _)"; [done|]. iDestruct "F" as (st) "[>% _]". subst v. iExists _. iFrame "Hl". iPureIntro. destruct st as [[|[[??]?]]| ]; simpl; try omega. lia. Qed. @@ -370,20 +310,6 @@ Section rwlock_inv. - iIntros (V'' ??). by iFrame. Qed. - Lemma rwlock_proto_inv_split l γ γs β tid ty Vb: - (monPred_in Vb - → ▷ ((∃ st, rwown γs (main_st st)) ∗ GPS_PPInv (rwlock_interp γs tid β ty) l γ)) - ⊣⊢ ((∃ st, ▷ rwown γs (main_st st)) - ∗ (monPred_in Vb → ▷ GPS_PPInv (rwlock_interp γs tid β ty) l γ)). - Proof. - rewrite /rwlock_proto_inv bi.later_sep bi.later_exist monPred_in_sep. - iSplit; iIntros "[mst $]". - - rewrite monPred_in_exist. iDestruct "mst" as (st) "mst". - iExists st. by rewrite -embed_later monPred_in_embed. - - iDestruct "mst" as (st) "mst". rewrite monPred_in_exist. - iExists st. by rewrite -embed_later monPred_in_embed. - Qed. - Lemma rwlock_interp_read_acq l s v γ γs α tyO tyS tid: (▽{tid} rwlock_interp γs α tyO tyS false l γ s v : vProp) -∗ ∃ st, ⌜v = #(Z_of_rwlock_st st)⌝. @@ -459,7 +385,7 @@ Section rwlock. Global Instance rwlock_type_ne : TypeNonExpansive rwlock. Proof. constructor; - solve_proper_core ltac:(fun _ => exact: type_dist2_S + solve_proper_core ltac:(fun _ => exact: type_dist2_S || (eapply rwlock_proto_lc_type_ne; try reflexivity) || f_type_equiv || f_equiv). Qed. diff --git a/theories/typing/lib/rwlock/rwlockreadguard.v b/theories/typing/lib/rwlock/rwlockreadguard.v index 58a03611..a53141f6 100644 --- a/theories/typing/lib/rwlock/rwlockreadguard.v +++ b/theories/typing/lib/rwlock/rwlockreadguard.v @@ -24,8 +24,9 @@ Section rwlockreadguard. ∃ ν q γs β, ty.(ty_shr) (α ⊓ ν) tid (l +ₗ 1) ∗ α ⊑ β ∗ q.[ν] ∗ rwown γs (reading_st q ν) ∗ (1.[ν] ={↑lftN ∪ ↑histN,↑histN}▷=∗ [†ν]) ∗ - (∃ γ tyO tyS, rwlock_proto_lc l γ tyO tyS tid ty ∗ - &at{β,rwlockN}(rwlock_proto_inv l γ γs β tyO tyS)) + (∃ γ tyO tyS, (∃ n, GPS_SWSharedReader l () #(Z.pos n) q γ) ∗ + rwlock_proto_lc l γ tyO tyS tid ty ∗ + &at{β,rwlockN}(rwlock_proto_inv l γ γs β tyO tyS)) | _ => False end; ty_shr κ tid l := @@ -90,8 +91,8 @@ Section rwlockreadguard. + iApply ty_shr_mono; last by iApply "Hs". iApply lft_intersect_mono. done. iApply lft_incl_refl. + by iApply lft_incl_trans. - + iDestruct "Hinv" as (γ tyO tyS) "(lc & inv)". - iExists γ, tyO, tyS. iFrame "inv". by iApply ("Hty1ty2" with "HE lc"). + + iDestruct "Hinv" as (γ tyO tyS) "(R & lc & inv)". + iExists γ, tyO, tyS. iFrame "R inv". by iApply ("Hty1ty2" with "HE lc"). - iIntros (κ tid l) "H". iDestruct "H" as (l') "[Hf Hshr]". iExists l'. iFrame. iApply ty_shr_mono; last by iApply "Hs". iApply lft_intersect_mono. done. iApply lft_incl_refl. diff --git a/theories/typing/lib/rwlock/rwlockreadguard_code.v b/theories/typing/lib/rwlock/rwlockreadguard_code.v index 2100479f..31e66639 100644 --- a/theories/typing/lib/rwlock/rwlockreadguard_code.v +++ b/theories/typing/lib/rwlock/rwlockreadguard_code.v @@ -73,40 +73,43 @@ Section rwlockreadguard_functions. rewrite tctx_interp_cons tctx_interp_singleton !tctx_hasty_val. iDestruct "HT" as "[Hx Hx']". destruct x' as [[|lx'|]|]; try done. simpl. - iDestruct "Hx'" as (ν q γs β) "(Hx' & #Hαβ & Hν & H◯ & H† & #Hinv)". - iDestruct "Hinv" as (γ tyO tyS) "((EqO & EqS & PP) & Hinv)". - iDestruct "PP" as (vP) "PP". + iDestruct "Hx'" as (ν q γs β) "(Hx' & #Hαβ & Hν & H◯ & H† & Hinv)". + iDestruct "Hinv" as (γ tyO tyS) "(R & (EqO & EqS) & #Hinv)". + iDestruct "R" as (vR) "R". iMod (lctx_lft_alive_tok α with "HE HL") as (qα) "(Hα & HL & Hclose)"; [solve_typing..|]. iMod (lft_incl_acc with "Hαβ Hα") as (qβ) "[Hβ Hcloseα]". done. wp_bind (!ʳˡˣ#lx')%E. iMod (at_bor_acc with "LFT Hinv Hβ") as (Vb) "[INV Hcloseβ]"; [done..|]. - iDestruct (rwlock_proto_inv_split with "INV") as "[mst INV]". - iDestruct "mst" as (st1) ">mst". - iApply (GPS_PPRaw_read with "[$PP $INV]"); [solve_ndisj|by left|..]. + iDestruct (GPS_SWSharedReader_RawReader with "R") as "#RR". + iApply (GPS_SWRawReader_read with "[$RR $INV]"); [solve_ndisj|by left|..]. { iNext. iIntros (? _). iLeft. iIntros "!>" (?). by iApply rwlock_interp_duplicable. } iNext. iIntros ([] v') "(_ & _ & INV & Int)". iDestruct (rwlock_interp_read_acq with "Int") as (st2) "Int". iDestruct "Int" as %?. subst v'. - iMod ("Hcloseβ" with "[mst INV]") as "Hβ". - { rewrite rwlock_proto_inv_split. iFrame "INV". by iExists _. } + iMod ("Hcloseβ" with "INV") as "Hβ". iModIntro. wp_let. wp_op. wp_bind (CAS _ _ _ _ _ _). iMod (at_bor_acc with "LFT Hinv Hβ") as (Vb') "[INV Hcloseβ]"; [done..|]. - iDestruct (rwlock_proto_inv_split with "INV") as "[mst INV]". - iDestruct (bi.later_exist_2 with "mst") as ">mst". - set Q : () → vProp Σ := (λ _, (∃ st, rwown γs (main_st st)))%I. - set R : () → lit → vProp Σ := (λ _ _, (∃ st, rwown γs (main_st st)))%I. - iApply (GPS_PPRaw_CAS_int_simple (rwlock_interp γs β tyO tyS) _ _ _ _ _ - _ #(Z_of_rwlock_st st2 - 1) () True%I Q R _ _ Vb' - with "[$PP $INV mst H◯ Hx' Hν H†]"); - [solve_ndisj|by left|done|by left|by right|iSplitL ""; last iSplitL ""|..]. + set P : vProp Σ := (rwown γs (reading_st q ν) ∗ (q).[ν])%I. + set Q : () → vProp Σ := (λ _, True)%I. + set R : () → lit → vProp Σ := (λ _ _, True)%I. + set T : () → () → vProp Σ := (λ _ _, True)%I. + iApply (GPS_SWSharedWriter_CAS_int_strong (rwlock_interp γs β tyO tyS) _ + rwlock_noCAS _ _ _ _ #(Z_of_rwlock_st st2 - 1) () _ _ _ + P T Q R _ Vb' _ (⊤ ∖ ↑rwlockN) + with "[$R $INV H◯ Hν]"); + [done|solve_ndisj|by left|done|by left|by right|iSplitL ""; last iSplitL ""|..]. { iIntros "!> !>" (???). by iApply rwlock_interp_comparable. } { iIntros "!> !>" (???). by iApply rwlock_interp_duplicable. } - { simpl. iSplitR ""; last done. - iNext. iIntros ([] _). iSplit; [|by iIntros (?) "_ _"]. - iDestruct "mst" as (st3) "mst". iIntros "_". - iDestruct 1 as (st2') "[Eqst INT]". iDestruct "Eqst" as %Eqst. - destruct st2' as [[[]|[[ν' q'] n]]|]. + { simpl. iSplitR "H◯ Hν"; last iFrame "∗". + iNext. iIntros ([] _). iSplit; [|by iIntros (?) "_ _"]. iSplitL "". + - iIntros "(H◯ & Hν)". iDestruct 1 as (st2') "[Eqst [g INT]]". + iDestruct "Eqst" as %Eqst. + iDestruct (rown_global_reading_st with "g H◯") as %[q' [n Eqst2']]. + subst st2'. iDestruct 1 as (?) "[_ #Share]". + iExists (). rewrite Eqst /=. iSplitL ""; [done|]. + admit. + - iIntros ([] _) "T W". wp_read. diff --git a/theories/typing/lib/rwlock/rwlockwriteguard.v b/theories/typing/lib/rwlock/rwlockwriteguard.v index 4094aecb..cee094bd 100644 --- a/theories/typing/lib/rwlock/rwlockwriteguard.v +++ b/theories/typing/lib/rwlock/rwlockwriteguard.v @@ -23,9 +23,10 @@ Section rwlockwriteguard. match vl return _ with | [ #(LitLoc l) ] => ∃ γs β, &{β}((l +ₗ 1) ↦∗: ty.(ty_own) tid) ∗ - α ⊑ β ∗ rwown γs writing_st ∗ rwown γs (sub_st (Some (inl ()))) ∗ - (∃ γ tyO tyS, rwlock_proto_lc l γ tyO tyS tid ty ∗ - &at{β,rwlockN}(rwlock_proto_inv l γ γs β tyO tyS)) + α ⊑ β ∗ rwown γs writing_st ∗ + (∃ γ tyO tyS, GPS_SWRawWriter l () #(-1) γ ∗ + rwlock_proto_lc l γ tyO tyS tid ty ∗ + &at{β,rwlockN}(rwlock_proto_inv l γ γs β tyO tyS)) | _ => False end; ty_shr κ tid l := @@ -84,14 +85,14 @@ Section rwlockwriteguard. iIntros "!# #HE". iDestruct ("Hα" with "HE") as "Hα1α2". iDestruct ("Hty" with "HE") as "(%&#Ho&#Hs)". iSplit; [done|iSplit; iAlways]. - iIntros (tid [|[[]|][]]) "H"; try done. - iDestruct "H" as (γs β) "(Hb & #H⊑ & Hown & Hsst & Hinv)". - iExists γs, β. iFrame "Hown Hsst". iSplit; last iSplit. + iDestruct "H" as (γs β) "(Hb & #H⊑ & Hown & Hinv)". + iExists γs, β. iFrame "Hown". iSplitL "Hb"; last iSplitR "Hinv". + iApply bor_iff; last done. iIntros "!>!#". iSplit; iIntros "H"; iDestruct "H" as (vl) "[??]"; iExists vl; iFrame; by iApply "Ho". + by iApply lft_incl_trans. - + iDestruct "Hinv" as (γ tyO tyS) "(lc & inv)". - iExists γ, tyO, tyS. iFrame "inv". by iApply ("Hty1ty2" with "HE lc"). + + iDestruct "Hinv" as (γ tyO tyS) "(W & lc & inv)". + iExists γ, tyO, tyS. iFrame "W inv". by iApply ("Hty1ty2" with "HE lc"). - iIntros (κ tid l) "H". iDestruct "H" as (l') "H". iExists l'. iDestruct "H" as "[$ #H]". iIntros "!# * % Htok". iMod (lft_incl_acc with "[] Htok") as (q') "[Htok Hclose]"; first solve_ndisj. -- GitLab