SHARE
TWEET

Untitled

a guest Oct 21st, 2019 76 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <getopt.h>
  5. #include <unistd.h>
  6.  
  7. #define down pthread_mutex_lock
  8. #define up pthread_mutex_unlock
  9. #define signal pthread_cond_signal
  10. #define wait pthread_cond_wait
  11. #define broadcast pthread_cond_broadcast
  12.  
  13. typedef struct person{
  14.     int id;
  15.     enum{
  16.         client,
  17.         detective
  18.     } type;
  19. } person_t;
  20.  
  21. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  22. pthread_cond_t detective_condition = PTHREAD_COND_INITIALIZER;
  23. pthread_cond_t client_condition = PTHREAD_COND_INITIALIZER;
  24. pthread_cond_t ready = PTHREAD_COND_INITIALIZER;
  25.  
  26.  
  27. int client_count = 0;
  28. int detective_count = 0;
  29.  
  30. int client_temp = 0;
  31. int detective_temp = 0;
  32.  
  33. int ready_to_go = 0;
  34.  
  35. // ----
  36.  
  37. void *client_visit_bar(void *ptr){
  38.  
  39.     person_t *person = (person_t *) ptr;
  40.  
  41.     down(&mutex);
  42.  
  43.     (void) printf("bar:  %d c  %d d  c%d entering\n",
  44.         client_count, detective_count, person->id);
  45.  
  46.     while (ready_to_go == 1){
  47.         wait(&ready, &mutex);
  48.     }
  49.  
  50.     while (detective_count > 0){
  51.         detective_count--;
  52.         signal(&detective_condition);
  53.     }
  54.  
  55.     while (detective_count <= 0){
  56.         client_count++;
  57.         (void) printf("bar:  %d c  %d d  c%d waiting...\n",
  58.             client_count, detective_count, person->id);
  59.         wait(&client_condition, &mutex);
  60.         (void) printf("bar:  %d c  %d d  ... c%d waking up\n",
  61.             client_count, detective_count, person->id);
  62.     }
  63.  
  64.     while (!client_count){
  65.         broadcast(&ready);
  66.         ready_to_go = 0;
  67.     }
  68.  
  69.     (void) printf("bar:  %d c  %d d  c%d leaving\n",
  70.             client_count, detective_count, person->id);
  71.  
  72.     up(&mutex);
  73.     return NULL;
  74. }
  75.  
  76. // ----
  77.  
  78. void *detective_visit_bar(void *ptr){
  79.  
  80.     person_t *person = (person_t *) ptr;
  81.  
  82.     down(&mutex);
  83.  
  84.     (void) printf("bar:  %d c  %d d  d%d entering\n",
  85.         client_count, detective_count, person->id);
  86.  
  87.     while (ready_to_go == 1){
  88.         wait(&ready, &mutex);
  89.     }
  90.  
  91.     while (client_count > 0){
  92.         client_count = 0;
  93.         (void) printf("bar:  %d c  %d d  d%d leaving (+ picking everyone)\n",
  94.             client_count, detective_count, person->id);
  95.         ready_to_go = 1;
  96.         broadcast(&client_condition);
  97.     }
  98.  
  99.     while(client_count <= 0){
  100.         detective_count++;
  101.         (void) printf("bar:  %d c  %d d  d%d talking...\n",
  102.             client_count, detective_count, person->id);
  103.  
  104.         wait(&detective_condition, &mutex);
  105.         (void) printf("bar:  %d c  %d d  d%d waking up\n",
  106.             client_count, detective_count, person->id);
  107.         (void) printf("bar:  %d c  %d d  d%d leaving\n",
  108.             client_count, detective_count, person->id);
  109.        
  110.     }
  111.  
  112.     up(&mutex);
  113.     return NULL;
  114. }
  115.  
  116. // ----
  117.  
  118. static void* enjoy_life(void *ptr){
  119.     person_t *person = (person_t*) ptr;
  120.     while(1)
  121.     {
  122.         switch (person->type)
  123.         {
  124.         case client:
  125.             detective_visit_bar(ptr);
  126.             break;
  127.         case detective:
  128.             client_visit_bar(ptr);    
  129.             break;
  130.         }
  131.         usleep(random()%100000);
  132.     }
  133.     return NULL;
  134. }
  135.  
  136. // ----
  137.  
  138. int main(int argc, char** argv){
  139.  
  140.     int opt, i, status, client_total = 1, detective_total = 1;
  141.     //person_t *person = NULL;
  142.  
  143.     while ((opt = getopt(argc, argv, "c:d:")) != -1){
  144.         // : consider another argument after
  145.         switch (opt){
  146.             case 'c':
  147.                 client_total = atoi(optarg); // set num of clients
  148.                 if (client_total <= 0){
  149.                     fprintf(stderr, "invalid number of people\n");
  150.                     return EXIT_FAILURE;
  151.                 }
  152.                 break;
  153.             case 'd':
  154.                 detective_total = atoi(optarg); // set num of detectives
  155.                 if (detective_total <= 0){
  156.                     fprintf(stderr, "invalid number of iterations\n");
  157.                     return EXIT_FAILURE;
  158.                 }
  159.                 break;
  160.         }
  161.     }
  162.  
  163.     int total_people = client_total+detective_total;
  164.     pthread_t people[total_people];
  165.  
  166.     person_t *clients;
  167.     clients = malloc(client_total * sizeof(person_t));
  168.     if(!clients) // check correct memory allocation
  169.         return EXIT_FAILURE;
  170.  
  171.     person_t *detectives;
  172.     detectives = malloc(detective_total * sizeof(person_t));
  173.     if(!detectives) // check correct memory allocation
  174.         return EXIT_FAILURE;
  175.  
  176.  
  177.  
  178.     /*
  179.     pthread_t client[client_total], detective[detective_total];
  180.  
  181. */
  182.     for(i=0;i<client_total;i++){  
  183.        (clients+i)->type = client;
  184.        (clients+i)->id = i;
  185.     }
  186.  
  187.     for(i=0;i<detective_total;i++){  
  188.        (detectives+i)->type = detective;
  189.        (detectives+i)->id = i;
  190.     }
  191.  
  192.     for (i=0;i<total_people;i++){
  193.         if (i<client_total)
  194.             status = pthread_create(&people[i],NULL,enjoy_life,(void*)(clients+i));
  195.         else
  196.             status = pthread_create(&people[i],NULL,enjoy_life,(void*)(detectives+i-client_total));
  197.         if (status){
  198.             fprintf(stderr,"failed to create thread");
  199.             return EXIT_FAILURE;
  200.         }
  201.     }
  202.     for (i=0;i<total_people;i++){
  203.         if(people[i]){
  204.             status = pthread_join(people[i],NULL);
  205.             if (status){
  206.                 fprintf(stderr,"failed to join thread");
  207.             }
  208.         }
  209.     }
  210.  
  211.     free(clients);
  212.     free(detectives);
  213.  
  214.     return EXIT_SUCCESS;
  215. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top