Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <pthread.h>
- #include <semaphore.h>
- #include <unistd.h>
- #include <time.h>
- #include <string.h>
- #include <math.h>
- typedef int bool;
- #define true 1
- #define false 0
- #define NUMBER_PASSENGERS 100
- FILE *fw;
- int M, N, P;
- int w, x, y, z;
- double tm=1;
- int *passLost, *vip;
- int kioskwaiting=0, boardwaiting=0, kioskpassing=0, boardpassing=0; //waiting in the left
- bool *emptykiosk; //holds the empty/non-empty state of all the kiosks
- sem_t *beltsem;
- sem_t kiosk;
- pthread_mutex_t mutx1, mutx2, mutx3, mutx4, viplock, boardhalter, kioskhalter, halt;
- pthread_mutex_t lockiosk, boarding;
- pthread_mutex_t specialkiosk_lock;
- int poissonRandom(double expectedValue) {
- int n = 0; //counter of iteration
- double limit;
- double x; //pseudo random number
- limit = exp(-expectedValue);
- x = rand()/(double)2147483691;
- while (x > limit) {
- n++;
- x *= rand()/(double)2147483691;
- }
- return n;
- }
- struct Passenger
- {
- int pid;
- bool boardingpass;
- bool isvip;
- int lost;
- };
- int getFreeKiosk()
- {
- for(int i=0; i<M; i++) {
- if(emptykiosk[i] == true) return i;
- }
- return rand()%M;
- }
- void* timecount(void * arg) {
- while(1) {
- usleep(10000);
- tm = round(tm+1);
- }
- }
- void specialKiosk(struct Passenger *p)
- {
- if(!p->isvip)
- fprintf(fw, "Passenger %d has started waiting at the special kiosk from time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has started waiting at the special kiosk from time %.f\n\n", p->pid, tm);
- usleep(10000); //Manual extra waiting
- pthread_mutex_lock(&specialkiosk_lock);
- if(!p->isvip)
- fprintf(fw, "Passenger %d has started self-check in at the speical kiosk at time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has started self-check in at the speical kiosk at time %.f\n\n", p->pid, tm);
- usleep(w * 10000);
- p->boardingpass = true;
- if(!p->isvip)
- fprintf(fw, "Passenger %d has finished check in at time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has finished check in at time %.f\n\n", p->pid, tm);
- pthread_mutex_unlock(&specialkiosk_lock);
- }
- bool atBoarding(struct Passenger *p)
- {
- if(!p->isvip)
- fprintf(fw, "Passenger %d has started waiting to be boarded from time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has started waiting to be boarded from time %.f\n\n", p->pid, tm);
- if(passLost[p->pid]==1 && p->lost==0) {
- p->boardingpass = false;
- p->lost++;
- return false;
- }
- usleep(10000); //Manual extra waiting
- pthread_mutex_lock(&boarding);
- if(!p->isvip)
- fprintf(fw, "Passenger %d has started boarding the plane at time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has started boarding the plane at time %.f\n\n", p->pid, tm);
- usleep(y * 10000);
- if(!p->isvip)
- fprintf(fw, "Passenger %d has boarded the plane at time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has boarded the plane at time %.f\n\n", p->pid, tm);
- pthread_mutex_unlock(&boarding);
- return true;
- }
- void vipChannel(struct Passenger *p, int dir)
- {
- //dir == 1 => passenger wants left to right (Kiosk to Boarding gate)
- //dir == 0 => passenger wants right to left (Boarding gate to kiosk)
- if(dir == 1) {
- pthread_mutex_lock(&mutx1);
- kioskwaiting++;
- if(!p->isvip)
- fprintf(fw, "Passenger %d has started waiting to enter the VIP channel (kiosk to boarding gate) from time %.f\n\n", p->pid, tm);
- else
- 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);
- usleep(10000); //Manual extra waiting
- if(kioskwaiting==1 && kioskpassing==0) { //first one to enter
- pthread_mutex_lock(&boardhalter);
- pthread_mutex_lock(&kioskhalter);
- pthread_mutex_lock(&viplock);
- kioskpassing++;
- kioskwaiting--;
- pthread_mutex_unlock(&kioskhalter);
- }
- else if(kioskpassing==0) {
- pthread_mutex_lock(&kioskhalter);
- kioskpassing++;
- kioskwaiting--;
- pthread_mutex_unlock(&kioskhalter);
- }
- else {
- kioskwaiting--;
- kioskpassing++;
- }
- pthread_mutex_unlock(&mutx1);
- //critical region
- if(!p->isvip)
- fprintf(fw, "Passenger %d has entered the VIP channel (kiosk to boarding gate) at time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has entered the VIP channel (kiosk to boarding gate) at time %.f\n\n", p->pid, tm);
- usleep(z * 10000);
- if(!p->isvip)
- fprintf(fw, "Passenger %d has crossed the VIP channel (kiosk to boarding gate) at time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has crossed the VIP channel (kiosk to boarding gate) at time %.f\n\n", p->pid, tm);
- pthread_mutex_lock(&mutx2);
- kioskpassing--;
- if(kioskpassing==0) {
- pthread_mutex_unlock(&viplock);
- pthread_mutex_unlock(&boardhalter);
- }
- pthread_mutex_unlock(&mutx2);
- }
- else {
- pthread_mutex_lock(&mutx3);
- boardwaiting++;
- if(!p->isvip)
- fprintf(fw, "Passenger %d has started waiting to enter the VIP channel (boarding gate to kiosk) from time %.f\n\n", p->pid, tm);
- else
- 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);
- usleep(10000); //Manual extra waiting
- if(boardwaiting==1 && boardpassing==0) { //the first one to enter
- pthread_mutex_lock(&halt);
- pthread_mutex_lock(&viplock);
- boardpassing++;
- boardwaiting--;
- pthread_mutex_unlock(&halt);
- }
- else if(boardpassing==0) {
- pthread_mutex_lock(&halt);
- boardpassing++;
- boardwaiting--;
- pthread_mutex_unlock(&halt);
- }
- else {
- if(kioskwaiting==0) {
- boardpassing++;
- boardwaiting--;
- }
- else {
- pthread_mutex_lock(&boardhalter);
- boardpassing++;
- boardwaiting--;
- if(boardpassing==1)
- pthread_mutex_lock(&viplock);
- pthread_mutex_unlock(&boardhalter);
- }
- }
- pthread_mutex_unlock(&mutx3);
- //critical region
- if(!p->isvip)
- fprintf(fw, "Passenger %d has entered the VIP channel (boarding gate to kiosk) at time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has entered the VIP channel (boarding gate to kiosk) at time %.f\n\n", p->pid, tm);
- usleep(z * 10000);
- if(!p->isvip)
- fprintf(fw, "Passenger %d has crossed the VIP channel (boarding gate to kiosk) at time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has crossed the VIP channel (boarding gate to kiosk) at time %.f\n\n", p->pid, tm);
- pthread_mutex_lock(&mutx4);
- boardpassing--;
- if(boardpassing==0) {
- pthread_mutex_unlock(&viplock);
- }
- pthread_mutex_unlock(&mutx4);
- }
- }
- void securityCheck(struct Passenger *p)
- {
- int beltid = rand()%N;
- if(!p->isvip)
- fprintf(fw, "Passenger %d has started waiting for security check in belt %d from time %.f\n\n", p->pid, beltid+1, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has started waiting for security check in belt %d from time %.f\n\n", p->pid, beltid+1, tm);
- usleep(10000); //Manual extra waiting
- sem_wait(&beltsem[beltid]); //each beltsem[beltid] can serve up to P passengers at a time
- if(!p->isvip)
- fprintf(fw, "Passenger %d has started the security check at time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has started the security check at time %.f\n\n", p->pid, tm);
- usleep(x * 10000 + 300); //10000+300 or 100000+60
- if(!p->isvip)
- fprintf(fw, "Passenger %d has crossed the security check at time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has crossed the security check at time %.f\n\n", p->pid, tm);
- sem_post(&beltsem[beltid]);
- }
- void atKiosk(struct Passenger *p)
- {
- if(!p->isvip)
- fprintf(fw, "Passenger %d has arrived at the airport at time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has arrived at the airport at time %.f\n\n", p->pid, tm);
- usleep(10000); //Manual extra waiting
- sem_wait(&kiosk);
- pthread_mutex_lock(&lockiosk);
- int kioskid = getFreeKiosk();
- emptykiosk[kioskid] = false;
- pthread_mutex_unlock(&lockiosk);
- if(!p->isvip)
- fprintf(fw, "Passenger %d has started self-check in at kiosk %d at time %.f\n\n", p->pid, kioskid+1, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has started self-check in at kiosk %d at time %.f\n\n", p->pid, kioskid+1, tm);
- usleep(w * 10000 + 500); //10000+500 or 100000+400
- p->boardingpass = true;
- if(!p->isvip)
- fprintf(fw, "Passenger %d has finished check in at time %.f\n\n", p->pid, tm);
- else
- fprintf(fw, "Passenger %d (VIP) has finished check in at time %.f\n\n", p->pid, tm);
- pthread_mutex_lock(&lockiosk);
- emptykiosk[kioskid] = true;
- pthread_mutex_unlock(&lockiosk);
- sem_post(&kiosk);
- }
- void* boardingProcess(void * arg)
- {
- struct Passenger *p = (struct Passenger *) arg;
- //KIOSK
- atKiosk(p);
- usleep(10000);
- if(!p->isvip) {
- //Security Check
- securityCheck(p);
- usleep(10000);
- }
- else {
- //VIP channel
- vipChannel(p, 1);
- usleep(10000);
- }
- //Boarding gate
- bool isboarded = atBoarding(p);
- if(isboarded == false) {
- usleep(10000);
- vipChannel(p, 0); //boarding gate to special kiosk
- usleep(10000);
- specialKiosk(p);
- usleep(10000);
- vipChannel(p, 1); //special kiosk to boarding gate
- usleep(10000);
- atBoarding(p);
- }
- }
- int main()
- {
- FILE *fp;
- int c, line=0;
- int status;
- srand(time(0));
- fp = fopen("input.txt", "r");
- if(fp == NULL) {
- printf("Error in opening the input file");
- return 0;
- }
- while((fscanf(fp, "%d", &c)) != EOF) {
- if(line == 0) M = c;
- else if(line == 1) N = c;
- else if(line == 2) P = c;
- else if(line == 3) w = c;
- else if(line == 4) x = c;
- else if(line == 5) y = c;
- else if(line == 6) z = c;
- line++;
- }
- fclose(fp);
- fw = fopen("output.txt", "w");
- /*-----------INITIALIZE SEMAPHORES & MUTEXES------------*/
- emptykiosk = (bool *) malloc(M*sizeof(bool));
- for (int i=0; i<M; i++) emptykiosk[i] = true;
- //kiosk locker initialization
- status = pthread_mutex_init(&lockiosk, NULL);
- if(status != 0) {
- printf("kiosk locker mutex initialization failed\n");
- exit(-1);
- }
- // kiosk sempahore initialization
- status = sem_init(&kiosk, 0, M);
- if(status != 0) {
- printf("kiosk sempahore initialization failed\n");
- exit(-1);
- }
- // belt semaphore initialization
- beltsem = (sem_t *) malloc(N*sizeof(sem_t));
- for(int i=0; i<N; i++) {
- status = sem_init(&beltsem[i], 0, P);
- if(status != 0) {
- printf("%dth belt mutex initialization failed\n", i);
- exit(-1);
- }
- }
- //viplock and halters semaphores initialization
- status = pthread_mutex_init(&viplock, NULL);
- if(status != 0) {
- printf("VIP channel lock sempahore initialization failed\n");
- exit(-1);
- }
- status = pthread_mutex_init(&boardhalter, NULL);
- if(status != 0) {
- printf("Board halter sempahore initialization failed\n");
- exit(-1);
- }
- status = pthread_mutex_init(&kioskhalter, NULL);
- if(status != 0) {
- printf("Board halter sempahore initialization failed\n");
- exit(-1);
- }
- status = pthread_mutex_init(&halt, NULL);
- if(status != 0) {
- printf("halte mutex initialization failed\n");
- exit(-1);
- }
- status = pthread_mutex_init(&mutx1, NULL);
- if(status != 0) {
- printf("VIP channel mutx 1 initialization failed\n");
- exit(-1);
- }
- status = pthread_mutex_init(&mutx2, NULL);
- if(status != 0) {
- printf("VIP channel mutx 2 initialization failed\n");
- exit(-1);
- }
- status = pthread_mutex_init(&mutx3, NULL);
- if(status != 0) {
- printf("VIP channel mutx 2 initialization failed\n");
- exit(-1);
- }
- status = pthread_mutex_init(&mutx4, NULL);
- if(status != 0) {
- printf("VIP channel mutx 2 initialization failed\n");
- exit(-1);
- }
- //boarding gate mutex initialization
- status = pthread_mutex_init(&boarding, NULL);
- if(status != 0) {
- printf("boarding gate mutex initialization failed\n");
- exit(-1);
- }
- //special kiosk mutex initialization
- status = pthread_mutex_init(&specialkiosk_lock, NULL);
- if(status != 0) {
- printf("special kiosk lock mutex initialization failed\n");
- exit(-1);
- }
- /*-----------THREADING PART-------------*/
- struct Passenger passenger[NUMBER_PASSENGERS];
- pthread_t thread[NUMBER_PASSENGERS];
- pthread_t timethread;
- status = pthread_create(&timethread, NULL, timecount, NULL);
- if (status != 0) {
- printf("time thread creation failed");
- exit(-1);
- }
- //creating random boarding pass lost;
- int special = NUMBER_PASSENGERS/3;
- passLost = (int *) calloc(NUMBER_PASSENGERS, sizeof(int));
- vip = (int *) calloc(NUMBER_PASSENGERS, sizeof(int));
- for(int i=0; i<special; i++) {
- int x = rand()%NUMBER_PASSENGERS;
- int y = rand()%NUMBER_PASSENGERS;
- passLost[x] = 1;
- vip[y] = 1;
- }
- for(int i=0; i<NUMBER_PASSENGERS; i++) {
- passenger[i].pid = i+1;
- if(vip[i]==1) passenger[i].isvip = true;
- else passenger[i].isvip = false;
- passenger[i].boardingpass = false;
- passenger[i].lost = 0;
- int passengerinterval = poissonRandom(3);
- status = pthread_create(&thread[i], NULL, boardingProcess, (void*) &passenger[i]);
- if (status != 0) {
- printf("%dth thread creation failed", i+1);
- exit(-1);
- }
- usleep(passengerinterval*10000);
- }
- for(int i=0; i<NUMBER_PASSENGERS; i++)
- pthread_join(thread[i], NULL);
- fclose(fw);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement