Timings for write.v
- /home/gitlab-runner/builds/gGKko-aj/0/coq/coq/_bench/opam.OLD/ocaml-OLD/.opam-switch/build/coq-perennial.dev/./src/program_proof/simple/write.v.timing
- /home/gitlab-runner/builds/gGKko-aj/0/coq/coq/_bench/opam.NEW/ocaml-NEW/.opam-switch/build/coq-perennial.dev/./src/program_proof/simple/write.v.timing
From RecordUpdate Require Import RecordSet.
Import RecordSetNotations.
From Perennial.algebra Require Import liftable auth_map.
From Perennial.Helpers Require Import Transitions.
From Perennial.program_proof Require Import disk_prelude.
From Goose.github_com.mit_pdos.go_nfsd Require Import simple.
From Perennial.program_proof Require Import obj.obj_proof marshal_proof addr_proof crash_lockmap_proof addr.addr_proof buf.buf_proof.
From Perennial.program_proof Require Import jrnl.sep_jrnl_proof.
From Perennial.program_proof Require Import disk_prelude.
From Perennial.program_proof Require Import disk_lib.
From Perennial.Helpers Require Import NamedProps Map List range_set.
From Perennial.program_logic Require Import spec_assert.
From Perennial.goose_lang.lib Require Import slice.typed_slice into_val.
From Perennial.program_proof Require Import simple.spec simple.invariant simple.common simple.iread simple.iwrite.
Implicit Types (stk:stuckness) (E: coPset).
Variable P : SimpleNFS.State -> iProp Σ.
Context `{Ptimeless : !forall σ, Timeless (P σ)}.
Opaque nfstypes.WRITE3res.
Lemma nfstypes_write3res_merge reply s ok fail :
( reply ↦[nfstypes.WRITE3res :: "Status"] s ∗
reply ↦[nfstypes.WRITE3res :: "Resok"] ok ∗
reply ↦[nfstypes.WRITE3res :: "Resfail"] fail ) -∗
reply ↦[struct.t nfstypes.WRITE3res]{1} (s, (ok, (fail, #()))).
iIntros "(Status & Resok & Resfail)".
iApply struct_fields_split.
Theorem wp_NFSPROC3_WRITE γ (nfs : loc) (fh : u64) (fhslice : Slice.t) (offset : u64) (dataslice : Slice.t) (databuf : list u8) (Q : SimpleNFS.res u32 -> iProp Σ) (stab : u32) dinit :
{{{ is_fs P γ nfs dinit ∗
is_fh fhslice fh ∗
own_slice dataslice u8T 1%Qp databuf ∗
⌜ (length databuf < 2^32)%Z ⌝ ∗
( ∀ σ σ' (r : SimpleNFS.res u32) E,
⌜relation.denote (SimpleNFS.wrapper fh (SimpleNFS.write fh offset databuf)) σ σ' r⌝ -∗
( P σ -∗ |={E}=> P σ' ∗ Q r ) )
}}}
Nfs__NFSPROC3_WRITE #nfs
(struct.mk_f nfstypes.WRITE3args [
"File" ::= struct.mk_f nfstypes.Nfs_fh3 [
"Data" ::= slice_val fhslice
];
"Offset" ::= #offset;
"Count" ::= #(U32 (length databuf));
"Stable" ::= #stab;
"Data" ::= (slice_val dataslice)
])%V
{{{ v,
RET v;
( ∃ (count : u32) resok,
⌜ getField_f nfstypes.WRITE3res "Status" v = #(U32 0) ⌝ ∗
⌜ getField_f nfstypes.WRITE3res "Resok" v = resok ⌝ ∗
⌜ getField_f nfstypes.WRITE3resok "Count" resok = #count ⌝ ∗
Q (SimpleNFS.OK count) ) ∨
( ∃ (stat : Z),
⌜ getField_f nfstypes.WRITE3res "Status" v = #(U32 stat) ⌝ ∗
⌜ stat ≠ 0 ⌝ ∗
Q SimpleNFS.Err )
}}}.
iIntros (Φ) "(Hfs & #Hfh & Hdata & %Hdatalenbound & Hfupd) HΦ".
wp_apply wp_ref_of_zero; first by auto.
iIntros (reply) "Hreply".
wp_apply util_proof.wp_DPrintf.
wp_apply (wp_Op__Begin with "[$Histxn $Htxnsys]").
iIntros (γtxn buftx) "Hjrnl".
wp_apply (wp_fh2ino with "Hfh").
wp_apply util_proof.wp_DPrintf.
iIntros (valid) "%Hvalid".
wp_apply (wp_storeField_struct with "Hreply"); first by auto.
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
destruct (src !! fh) eqn:He.
assert (fh ∈ dom src) as Hin.
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
wp_apply (wp_LockMap__Acquire with "[$Hislm]"); first by intuition eauto.
wp_bind (NFSPROC3_WRITE_internal _ _ _ _).
iApply (wpc_wp _ _ _ _ True).
iApply (use_CrashLocked _ with "Hcrashlocked").
iApply ncfupd_wpc; iSplit.
iMod (is_inode_stable_crash with "Htxncrash Hstable") as "Hcrash".
iSplit; try (iIntros "? !>"); done.
iMod (lift_liftable_into_txn with "Hjrnl Hinode_disk") as "[Hinode_disk Hjrnl]";
[ solve_ndisj .. | ].
iCache with "Hinode_state Hjrnl_durable".
iDestruct (is_jrnl_durable_to_old_pred with "Hjrnl_durable") as "[Hold _]".
iMod (is_inode_crash_prev with "Htxncrash [$Hinode_state $Hold]") as "H".
iSplit; try (iIntros "? !>"); done.
wpc_bind (NFSPROC3_WRITE_wp _ _ _ _).
wp_apply (wp_ReadInode with "[$Hjrnl_mem $Hinode_enc]"); first by intuition eauto.
iIntros (ip) "(Hjrnl_mem & Hinode_enc & Hinode_mem)".
wp_apply (wp_Inode__Write with "[$Hjrnl_mem $Hinode_mem $Hinode_data $Hinode_enc Hdata]").
iDestruct (own_slice_to_small with "Hdata") as "$".
iIntros (wcount ok) "[Hjrnl_mem [(Hinode_mem & Hinode_enc & Hinode_data & %Hok) | Hok]]"; intuition subst.
iDestruct (struct_fields_split with "Hreply") as "Hreply".
wp_apply (wp_struct_fieldRef_mapsto with "Resok"); first done.
iIntros (fl) "[%Hfl Resok]".
wp_apply (wp_storeField_struct with "Resok").
rewrite Hfl; clear Hfl fl.
wp_apply (wp_struct_fieldRef_mapsto with "Resok"); first done.
iIntros (fl) "[%Hfl Resok]".
wp_apply (wp_storeField_struct with "Resok").
rewrite Hfl; clear Hfl fl.
iDestruct (is_jrnl_mem_durable with "Hjrnl_mem Hjrnl_durable") as "Hjrnl".
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh".
iDestruct (big_sepM_lookup with "Hnooverflow") as %Hnooverflow; eauto.
iMod ("Hclose" with "[Hsrcheap HP]").
replace (int.Z (length state)
`max` (int.Z offset + int.Z (u32_to_u64 (U32 (length databuf)))))%Z
with (length (take (int.nat offset) state ++
databuf ++ drop (int.nat offset + length databuf) state) : Z).
destruct (decide (int.Z offset + length databuf ≤ length state)%Z).
rewrite Z.max_l; last by lia.
rewrite take_length_le; lia.
rewrite Z.max_r; last by lia.
rewrite take_length_le; try lia.
rewrite (firstn_all2 databuf); last by lia.
replace (Z.to_nat (length databuf)) with (length databuf) by lia.
wpc_apply (wpc_Op__CommitWait with "[$Hjrnl $Htxncrash Hinode_enc Hinode_data]").
(* XXX is there a clean version of this? *)
generalize (jrnl_maps_to γtxn).
iIntros "[[H _]|[H0 H1]]".
iApply is_inode_crash_next.
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh2".
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
eapply relation.bind_runs with (x:=false).
rewrite -> decide_True by (move: H3; word).
iMod (map_update with "Hsrcheap Hinode_state") as "[Hsrcheap Hinode_state]".
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
iDestruct (big_sepM_delete with "Hnooverflow") as "[H0 H1]"; eauto.
iApply (big_sepM_insert_delete with "[$H1]").
rewrite !app_length drop_length.
iApply is_inode_crash_next.
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh2".
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
eapply relation.bind_runs with (x:=false).
rewrite -> decide_True by (move: H3; word).
iMod (map_update with "Hsrcheap Hinode_state") as "[Hsrcheap Hinode_state]".
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
iDestruct (big_sepM_delete with "Hnooverflow") as "[H0 H1]"; eauto.
iApply (big_sepM_insert_delete with "[$H1]").
rewrite !app_length drop_length.
wpc_frame "Hinode_state Hcommit".
iMod (is_inode_crash_prev_own with "Htxncrash [$Hinode_state $Hcommit]") as "H".
iSplit; try (iIntros "? !>"); done.
iSplitR "Hinode_state Hcommit".
iDestruct "Hcommit" as "(Hinode_enc & Hinode_data)".
wp_apply (wp_LockMap__Release with "Hcrashlocked").
wp_apply (wp_LoadAt with "[Status Resok Resfail]").
iApply nfstypes_write3res_merge.
rewrite /u32_from_u64 /u32_to_u64.
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh2".
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
eapply relation.bind_runs with (x:=true).
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
iDestruct "Hcommit" as "[Hcommit _]".
wpc_frame "Hinode_state Hcommit".
iMod (is_inode_crash_prev_own with "Htxncrash [$Hinode_state $Hcommit]") as "H".
iSplit; try (iIntros "? !>"); done.
iSplitR "Hinode_state Hcommit".
wp_apply (wp_LockMap__Release with "Hcrashlocked").
wp_apply (wp_LoadAt with "[Status Resok Resfail]").
iApply nfstypes_write3res_merge.
iDestruct "Hok" as "(Hinode_mem & Hinode_enc & Hinode_data & %Hok)".
iDestruct (struct_fields_split with "Hreply") as "Hreply".
iDestruct (is_jrnl_mem_durable with "Hjrnl_mem Hjrnl_durable") as "Hjrnl".
(* Implicit transaction abort *)
iDestruct (is_jrnl_to_old_pred with "Hjrnl") as "[Hold _]".
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh".
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
eapply relation.bind_runs with (x:=true).
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
iMod (is_inode_crash_prev_own with "Htxncrash [$Hinode_state $Hold]") as "H".
iSplit; try (iIntros "? !>"); done.
iSplitR "Hinode_state Hold".
iIntros "!> Hcrashlocked".
wp_apply (wp_LockMap__Release with "Hcrashlocked").
wp_apply (wp_LoadAt with "[Status Resok Resfail]").
iApply nfstypes_write3res_merge.