Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <ncurses.h>
- #include <random>
- #include <unistd.h>
- #include <pthread.h>
- #include <iostream>
- #include <sstream>
- #include <iomanip>
- #include <sys/time.h>
- constexpr int delay = 33333;
- enum philosopherAction {
- Eating,
- Waiting,
- Thinking
- };
- std::mt19937 twisterEngine;
- int roll() {
- static std::uniform_int_distribution<int> uid(2000, 4000);
- return uid(twisterEngine);
- }
- struct Fork {
- int requestedBy = -1;
- bool dirty = true;
- int owner = -1;
- };
- struct Philosopher {
- float time = 0;
- philosopherAction action = Thinking;
- pthread_t thread;
- };
- Philosopher *philosophers;
- Fork *forks;
- int instanceSize;
- pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
- bool done = false;
- void *philExist(void *threadID) {
- int id = (long) threadID;
- Philosopher *cPhil; //current Philosopher
- cPhil = &philosophers[(long) threadID];
- int timeLeft;
- int other = (id + 1) % instanceSize;
- while (!done) {
- timeLeft = roll();
- for (int i = timeLeft; i >= 0; i--) {
- usleep(1000);
- if (done)
- pthread_exit(nullptr);
- cPhil->time = i / 1000.0;
- }
- if (cPhil->action == Eating) {
- pthread_mutex_lock(&mutex);
- forks[other].dirty = true;
- forks[id].dirty = true;
- if (forks[id].requestedBy != -1 && forks[id].dirty) {
- forks[id].dirty = false;
- forks[id].owner = forks[id].requestedBy;
- forks[id].requestedBy = -1;
- }
- if (forks[other].requestedBy != -1 && forks[other].dirty) {
- forks[other].dirty = false;
- forks[other].owner = forks[other].requestedBy;
- forks[other].requestedBy = -1;
- }
- pthread_cond_broadcast(&cond);
- forks[other].dirty = true;
- forks[id].dirty = true;
- pthread_mutex_unlock(&mutex);
- cPhil->action = Thinking;
- continue;
- }
- cPhil->action = Waiting;
- //Waiting for forks
- pthread_mutex_lock(&mutex);
- if (forks[id].owner != id) {
- if (forks[id].dirty) {
- forks[id].owner = id;
- forks[id].dirty = false;
- forks[id].requestedBy = -1;
- } else {
- forks[id].requestedBy = id;
- }
- }
- if (forks[other].owner != id) {
- if (forks[other].dirty) {
- forks[other].owner = id;
- forks[other].dirty = false;
- forks[other].requestedBy = -1;
- } else {
- forks[other].requestedBy = id;
- }
- }
- pthread_cond_broadcast(&cond);
- pthread_mutex_unlock(&mutex);
- //Waiting for forks
- //pthread_mutex_unlock(&mutex);
- //pthread_mutex_lock(&mutex);
- while (true) {
- if (forks[id].owner == id && forks[other].owner == id) {
- cPhil->action = Eating;
- break;
- } else {
- pthread_mutex_lock(&mutex);
- pthread_cond_wait(&cond, &mutex);
- pthread_mutex_unlock(&mutex);
- }
- if (done) {
- pthread_exit(nullptr);
- }
- }
- // pthread_mutex_unlock(&mutex);
- }
- pthread_exit(nullptr);
- }
- void show() {
- mvprintw(0, 0, " Philosopher | Time | Action Fork | User |");
- for (int i = 0; i < instanceSize; i++) {
- std::string result;
- std::stringstream stringstream;
- stringstream << "Philosopher %02d | %2.2f";
- switch (philosophers[i].action) {
- case Thinking:
- stringstream << " | Think ";
- break;
- case Eating:
- stringstream << " | Eat ";
- break;
- case Waiting:
- stringstream << " | Sleep ";
- break;
- }
- result = stringstream.str();
- mvprintw(i + 2, 0, result.c_str(), i, philosophers[i].time);
- }
- for (int i = 0; i < instanceSize; i++) {
- std::string result;
- std::stringstream stringstream;
- stringstream << " Fork %02d |";
- stringstream << " %02d |";
- stringstream << forks[i].requestedBy << " - " << (forks[i].dirty ? "Dirty" : "Clean");
- result = stringstream.str();
- mvprintw(i + 2, 40, result.c_str(), i, forks[i].owner);
- }
- }
- int main(int argc, char *argv[]) {
- if (argc == 1) {
- instanceSize = 5;
- } else {
- if (argc == 3) {
- if (std::string(argv[1]) == "-i" || std::string(argv[1]) == "--instances") {
- instanceSize = std::stoi(argv[2]);
- }
- }
- }
- philosophers = new Philosopher[instanceSize];
- forks = new Fork[instanceSize];
- for (int i = 0; i < instanceSize; i++) {
- forks[i].owner = -1;
- }
- int code;
- for (int i = 0; i < instanceSize; i++) {
- code = pthread_create(&philosophers[i].thread, nullptr, philExist, (void *) i);
- forks[i].owner = i - 1;
- }
- //forks[0].owner = 0;
- initscr();
- nodelay(stdscr, TRUE);
- curs_set(FALSE);
- while (true) {
- if (getch() == 'q') {
- done = true;
- pthread_cond_broadcast(&cond);
- pthread_cond_destroy(&cond);
- endwin();
- pthread_exit(nullptr);
- }
- erase();
- show();
- usleep(delay);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement