Definition thread_safety {Z} (Jspec : juicy_ext_spec Z) m ge (tp : jstate ge) PHI (mcompat : mem_compatible_with tp m PHI) n
i (cnti : containsThread tp i) := forall (ora : Z),
match getThreadC cnti with
| Krun c => semax.jsafeN Jspec ge n ora c (jm_ cnti mcompat)
| Kblocked c =>
(* The dry memory will change, so when we prove safety after an external we must only inspect the rmap m_phi part of the juicy memory.  This means more proof for each of the synchronisation primitives. *)
jsafe_phi Jspec ge n ora c (getThreadR cnti)
| Kresume c v =>
forall c',
(* [v] is not used here. The problem is probably coming from the definition of JuicyMachine.resume_thread'. *)
cl_after_external None c = Some c' ->
(* same quantification as in Kblocked *)
jsafe_phi_bupd Jspec ge n ora c' (getThreadR cnti)
| Kinit v1 v2 =>
val_inject (Mem.flat_inj (Mem.nextblock m)) v2 v2 /\
exists q_new,
cl_initial_core ge v1 (v2 :: nil) q_new /\
jsafe_phi Jspec ge n ora q_new (getThreadR cnti)
end.

Lemma mem_cohere'_res : forall m phi phi', mem_cohere' m phi ->
resource_at phi' = resource_at phi -> mem_cohere' m phi'.