/* * CS460: Operating Systems * Jim Plank / Rich Wolski * dphil_5_book.c -- Dining philosophers solution #5 -- the book's solution */ #include #include #include "dphil.h" #define THINKING 0 #define HUNGRY 1 #define EATING 2 typedef struct { pthread_mutex_t *mon; pthread_cond_t **cv; int *state; int phil_count; } Phil; test(Phil *pp, int n) { int phil_count; phil_count = pp->phil_count; if (pp->state[(n+(phil_count-1))%phil_count] != EATING && pp->state[n] == HUNGRY && pp->state[(n+1)%phil_count] != EATING) { pp->state[n] = EATING; pthread_cond_signal(pp->cv[n]); } } void pickup(Phil_struct *ps) { Phil *pp; pp = (Phil *) ps->v; pthread_mutex_lock(pp->mon); pp->state[ps->id] = HUNGRY; test(pp, ps->id); while (pp->state[ps->id] != EATING) { pthread_cond_wait(pp->cv[ps->id], pp->mon); } pthread_mutex_unlock(pp->mon); } void putdown(Phil_struct *ps) { Phil *pp; int phil_count; pp = (Phil *) ps->v; phil_count = pp->phil_count; pthread_mutex_lock(pp->mon); pp->state[ps->id] = THINKING; test(pp, (ps->id+(phil_count-1))%phil_count); test(pp, (ps->id+1)%phil_count); pthread_mutex_unlock(pp->mon); } void *initialize_v(int phil_count) { Phil *pp; int i; pp = (Phil *) malloc(sizeof(Phil)); pp->phil_count = phil_count; pp->mon = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); pp->cv = (pthread_cond_t **) malloc(sizeof(pthread_cond_t *)*phil_count); if (pp->cv == NULL) { perror("malloc"); exit(1); } pp->state = (int *) malloc(sizeof(int)*phil_count); if (pp->state == NULL) { perror("malloc"); exit(1); } pthread_mutex_init(pp->mon, NULL); for (i = 0; i < phil_count; i++) { pp->cv[i] = (pthread_cond_t *) malloc(sizeof(pthread_cond_t)); if (pp->cv[i] == NULL) { perror("malloc"); exit(1); } pthread_cond_init(pp->cv[i], NULL); pp->state[i] = THINKING; } return (void *) pp; }