Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <semaphore.h>
- #include <string.h>
- #include <stdbool.h>
- #include "ferry.h"
- unsigned int numOfCars = 0;
- unsigned int numOfCarsWaiting = 0;
- unsigned int numOfCarsOnBoard = 0;
- pthread_mutex_t mutex;
- sem_t sem;
- bool isFerryPresent = false;
- bool isFerryTravelling = false;
- void *embark(void *i)
- { // producer
- int id = *((int *)i);
- sleep(rand() % 5 + 1); // random arival time in range [1,5]
- pthread_mutex_lock(&mutex);
- numOfCarsWaiting++;
- pthread_mutex_unlock(&mutex);
- printf("Car #%d arrived at the port (cars waiting to board = %d)\n", id, numOfCarsWaiting);
- // wait for the ferry to arrive
- while (!isFerryPresent)
- sleep(1);
- //tofix while the ferry hasn't left and is full, some cars reach this point
- // we want them to wait until all cars have disembarked
- // start embarking if there is space on the ferry
- sem_wait(&sem);
- printf("Car #%d embarking on the ferry!\n", id);
- pthread_mutex_lock(&mutex); // enter critical region
- numOfCarsOnBoard++;
- numOfCarsWaiting--;
- pthread_mutex_unlock(&mutex); // leave critical region
- sleep(1); // embarking time
- printf("Car #%d embarked on the ferry!\n", id);
- // while ferry is waiting or travelling sleep/stay embarked
- while (isFerryPresent || isFerryTravelling)
- sleep(1);
- // disembark from the ferry
- pthread_mutex_lock(&mutex);
- numOfCarsOnBoard--;
- pthread_mutex_unlock(&mutex);
- printf("Car #%d disemabarked from the ferry!\n", id);
- sem_post(&sem);
- free(i);
- pthread_exit(NULL);
- }
- void *initFerrySchedule()
- { // consumer
- while (numOfCars > 0)
- {
- while (numOfCarsWaiting == 0 || numOfCarsOnBoard != 0)
- sleep(1);
- printf("Someone woke up the ferry!\nFerry is waiting for cars to board...\n");
- // signal that boarding is allowed
- pthread_mutex_lock(&mutex);
- isFerryPresent = true;
- isFerryTravelling = false;
- pthread_mutex_unlock(&mutex);
- sleep(7); // wait for cars to board
- printf("Ferry is leaving with %d cars on board\n", numOfCarsOnBoard);
- // signal that boarding is not allowed and cars
- // should wait for the next ferry
- pthread_mutex_lock(&mutex);
- isFerryPresent = false;
- isFerryTravelling = true;
- numOfCars -= numOfCarsOnBoard;
- pthread_mutex_unlock(&mutex);
- // go to antirio
- sleep(2); // travel time
- printf("Ferry has reached Antirio!\n");
- pthread_mutex_lock(&mutex);
- isFerryTravelling = false;
- pthread_mutex_unlock(&mutex);
- }
- pthread_exit(NULL);
- }
- void parseCarArg(int argc, char *argv[])
- {
- int i;
- for (i = 0; i < argc; i++)
- {
- if (strcmp(argv[i], "-c") == 0)
- {
- if (++i < argc && strlen(argv[i]) > 0)
- numOfCars = strtol(argv[i], NULL, 10); // convert to long
- if (numOfCars == 0)
- {
- perror("You must enter a number of cars > 0!\n");
- exit(EXIT_FAILURE);
- }
- break;
- }
- }
- }
- int main(int argc, char *argv[])
- {
- if (argc == 0)
- exit(EXIT_FAILURE);
- parseCarArg(argc, argv);
- srand(time(NULL)); // seed the generator using epoch time in millis
- if (sem_init(&sem, 0, MAX_FERRY_CAP) == -1) // up to 20 cars can board at a time
- {
- perror("Failed to initialize semaphore!\n");
- exit(EXIT_FAILURE);
- }
- if (pthread_mutex_init(&mutex, NULL) != 0)
- {
- perror("Failed to initialize mutex!\n");
- exit(EXIT_FAILURE);
- }
- pthread_t cars[numOfCars];
- int i;
- for (i = 0; i < numOfCars; i++)
- {
- int *id = malloc(sizeof(int));
- *id = i;
- if (pthread_create(&cars[i], NULL, embark, id) != 0)
- {
- perror("Failed to create threads for the cars!\n");
- exit(EXIT_FAILURE);
- }
- }
- // ferry setup
- pthread_t ferry;
- pthread_create(&ferry, NULL, initFerrySchedule, NULL);
- pthread_join(ferry, NULL);
- // wait for all threads to finish
- for (i = 0; i < numOfCars; i++)
- pthread_join(cars[i], NULL);
- sem_destroy(&sem);
- pthread_mutex_destroy(&mutex);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement