From 3c9a259277e573e7f0bafcb15ec69962b6b7fef3 Mon Sep 17 00:00:00 2001 From: William Mansky <mansky1@uic.edu> Date: Mon, 10 Mar 2025 10:44:29 -0500 Subject: [PATCH] two more styles of lock spec --- theories/locks/lockspecs/atomic_lock.v | 108 ++++++++++++++++++++++++ theories/locks/lockspecs/share_locks.v | 109 +++++++++++++++++++++++++ 2 files changed, 217 insertions(+) create mode 100644 theories/locks/lockspecs/atomic_lock.v create mode 100644 theories/locks/lockspecs/share_locks.v diff --git a/theories/locks/lockspecs/atomic_lock.v b/theories/locks/lockspecs/atomic_lock.v new file mode 100644 index 00000000..9f511b74 --- /dev/null +++ b/theories/locks/lockspecs/atomic_lock.v @@ -0,0 +1,108 @@ +From iris.proofmode Require Import proofmode. +From iris.base_logic.lib Require Export invariants ghost_var. +From iris.bi.lib Require Import fractional. +From iris.heap_lang Require Import proofmode primitive_laws notation atomic_heap. +From iris.prelude Require Import options. + +(** Deallocatable lock with share, operations are atomic. *) +Structure atomic_lock `{!heapGS Σ} := AtomicLock { + (** * Operations *) + newlock : val; + acquire : val; + release : val; + freelock : val; + (** * Predicates *) + (** [name] is used to associate locked with [is_lock] *) + name : Type; + (** No namespace [N] parameter because we only expose program specs, which + anyway have the full mask. *) + is_lock (f: Qp) (γ: name) (lock: val) (R: iProp Σ) : iProp Σ; + locked (γ: name) : iProp Σ; + (** * General properties of the predicates *) + is_lock_ne f γ lk : Contractive (is_lock f γ lk); + is_lock_persistent γ lk R : Fractional (fun f => is_lock f γ lk R); + is_lock_iff f γ lk R1 R2 : + is_lock f γ lk R1 -∗ ▷ □ (R1 ↔ R2) -∗ is_lock f γ lk R2; + locked_timeless γ : Timeless (locked γ); + locked_exclusive γ : locked γ -∗ locked γ -∗ False; + (** * Program specs *) + newlock_spec (R : iProp Σ) : + {{{ R }}} newlock #() {{{ lk γ, RET lk; is_lock 1 γ lk R }}}; + acquire_spec f γ (lk : val) R : + ⊢ <<{ is_lock f γ lk R }>> acquire lk @ ∅ <<{ is_lock f γ lk R ∗ locked γ ∗ R | RET #() }>>; + release_spec f γ lk R : + {{{ is_lock f γ lk R ∗ locked γ ∗ R }}} release lk {{{ RET #(); is_lock f γ lk R }}}; + freelock_spec γ lk (R : iProp Σ) : + {{{ is_lock 1 γ lk R ∗ R }}} freelock #() {{{ RET #(); R }}} +}. + +Inductive state := Free | Locked. + +Class lockG Σ := LockG { lock_tokG : ghost_varG Σ state }. +Local Existing Instance lock_tokG. +Definition lockΣ : gFunctors := #[ghost_varΣ state]. +Global Instance subG_lockΣ {Σ} : subG lockΣ Σ → lockG Σ. +Proof. solve_inG. Qed. + +Section tada. + Context `{!heapGS Σ, !lockG Σ} (l : atomic_lock). + + Record tada_lock_name := TadaLockName { + tada_lock_name_state : gname; + tada_lock_name_lock : l.(name); + }. + + Definition tada_is_lock (γ : tada_lock_name) (lk : val) : iProp Σ := + l.(is_lock) 1 γ.(tada_lock_name_lock) lk + (ghost_var γ.(tada_lock_name_state) (1/4) Free). + Definition tada_lock_state (γ : tada_lock_name) (lk : val) (s : state) : iProp Σ := + tada_is_lock γ lk ∗ ghost_var γ.(tada_lock_name_state) (3/4) s ∗ + if s is Locked then + l.(locked) γ.(tada_lock_name_lock) ∗ ghost_var γ.(tada_lock_name_state) (1/4) Locked + else True. + +(* Global Instance tada_is_lock_persistent γ lk : Persistent (tada_is_lock γ lk). + Proof. apply _. Qed. *) +(* Global Instance tada_lock_state_timeless γ s : Timeless (tada_lock_state γ lk s). + Proof. destruct s; apply _. Qed.*) + + Lemma tada_lock_state_exclusive γ lk s1 s2 : + tada_lock_state γ lk s1 -∗ tada_lock_state γ lk s2 -∗ False. + Proof. + iIntros "[_ [Hvar1 _]] [_ [Hvar2 _]]". + iDestruct (ghost_var_valid_2 with "Hvar1 Hvar2") as %[Hval _]. + exfalso. done. + Qed. + + Lemma newlock_tada_spec : + {{{ True }}} + l.(newlock) #() + {{{ lk γ, RET lk; tada_lock_state γ lk Free }}}. + Proof. + iIntros (Φ) "_ HΦ". + iMod (ghost_var_alloc Free) as (γvar) "Hvar". + rewrite -Qp.three_quarter_quarter. + iDestruct "Hvar" as "[Hvar1 Hvar2]". + wp_apply (l.(newlock_spec) with "Hvar2"). + iIntros (lk γlock) "Hlock". + iApply ("HΦ" $! lk (TadaLockName _ _)). + iFrame. + Qed. + + Lemma acquire_tada_spec γ (lk : val) : + ⊢<<{ ∀ s, tada_lock_state γ lk s }>> + l.(acquire) lk @ ∅ + <<{ tada_lock_state γ lk Locked | RET #() }>>. + Proof. + iIntros "%Φ AU". + iApply fupd_wp. + Abort. + + Lemma release_tada_spec γ (lk : val) : + ⊢<<{ tada_lock_state γ lk Locked }>> + l.(release) lk @ ∅ + <<{ tada_lock_state γ lk Free | RET #() }>>. + Proof. + Abort. + +End tada. diff --git a/theories/locks/lockspecs/share_locks.v b/theories/locks/lockspecs/share_locks.v new file mode 100644 index 00000000..09ce3d11 --- /dev/null +++ b/theories/locks/lockspecs/share_locks.v @@ -0,0 +1,109 @@ +From iris.base_logic.lib Require Export invariants ghost_var. +From iris.bi.lib Require Import fractional. +From iris.heap_lang Require Import primitive_laws notation proofmode atomic_heap. +From iris.prelude Require Import options. + +(** Deallocatable lock with share. *) +Structure lock `{!heapGS Σ} := Lock { + (** * Operations *) + newlock : val; + acquire : val; + release : val; + freelock : val; + (** * Predicates *) + (** [name] is used to associate locked with [is_lock] *) + name : Type; + (** No namespace [N] parameter because we only expose program specs, which + anyway have the full mask. *) + is_lock (f: Qp) (γ: name) (lock: val) (R: iProp Σ) : iProp Σ; + locked (γ: name) : iProp Σ; + (** * General properties of the predicates *) + is_lock_ne f γ lk : Contractive (is_lock f γ lk); + is_lock_persistent γ lk R : Fractional (fun f => is_lock f γ lk R); + is_lock_iff f γ lk R1 R2 : + is_lock f γ lk R1 -∗ ▷ □ (R1 ↔ R2) -∗ is_lock f γ lk R2; + locked_timeless γ : Timeless (locked γ); + locked_exclusive γ : locked γ -∗ locked γ -∗ False; + (** * Program specs *) + newlock_spec (R : iProp Σ) : + {{{ R }}} newlock #() {{{ lk γ, RET lk; is_lock 1 γ lk R }}}; + acquire_spec f γ lk R : + {{{ is_lock f γ lk R }}} acquire lk {{{ RET #(); is_lock f γ lk R ∗ locked γ ∗ R }}}; + release_spec f γ lk R : + {{{ is_lock f γ lk R ∗ locked γ ∗ R }}} release lk {{{ RET #(); is_lock f γ lk R }}}; + freelock_spec γ lk (R : iProp Σ) : + {{{ is_lock 1 γ lk R ∗ R }}} freelock #() {{{ RET #(); R }}} +}. + +Inductive state := Free | Locked. + +Class lockG Σ := LockG { lock_tokG : ghost_varG Σ state }. +Local Existing Instance lock_tokG. +Definition lockΣ : gFunctors := #[ghost_varΣ state]. +Global Instance subG_lockΣ {Σ} : subG lockΣ Σ → lockG Σ. +Proof. solve_inG. Qed. + +Section tada. + Context `{!heapGS Σ, !lockG Σ} (l : lock). + + Record tada_lock_name := TadaLockName { + tada_lock_name_state : gname; + tada_lock_name_lock : l.(name); + }. + + Definition tada_is_lock f (γ : tada_lock_name) (lk : val) : iProp Σ := + l.(is_lock) f γ.(tada_lock_name_lock) lk + (ghost_var γ.(tada_lock_name_state) (1/4) Free). + Definition tada_lock_state f (γ : tada_lock_name) (lk : val) (s : state) : iProp Σ := + tada_is_lock f γ lk ∗ ghost_var γ.(tada_lock_name_state) (3/4) s ∗ + if s is Locked then + l.(locked) γ.(tada_lock_name_lock) ∗ ghost_var γ.(tada_lock_name_state) (1/4) Locked + else True. + + Lemma tada_lock_state_exclusive f1 f2 γ lk s1 s2 : + tada_lock_state f1 γ lk s1 -∗ tada_lock_state f2 γ lk s2 -∗ False. + Proof. + iIntros "[_ [Hvar1 _]] [_ [Hvar2 _]]". + iDestruct (ghost_var_valid_2 with "Hvar1 Hvar2") as %[Hval _]. + exfalso. done. + Qed. + + Lemma newlock_tada_spec : + {{{ True }}} + l.(newlock) #() + {{{ lk γ, RET lk; tada_lock_state 1 γ lk Free }}}. + Proof. + iIntros (Φ) "_ HΦ". + iMod (ghost_var_alloc Free) as (γvar) "Hvar". + rewrite -{2}Qp.three_quarter_quarter. + iDestruct "Hvar" as "[Hvar1 Hvar2]". + wp_apply (l.(newlock_spec) with "Hvar2"). + iIntros (lk γlock) "Hlock". + iApply ("HΦ" $! lk (TadaLockName _ _)). + iFrame. + Qed. + + Lemma acquire_tada_spec f γ (lk : val) : + ⊢<<{ ∀ s, tada_lock_state f γ lk s }>> + l.(acquire) lk @ ∅ + <<{ tada_lock_state f γ lk Locked | RET #() }>>. + Proof. + iIntros "%Φ AU". + iApply fupd_wp. + iMod "AU" as "[Hislock [Hclose _]]". + (* we have l.(is_lock), but have to return it before applying l.(acquire_spec) -- + probably need the loan trick from freeable_logatom_lock *) + iMod ("Hclose" with "[$Hislock]") as "AU". + iModIntro. + iApply wp_fupd. + wp_apply (l.(acquire_spec)). +(* iIntros "[Hlocked Hvar1]". + iMod "AU" as (s) "[[_ [Hvar2 _]] [_ Hclose]]". + iDestruct (ghost_var_agree with "Hvar1 Hvar2") as %<-. + iMod (ghost_var_update_2 Locked with "Hvar1 Hvar2") as "[Hvar1 Hvar2]". + { admit. } + iMod ("Hclose" with "[$Hislock $Hvar2 $Hlocked $Hvar1]"). done. + Qed.*) + Abort. + +End tada. -- GitLab