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 cptr_lock_inv g1 g2 ctr := EX z : Z, data_at Ews tuint (Vint (Int.repr z)) ctr *
EX x : Z, EX y : Z, !!(z = x + y) && ghost_var gsh1 x g1 * ghost_var gsh1 y g2.
Definition incr_spec :=
DECLARE _incr
WITH sh : share, g1 : gname, g2 : gname, left : bool, n : Z, gv: globals
PRE [ ]
PROP  (readable_share sh)
LOCAL (gvars gv)
SEP   (lock_inv sh (gv _ctr_lock) (cptr_lock_inv g1 g2 (gv _ctr)); ghost_var gsh2 n (if left then g1 else g2))
POST [ tvoid ]
PROP ()
LOCAL ()
SEP (lock_inv sh (gv _ctr_lock) (cptr_lock_inv g1 g2 (gv _ctr)); ghost_var gsh2 (n+1) (if left then g1 else g2)).
Definition read_spec :=
DECLARE _read
WITH sh : share, g1 : gname, g2 : gname, n1 : Z, n2 : Z, gv: globals
PRE [ ]
PROP  (readable_share sh)
LOCAL (gvars gv)
SEP   (lock_inv sh (gv _ctr_lock) (cptr_lock_inv g1 g2 (gv _ctr)); ghost_var gsh2 n1 g1; ghost_var gsh2 n2 g2)
POST [ tuint ]
PROP ()
LOCAL (temp ret_temp (Vint (Int.repr (n1 + n2))))
SEP (lock_inv sh (gv _ctr_lock) (cptr_lock_inv g1 g2 (gv _ctr)); ghost_var gsh2 n1 g1; ghost_var gsh2 n2 g2).
Definition thread_lock_R sh g1 g2 ctr lockc :=
lock_inv sh lockc (cptr_lock_inv g1 g2 ctr) * ghost_var gsh2 1 g1.
Definition thread_lock_inv sh g1 g2 ctr lockc lockt :=
selflock (thread_lock_R sh g1 g2 ctr lockc) sh lockt.
Definition thread_func_spec :=
DECLARE _thread_func
WITH y : val, x : share * gname * gname * globals
PRE [ _args OF (tptr tvoid) ]
let '(sh, g1, g2, gv) := x in
PROP  (readable_share sh)
LOCAL (temp _args y; gvars gv)
SEP   (lock_inv sh (gv _ctr_lock) (cptr_lock_inv g1 g2 (gv _ctr));
ghost_var gsh2 0 g1;
lock_inv sh (gv _thread_lock) (thread_lock_inv sh g1 g2 (gv _ctr) (gv _ctr_lock) (gv _thread_lock)))
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; incr_spec; read_spec; thread_func_spec; main_spec]).

Lemma ctr_inv_exclusive : forall g1 g2 p,
exclusive_mpred (cptr_lock_inv g1 g2 p).