/* * Implementação de mutex locks e variáveis de condição * utilizando semáforos. * Estrutura dinâmica para compartilhamento de semáforos. * Será que funciona? */ #include #include "mutex_comp.h" int mutex_init(mutex_t *lock, mutexattr_t* attr) { return sem_init(&lock->sem, 0, 1); } int mutex_destroy(mutex_t *lock) { return sem_destroy(&lock->sem); } int mutex_lock(mutex_t *lock) { return sem_wait(&lock->sem); } int mutex_unlock(mutex_t *lock) { return sem_post(&lock->sem); } /*------------------------------------------------------*/ int cond_init(cond_t *cond, condattr_t* attr) { mutex_init(&cond->lock, NULL); cond->signal = cond->wait = NULL; return 0; } int cond_destroy(cond_t *cond) { mutex_destroy(&cond->lock); if (cond->signal) { sem_destroy(&cond->signal->sem); free(cond->signal); } if (cond->wait) { sem_destroy(&cond->wait->sem); free(cond->wait); } return 0; } int cond_wait(cond_t *cond, mutex_t *mutex_externo) { node_t* n; mutex_lock(&cond->lock); if (!cond->wait) { cond->wait = malloc(sizeof(node_t)); sem_init(&cond->wait->sem, 0, 0); cond->wait->n_wait = 0; } n = cond->wait; n->n_wait++; mutex_unlock(&cond->lock); mutex_unlock(mutex_externo); sem_wait(&n->sem); mutex_lock(&cond->lock); n->n_signal--; n->n_wait--; if (n->n_wait == 0 && n->n_signal == 0) { sem_destroy(&n->sem); free(n); } mutex_unlock(&cond->lock); mutex_lock(mutex_externo); return 0; } int cond_signal(cond_t *cond) { mutex_lock(&cond->lock); if (cond->signal || cond->wait) { if (!cond->signal) { cond->signal = cond->wait; cond->wait = NULL; } cond->signal->n_signal++; sem_post(&cond->signal->sem); if (cond->signal->n_signal == cond->signal->n_wait) cond->signal = NULL; } mutex_unlock(&cond->lock); return 0; } int cond_broadcast(cond_t *cond){ mutex_lock(&cond->lock); if (cond->signal) { while (cond->signal->n_signal < cond->signal->n_wait) { cond->signal->n_signal++; sem_post(&cond->signal->sem); } } if (cond->wait) { while (cond->wait->n_signal < cond->wait->n_wait) { cond->signal->n_signal++; sem_post(&cond->wait->sem); } } cond->signal = NULL; cond->wait = NULL; mutex_unlock(&cond->lock); return 0; }