/* * Implementação assimétrica do jantar dos filósofos * utilizando futex. */ #include #include #include #include #include "myfutex.h" #include #define N 15 #define N_CICLOS 8 /* Variáveis e funções extra para mostrar o estado da mesa */ volatile atomic_t seq = {0}, lock = {1}, n = {0}; enum pos_garfo {ESQ, MESA, DIR} pos_garfo[N]; char mesa[4*N+1]; void print() { printf("%s%c%c\n", &mesa[1], mesa[0], mesa[1]); } void lock_mesa() { int lseq; atomic_inc(&n); while(1) { lseq = seq.counter; if (atomic_dec_and_test(&lock)) return; futex_wait(&seq, lseq); } } void unlock_mesa() { lock.counter = 1; atomic_inc(&seq); atomic_dec(&n); if (n.counter > 0) futex_wake(&seq, 1); } /* * garfo esq = phil_id * garfo dir = (phil_id + 1) % N */ void fica_com_fome(int phil_id) { lock_mesa(); mesa[4 * phil_id + 3] = 'H'; print(); unlock_mesa(); sleep(1); } void come(int phil_id) { lock_mesa(); mesa[4 * phil_id + 3] = 'E'; print(); unlock_mesa(); sleep(1); } void pega_garfo_esq(int phil_id) { /* Espera garfo esquerdo */ lock_mesa(); mesa[4 * phil_id] = ' '; mesa[4 * phil_id + 1] = ' '; mesa[4 * phil_id + 2] = '|'; print(); unlock_mesa(); sleep(1); } void pega_garfo_dir(int phil_id) { int dir = (phil_id + 1) % N; /* Espera garfo direito */ lock_mesa(); mesa[4 * dir] = '|'; mesa[4 * dir + 1] = ' '; mesa[4 * dir + 2] = ' '; print(); unlock_mesa(); sleep(1); } void solta_garfos_pensa(int phil_id) { int dir = (phil_id + 1) % N; lock_mesa(); /* Libera garfos */ mesa[4 * phil_id] = ' '; mesa[4 * phil_id + 1] = '-'; mesa[4 * phil_id + 2] = ' '; mesa[4 * dir] = ' '; mesa[4 * dir + 1] = '-'; mesa[4 * dir + 2] = ' '; mesa[4 * phil_id + 3] = 'T'; print(); unlock_mesa(); sleep(1); } void* f_phil(void *v) { int phil_id = *(int *) v; int i; for (i = 0; i < N_CICLOS; i++) { fica_com_fome(phil_id); if (phil_id % 2) { pega_garfo_dir(phil_id); pega_garfo_esq(phil_id); } else { pega_garfo_esq(phil_id); pega_garfo_dir(phil_id); } come(phil_id); solta_garfos_pensa(phil_id); } return NULL; } int main() { pthread_t thr[N]; int i, phil_id[N]; for (i = 0; i < N; i++) { pos_garfo[i] = MESA; mesa[4*i] = ' '; mesa[4*i+1] = '-'; mesa[4*i+2] = ' '; mesa[4*i+3] = 'T'; } mesa[4*N] = '\0'; for (i = 0; i < N; i++) { phil_id[i] = i; pthread_create(&thr[i], NULL, f_phil, (void*) &phil_id[i]); } for (i = 0; i < N; i++) pthread_join(thr[i], NULL); return 0; }