#include <sys/types.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PHILNUM 5
typedef enum {thinking, hungry, eating} philstat;
typedef struct tablestruct {
pthread_t t[PHILNUM];
int self[PHILNUM];
pthread_mutex_t mutex;
pthread_cond_t condition[PHILNUM];
philstat status[PHILNUM];
} table;
table * tab;
void printstate(void){
static char stat[] = "THE";
int i;
for (i=0; i<PHILNUM; i++) {
printf("%c", stat[(int)(tab->status)[i]]);}
printf("\n");
}
int test (int i) {
if (
((tab->status)[i] == hungry) &&
((tab->status)[(i+1)% PHILNUM] != eating) &&
((tab->status)[(i-1+PHILNUM)% PHILNUM] != eating)) {
(tab->status)[i] = eating;
pthread_cond_signal(&((tab->condition)[i]));
return 1;
}
return 0;
}
void pickup(int k) {
pthread_mutex_lock(&(tab->mutex));
(tab->status)[k] = hungry;
printstate();
if (!test(k)) {
pthread_cond_wait(&((tab->condition)[k]), &(tab->mutex));}
printstate();
pthread_mutex_unlock(&(tab->mutex));
}
void putdown(int k) {
pthread_mutex_lock(&(tab->mutex));
(tab->status)[k] = thinking;
printstate();
test((k+1)%PHILNUM);
test((k-1+PHILNUM)%PHILNUM);
pthread_mutex_unlock(&(tab->mutex));
}
table * tableinit(void *(* philosopher)(void *)) {
int i, rc;
tab = (table *) malloc (sizeof(table));
if((rc = pthread_mutex_init(&(tab->mutex), NULL)) != 0) {
fprintf(stderr, "pthread_mutex_init %s\n", strerror(rc));
exit(1);}
for (i=0; i<PHILNUM; i++) {
(tab->self)[i] = i;
(tab->status)[i] = thinking;
if((rc = pthread_cond_init(&((tab->condition)[i]), NULL))
!= 0) {
fprintf(stderr, "pthread_cond_init %s\n", strerror(rc));
exit(1);}
}
for (i=0; i<PHILNUM; i++) {
if ((rc = pthread_create(&((tab->t)[i]),NULL,
philosopher, &((tab->self)[i])))!= 0) {
fprintf(stderr, "Cannot create thread %s\n", strerror(rc));
exit(1);}
}
return tab;
}