Next Obligation.
intro cs; hnf.
intros.
destruct x as [[[[v sh] sh'] Q] R]; simpl in *.
apply (nonexpansive2_super_non_expansive
(fun Q R => (PROP (writable_share sh)
LOCAL (temp _lock v)
SEP (weak_exclusive_mpred R && weak_rec_inv sh' v Q R && emp; lock_inv sh v R)) rho));
[ clear Q R; intros Q;
apply (PROP_LOCAL_SEP_nonexpansive
((fun _ => writable_share sh) :: nil)
(temp _lock v :: nil)
((fun R => weak_exclusive_mpred R && weak_rec_inv sh' v Q R && emp)%logic :: (fun R => lock_inv sh v R) :: nil))
| clear Q R; intros R;
apply (PROP_LOCAL_SEP_nonexpansive
((fun _ => writable_share sh) :: nil)
(temp _lock v :: nil)
((fun Q => weak_exclusive_mpred R && weak_rec_inv sh' v Q R && emp)%logic :: (fun _ => lock_inv sh v R) :: nil))];
repeat apply Forall_cons; try apply Forall_nil.
+ apply const_nonexpansive.
+ apply (conj_nonexpansive (fun R => weak_exclusive_mpred R && weak_rec_inv sh' v Q R)%logic); [apply (conj_nonexpansive weak_exclusive_mpred) |].
- apply exclusive_mpred_nonexpansive.
- apply rec_inv1_nonexpansive.
- apply const_nonexpansive.
+ apply nonexpansive_lock_inv.
+ apply const_nonexpansive.
+ apply (conj_nonexpansive (fun Q => weak_exclusive_mpred R && weak_rec_inv sh' v Q R)%logic); [apply (conj_nonexpansive (fun _ => weak_exclusive_mpred R)) |].
- apply const_nonexpansive.
- apply rec_inv2_nonexpansive.
- apply const_nonexpansive.
+ apply const_nonexpansive.
Qed.
Next Obligation.
intro cs; hnf.
intros.
destruct x as [[[[v sh] sh'] Q] R]; simpl in *.
auto.
Qed.
Program Definition release2_spec: funspec := mk_funspec
((_lock OF tptr Tvoid)%formals :: nil, tvoid)
cc_default
(rmaps.ProdType (rmaps.ProdType (rmaps.ConstType (val * share)) rmaps.Mpred) rmaps.Mpred)
(fun _ x =>
match x with
| (v, sh, Q, R) =>
PROP (readable_share sh)
LOCAL (temp _lock v)
SEP (weak_exclusive_mpred R && weak_rec_inv sh v Q R && emp; R)
end)
(fun _ x =>
match x with
| (v, sh, Q, R) =>
PROP ()
LOCAL ()
SEP (emp)
end)
_
_
.
Next Obligation.
intro cs; hnf.
intros.
destruct x as [[[v sh] Q] R]; simpl in *.
apply (nonexpansive2_super_non_expansive
(fun Q R => (PROP (readable_share sh)
LOCAL (temp _lock v)
SEP (weak_exclusive_mpred R && weak_rec_inv sh v Q R && emp; R)) rho));
[ clear Q R; intros Q;
apply (PROP_LOCAL_SEP_nonexpansive
((fun _ => readable_share sh) :: nil)
(temp _lock v :: nil)
((fun R => weak_exclusive_mpred R && weak_rec_inv sh v Q R && emp)%logic :: (fun R => R) :: nil))
| clear Q R; intros R;
apply (PROP_LOCAL_SEP_nonexpansive
((fun _ => readable_share sh) :: nil)
(temp _lock v :: nil)
((fun Q => weak_exclusive_mpred R && weak_rec_inv sh v Q R && emp)%logic :: (fun _ => R) :: nil))];
repeat apply Forall_cons; try apply Forall_nil.
+ apply const_nonexpansive.
+ apply (conj_nonexpansive (fun R => weak_exclusive_mpred R && weak_rec_inv sh v Q R)%logic); [apply (conj_nonexpansive (fun R => weak_exclusive_mpred R)%logic) |].
- apply exclusive_mpred_nonexpansive.
- apply rec_inv1_nonexpansive.
- apply const_nonexpansive.
+ apply identity_nonexpansive.
+ apply const_nonexpansive.
+ apply (conj_nonexpansive (fun Q => weak_exclusive_mpred R && weak_rec_inv sh v Q R)%logic); [apply (conj_nonexpansive (fun Q => weak_exclusive_mpred R)%logic) |].
- apply const_nonexpansive.
- apply rec_inv2_nonexpansive.
- apply const_nonexpansive.
+ apply const_nonexpansive.
Qed.
Next Obligation.
intro cs; hnf.
intros.
destruct x as [[[v sh] Q] R]; simpl in *.
auto.
Qed.
(* condition variables *)
Definition makecond_spec cs :=
WITH v : val, sh : share
PRE [ _cond OF tptr tcond ]
PROP (writable_share sh)
LOCAL (temp _cond v)
SEP (@data_at_ cs sh tcond v)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP (cond_var sh v).
Definition freecond_spec cs :=
WITH v : val, sh : share
PRE [ _cond OF tptr tcond ]
PROP (writable_share sh)
LOCAL (temp _cond v)
SEP (@cond_var cs sh v)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP (@data_at_ cs sh tcond v).
Program Definition wait_spec cs: funspec := mk_funspec
((_cond OF tptr tcond)%formals :: (_lock OF tptr Tvoid)%formals :: nil, tvoid)
cc_default
(rmaps.ProdType (rmaps.ConstType (val * val * share * share)) rmaps.Mpred)
(fun _ x =>
match x with
| (c, l, shc, shl, R) =>
PROP (readable_share shc)
LOCAL (temp _cond c; temp _lock l)
SEP (@cond_var cs shc c; lock_inv shl l R; R)
end)
(fun _ x =>
match x with
| (c, l, shc, shl, R) =>
PROP ()
LOCAL ()
SEP (cond_var shc c; lock_inv shl l R; R)
end)
_
_
.
Next Obligation.
intros cs; hnf.
intros.
destruct x as [[[[c l] shc] shl] R]; simpl in *.
apply (nonexpansive_super_non_expansive
(fun R => (PROP (readable_share shc)
LOCAL (temp _cond c; temp _lock l)
SEP (cond_var shc c; lock_inv shl l R; R)) rho)).
apply (PROP_LOCAL_SEP_nonexpansive
((fun _ => readable_share shc) :: nil)
(temp _cond c :: temp _lock l :: nil)
((fun R => cond_var shc c) :: (fun R => lock_inv shl l R) :: (fun R => R) :: nil));
repeat apply Forall_cons; try apply Forall_nil.
+ apply const_nonexpansive.
+ apply const_nonexpansive.
+ apply nonexpansive_lock_inv.
+ apply identity_nonexpansive.
Qed.
Next Obligation.
intros cs; hnf.
intros.
destruct x as [[[[c l] shc] shl] R]; simpl in *.
apply (nonexpansive_super_non_expansive
(fun R => (PROP ()
LOCAL ()
SEP (cond_var shc c; lock_inv shl l R; R)) rho)).
apply (PROP_LOCAL_SEP_nonexpansive
nil
nil
((fun R => cond_var shc c) :: (fun R => lock_inv shl l R) :: (fun R => R) :: nil));
repeat apply Forall_cons; try apply Forall_nil.
+ apply const_nonexpansive.
+ apply nonexpansive_lock_inv.
+ apply identity_nonexpansive.
Qed.
Program Definition wait2_spec cs: funspec := mk_funspec
((_cond OF tptr tcond)%formals :: (_lock OF tptr Tvoid)%formals :: nil, tvoid)
cc_default
(rmaps.ProdType (rmaps.ConstType (val * val * share * share)) rmaps.Mpred)
(fun _ x =>
match x with
| (c, l, shc, shl, R) =>
PROP (readable_share shc)
LOCAL (temp _cond c; temp _lock l)
SEP (lock_inv shl l R; R && (@cond_var cs shc c * TT))
end)
(fun _ x =>
match x with
| (c, l, shc, shl, R) =>
PROP ()
LOCAL ()
SEP (lock_inv shl l R; R)
end)
_
_
.
Next Obligation.
intros cs; hnf.
intros.
destruct x as [[[[c l] shc] shl] R]; simpl in *.
apply (nonexpansive_super_non_expansive
(fun R => (PROP (readable_share shc)
LOCAL (temp _cond c; temp _lock l)
SEP (lock_inv shl l R; R && (@cond_var cs shc c * TT))) rho)).
apply (PROP_LOCAL_SEP_nonexpansive
((fun _ => readable_share shc) :: nil)
(temp _cond c :: temp _lock l :: nil)
((fun R => lock_inv shl l R) :: (fun R => R && (@cond_var cs shc c * TT))%logic :: nil));
repeat apply Forall_cons; try apply Forall_nil.
+ apply const_nonexpansive.
+ apply nonexpansive_lock_inv.
+ apply (conj_nonexpansive (fun R => R) (fun _ => (cond_var shc c * TT)%logic)).
- apply identity_nonexpansive.
- apply const_nonexpansive.
Qed.
Next Obligation.
intros cs; hnf.
intros.
destruct x as [[[[c l] shc] shl] R]; simpl in *.
apply (nonexpansive_super_non_expansive
(fun R => (PROP ()
LOCAL ()
SEP (lock_inv shl l R; R)) rho)).
apply (PROP_LOCAL_SEP_nonexpansive
nil
nil
((fun R => lock_inv shl l R) :: (fun R => R) :: nil));
repeat apply Forall_cons; try apply Forall_nil.
+ apply nonexpansive_lock_inv.
+ apply identity_nonexpansive.
Qed.
Definition signal_spec cs :=
WITH c : val, shc : share
PRE [ _cond OF tptr tcond ]
PROP (readable_share shc)
LOCAL (temp _cond c)
SEP (@cond_var cs shc c)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP (@cond_var cs shc c).
(* Notes about spawn_thread:  The spawned function has for argument name [_y], which is existentially quantified.  The function also can use a list of global variables [globals].  For now, the specification of the spawned function has to be exactly of the form that you can see below (inside the "match ..."). Cao Qinxiang is working on a notion of sub-specification that might enable us to have smoother specifications.  The postcondition might not be emp, so we have potential memory leaks when a thread exists (those maps are still handled by the concurrent machine).  To enable joinable threads, the postcondition would be [tptr tthread] with a type [tthread] related to the postcondition through a [thread] predicate in the logic.  The [join] would then also be implemented using the oracle, as [acquire] is.  The postcondition would be [match PrePost with existT ty (w, pre, post) => thread th (post w b) end] *)
Local Open Scope logic.
(* @Qinxiang: it would be great to complete the annotation *)
Definition spawn_arg_type := rmaps.ProdType (rmaps.ProdType (rmaps.ProdType (rmaps.ConstType (val * val))
(rmaps.ArrowType (rmaps.DependentType 0) (rmaps.ConstType globals))) (rmaps.DependentType 0))
(rmaps.ArrowType (rmaps.DependentType 0) (rmaps.ArrowType (rmaps.ConstType val) rmaps.Mpred)).
Definition spawn_pre :=
(fun (ts: list Type) (x: val * val * (nth 0 ts unit -> globals) * nth 0 ts unit *
(nth 0 ts unit -> val -> mpred)) =>
match x with
| (f, b, gv, w, pre) =>
PROP (tc_val (tptr Tvoid) b)
(LOCALx (temp _f f :: temp _args b :: gvars (gv w) :: nil)
(SEP (
EX _y : ident,
(func_ptr'
(WITH y : val, x : nth 0 ts unit
PRE [ _y OF tptr tvoid ]
PROP ()
(LOCALx (temp _y y :: gvars (gv x) :: nil)
(SEP   (pre x y)))
POST [tptr tvoid]
PROP  ()
LOCAL ()
SEP   ())
f);
pre w b)))
end).
Definition spawn_post :=
(fun (ts: list Type) (x: val * val * (nth 0 ts unit -> globals) * nth 0 ts unit *
(nth 0 ts unit -> val -> mpred)) =>
match x with
| (f, b, w, pre) =>
PROP ()
LOCAL ()
SEP ()
end).

Lemma spawn_post_nonexpansive: @super_non_expansive spawn_arg_type spawn_post.
Definition spawn_spec := mk_funspec
((_f OF tptr voidstar_funtype)%formals :: (_args OF tptr tvoid)%formals :: nil, tvoid)
cc_default
spawn_arg_type
spawn_pre
spawn_post
spawn_pre_nonexpansive
spawn_post_nonexpansive.