Require Import Blockset Footprint GMemory InteractionSemantics GlobDefs GAST ETrace NPSemantics.
Require Import GlobSim.
NP-DRF
This file defines a non-preemptive version of data-race-free property
Local Notation "'[['
thdp ','
t ','
m ','
b ']]'" :=
({|
thread_pool:=
thdp;
cur_tid:=
t;
gm:=
m;
atom_bit:=
b |})
(
at level 70,
right associativity).
Local Notation "'[['
thdp ','
t ','
m ','
b ']]@'
G " :=
(
Build_ProgConfig G thdp t m b) (
at level 70,
right associativity).
Local Notation "
GE '|-'
pc1 '=['
l '|'
fp ']=>>'
pc2 " :=
(@
np_step GE pc1 l fp pc2) (
at level 80,
right associativity).
Inductive np_ent_atom {
GE} :
ProgConfig ->
tid ->
ProgConfig ->
Prop :=
|
np_ent_atom_intro:
forall thdp tid gm thdp'
gm',
GE |- [[
thdp,
tid,
gm,
O]] =[
tau |
FP.emp]=>> [[
thdp',
tid,
gm',
I]] ->
np_ent_atom ([[
thdp,
tid,
gm,
O]])
tid ([[
thdp',
tid,
gm',
I]]).
Corollary tau_step_bitchange_np_ent_atom :
forall ge pc pc1,
ge|-
pc =[
tau|
FP.emp]=>>
pc1 ->
atom_bit pc <>
atom_bit pc1 ->
np_ent_atom pc pc.(
cur_tid)
pc1.
Proof.
intros.
inversion H;subst;try contradiction.
constructor;auto.
Qed.
Corollary np_ent_atom_tau_step_bitchange:
forall ge pc pc1 id,
np_ent_atom pc id pc1->
(
ge|-
pc =[
tau|
FP.emp]=>>
pc1) /\
atom_bit pc <>
atom_bit pc1 /\
id =
cur_tid pc.
Proof.
intros.
inversion H;clear H;subst.
split;auto.
split;auto.
compute.
intro.
inversion H.
Qed.
this relation np_normal_tau pc t b fp pc' states that
- pc could step to another configuration pc', with zero or more tau steps of thread t.
- All intermediate states has atomic bit b,
- and we accumulate the footprint of all step in fp.
Inductive np_normal_tau {
GE} : @
ProgConfig GE ->
tid ->
Bit ->
FP.t ->
ProgConfig ->
Prop :=
|
predict_nil:
forall thdp t gm b,
np_normal_tau ([[
thdp,
t,
gm,
b]])
t b FP.emp ([[
thdp,
t,
gm,
b]])
|
predict_cons:
forall thdp t gm b fp thdp'
gm'
fp'
pc',
GE |- [[
thdp,
t,
gm,
b]] =[
tau |
fp ]=>> [[
thdp',
t,
gm',
b]] ->
np_normal_tau ([[
thdp',
t,
gm',
b]])
t b fp'
pc' ->
np_normal_tau ([[
thdp,
t,
gm,
b]])
t b (
FP.union fp fp')
pc'.
Lemma tau_step_bitpreservation_np_normal_tau :
forall ge pc pc1 fp,
@
np_step ge pc tau fp pc1 ->
atom_bit pc =
atom_bit pc1 ->
np_normal_tau pc pc.(
cur_tid)
pc.(
atom_bit)
fp pc1.
Proof.
Lemma tau_N_bitpreservation_np_normal_tau:
forall i ge pc pc1 fp ,
tau_N (@
np_step ge)
i pc fp pc1->
atom_bit pc =
atom_bit pc1 ->
np_normal_tau pc pc.(
cur_tid)
pc.(
atom_bit)
fp pc1.
Proof.
induction i.
{
intros.
inversion H;
subst.
destruct pc1.
constructor.
}
{
intros.
inversion H;
clear H;
subst.
pose GlobSim.tau_N_tau_step_bit_rule.
pose proof H2 as P1.
eapply e in H2;
eauto.
rewrite H0 in H2.
symmetry in H2.
eapply IHi in H2;
eauto.
pose @
predict_cons .
destruct pc,
pc1,
s'.
assert(
cur_tid=
cur_tid1).
inversion P1;
subst;
auto.
assert(
atom_bit=
atom_bit1).
inversion P1;
subst;
try contradiction;
auto.
apply GlobSim.tau_N_bit_I_preservation in H3;
auto.
compute in H0,
H3;
rewrite <-
H0 in H3;
auto.
subst.
eapply n in P1;
eauto.
}
Qed.
Lemma np_normal_tau_N_exists:
forall ge pc pc1 fp id bit,
np_normal_tau pc id bit fp pc1 ->
atom_bit pc =
atom_bit pc1 /\
atom_bit pc =
bit /\
cur_tid pc =
id /\
exists i,
tau_N (@
np_step ge)
i pc fp pc1.
Proof.
intros.
induction H.
{
split;
auto.
split;
auto.
split;
auto.
exists 0;
constructor.
}
{
destruct IHnp_normal_tau as[
eq[
eq2[
eq3 [
i ] ] ] ].
split;
auto.
split;
auto.
split;
auto.
exists (
S i);
econstructor 2;
eauto.
}
Qed.
Corollary np_normal_iff_tau_star_bitpreservation :
forall ge pc pc1 fp id bit,
np_normal_tau pc id bit fp pc1 <->
atom_bit pc =
atom_bit pc1 /\
atom_bit pc =
bit /\
cur_tid pc =
id /\
tau_star (@
np_step ge)
pc fp pc1.
Proof.
The non-preemptive "prediction"s
We do prediction on a program configuration for some thread t
np_predict is the non-preemptive version of predict.
We predict two sections of footprints, the former is predicted outside atomic blocks, the latter (if exists) is predicted inside the atomic blocks.
-- Note that np_normal_tau means one or multiple tau steps, so we may predict multiple steps in non-preemptive in one time.
Inductive np_predict {
ge:
GlobEnv.t}: @
ProgConfig ge ->
tid ->
FP.t ->
FP.t ->
Prop :=
|
np_predict_only_tau:
forall thdp i'
gm i fp0 pc',
np_normal_tau ([[
thdp,
i,
gm,
O]])
i O fp0 pc'->
np_predict ([[
thdp,
i',
gm,
O]])
i fp0 FP.emp
|
np_predict_with_atom:
forall thdp i'
gm i fp0 pc'
pc''
fp1 pc''',
np_normal_tau ([[
thdp,
i,
gm,
O]])
i O fp0 pc' ->
np_ent_atom pc'
i pc'' ->
np_normal_tau pc''
i I fp1 pc''' ->
np_predict ([[
thdp,
i',
gm,
O]])
i fp0 fp1.
It is not conflicting if the footprints are both predicted inside atomic blocks.
Inductive conflict_fps:
FP.t *
FP.t ->
FP.t *
FP.t ->
Prop :=
|
conflict_fps_00:
forall fp10 fp11 fp20 fp21,
FP.conflict fp10 fp20 ->
conflict_fps (
fp10,
fp11) (
fp20,
fp21)
|
conflict_fps_10:
forall fp10 fp11 fp20 fp21,
FP.conflict fp11 fp20 ->
conflict_fps (
fp10,
fp11) (
fp20,
fp21)
|
conflict_fps_01:
forall fp10 fp11 fp20 fp21,
FP.conflict fp10 fp21 ->
conflict_fps (
fp10,
fp11) (
fp20,
fp21).
The definition of data-race in non-preemptive.
Configuration S is racy if two different threads of S are predicted to generated conflicting footprints and at least one thread is not predicted inside atomic block.
Inductive np_race_config {
ge:
GlobEnv.t} : @
ProgConfig ge ->
Prop :=
NP_Race_config:
forall s t1 fp10 fp11 t2 fp20 fp21,
t1 <>
t2 ->
np_predict s t1 fp10 fp11 ->
np_predict s t2 fp20 fp21 ->
conflict_fps (
fp10,
fp11) (
fp20,
fp21) ->
np_race_config s.
np_star_race_config requires the prediction be made at switching points.
Inductive np_star_race_config {
ge:
GlobEnv.t} : @
ProgConfig ge ->
Prop :=
|
NP_Race_point:
forall s l fp s',
np_step s l fp s' ->
l <>
tau ->
np_race_config s' ->
np_star_race_config s
|
NP_Race_progress:
forall s l fp s',
np_step s l fp s' ->
np_star_race_config s' ->
np_star_race_config s.
Either the prediction is made exactly after the initialization, or it is made after switching points.
Inductive np_race_prog {
NL:
nat} {
L: @
langs NL} :
prog L ->
Prop :=
|
NPRace_init:
forall p gm ge s t,
init_config p gm ge s t ->
np_race_config s ->
np_race_prog p
|
NPRace_plus:
forall p gm ge s t,
init_config p gm ge s t ->
np_star_race_config s ->
np_race_prog p.
Definition npdrf {
NL} {
L}
p:
Prop := ~ @
np_race_prog NL L p.