Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs. mk_varspecs prog. Defined.
Definition acquire_spec := DECLARE _acquire acquire_spec.
Definition release_spec := DECLARE _release release_spec.
Definition makelock_spec := DECLARE _makelock (makelock_spec _).
Definition freelock_spec := DECLARE _freelock (freelock_spec _).
Definition spawn_spec := DECLARE _spawn spawn_spec.
Definition freelock2_spec := DECLARE _freelock2 (freelock2_spec _).
Definition release2_spec := DECLARE _release2 release2_spec.
Definition makecond_spec := DECLARE _makecond (makecond_spec _).
Definition freecond_spec := DECLARE _freecond (freecond_spec _).
Definition wait_spec := DECLARE _waitcond (wait_spec _).
Definition signal_spec := DECLARE _signalcond (signal_spec _).
Definition dlock_inv data := EX i : Z, data_at Ews tint (vint i) data.
Definition tlock_inv sh lockt lock cond data :=
selflock (cond_var sh cond * lock_inv sh lock (dlock_inv data)) sh lockt.
Definition thread_func_spec :=
DECLARE _thread_func
WITH y : val, x : share * globals
PRE [ _args OF (tptr tvoid) ]
let '(sh, gv) := x in
PROP  (readable_share sh)
LOCAL (temp _args y; gvars gv)
SEP   (cond_var sh (gv _cond);
lock_inv sh (gv _mutex) (dlock_inv (gv _data));
lock_inv sh (gv _tlock) (tlock_inv sh (gv _tlock) (gv _mutex) (gv _cond) (gv _data)))
POST [ tptr tvoid ]
PROP ()
LOCAL ()
SEP ().
Definition main_spec :=
DECLARE _main
WITH gv : globals
PRE  [] main_pre prog tt nil gv
POST [ tint ] main_post prog nil gv.
Definition Gprog : funspecs :=   ltac:(with_library prog [acquire_spec; release_spec; release2_spec; makelock_spec;
freelock_spec; freelock2_spec; spawn_spec; makecond_spec; freecond_spec; wait_spec; signal_spec;
thread_func_spec; main_spec]).
Hint Resolve inv_exclusive.

Lemma body_thread_func : semax_body Vprog Gprog f_thread_func thread_func_spec.