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

fix lock spec code depending on Σ

parent 0d0ae3d3
No related branches found
No related tags found
No related merge requests found
...@@ -8,42 +8,52 @@ All parameters are implicit, since it is expected that there is only one ...@@ -8,42 +8,52 @@ All parameters are implicit, since it is expected that there is only one
[heapGS_gen] in scope that could possibly apply. [heapGS_gen] in scope that could possibly apply.
Only one instance of this class should ever be in scope. To write a library that Only one instance of this class should ever be in scope. To write a library that
is generic over the lock, just add a [`{lock}] implicit parameter. To use a is generic over the lock, just add a [`{!lock}] implicit parameter around the
particular lock instance, use [Local Existing Instance <lock instance>]. code and [`{!lockG Σ}] around the proofs. To use a particular lock instance, use
[Local Existing Instance <lock instance>].
When writing an instance of this class, please take care not to shadow the class When writing an instance of this class, please take care not to shadow the class
projections (e.g., either use [Local Definition newlock] or avoid the name projections (e.g., either use [Local Definition newlock] or avoid the name
[newlock] altogether), and do not register an instance -- just make it a [newlock] altogether), and do not register an instance -- just make it a
[Definition] that others can register later. *) [Definition] that others can register later. *)
Class lock `{!heapGS_gen hlc Σ} := Lock { Class lock := Lock {
(** * Operations *) (** * Operations *)
newlock : val; newlock : val;
acquire : val; acquire : val;
release : val; release : val;
(** * Predicates *) (** * Ghost state *)
(** [name] is used to associate locked with [is_lock] *) (** The assumptions about [Σ] *)
lockG : gFunctors Type;
(** [name] is used to associate [locked] with [is_lock] *)
lock_name : Type; lock_name : Type;
(** * Predicates *)
(** No namespace [N] parameter because we only expose program specs, which (** No namespace [N] parameter because we only expose program specs, which
anyway have the full mask. *) anyway have the full mask. *)
is_lock (γ: lock_name) (lock: val) (R: iProp Σ) : iProp Σ; is_lock `{!heapGS_gen hlc Σ} {L : lockG Σ} (γ: lock_name) (lock: val) (R: iProp Σ) : iProp Σ;
locked (γ: lock_name) : iProp Σ; locked `{!heapGS_gen hlc Σ} {L : lockG Σ} (γ: lock_name) : iProp Σ;
(** * General properties of the predicates *) (** * General properties of the predicates *)
is_lock_persistent γ lk R :> Persistent (is_lock γ lk R); is_lock_persistent `{!heapGS_gen hlc Σ} {L : lockG Σ} γ lk R :>
is_lock_iff γ lk R1 R2 : Persistent (is_lock (L:=L) γ lk R);
is_lock γ lk R1 -∗ (R1 ∗-∗ R2) -∗ is_lock γ lk R2; is_lock_iff `{!heapGS_gen hlc Σ} {L : lockG Σ} γ lk R1 R2 :
locked_timeless γ :> Timeless (locked γ); is_lock (L:=L) γ lk R1 -∗ (R1 ∗-∗ R2) -∗ is_lock (L:=L) γ lk R2;
locked_exclusive γ : locked γ -∗ locked γ -∗ False; locked_timeless `{!heapGS_gen hlc Σ} {L : lockG Σ} γ :>
Timeless (locked (L:=L) γ);
locked_exclusive `{!heapGS_gen hlc Σ} {L : lockG Σ} γ :
locked (L:=L) γ -∗ locked (L:=L) γ -∗ False;
(** * Program specs *) (** * Program specs *)
newlock_spec (R : iProp Σ) : newlock_spec `{!heapGS_gen hlc Σ} {L : lockG Σ} (R : iProp Σ) :
{{{ R }}} newlock #() {{{ lk γ, RET lk; is_lock γ lk R }}}; {{{ R }}} newlock #() {{{ lk γ, RET lk; is_lock (L:=L) γ lk R }}};
acquire_spec γ lk R : acquire_spec `{!heapGS_gen hlc Σ} {L : lockG Σ} γ lk R :
{{{ is_lock γ lk R }}} acquire lk {{{ RET #(); locked γ R }}}; {{{ is_lock (L:=L) γ lk R }}} acquire lk {{{ RET #(); locked (L:=L) γ R }}};
release_spec γ lk R : release_spec `{!heapGS_gen hlc Σ} {L : lockG Σ} γ lk R :
{{{ is_lock γ lk R locked γ R }}} release lk {{{ RET #(); True }}} {{{ is_lock (L:=L) γ lk R locked (L:=L) γ R }}} release lk {{{ RET #(); True }}}
}. }.
Global Hint Mode lock + + + : typeclass_instances.
Global Instance is_lock_contractive `{!heapGS_gen hlc Σ, !lock} γ lk : Existing Class lockG.
Global Hint Mode lockG + + : typeclass_instances.
Global Hint Extern 0 (lockG _) => progress simpl : typeclass_instances.
Global Instance is_lock_contractive `{!heapGS_gen hlc Σ, !lock, !lockG Σ} γ lk :
Contractive (is_lock γ lk). Contractive (is_lock γ lk).
Proof. Proof.
apply (uPred.contractive_internal_eq (M:=iResUR Σ)). apply (uPred.contractive_internal_eq (M:=iResUR Σ)).
...@@ -52,5 +62,5 @@ Proof. ...@@ -52,5 +62,5 @@ Proof.
iNext; iRewrite "HPQ"; auto. iNext; iRewrite "HPQ"; auto.
Qed. Qed.
Global Instance is_lock_proper `{!heapGS_gen hlc Σ, !lock} γ lk : Global Instance is_lock_proper `{!heapGS_gen hlc Σ, !lock, !lockG Σ} γ lk :
Proper (() ==> ()) (is_lock γ lk) := ne_proper _. Proper (() ==> ()) (is_lock γ lk) := ne_proper _.
...@@ -18,14 +18,14 @@ From iris.prelude Require Import options. ...@@ -18,14 +18,14 @@ From iris.prelude Require Import options.
Inductive state := Free | Locked. Inductive state := Free | Locked.
Class lockG Σ := LockG { lock_tokG : ghost_varG Σ state }. Class alockG Σ := LockG { lock_tokG : ghost_varG Σ state }.
Local Existing Instance lock_tokG. Local Existing Instance lock_tokG.
Definition lockΣ : gFunctors := #[ghost_varΣ state]. Definition alockΣ : gFunctors := #[ghost_varΣ state].
Global Instance subG_lockΣ {Σ} : subG lockΣ Σ lockG Σ. Global Instance subG_alockΣ {Σ} : subG alockΣ Σ alockG Σ.
Proof. solve_inG. Qed. Proof. solve_inG. Qed.
Section tada. Section tada.
Context `{!heapGS Σ, !lockG Σ, !lock}. Context `{!heapGS Σ, !alockG Σ, !lock, !lockG Σ}.
Record tada_lock_name := TadaLockName { Record tada_lock_name := TadaLockName {
tada_lock_name_state : gname; tada_lock_name_state : gname;
......
...@@ -14,16 +14,16 @@ Local Definition release : val := λ: "l", "l" <- #false. ...@@ -14,16 +14,16 @@ Local Definition release : val := λ: "l", "l" <- #false.
(** The CMRA we need. *) (** The CMRA we need. *)
(* Not bundling heapGS, as it may be shared with other users. *) (* Not bundling heapGS, as it may be shared with other users. *)
Class lockG Σ := LockG { lock_tokG : inG Σ (exclR unitO) }. Class spin_lockG Σ := LockG { lock_tokG : inG Σ (exclR unitO) }.
Local Existing Instance lock_tokG. Local Existing Instance lock_tokG.
Definition lockΣ : gFunctors := #[GFunctor (exclR unitO)]. Definition spin_lockΣ : gFunctors := #[GFunctor (exclR unitO)].
Global Instance subG_lockΣ {Σ} : subG lockΣ Σ lockG Σ. Global Instance subG_spin_lockΣ {Σ} : subG spin_lockΣ Σ spin_lockG Σ.
Proof. solve_inG. Qed. Proof. solve_inG. Qed.
Section proof. Section proof.
Context `{!heapGS_gen hlc Σ, !lockG Σ}. Context `{!heapGS_gen hlc Σ, !spin_lockG Σ}.
Let N := nroot .@ "spin_lock". Let N := nroot .@ "spin_lock".
Local Definition lock_inv (γ : gname) (l : loc) (R : iProp Σ) : iProp Σ := Local Definition lock_inv (γ : gname) (l : loc) (R : iProp Σ) : iProp Σ :=
...@@ -92,7 +92,12 @@ Section proof. ...@@ -92,7 +92,12 @@ Section proof.
Qed. Qed.
End proof. End proof.
Definition spin_lock `{!heapGS_gen hlc Σ, !lockG Σ} : lock := (* NOT an instance because users should choose explicitly to use it
{| lock.locked_exclusive := locked_exclusive; lock.is_lock_iff := is_lock_iff; (using [Explicit Instance]). *)
lock.newlock_spec := newlock_spec; Definition spin_lock : lock :=
lock.acquire_spec := acquire_spec; lock.release_spec := release_spec |}. {| lock.lockG := spin_lockG;
lock.locked_exclusive _ _ _ _ := locked_exclusive;
lock.is_lock_iff _ _ _ _ := is_lock_iff;
lock.newlock_spec _ _ _ _ := newlock_spec;
lock.acquire_spec _ _ _ _ := acquire_spec;
lock.release_spec _ _ _ _ := release_spec |}.
...@@ -163,7 +163,10 @@ Section proof. ...@@ -163,7 +163,10 @@ Section proof.
Qed. Qed.
End proof. End proof.
Definition ticket_lock `{!heapGS_gen hlc Σ, !tlockG Σ} : lock := Definition ticket_lock : lock :=
{| lock.locked_exclusive := locked_exclusive; lock.is_lock_iff := is_lock_iff; {| lock.lockG := tlockG;
lock.newlock_spec := newlock_spec; lock.locked_exclusive _ _ _ _ := locked_exclusive;
lock.acquire_spec := acquire_spec; lock.release_spec := release_spec |}. lock.is_lock_iff _ _ _ _ := is_lock_iff;
lock.newlock_spec _ _ _ _ := newlock_spec;
lock.acquire_spec _ _ _ _ := acquire_spec;
lock.release_spec _ _ _ _ := release_spec |}.
From iris.base_logic.lib Require Import gen_inv_heap invariants. From iris.base_logic.lib Require Import gen_inv_heap invariants.
From iris.program_logic Require Export weakestpre total_weakestpre. From iris.program_logic Require Export weakestpre total_weakestpre.
From iris.heap_lang Require Import lang adequacy total_adequacy proofmode notation lib.lock. From iris.heap_lang Require Import lang adequacy total_adequacy proofmode notation lib.spin_lock.
From iris.prelude Require Import options. From iris.prelude Require Import options.
Unset Mangle Names. Unset Mangle Names.
...@@ -516,7 +516,7 @@ Qed. ...@@ -516,7 +516,7 @@ Qed.
(** Just making sure the lock typeclass actually works. *) (** Just making sure the lock typeclass actually works. *)
Section lock. Section lock.
Context `{!heapGS Σ, !lock}. Context `{!lock}.
Definition lock_client : val := Definition lock_client : val :=
λ: "loc" "lock", λ: "loc" "lock",
...@@ -524,6 +524,8 @@ Section lock. ...@@ -524,6 +524,8 @@ Section lock.
"loc" <- #42;; "loc" <- #42;;
release "lock". release "lock".
Context `{!heapGS Σ, !lockG Σ}.
Lemma wp_lock_client loc lock γ : Lemma wp_lock_client loc lock γ :
is_lock γ lock ( v, loc v) -∗ is_lock γ lock ( v, loc v) -∗
WP lock_client #loc lock {{ _, True }}. WP lock_client #loc lock {{ _, True }}.
...@@ -535,6 +537,28 @@ Section lock. ...@@ -535,6 +537,28 @@ Section lock.
{ iFrame "Hislock". eauto. } { iFrame "Hislock". eauto. }
eauto. eauto.
Qed. Qed.
End lock. End lock.
Section spin_lock.
Local Existing Instance spin_lock.
Definition spin_lock_client : val :=
λ: "loc" "lock",
acquire "lock";;
"loc" <- #42;;
release "lock".
(* Making sure that using [spin_lockG] here works, not just [lockG]. *)
Context `{!heapGS Σ, !spin_lockG Σ}.
Lemma wp_spin_lock_client loc lock γ :
is_lock γ lock ( v, loc v) -∗
WP spin_lock_client #loc lock {{ _, True }}.
Proof.
iIntros "#Hislock".
wp_lam. wp_smart_apply (acquire_spec with "Hislock") as "[Hlocked [%v Hloc]]".
wp_store.
wp_smart_apply (release_spec with "[$Hlocked Hloc]").
{ iFrame "Hislock". eauto. }
eauto.
Qed.
End spin_lock.
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