Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <pthread.h>
- #include <ncurses.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <iostream>
- #include <map>
- #include <vector>
- #include <algorithm>
- #include <set>
- #include <functional>
- using namespace std;
- typedef pair<int,int> pairCar;
- //
- // Created by rafkamin on 4/21/19.
- // How to run:
- // In Linux terminal type: $ gcc -std=c++11 main.cpp -lstdc++ -pthread -o main.o -lncurses
- // $ ./main.o
- //
- // TODO:
- // global map of cars (possibly 'number' of car structure) and their progress (lap * 100 + lap progress :: car->number)
- // somehow determine at which position in a map the current car->number is placed
- // use that to display additional "Position" info in start_car function
- const int SIMULATION_TIME = 500;
- int current_time = 0;
- int cars_in_queue = 0;
- pthread_mutex_t display_mutex = PTHREAD_MUTEX_INITIALIZER;
- pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
- struct racecar {
- pthread_mutex_t lap_progress_mutex;
- pthread_mutex_t lap_mutex;
- pthread_mutex_t fuel_mutex;
- pthread_mutex_t queue_mutex;
- int number; // for recognition purposes
- int position;
- int lap;
- int lap_progress; // 0 - startline of the lap, 50 - halfway of the lap, 100 - overlapping
- int fuel;
- bool damaged;
- bool in_pit_stop;
- };
- struct racecar *car1 = (struct racecar *)malloc(sizeof(struct racecar));
- struct racecar *car2 = (struct racecar *)malloc(sizeof(struct racecar));
- struct racecar *car3 = (struct racecar *)malloc(sizeof(struct racecar));
- struct racecar *car4 = (struct racecar *)malloc(sizeof(struct racecar));
- struct racecar *car5 = (struct racecar *)malloc(sizeof(struct racecar));
- // table of results:
- // key: number of a car (e.g. car1->number)
- // value: progress so far (e.g. car1->lap * 100 + car1->lap_progress)
- map<int, int> table_of_results;
- vector<racecar*> cars;
- void *timer_thread(void *arg) {
- while (current_time != SIMULATION_TIME) {
- current_time += 1;
- pthread_mutex_lock(&display_mutex);
- mvprintw(0, 15, "Time: %d ", current_time);
- pthread_mutex_unlock(&display_mutex);
- sleep(1);
- }
- pthread_exit(NULL);
- }
- void *start_car(void *car) {
- while (current_time != SIMULATION_TIME) {
- if (((struct racecar*)car)->in_pit_stop) {
- sleep(1);
- continue;
- }
- if (((struct racecar*)car)->lap_progress < 100) {
- int progress = (random() % 3) + 1; // random number between 1 and 3 - progress made
- int fuel_used = (random() % 5) + 1; // random number between 1 and 5 - fuel used
- //DISCLAIMER: Currently mutex locks are commented out
- // They should be used once the structure attributes are used in different threads (functions)
- // Lock lap progress
- pthread_mutex_lock(&((struct racecar*)car)->lap_progress_mutex);
- ((struct racecar*)car)->lap_progress += progress;
- ((struct racecar*)car)->fuel -= fuel_used;
- // Unlock lap progress
- pthread_mutex_unlock(&((struct racecar*)car)->lap_progress_mutex);
- sleep(1);
- }
- else {
- // Lock lap progress
- pthread_mutex_lock(&((struct racecar*)car)->lap_progress_mutex);
- ((struct racecar*)car)->lap_progress = 0;
- // Unlock lap progress
- pthread_mutex_unlock(&((struct racecar*)car)->lap_progress_mutex);
- // Lock lap
- pthread_mutex_lock(&((struct racecar*)car)->lap_mutex);
- ((struct racecar*)car)->lap += 1;
- // Unlock lap
- pthread_mutex_unlock(&((struct racecar*)car)->lap_mutex);
- }
- pthread_mutex_lock(&display_mutex);
- mvprintw(((struct racecar*)car)->number * 4, 5, "Lap progress: %d ", ((struct racecar*)car)->lap_progress);
- mvprintw(((struct racecar*)car)->number * 4, 30, "Current lap: %d ", ((struct racecar*)car)->lap);
- mvprintw(((struct racecar*)car)->number * 4, 55, "Fuel: %d ", ((struct racecar*)car)->fuel);
- pthread_mutex_unlock(&display_mutex);
- }
- pthread_exit(NULL);
- }
- void *pitstop(void *car) {
- // Start cars sequentially
- sleep(((struct racecar*)car)->number);
- while (current_time != SIMULATION_TIME) {
- if ((((struct racecar*)car)->fuel <= 20 || ((struct racecar*)car)->damaged)) {
- ((struct racecar*)car)->in_pit_stop = true;
- //Start of pit stop
- pthread_mutex_lock(&queue_mutex);
- if (cars_in_queue < 2) {
- cars_in_queue += 1;
- pthread_mutex_unlock(&queue_mutex);
- } else {
- pthread_mutex_unlock(&queue_mutex);
- sleep(1);
- continue;
- }
- // Regain fuel, takes 5 seconds to go from 0 to 100 fuel
- while (((struct racecar*)car)->fuel < 100) {
- ((struct racecar*)car)->fuel += 20;
- sleep(1);
- }
- // Repair car, takes 3 seconds to repair
- if (((struct racecar*)car)->damaged) {
- sleep(3);
- ((struct racecar*)car)->damaged = false;
- }
- ((struct racecar*)car)->in_pit_stop = false;
- pthread_mutex_lock(&queue_mutex);
- cars_in_queue -= 1;
- pthread_mutex_unlock(&queue_mutex);
- }
- sleep(1);
- }
- pthread_exit(NULL);
- }
- void *refresh_and_display_results(void *arg) {
- vector<pairCar> vec;
- while (current_time != SIMULATION_TIME) {
- sleep(1);
- for (auto &car : cars) {
- pthread_mutex_lock(&car->lap_progress_mutex);
- pthread_mutex_lock(&car->lap_mutex);
- table_of_results[car->number] = car->lap * 100 + car->lap_progress;
- pthread_mutex_unlock(&car->lap_progress_mutex);
- pthread_mutex_unlock(&car->lap_mutex);
- }
- /* copy(table_of_results.begin()
- ,table_of_results.end(),back_inserter<vector<pairCar>>(vec));
- sort(vec.begin(),vec.end(),[](const pairCar& l, const pairCar& r){
- if(l.second!=r.second){
- return l.second<r.second;
- }
- return l.first<r.first;
- });
- for(vector<pairCar>::iterator it=vec.begin();it!=vec.end(); ++it ){
- mvprintw(it->first * 4, 70, "Lap progress: %d ", it->second);
- }
- */
- typedef function<bool(pair<int, int>, pair<int, int>)> Comparator;
- Comparator compFunctor =
- [](pair<int, int> elem1 ,pair<int, int> elem2)
- {
- return elem1.second < elem2.second;
- };
- set<pair<int, int>, Comparator> setOfCars(
- table_of_results.begin(), table_of_results.end(), compFunctor);
- for (pair<int, int> element : setOfCars) {
- //mvprintw(element.first * 4, 70,"cze: %d", to_string(element.first).c_str(),"elo: %d ", element.second);
- mvprintw(element.first * 4, 70, "Lap progress: %d ", element.second);
- }
- //TODO: sort table_of_results values and display them
- //TODO: run this as thread in main()
- }
- }
- void init_car(racecar *car, int i) {
- car->lap_progress_mutex = PTHREAD_MUTEX_INITIALIZER;
- car->lap_mutex = PTHREAD_MUTEX_INITIALIZER;
- car->queue_mutex = PTHREAD_MUTEX_INITIALIZER;
- car->fuel_mutex = PTHREAD_MUTEX_INITIALIZER;
- car->lap = 0;
- car->lap_progress = 0;
- car->damaged = false;
- car->fuel = 100;
- car->number = i;
- car->position = 0;
- car->in_pit_stop = false;
- }
- int main() {
- srandom(time(NULL));
- pthread_t timer_t, car1_t, car2_t, car3_t, car4_t, car5_t;
- pthread_t pit1, pit2, pit3, pit4, pit5;
- pthread_t disp_t;
- initscr();
- curs_set(FALSE);
- init_car(car1, 1);
- init_car(car2, 2);
- init_car(car3, 3);
- init_car(car4, 4);
- init_car(car5, 5);
- cars.push_back(car1);
- cars.push_back(car2);
- cars.push_back(car3);
- cars.push_back(car4);
- cars.push_back(car5);
- if (pthread_create(&timer_t, NULL, timer_thread, NULL)) {
- cout << "Error while creating timer thread\n";
- abort();
- }
- if(pthread_create(&disp_t, NULL, refresh_and_display_results,NULL)){
- cout<<"Error while creating refresh_and_display_results\n";
- abort();
- }
- if (pthread_create(&car1_t, NULL, start_car, (void *)car1)) {
- cout << "Error while creating car thread\n";
- abort();
- }
- if (pthread_create(&car2_t, NULL, start_car, (void *)car2)) {
- cout << "Error while creating car thread\n";
- abort();
- }
- if (pthread_create(&car3_t, NULL, start_car, (void *)car3)) {
- cout << "Error while creating car thread\n";
- abort();
- }
- if (pthread_create(&car4_t, NULL, start_car, (void *)car4)) {
- cout << "Error while creating car thread\n";
- abort();
- }
- if (pthread_create(&car5_t, NULL, start_car, (void *)car5)) {
- cout << "Error while creating car thread\n";
- abort();
- }
- if (pthread_create(&pit1, NULL, pitstop, (void *)car1)) {
- cout << "Error while creating car thread\n";
- abort();
- }
- if (pthread_create(&pit2, NULL, pitstop, (void *)car2)) {
- cout << "Error while creating car thread\n";
- abort();
- }
- if (pthread_create(&pit3, NULL, pitstop, (void *)car3)) {
- cout << "Error while creating car thread\n";
- abort();
- }
- if (pthread_create(&pit4, NULL, pitstop, (void *)car4)) {
- cout << "Error while creating car thread\n";
- abort();
- }
- if (pthread_create(&pit5, NULL, pitstop, (void *)car5)) {
- cout << "Error while creating car thread\n";
- abort();
- }
- while (current_time != SIMULATION_TIME) {
- pthread_mutex_lock(&display_mutex);
- refresh();
- pthread_mutex_unlock(&display_mutex);
- }
- if (pthread_join(timer_t, NULL)) {
- cout << "Error while ending thread\n";
- abort();
- }
- if (pthread_join(car1_t, NULL)) {
- cout << "Error while ending thread\n";
- abort();
- }
- if (pthread_join(car2_t, NULL)) {
- cout << "Error while ending thread\n";
- abort();
- }
- if (pthread_join(car3_t, NULL)) {
- cout << "Error while ending thread\n";
- abort();
- }
- if (pthread_join(car4_t, NULL)) {
- cout << "Error while ending thread\n";
- abort();
- }
- if (pthread_join(car5_t, NULL)) {
- cout << "Error while ending thread\n";
- abort();
- }
- if (pthread_join(pit1, NULL)) {
- cout << "Error while ending thread\n";
- abort();
- }
- if (pthread_join(pit2, NULL)) {
- cout << "Error while ending thread\n";
- abort();
- }
- if (pthread_join(pit3, NULL)) {
- cout << "Error while ending thread\n";
- abort();
- }
- if (pthread_join(pit4, NULL)) {
- cout << "Error while ending thread\n";
- abort();
- }
- if (pthread_join(pit5, NULL)) {
- cout << "Error while ending thread\n";
- abort();
- }
- if (pthread_mutex_destroy(&display_mutex)) {
- cout << "Error while destroying mutex\n";
- abort();
- }
- endwin();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement