Advertisement
Soham_K

pthread_semaphore_mutex.c

Jan 5th, 2022 (edited)
999
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 15.22 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <semaphore.h>
  5. #include <unistd.h>
  6. #include <time.h>
  7. #include <string.h>
  8. #include <math.h>
  9.  
  10.  
  11. typedef int bool;
  12. #define true 1
  13. #define false 0
  14. #define NUMBER_PASSENGERS 100
  15.  
  16. FILE *fw;
  17. int M, N, P;
  18. int w, x, y, z;
  19. double tm=1;
  20. int *passLost, *vip;
  21. int kioskwaiting=0, boardwaiting=0, kioskpassing=0, boardpassing=0;     //waiting in the left
  22. bool *emptykiosk;                           //holds the empty/non-empty state of all the kiosks
  23.  
  24. sem_t *beltsem;
  25. sem_t kiosk;
  26. pthread_mutex_t mutx1, mutx2, mutx3, mutx4, viplock, boardhalter, kioskhalter, halt;
  27. pthread_mutex_t lockiosk, boarding;
  28. pthread_mutex_t specialkiosk_lock;
  29.  
  30.  
  31. int poissonRandom(double expectedValue) {
  32.   int n = 0; //counter of iteration
  33.   double limit;
  34.   double x;  //pseudo random number
  35.   limit = exp(-expectedValue);
  36.   x = rand()/(double)2147483691;
  37.   while (x > limit) {
  38.     n++;
  39.     x *= rand()/(double)2147483691;
  40.   }
  41.   return n;
  42. }
  43.  
  44.  
  45. struct Passenger
  46. {
  47.     int pid;
  48.     bool boardingpass;
  49.     bool isvip;
  50.     int lost;
  51. };
  52.  
  53. int getFreeKiosk()
  54. {
  55.     for(int i=0; i<M; i++) {
  56.         if(emptykiosk[i] == true) return i;
  57.     }
  58.     return rand()%M;
  59. }
  60.  
  61. void* timecount(void * arg) {
  62.     while(1) {
  63.         usleep(10000);
  64.         tm = round(tm+1);
  65.     }
  66. }
  67.  
  68. void specialKiosk(struct Passenger *p)
  69. {
  70.     if(!p->isvip)
  71.         fprintf(fw, "Passenger %d has started waiting at the special kiosk from time %.f\n\n", p->pid, tm);
  72.     else
  73.         fprintf(fw, "Passenger %d (VIP) has started waiting at the special kiosk from time %.f\n\n", p->pid, tm);
  74.  
  75.     usleep(10000);                  //Manual extra waiting
  76.  
  77.     pthread_mutex_lock(&specialkiosk_lock);
  78.  
  79.     if(!p->isvip)
  80.         fprintf(fw, "Passenger %d has started self-check in at the speical kiosk at time %.f\n\n", p->pid, tm);
  81.     else
  82.         fprintf(fw, "Passenger %d (VIP) has started self-check in at the speical kiosk at time %.f\n\n", p->pid, tm);
  83.  
  84.     usleep(w * 10000);
  85.     p->boardingpass = true;
  86.  
  87.     if(!p->isvip)
  88.         fprintf(fw, "Passenger %d has finished check in at time %.f\n\n", p->pid, tm);
  89.     else
  90.         fprintf(fw, "Passenger %d (VIP) has finished check in at time %.f\n\n", p->pid, tm);
  91.  
  92.     pthread_mutex_unlock(&specialkiosk_lock);
  93. }
  94.  
  95. bool atBoarding(struct Passenger *p)
  96. {
  97.     if(!p->isvip)
  98.         fprintf(fw, "Passenger %d has started waiting to be boarded from time %.f\n\n", p->pid, tm);
  99.     else
  100.         fprintf(fw, "Passenger %d (VIP) has started waiting to be boarded from time %.f\n\n", p->pid, tm);
  101.    
  102.     if(passLost[p->pid]==1 && p->lost==0) {
  103.         p->boardingpass = false;
  104.         p->lost++;
  105.         return false;
  106.     }
  107.     usleep(10000);          //Manual extra waiting
  108.  
  109.     pthread_mutex_lock(&boarding);
  110.     if(!p->isvip)
  111.         fprintf(fw, "Passenger %d has started boarding the plane at time %.f\n\n", p->pid, tm);
  112.     else
  113.         fprintf(fw, "Passenger %d (VIP) has started boarding the plane at time %.f\n\n", p->pid, tm);
  114.  
  115.     usleep(y * 10000);
  116.  
  117.     if(!p->isvip)
  118.         fprintf(fw, "Passenger %d has boarded the plane at time %.f\n\n", p->pid, tm);
  119.     else
  120.         fprintf(fw, "Passenger %d (VIP) has boarded the plane at time %.f\n\n", p->pid, tm);
  121.  
  122.     pthread_mutex_unlock(&boarding);
  123.  
  124.     return true;
  125. }
  126.  
  127.  
  128. void vipChannel(struct Passenger *p, int dir)
  129. {
  130.     //dir == 1 => passenger wants left to right (Kiosk to Boarding gate)
  131.     //dir == 0 => passenger wants right to left (Boarding gate to kiosk)
  132.     if(dir == 1) {
  133.         pthread_mutex_lock(&mutx1);
  134.         kioskwaiting++;
  135.         if(!p->isvip)
  136.             fprintf(fw, "Passenger %d has started waiting to enter the VIP channel (kiosk to boarding gate) from time %.f\n\n", p->pid, tm);
  137.         else
  138.             fprintf(fw, "Passenger %d (VIP) has started waiting to enter the VIP channel (kiosk to boarding gate) from time %.f\n\n", p->pid, tm);
  139.         usleep(10000);                           //Manual extra waiting
  140.         if(kioskwaiting==1 && kioskpassing==0) { //first one to enter
  141.             pthread_mutex_lock(&boardhalter);
  142.             pthread_mutex_lock(&kioskhalter);
  143.             pthread_mutex_lock(&viplock);
  144.             kioskpassing++;
  145.             kioskwaiting--;
  146.             pthread_mutex_unlock(&kioskhalter);
  147.         }
  148.         else if(kioskpassing==0) {
  149.             pthread_mutex_lock(&kioskhalter);
  150.             kioskpassing++;
  151.             kioskwaiting--;
  152.             pthread_mutex_unlock(&kioskhalter);
  153.         }
  154.         else {
  155.             kioskwaiting--;
  156.             kioskpassing++;
  157.         }
  158.         pthread_mutex_unlock(&mutx1);
  159.        
  160.         //critical region
  161.         if(!p->isvip)
  162.             fprintf(fw, "Passenger %d has entered the VIP channel (kiosk to boarding gate) at time %.f\n\n", p->pid, tm);
  163.         else
  164.             fprintf(fw, "Passenger %d (VIP) has entered the VIP channel (kiosk to boarding gate) at time %.f\n\n", p->pid, tm);
  165.        
  166.         usleep(z * 10000);
  167.        
  168.         if(!p->isvip)
  169.             fprintf(fw, "Passenger %d has crossed the VIP channel (kiosk to boarding gate) at time %.f\n\n", p->pid, tm);
  170.         else
  171.             fprintf(fw, "Passenger %d (VIP) has crossed the VIP channel (kiosk to boarding gate) at time %.f\n\n", p->pid, tm);
  172.  
  173.         pthread_mutex_lock(&mutx2);
  174.         kioskpassing--;
  175.         if(kioskpassing==0) {
  176.             pthread_mutex_unlock(&viplock);
  177.             pthread_mutex_unlock(&boardhalter);
  178.         }
  179.         pthread_mutex_unlock(&mutx2);
  180.     }
  181.     else {
  182.         pthread_mutex_lock(&mutx3);
  183.         boardwaiting++;
  184.         if(!p->isvip)
  185.             fprintf(fw, "Passenger %d has started waiting to enter the VIP channel (boarding gate to kiosk) from time %.f\n\n", p->pid, tm);
  186.         else
  187.             fprintf(fw, "Passenger %d (VIP) has started waiting to enter the VIP channel (boarding gate to kiosk) from time %.f\n\n", p->pid, tm);
  188.         usleep(10000);                           //Manual extra waiting
  189.        
  190.         if(boardwaiting==1 && boardpassing==0) { //the first one to enter
  191.             pthread_mutex_lock(&halt);
  192.             pthread_mutex_lock(&viplock);
  193.             boardpassing++;
  194.             boardwaiting--;
  195.             pthread_mutex_unlock(&halt);
  196.         }
  197.         else if(boardpassing==0) {
  198.             pthread_mutex_lock(&halt);
  199.             boardpassing++;
  200.             boardwaiting--;
  201.             pthread_mutex_unlock(&halt);
  202.         }
  203.         else {
  204.             if(kioskwaiting==0) {
  205.                 boardpassing++;
  206.                 boardwaiting--;
  207.             }
  208.             else {
  209.                 pthread_mutex_lock(&boardhalter);
  210.                 boardpassing++;
  211.                 boardwaiting--;
  212.                 if(boardpassing==1)
  213.                     pthread_mutex_lock(&viplock);
  214.                 pthread_mutex_unlock(&boardhalter);
  215.             }
  216.         }
  217.         pthread_mutex_unlock(&mutx3);
  218.  
  219.         //critical region
  220.         if(!p->isvip)
  221.             fprintf(fw, "Passenger %d has entered the VIP channel (boarding gate to kiosk) at time %.f\n\n", p->pid, tm);
  222.         else
  223.             fprintf(fw, "Passenger %d (VIP) has entered the VIP channel (boarding gate to kiosk) at time %.f\n\n", p->pid, tm);
  224.        
  225.         usleep(z * 10000);
  226.         if(!p->isvip)
  227.             fprintf(fw, "Passenger %d has crossed the VIP channel (boarding gate to kiosk) at time %.f\n\n", p->pid, tm);
  228.         else
  229.             fprintf(fw, "Passenger %d (VIP) has crossed the VIP channel (boarding gate to kiosk) at time %.f\n\n", p->pid, tm);
  230.  
  231.         pthread_mutex_lock(&mutx4);
  232.         boardpassing--;
  233.         if(boardpassing==0) {
  234.             pthread_mutex_unlock(&viplock);
  235.         }
  236.         pthread_mutex_unlock(&mutx4);
  237.     }
  238. }
  239.  
  240.  
  241. void securityCheck(struct Passenger *p)
  242. {
  243.     int beltid = rand()%N;
  244.    
  245.     if(!p->isvip)
  246.         fprintf(fw, "Passenger %d has started waiting for security check in belt %d from time %.f\n\n", p->pid, beltid+1, tm);
  247.     else
  248.         fprintf(fw, "Passenger %d (VIP) has started waiting for security check in belt %d from time %.f\n\n", p->pid, beltid+1, tm);
  249.    
  250.     usleep(10000);                           //Manual extra waiting
  251.     sem_wait(&beltsem[beltid]);     //each beltsem[beltid] can serve up to P passengers at a time
  252.    
  253.     if(!p->isvip)
  254.         fprintf(fw, "Passenger %d has started the security check at time %.f\n\n", p->pid, tm);
  255.     else
  256.         fprintf(fw, "Passenger %d (VIP) has started the security check at time %.f\n\n", p->pid, tm);
  257.    
  258.     usleep(x * 10000 + 300);      //10000+300 or 100000+60
  259.  
  260.     if(!p->isvip)    
  261.         fprintf(fw, "Passenger %d has crossed the security check at time %.f\n\n", p->pid, tm);
  262.     else
  263.         fprintf(fw, "Passenger %d (VIP) has crossed the security check at time %.f\n\n", p->pid, tm);
  264.  
  265.     sem_post(&beltsem[beltid]);
  266. }
  267.  
  268. void atKiosk(struct Passenger *p)
  269. {
  270.     if(!p->isvip)
  271.         fprintf(fw, "Passenger %d has arrived at the airport at time %.f\n\n", p->pid, tm);
  272.     else
  273.         fprintf(fw, "Passenger %d (VIP) has arrived at the airport at time %.f\n\n", p->pid, tm);
  274.  
  275.     usleep(10000);                           //Manual extra waiting
  276.  
  277.     sem_wait(&kiosk);
  278.  
  279.     pthread_mutex_lock(&lockiosk);
  280.     int kioskid = getFreeKiosk();
  281.     emptykiosk[kioskid] = false;
  282.     pthread_mutex_unlock(&lockiosk);
  283.  
  284.     if(!p->isvip)
  285.         fprintf(fw, "Passenger %d has started self-check in at kiosk %d at time %.f\n\n", p->pid, kioskid+1, tm);
  286.     else
  287.         fprintf(fw, "Passenger %d (VIP) has started self-check in at kiosk %d at time %.f\n\n", p->pid, kioskid+1, tm);
  288.    
  289.     usleep(w * 10000 + 500);      //10000+500 or 100000+400
  290.     p->boardingpass = true;
  291.    
  292.     if(!p->isvip)
  293.         fprintf(fw, "Passenger %d has finished check in at time %.f\n\n", p->pid, tm);
  294.     else
  295.         fprintf(fw, "Passenger %d (VIP) has finished check in at time %.f\n\n", p->pid, tm);
  296.  
  297.     pthread_mutex_lock(&lockiosk);
  298.     emptykiosk[kioskid] = true;
  299.     pthread_mutex_unlock(&lockiosk);
  300.    
  301.     sem_post(&kiosk);
  302. }
  303.  
  304. void* boardingProcess(void * arg)
  305. {
  306.     struct Passenger *p = (struct Passenger *) arg;
  307.     //KIOSK
  308.     atKiosk(p);
  309.     usleep(10000);
  310.     if(!p->isvip) {
  311.         //Security Check
  312.         securityCheck(p);
  313.         usleep(10000);
  314.     }
  315.     else {
  316.         //VIP channel
  317.         vipChannel(p, 1);
  318.         usleep(10000);
  319.     }
  320.     //Boarding gate
  321.     bool isboarded = atBoarding(p);
  322.     if(isboarded == false) {
  323.         usleep(10000);
  324.         vipChannel(p, 0);       //boarding gate to special kiosk
  325.         usleep(10000);
  326.         specialKiosk(p);
  327.         usleep(10000);
  328.         vipChannel(p, 1);       //special kiosk to boarding gate
  329.         usleep(10000);
  330.         atBoarding(p);
  331.     }
  332. }
  333.  
  334.  
  335. int main()
  336. {
  337.     FILE *fp;
  338.     int c, line=0;
  339.     int status;
  340.     srand(time(0));
  341.  
  342.     fp = fopen("input.txt", "r");
  343.     if(fp == NULL) {
  344.         printf("Error in opening the input file");
  345.         return 0;
  346.     }
  347.     while((fscanf(fp, "%d", &c)) != EOF) {
  348.         if(line == 0) M = c;
  349.         else if(line == 1) N = c;
  350.         else if(line == 2) P = c;
  351.         else if(line == 3) w = c;
  352.         else if(line == 4) x = c;
  353.         else if(line == 5) y = c;
  354.         else if(line == 6) z = c;
  355.         line++;
  356.     }
  357.     fclose(fp);
  358.  
  359.     fw = fopen("output.txt", "w");
  360.  
  361.    
  362.     /*-----------INITIALIZE SEMAPHORES & MUTEXES------------*/
  363.    
  364.     emptykiosk = (bool *) malloc(M*sizeof(bool));
  365.     for (int i=0; i<M; i++) emptykiosk[i] = true;
  366.  
  367.     //kiosk locker initialization
  368.     status = pthread_mutex_init(&lockiosk, NULL);
  369.     if(status != 0) {
  370.         printf("kiosk locker mutex initialization failed\n");
  371.         exit(-1);
  372.     }
  373.  
  374.     // kiosk sempahore initialization
  375.     status = sem_init(&kiosk, 0, M);
  376.     if(status != 0) {
  377.         printf("kiosk sempahore initialization failed\n");
  378.         exit(-1);
  379.     }
  380.  
  381.     // belt semaphore initialization
  382.     beltsem = (sem_t *) malloc(N*sizeof(sem_t));
  383.     for(int i=0; i<N; i++) {
  384.         status = sem_init(&beltsem[i], 0, P);
  385.         if(status != 0) {
  386.             printf("%dth belt mutex initialization failed\n", i);
  387.             exit(-1);
  388.         }
  389.     }
  390.  
  391.     //viplock and halters semaphores initialization
  392.     status = pthread_mutex_init(&viplock, NULL);
  393.     if(status != 0) {
  394.         printf("VIP channel lock sempahore initialization failed\n");
  395.         exit(-1);
  396.     }
  397.     status = pthread_mutex_init(&boardhalter, NULL);
  398.     if(status != 0) {
  399.         printf("Board halter sempahore initialization failed\n");
  400.         exit(-1);
  401.     }
  402.     status = pthread_mutex_init(&kioskhalter, NULL);
  403.     if(status != 0) {
  404.         printf("Board halter sempahore initialization failed\n");
  405.         exit(-1);
  406.     }
  407.     status = pthread_mutex_init(&halt, NULL);
  408.     if(status != 0) {
  409.         printf("halte mutex initialization failed\n");
  410.         exit(-1);
  411.     }
  412.     status = pthread_mutex_init(&mutx1, NULL);
  413.     if(status != 0) {
  414.         printf("VIP channel mutx 1 initialization failed\n");
  415.         exit(-1);
  416.     }
  417.     status = pthread_mutex_init(&mutx2, NULL);
  418.     if(status != 0) {
  419.         printf("VIP channel mutx 2 initialization failed\n");
  420.         exit(-1);
  421.     }
  422.     status = pthread_mutex_init(&mutx3, NULL);
  423.     if(status != 0) {
  424.         printf("VIP channel mutx 2 initialization failed\n");
  425.         exit(-1);
  426.     }
  427.     status = pthread_mutex_init(&mutx4, NULL);
  428.     if(status != 0) {
  429.         printf("VIP channel mutx 2 initialization failed\n");
  430.         exit(-1);
  431.     }
  432.  
  433.     //boarding gate mutex initialization
  434.     status = pthread_mutex_init(&boarding, NULL);
  435.     if(status != 0) {
  436.         printf("boarding gate mutex initialization failed\n");
  437.         exit(-1);
  438.     }
  439.  
  440.     //special kiosk mutex initialization
  441.     status = pthread_mutex_init(&specialkiosk_lock, NULL);
  442.     if(status != 0) {
  443.         printf("special kiosk lock mutex initialization failed\n");
  444.         exit(-1);
  445.     }
  446.  
  447.  
  448.     /*-----------THREADING PART-------------*/
  449.     struct Passenger passenger[NUMBER_PASSENGERS];
  450.     pthread_t thread[NUMBER_PASSENGERS];
  451.     pthread_t timethread;
  452.     status = pthread_create(&timethread, NULL, timecount, NULL);
  453.     if (status != 0) {
  454.         printf("time thread creation failed");
  455.         exit(-1);
  456.     }
  457.     //creating random boarding pass lost;
  458.     int special = NUMBER_PASSENGERS/3;
  459.     passLost = (int *) calloc(NUMBER_PASSENGERS, sizeof(int));
  460.     vip = (int *) calloc(NUMBER_PASSENGERS, sizeof(int));
  461.  
  462.     for(int i=0; i<special; i++) {
  463.         int x = rand()%NUMBER_PASSENGERS;
  464.         int y = rand()%NUMBER_PASSENGERS;
  465.         passLost[x] = 1;
  466.         vip[y] = 1;
  467.     }
  468.  
  469.     for(int i=0; i<NUMBER_PASSENGERS; i++) {
  470.         passenger[i].pid = i+1;
  471.         if(vip[i]==1)   passenger[i].isvip = true;
  472.         else    passenger[i].isvip = false;
  473.         passenger[i].boardingpass = false;
  474.         passenger[i].lost = 0;
  475.         int passengerinterval = poissonRandom(3);
  476.         status = pthread_create(&thread[i], NULL, boardingProcess, (void*) &passenger[i]);
  477.         if (status != 0) {
  478.             printf("%dth thread creation failed", i+1);
  479.             exit(-1);
  480.         }
  481.         usleep(passengerinterval*10000);
  482.     }
  483.  
  484.     for(int i=0; i<NUMBER_PASSENGERS; i++)
  485.         pthread_join(thread[i], NULL);
  486.  
  487.     fclose(fw);
  488.     return 0;
  489. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement