Advertisement
Guest User

Untitled

a guest
Apr 24th, 2019
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.46 KB | None | 0 0
  1. #include <pthread.h>
  2. #include <ncurses.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <stdio.h>
  6. #include <iostream>
  7. #include <map>
  8. #include <vector>
  9. #include <algorithm>
  10. #include <set>
  11. #include <functional>
  12.  
  13. using namespace std;
  14. typedef pair<int,int> pairCar;
  15.  
  16. //
  17. // Created by rafkamin on 4/21/19.
  18. // How to run:
  19. // In Linux terminal type: $ gcc -std=c++11 main.cpp -lstdc++ -pthread -o main.o -lncurses
  20. // $ ./main.o
  21. //
  22.  
  23.  
  24. // TODO:
  25. // global map of cars (possibly 'number' of car structure) and their progress (lap * 100 + lap progress :: car->number)
  26. // somehow determine at which position in a map the current car->number is placed
  27. // use that to display additional "Position" info in start_car function
  28.  
  29. const int SIMULATION_TIME = 500;
  30. int current_time = 0;
  31. int cars_in_queue = 0;
  32.  
  33. pthread_mutex_t display_mutex = PTHREAD_MUTEX_INITIALIZER;
  34. pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
  35.  
  36.  
  37. struct racecar {
  38. pthread_mutex_t lap_progress_mutex;
  39. pthread_mutex_t lap_mutex;
  40. pthread_mutex_t fuel_mutex;
  41. pthread_mutex_t queue_mutex;
  42.  
  43. int number; // for recognition purposes
  44.  
  45. int position;
  46. int lap;
  47. int lap_progress; // 0 - startline of the lap, 50 - halfway of the lap, 100 - overlapping
  48. int fuel;
  49. bool damaged;
  50.  
  51. bool in_pit_stop;
  52. };
  53.  
  54.  
  55.  
  56. struct racecar *car1 = (struct racecar *)malloc(sizeof(struct racecar));
  57. struct racecar *car2 = (struct racecar *)malloc(sizeof(struct racecar));
  58. struct racecar *car3 = (struct racecar *)malloc(sizeof(struct racecar));
  59. struct racecar *car4 = (struct racecar *)malloc(sizeof(struct racecar));
  60. struct racecar *car5 = (struct racecar *)malloc(sizeof(struct racecar));
  61.  
  62.  
  63. // table of results:
  64. // key: number of a car (e.g. car1->number)
  65. // value: progress so far (e.g. car1->lap * 100 + car1->lap_progress)
  66. map<int, int> table_of_results;
  67.  
  68. vector<racecar*> cars;
  69.  
  70.  
  71. void *timer_thread(void *arg) {
  72. while (current_time != SIMULATION_TIME) {
  73. current_time += 1;
  74. pthread_mutex_lock(&display_mutex);
  75. mvprintw(0, 15, "Time: %d ", current_time);
  76. pthread_mutex_unlock(&display_mutex);
  77. sleep(1);
  78. }
  79. pthread_exit(NULL);
  80. }
  81.  
  82. void *start_car(void *car) {
  83. while (current_time != SIMULATION_TIME) {
  84.  
  85.  
  86. if (((struct racecar*)car)->in_pit_stop) {
  87. sleep(1);
  88. continue;
  89. }
  90.  
  91. if (((struct racecar*)car)->lap_progress < 100) {
  92. int progress = (random() % 3) + 1; // random number between 1 and 3 - progress made
  93. int fuel_used = (random() % 5) + 1; // random number between 1 and 5 - fuel used
  94.  
  95. //DISCLAIMER: Currently mutex locks are commented out
  96. // They should be used once the structure attributes are used in different threads (functions)
  97.  
  98. // Lock lap progress
  99. pthread_mutex_lock(&((struct racecar*)car)->lap_progress_mutex);
  100. ((struct racecar*)car)->lap_progress += progress;
  101. ((struct racecar*)car)->fuel -= fuel_used;
  102. // Unlock lap progress
  103. pthread_mutex_unlock(&((struct racecar*)car)->lap_progress_mutex);
  104. sleep(1);
  105. }
  106. else {
  107. // Lock lap progress
  108. pthread_mutex_lock(&((struct racecar*)car)->lap_progress_mutex);
  109. ((struct racecar*)car)->lap_progress = 0;
  110. // Unlock lap progress
  111. pthread_mutex_unlock(&((struct racecar*)car)->lap_progress_mutex);
  112. // Lock lap
  113. pthread_mutex_lock(&((struct racecar*)car)->lap_mutex);
  114. ((struct racecar*)car)->lap += 1;
  115. // Unlock lap
  116. pthread_mutex_unlock(&((struct racecar*)car)->lap_mutex);
  117. }
  118.  
  119.  
  120. pthread_mutex_lock(&display_mutex);
  121. mvprintw(((struct racecar*)car)->number * 4, 5, "Lap progress: %d ", ((struct racecar*)car)->lap_progress);
  122. mvprintw(((struct racecar*)car)->number * 4, 30, "Current lap: %d ", ((struct racecar*)car)->lap);
  123. mvprintw(((struct racecar*)car)->number * 4, 55, "Fuel: %d ", ((struct racecar*)car)->fuel);
  124. pthread_mutex_unlock(&display_mutex);
  125. }
  126. pthread_exit(NULL);
  127. }
  128.  
  129. void *pitstop(void *car) {
  130. // Start cars sequentially
  131. sleep(((struct racecar*)car)->number);
  132. while (current_time != SIMULATION_TIME) {
  133. if ((((struct racecar*)car)->fuel <= 20 || ((struct racecar*)car)->damaged)) {
  134. ((struct racecar*)car)->in_pit_stop = true;
  135. //Start of pit stop
  136. pthread_mutex_lock(&queue_mutex);
  137. if (cars_in_queue < 2) {
  138. cars_in_queue += 1;
  139. pthread_mutex_unlock(&queue_mutex);
  140. } else {
  141. pthread_mutex_unlock(&queue_mutex);
  142. sleep(1);
  143. continue;
  144. }
  145.  
  146. // Regain fuel, takes 5 seconds to go from 0 to 100 fuel
  147. while (((struct racecar*)car)->fuel < 100) {
  148. ((struct racecar*)car)->fuel += 20;
  149. sleep(1);
  150. }
  151.  
  152. // Repair car, takes 3 seconds to repair
  153. if (((struct racecar*)car)->damaged) {
  154. sleep(3);
  155. ((struct racecar*)car)->damaged = false;
  156. }
  157. ((struct racecar*)car)->in_pit_stop = false;
  158. pthread_mutex_lock(&queue_mutex);
  159. cars_in_queue -= 1;
  160. pthread_mutex_unlock(&queue_mutex);
  161. }
  162. sleep(1);
  163. }
  164. pthread_exit(NULL);
  165. }
  166.  
  167.  
  168. void *refresh_and_display_results(void *arg) {
  169.  
  170. vector<pairCar> vec;
  171.  
  172. while (current_time != SIMULATION_TIME) {
  173. sleep(1);
  174. for (auto &car : cars) {
  175. pthread_mutex_lock(&car->lap_progress_mutex);
  176. pthread_mutex_lock(&car->lap_mutex);
  177. table_of_results[car->number] = car->lap * 100 + car->lap_progress;
  178. pthread_mutex_unlock(&car->lap_progress_mutex);
  179. pthread_mutex_unlock(&car->lap_mutex);
  180. }
  181.  
  182.  
  183.  
  184. /* copy(table_of_results.begin()
  185. ,table_of_results.end(),back_inserter<vector<pairCar>>(vec));
  186.  
  187.  
  188. sort(vec.begin(),vec.end(),[](const pairCar& l, const pairCar& r){
  189.  
  190. if(l.second!=r.second){
  191. return l.second<r.second;
  192. }
  193. return l.first<r.first;
  194. });
  195.  
  196.  
  197.  
  198. for(vector<pairCar>::iterator it=vec.begin();it!=vec.end(); ++it ){
  199. mvprintw(it->first * 4, 70, "Lap progress: %d ", it->second);
  200. }
  201. */
  202.  
  203.  
  204. typedef function<bool(pair<int, int>, pair<int, int>)> Comparator;
  205.  
  206. Comparator compFunctor =
  207. [](pair<int, int> elem1 ,pair<int, int> elem2)
  208. {
  209. return elem1.second < elem2.second;
  210. };
  211.  
  212.  
  213. set<pair<int, int>, Comparator> setOfCars(
  214. table_of_results.begin(), table_of_results.end(), compFunctor);
  215.  
  216.  
  217. for (pair<int, int> element : setOfCars) {
  218. //mvprintw(element.first * 4, 70,"cze: %d", to_string(element.first).c_str(),"elo: %d ", element.second);
  219. mvprintw(element.first * 4, 70, "Lap progress: %d ", element.second);
  220. }
  221.  
  222. //TODO: sort table_of_results values and display them
  223. //TODO: run this as thread in main()
  224. }
  225.  
  226.  
  227. }
  228.  
  229.  
  230. void init_car(racecar *car, int i) {
  231. car->lap_progress_mutex = PTHREAD_MUTEX_INITIALIZER;
  232. car->lap_mutex = PTHREAD_MUTEX_INITIALIZER;
  233. car->queue_mutex = PTHREAD_MUTEX_INITIALIZER;
  234. car->fuel_mutex = PTHREAD_MUTEX_INITIALIZER;
  235. car->lap = 0;
  236. car->lap_progress = 0;
  237. car->damaged = false;
  238. car->fuel = 100;
  239. car->number = i;
  240. car->position = 0;
  241. car->in_pit_stop = false;
  242. }
  243.  
  244.  
  245. int main() {
  246. srandom(time(NULL));
  247. pthread_t timer_t, car1_t, car2_t, car3_t, car4_t, car5_t;
  248. pthread_t pit1, pit2, pit3, pit4, pit5;
  249. pthread_t disp_t;
  250.  
  251. initscr();
  252. curs_set(FALSE);
  253.  
  254.  
  255. init_car(car1, 1);
  256. init_car(car2, 2);
  257. init_car(car3, 3);
  258. init_car(car4, 4);
  259. init_car(car5, 5);
  260.  
  261. cars.push_back(car1);
  262. cars.push_back(car2);
  263. cars.push_back(car3);
  264. cars.push_back(car4);
  265. cars.push_back(car5);
  266.  
  267.  
  268.  
  269. if (pthread_create(&timer_t, NULL, timer_thread, NULL)) {
  270. cout << "Error while creating timer thread\n";
  271. abort();
  272. }
  273.  
  274. if(pthread_create(&disp_t, NULL, refresh_and_display_results,NULL)){
  275. cout<<"Error while creating refresh_and_display_results\n";
  276. abort();
  277. }
  278.  
  279. if (pthread_create(&car1_t, NULL, start_car, (void *)car1)) {
  280. cout << "Error while creating car thread\n";
  281. abort();
  282. }
  283.  
  284. if (pthread_create(&car2_t, NULL, start_car, (void *)car2)) {
  285. cout << "Error while creating car thread\n";
  286. abort();
  287. }
  288.  
  289. if (pthread_create(&car3_t, NULL, start_car, (void *)car3)) {
  290. cout << "Error while creating car thread\n";
  291. abort();
  292. }
  293.  
  294. if (pthread_create(&car4_t, NULL, start_car, (void *)car4)) {
  295. cout << "Error while creating car thread\n";
  296. abort();
  297. }
  298.  
  299. if (pthread_create(&car5_t, NULL, start_car, (void *)car5)) {
  300. cout << "Error while creating car thread\n";
  301. abort();
  302. }
  303.  
  304. if (pthread_create(&pit1, NULL, pitstop, (void *)car1)) {
  305. cout << "Error while creating car thread\n";
  306. abort();
  307. }
  308.  
  309. if (pthread_create(&pit2, NULL, pitstop, (void *)car2)) {
  310. cout << "Error while creating car thread\n";
  311. abort();
  312. }
  313.  
  314. if (pthread_create(&pit3, NULL, pitstop, (void *)car3)) {
  315. cout << "Error while creating car thread\n";
  316. abort();
  317. }
  318.  
  319. if (pthread_create(&pit4, NULL, pitstop, (void *)car4)) {
  320. cout << "Error while creating car thread\n";
  321. abort();
  322. }
  323.  
  324. if (pthread_create(&pit5, NULL, pitstop, (void *)car5)) {
  325. cout << "Error while creating car thread\n";
  326. abort();
  327. }
  328.  
  329. while (current_time != SIMULATION_TIME) {
  330. pthread_mutex_lock(&display_mutex);
  331. refresh();
  332. pthread_mutex_unlock(&display_mutex);
  333. }
  334.  
  335. if (pthread_join(timer_t, NULL)) {
  336. cout << "Error while ending thread\n";
  337. abort();
  338. }
  339.  
  340. if (pthread_join(car1_t, NULL)) {
  341. cout << "Error while ending thread\n";
  342. abort();
  343. }
  344.  
  345. if (pthread_join(car2_t, NULL)) {
  346. cout << "Error while ending thread\n";
  347. abort();
  348. }
  349.  
  350. if (pthread_join(car3_t, NULL)) {
  351. cout << "Error while ending thread\n";
  352. abort();
  353. }
  354.  
  355. if (pthread_join(car4_t, NULL)) {
  356. cout << "Error while ending thread\n";
  357. abort();
  358. }
  359.  
  360. if (pthread_join(car5_t, NULL)) {
  361. cout << "Error while ending thread\n";
  362. abort();
  363. }
  364.  
  365. if (pthread_join(pit1, NULL)) {
  366. cout << "Error while ending thread\n";
  367. abort();
  368. }
  369.  
  370. if (pthread_join(pit2, NULL)) {
  371. cout << "Error while ending thread\n";
  372. abort();
  373. }
  374.  
  375. if (pthread_join(pit3, NULL)) {
  376. cout << "Error while ending thread\n";
  377. abort();
  378. }
  379.  
  380. if (pthread_join(pit4, NULL)) {
  381. cout << "Error while ending thread\n";
  382. abort();
  383. }
  384.  
  385. if (pthread_join(pit5, NULL)) {
  386. cout << "Error while ending thread\n";
  387. abort();
  388. }
  389.  
  390. if (pthread_mutex_destroy(&display_mutex)) {
  391. cout << "Error while destroying mutex\n";
  392. abort();
  393. }
  394.  
  395. endwin();
  396.  
  397. return 0;
  398.  
  399. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement