Section ConcurMatch. (* 360 *)
Record concur_match (ocd: option compiler_index)
(j:meminj) (cstate1: ThreadPool (Some hb)) (m1: Mem.mem) (cstate2: ThreadPool(Some (S hb))) (m2: mem):=
{ same_length: num_threads cstate1 = num_threads cstate2
; full_inj: Events.injection_full j m1 (* this is needed until we can prove
permission transfer is not deleted*)
; memcompat1: mem_compatible cstate1 m1
; memcompat2: mem_compatible cstate2 m2
(*; INJ: Mem.inject j m1 m2 *)
; lock_perm_preimage:
forall i (cnt1: ThreadPool.containsThread cstate1 i)
(cnt2: ThreadPool.containsThread cstate2 i),
perm_surj j (lock_perms _ _ cnt1) (lock_perms _ _  cnt2)
; INJ_threads:
forall i (cnt1: ThreadPool.containsThread cstate1 i)
(cnt2: ThreadPool.containsThread cstate2 i)
Hlt1 Hlt2,
Mem.inject j
(@restrPermMap (fst (ThreadPool.getThreadR cnt1)) m1 Hlt1)
(@restrPermMap (fst (ThreadPool.getThreadR cnt2)) m2 Hlt2)
; INJ_locks:
forall i (cnt1: ThreadPool.containsThread cstate1 i)
(cnt2: ThreadPool.containsThread cstate2 i)
Hlt1 Hlt2,
Mem.inject j
(@restrPermMap (snd (ThreadPool.getThreadR cnt1)) m1 Hlt1)
(@restrPermMap (snd (ThreadPool.getThreadR cnt2)) m2 Hlt2)
; INJ_lock_permissions:
forall b b' delt opt_rmap,
j b = Some (b', delt) ->
forall ofs, lockRes cstate1 (b, unsigned ofs) = opt_rmap ->
lockRes cstate2 (b', unsigned (add ofs (repr delt))) =
(option_map (virtueLP_inject m2 j) opt_rmap)
; INJ_lock_content:
forall b ofs rmap,
lockRes cstate1 (b, ofs) = Some rmap ->
inject_lock j b ofs m1 m2
; source_invariant: invariant cstate1
; target_invariant: invariant cstate2
; mtch_source:
forall (i:nat),
(i > hb)%nat ->
forall  (cnt1: ThreadPool.containsThread cstate1 i)
(cnt2: ThreadPool.containsThread cstate2 i)
Hlt1 Hlt2,
match_thread_source j
(getThreadC cnt1)
(@restrPermMap (fst (ThreadPool.getThreadR cnt1)) m1 Hlt1)
(getThreadC cnt2)
(@restrPermMap (fst (ThreadPool.getThreadR cnt2)) m2 Hlt2)
; mtch_target:
forall (i:nat),
(i < hb)%nat ->
forall (cnt1: ThreadPool.containsThread cstate1 i)
(cnt2: ThreadPool.containsThread cstate2 i)
Hlt1 Hlt2,
match_thread_target  j
(getThreadC cnt1)
(@restrPermMap (fst (ThreadPool.getThreadR cnt1)) m1 Hlt1)
(getThreadC cnt2)
(@restrPermMap (fst (ThreadPool.getThreadR cnt2)) m2 Hlt2)
; mtch_compiled:
forall (i:nat),
(i = hb)%nat ->
forall (cnt1: ThreadPool.containsThread cstate1 i)
(cnt2: ThreadPool.containsThread cstate2 i)
Hlt1 Hlt2,
match_thread_compiled ocd j
(getThreadC cnt1)
(@restrPermMap (fst (ThreadPool.getThreadR cnt1)) m1 Hlt1)
(getThreadC cnt2)
(@restrPermMap (fst (ThreadPool.getThreadR cnt2)) m2 Hlt2) }.
Arguments INJ_locks {ocd j cstate1 m1 cstate2 m2}.
Arguments memcompat1 {ocd j cstate1 m1 cstate2 m2}.
Arguments memcompat2 {ocd j cstate1 m1 cstate2 m2}.
Inductive state_indicator:=
| Krun_indi
| Kblocked_indi
| Kresume_indi
| Kinit_indi.
Definition get_indicator {T: Type} (st:@ctl T): state_indicator:=
match st with
| Krun _ => Krun_indi
| Kblocked _ => Kblocked_indi
| Kresume _ _ => Kresume_indi
| Kinit _ _ => Kinit_indi
end.
Definition thread_indicator {Res Sem} i st cnt:=
get_indicator (@getThreadC Res Sem i st cnt).
Inductive individual_match i:
(option compiler_index) -> meminj -> ctl -> mem -> ctl -> mem -> Prop:=
|individual_mtch_source:
(i > hb)%nat ->
forall j s1 m1 s2 m2 cd,
match_thread_source j s1 m1 s2 m2 ->
individual_match i cd j s1 m1 s2 m2
|individual_mtch_target:
(i < hb)%nat ->
forall j s1 m1 s2 m2 cd,
match_thread_target j s1 m1 s2 m2 ->
individual_match  i cd j s1 m1 s2 m2
| individual_mtch_compiled:
(i = hb)%nat ->
forall cd j s1 m1 s2 m2,
match_thread_compiled cd j s1 m1 s2 m2 ->
individual_match i cd j s1 m1 s2 m2.
Inductive lock_update {hb}: nat -> ThreadPool hb -> Address.address ->
(Pair access_map) -> lock_info -> _ -> ThreadPool hb -> Prop:=
| Build_lock_update:
forall st st' i add th_perms lock_perms c
(cnt : containsThread st i),
st' = updLockSet
(updThread(resources:=dryResources) cnt c th_perms)
add lock_perms ->
@lock_update hb i st add th_perms lock_perms c st'.
Notation sstate:= (state_sum (@semC CSem) (@semC AsmSem)).
Inductive one_thread_match  (hb i:nat): option compiler_index ->
meminj -> @ctl sstate -> mem -> @ctl sstate -> mem -> Prop:=
| build_match_source:
forall ocd f c1 m1 c2 m2,
(i > hb)%nat ->
match_thread_source f c1 m1 c2 m2 ->
one_thread_match hb i ocd f c1 m1 c2 m2
| build_match_target:
forall ocd f c1 m1 c2 m2,
(i < hb)%nat ->
match_thread_target f c1 m1 c2 m2 ->
one_thread_match hb i ocd f c1 m1 c2 m2
| build_match_compiled:
forall ocd f c1 m1 c2 m2,
(i = hb)%nat ->
match_thread_compiled ocd f c1 m1 c2 m2 ->
one_thread_match hb i ocd f c1 m1 c2 m2.
Inductive lock_update' {hb}:
nat -> ThreadPool hb -> Address.address ->
(Pair access_map) -> @lock_info dryResources -> _ -> ThreadPool hb -> Prop:=
| Build_lock_update':
forall (st st': ThreadPool hb)
i add th_perms th_lock_perms lk_perms c
(* contains *)
(Hcnt_iff: forall i, ThreadPool.containsThread st i ->
ThreadPool.containsThread st' i)
(Hcnt_iff': forall i, ThreadPool.containsThread st' i ->
ThreadPool.containsThread st i)
(* Code  *)
(gcs: forall (cnt':ThreadPool.containsThread st' i),
ThreadPool.getThreadC cnt' = c )
(gco: forall j (cnt:ThreadPool.containsThread st j) (cnt':ThreadPool.containsThread st' j),
j<>i -> ThreadPool.getThreadC cnt' = ThreadPool.getThreadC cnt)
(* Thread Perms and Thread lock perms *)
(gts: forall (cnt':ThreadPool.containsThread st' i),
ThreadPool.getThreadR(resources:=dryResources) cnt' = (th_perms,th_lock_perms))
(gto: forall j (cnt:ThreadPool.containsThread st j) (cnt':ThreadPool.containsThread st' j),
j<>i -> ThreadPool.getThreadR cnt' = ThreadPool.getThreadR cnt)
(* Thread Perms *)
(gtts: forall (cnt':ThreadPool.containsThread st' i),
fst (ThreadPool.getThreadR(resources:=dryResources) cnt') = th_perms)
(gtto: forall j (cnt:ThreadPool.containsThread st j) (cnt':ThreadPool.containsThread st' j),
j<>i -> fst (ThreadPool.getThreadR cnt') = fst  (ThreadPool.getThreadR cnt))
(* Thread lock Perms*)
(gtls: forall (cnt':ThreadPool.containsThread st' i),
snd (ThreadPool.getThreadR(resources:=dryResources) cnt') = th_lock_perms)
(gtlo: forall j (cnt:ThreadPool.containsThread st j) (cnt':ThreadPool.containsThread st' j),
j<>i -> snd (ThreadPool.getThreadR cnt') = snd (ThreadPool.getThreadR cnt))
(* Lock perms *)
(gls: ThreadPool.lockRes st' add  = Some lk_perms)
(glo: forall add', add<>add' -> ThreadPool.lockRes st' add' = ThreadPool.lockRes st add'),
@lock_update' hb i st add (th_perms,th_lock_perms) lk_perms  c st'.

Lemma lock_update_getters:
forall {hb  i st b ofs th_perms th_lock_perms lock_perms c st'},
@lock_update hb i st (b,ofs) (th_perms,th_lock_perms)
lock_perms  c st' ->
@lock_update' hb i st (b,ofs) (th_perms,th_lock_perms)
lock_perms  c st'.