Advertisement
Guest User

Untitled

a guest
Jun 25th, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.46 KB | None | 0 0
  1. #include <ncurses.h>
  2. #include <random>
  3. #include <unistd.h>
  4. #include <pthread.h>
  5. #include <iostream>
  6. #include <sstream>
  7. #include <iomanip>
  8. #include <sys/time.h>
  9.  
  10. constexpr int delay = 33333;
  11.  
  12. enum philosopherAction {
  13. Eating,
  14. Waiting,
  15. Thinking
  16. };
  17.  
  18. std::mt19937 twisterEngine;
  19.  
  20. int roll() {
  21. static std::uniform_int_distribution<int> uid(2000, 4000);
  22. return uid(twisterEngine);
  23. }
  24.  
  25. struct Fork {
  26. int requestedBy = -1;
  27. bool dirty = true;
  28. int owner = -1;
  29. };
  30.  
  31. struct Philosopher {
  32. float time = 0;
  33. philosopherAction action = Thinking;
  34. pthread_t thread;
  35. };
  36.  
  37.  
  38. Philosopher *philosophers;
  39. Fork *forks;
  40.  
  41. int instanceSize;
  42.  
  43.  
  44. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  45. pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  46.  
  47.  
  48.  
  49. bool done = false;
  50.  
  51. void *philExist(void *threadID) {
  52. int id = (long) threadID;
  53. Philosopher *cPhil; //current Philosopher
  54. cPhil = &philosophers[(long) threadID];
  55. int timeLeft;
  56. int other = (id + 1) % instanceSize;
  57. while (!done) {
  58. timeLeft = roll();
  59. for (int i = timeLeft; i >= 0; i--) {
  60. usleep(1000);
  61. if (done)
  62. pthread_exit(nullptr);
  63. cPhil->time = i / 1000.0;
  64. }
  65. if (cPhil->action == Eating) {
  66. pthread_mutex_lock(&mutex);
  67. forks[other].dirty = true;
  68. forks[id].dirty = true;
  69.  
  70. if (forks[id].requestedBy != -1 && forks[id].dirty) {
  71. forks[id].dirty = false;
  72. forks[id].owner = forks[id].requestedBy;
  73. forks[id].requestedBy = -1;
  74. }
  75.  
  76. if (forks[other].requestedBy != -1 && forks[other].dirty) {
  77. forks[other].dirty = false;
  78. forks[other].owner = forks[other].requestedBy;
  79. forks[other].requestedBy = -1;
  80. }
  81.  
  82. pthread_cond_broadcast(&cond);
  83. forks[other].dirty = true;
  84. forks[id].dirty = true;
  85. pthread_mutex_unlock(&mutex);
  86. cPhil->action = Thinking;
  87.  
  88. continue;
  89. }
  90.  
  91. cPhil->action = Waiting;
  92.  
  93. //Waiting for forks
  94. pthread_mutex_lock(&mutex);
  95.  
  96. if (forks[id].owner != id) {
  97. if (forks[id].dirty) {
  98. forks[id].owner = id;
  99. forks[id].dirty = false;
  100. forks[id].requestedBy = -1;
  101.  
  102. } else {
  103. forks[id].requestedBy = id;
  104. }
  105. }
  106.  
  107. if (forks[other].owner != id) {
  108. if (forks[other].dirty) {
  109. forks[other].owner = id;
  110. forks[other].dirty = false;
  111. forks[other].requestedBy = -1;
  112.  
  113. } else {
  114. forks[other].requestedBy = id;
  115. }
  116. }
  117. pthread_cond_broadcast(&cond);
  118. pthread_mutex_unlock(&mutex);
  119. //Waiting for forks
  120. //pthread_mutex_unlock(&mutex);
  121.  
  122. //pthread_mutex_lock(&mutex);
  123.  
  124. while (true) {
  125. if (forks[id].owner == id && forks[other].owner == id) {
  126. cPhil->action = Eating;
  127. break;
  128. } else {
  129. pthread_mutex_lock(&mutex);
  130.  
  131. pthread_cond_wait(&cond, &mutex);
  132. pthread_mutex_unlock(&mutex);
  133.  
  134. }
  135. if (done) {
  136. pthread_exit(nullptr);
  137. }
  138. }
  139. // pthread_mutex_unlock(&mutex);
  140. }
  141. pthread_exit(nullptr);
  142. }
  143.  
  144. void show() {
  145. mvprintw(0, 0, " Philosopher | Time | Action Fork | User |");
  146. for (int i = 0; i < instanceSize; i++) {
  147. std::string result;
  148. std::stringstream stringstream;
  149. stringstream << "Philosopher %02d | %2.2f";
  150.  
  151. switch (philosophers[i].action) {
  152. case Thinking:
  153. stringstream << " | Think ";
  154. break;
  155. case Eating:
  156. stringstream << " | Eat ";
  157. break;
  158. case Waiting:
  159. stringstream << " | Sleep ";
  160. break;
  161. }
  162.  
  163. result = stringstream.str();
  164.  
  165. mvprintw(i + 2, 0, result.c_str(), i, philosophers[i].time);
  166. }
  167. for (int i = 0; i < instanceSize; i++) {
  168. std::string result;
  169. std::stringstream stringstream;
  170. stringstream << " Fork %02d |";
  171. stringstream << " %02d |";
  172.  
  173. stringstream << forks[i].requestedBy << " - " << (forks[i].dirty ? "Dirty" : "Clean");
  174. result = stringstream.str();
  175. mvprintw(i + 2, 40, result.c_str(), i, forks[i].owner);
  176. }
  177. }
  178.  
  179. int main(int argc, char *argv[]) {
  180. if (argc == 1) {
  181. instanceSize = 5;
  182. } else {
  183. if (argc == 3) {
  184. if (std::string(argv[1]) == "-i" || std::string(argv[1]) == "--instances") {
  185. instanceSize = std::stoi(argv[2]);
  186. }
  187. }
  188. }
  189.  
  190. philosophers = new Philosopher[instanceSize];
  191. forks = new Fork[instanceSize];
  192.  
  193. for (int i = 0; i < instanceSize; i++) {
  194. forks[i].owner = -1;
  195. }
  196.  
  197. int code;
  198.  
  199. for (int i = 0; i < instanceSize; i++) {
  200. code = pthread_create(&philosophers[i].thread, nullptr, philExist, (void *) i);
  201. forks[i].owner = i - 1;
  202. }
  203.  
  204. //forks[0].owner = 0;
  205. initscr();
  206.  
  207. nodelay(stdscr, TRUE);
  208. curs_set(FALSE);
  209.  
  210. while (true) {
  211. if (getch() == 'q') {
  212. done = true;
  213. pthread_cond_broadcast(&cond);
  214. pthread_cond_destroy(&cond);
  215. endwin();
  216. pthread_exit(nullptr);
  217. }
  218. erase();
  219. show();
  220.  
  221. usleep(delay);
  222. }
  223.  
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement