// Allocates and returns a new reentrant lock. Sets errno and returns NULL if // initialization failed. reentrant_lock_t* reentrant_lock_init() { mutex_t* mu = mutex_init(); if (!mu) { return NULL; } mutex_t* owner_mu = mutex_init(); if (!owner_mu) { mutex_dispose(mu); return NULL; } reentrant_lock_t* lock = (reentrant_lock_t*) malloc(sizeof(reentrant_lock_t)); if (!lock) { errno = ENOMEM; mutex_dispose(mu); mutex_dispose(owner_mu); return NULL; } lock->mu = mu; lock->owner = NULL; lock->owner_mu = owner_mu; lock->count = 0; return lock; }
void mylock_dispose(struct tlock *lock) //@ requires tlock(lock, ?p); //@ ensures p(); { //@ open tlock(lock, p); struct mutex *mutex = lock->mutex; mutex_dispose(mutex); //@ box boxId = lock->boxId; //@ open tlock_ctor (lock, boxId, p)(); //@ dispose_box tlock_box(boxId, lock, ?next, ?owner, ?locked, ?th, p); //@ assert (!locked); free (lock); }
// Releases the lock resources. void reentrant_lock_dispose(reentrant_lock_t* lock) { mutex_dispose(lock->owner_mu); mutex_dispose(lock->mu); free(lock); }
int main() //@ requires true; //@ ensures result == 'i' || result == 'h'; { struct buffer *b = malloc(sizeof(struct buffer)); if (b == 0){ abort(); } //@ int id = create_gcf(); //@ iot iot1 = iot_init; //@ iot ioth = iot_split_left(iot1); //@ iot ioti = iot_split_right(iot1); //@ iot iot2 = iot_join(ioth, ioti); //@ create_gcf_instance(id, iot1, {}); //@ create_gcf_instance(id, ioth, {}); //@ create_gcf_instance(id, ioti, {}); //@ create_gcf_instance(id, iot2, {}); //@ close exists<pair<int, list<int> > >(pair('l', {'h'})); //@ close exists<pair<int, list<int> > >(pair('r', {'i'})); //@ close buffer_invar(id, b)(); //@ close create_mutex_ghost_arg(buffer_invar(id, b)); b->mutex = create_mutex(); //@ close buffer(id, b); //@ place t1 = place(iot1, {}, place_none, place_none, id); //@ place th1 = place(ioth, {}, t1, place_none, id); //@ place th2 = place(ioth, {'h'}, t1, place_none, id); //@ place ti1 = place(ioti, {}, t1, place_none, id); //@ place ti2 = place(ioti, {'i'}, t1, place_none, id); //@ place t2 = place(iot2, {}, th2, ti2, id); //@ close token(t1); //@ close split(t1, th1, ti1); //@ close putchar_io(id, th1, 'h', th2); //@ close putchar_io(id, ti1, 'i', ti2); //@ close join(th2, ti2, t2); print_hi(b); //@ open buffer(id, b); mutex_dispose(b->mutex); //@ open buffer_invar(id, b)(); int x = b->c; free(b); return x; // Open tokens to obtain info about progresses. // We need this to prove the postcondition. //@ open token(_); //@ open token(_); //@ open token(_); //@ open token(_); //@ open token(_); // Leak ghost data //@ leak gcf_instance(_, _, _); //@ leak gcf_instance(_, _, _); //@ leak gcf_instance(_, _, _); //@ leak gcf_instance(_, _, _); //@ leak gcf(_, _); //@ leak exists(_); //@ leak exists(_); }