Advertisement
DanFloyd

Dinings Philosophers

May 21st, 2014
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.87 KB | None | 0 0
  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <errno.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6.  
  7. /* Macros */
  8. #define print_info \
  9. printf("*** Type q, then press ret to exit!\n"); \
  10. sleep(3)
  11. #define ec_zero(s,m) \
  12. if((s) != 0){perror(m); exit(err);}
  13. #define ec_killing(s,m) \
  14. if((s) != 0){printf("WARNING: Couldn't kill this thread: %d\n",m);}
  15. #define ec_null(s,m) \
  16. if((s) == NULL){perror(m); exit (errno);}
  17. #define LOCK(s) {ec_zero((pthread_mutex_lock(&s)),("Couldn't lock"))}
  18. #define UNLOCK(s) {ec_zero((err=pthread_mutex_unlock(&s)),("Couldn't unlock"))}
  19. #define WAIT(s,m) {ec_zero((err=pthread_cond_wait(&s,&m)),("Couldn't wait"))}
  20. #define SIGNAL(s) {ec_zero((err=pthread_cond_signal(&s)),("Couldn't send signal"))}
  21.  
  22. /* Dichiarazione di variabile mutex ed array di condition*/
  23. pthread_cond_t *cond_array = NULL;
  24. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  25.  
  26. /* Dichiarazione variabili e array globali*/
  27. static int N;
  28. int *fks;
  29. pthread_t *tid_array = NULL;
  30.  
  31. /* Dichiarazione funzioni */
  32. void* phi(void* args);
  33. void gcollector();
  34. static void cleanup_handler(void* arg);
  35.  
  36. int main(){
  37.  
  38.     int i, err;
  39.     char ctrl = NULL;
  40.  
  41.     /* Ricevo in input il numero ed alloco dinamicamente un array di tid */
  42.     printf("Please tell me how many philosophes you want at the table...\n");
  43.     scanf("%d",&N);
  44.     ec_null((tid_array = (pthread_t*) malloc(N*sizeof(pthread_t))),"Couldn't allocate tid array");
  45.  
  46.     /* Creo i threads filosofo salvando i tid nell'array predisposto */
  47.     for(i=0;i<N;i++){
  48.         ec_zero((err = pthread_create(&tid_array[i], NULL, &phi, (void*) i)),"Couldn't create a thread");
  49.         printf("*** Philosopher no. %d created !\n",i);
  50.     }
  51.  
  52.     /* Creo l' array di conditions e le inizializzo */
  53.     ec_null((cond_array = (pthread_cond_t*) malloc(N*sizeof(pthread_cond_t))),"Couldn't allocate cond array");
  54.     for(i=0;i<N;i++) ec_zero((pthread_cond_init(&cond_array[i], NULL)),"Couln't initialize a condition");
  55.  
  56.     /* Creo l'array di stato e lo inizializzo */
  57.     ec_null((fks = (int*) malloc(N*sizeof(int))),"Couldn't allocate forks's status array");
  58.     for(i=0;i<N;i++) fks[i]=0;
  59.  
  60.     /* Condizione di terminazione del programma */
  61.     while(ctrl != 'q'){
  62.         scanf("%c",&ctrl);
  63.         if(ctrl!='q') {print_info;}
  64.         else{
  65.             /* Uccido i threads */
  66.             for(i=0;i<N;i++){
  67.                 printf("*** Killing the philosopher no. %d !\n",i);
  68.                 ec_killing((err = pthread_cancel(tid_array[i])),i);
  69.             }
  70.             /* Invoco la atextit */
  71.             if(atexit(gcollector)) perror("Atexit failed! Possible memory leak\n");
  72.  
  73.             return 0;
  74.         }
  75.     }
  76.     return ECANCELED;
  77. }
  78.  
  79. /* Implementazione della funzione filosofo */
  80. void* phi(void *args){
  81.     pthread_cleanup_push(cleanup_handler,NULL);
  82.     while(1){
  83.         /* Recupero l'identità del filosofo */
  84.         int my_id = (int) args, err;
  85.    
  86.         /* Fase 1 : il filosofo è affamato */
  87.         LOCK(mutex);
  88.         printf("# I'm %d and I'm hungry!\n",my_id);
  89.         /* Testo le var di condizione sulle forchette*/
  90.         while(fks[((my_id)%N)] || fks[((my_id+1)%N)]) WAIT(cond_array[my_id],mutex);
  91.         /* Occupo le forchette */
  92.         fks[((my_id)%N)]=1;
  93.         fks[((my_id+1)%N)]=1;
  94.         UNLOCK(mutex);
  95.  
  96.         /* Fase 2 : il filosofo mangia se può */
  97.         printf("# I'm %d and I'm eating spaghetti!\n",my_id);
  98.         sleep(3);
  99.         LOCK(mutex);
  100.         /* Libero le forchette */
  101.         fks[((my_id)%N)]=0;
  102.         fks[((my_id+1)%N)]=0;
  103.         /* Invio le signal alle var di condizione */
  104.         SIGNAL(cond_array[((my_id-1)%N)]);
  105.         SIGNAL(cond_array[((my_id+1)%N)]);
  106.         UNLOCK(mutex);
  107.  
  108.         /* Fase 3 : il filosofo pensa */
  109.         printf("# I'm %d and I'm pondering about the meaning of life!\n",my_id);
  110.         sleep(3);
  111.     }
  112.     pthread_cleanup_pop(0);
  113.     return (void*) 0;
  114. }
  115.  
  116. /* Implementazione della funzione spazzino */
  117. void gcollector(){
  118.     printf("*** Collecting some garbage...\n");
  119.     free(tid_array);
  120.     free(cond_array);
  121.     free(fks);
  122.     printf("Bye!\n");
  123. }
  124.  
  125. static void cleanup_handler(void* arg){
  126.     int err =0;
  127.     printf("*** Running cleanup handler...\n");
  128.     UNLOCK(mutex);
  129. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement