From 70efd1b3fab09da6cd383ec617c4d781ca73a461 Mon Sep 17 00:00:00 2001 From: Diego Herrera Date: Thu, 7 Oct 2021 21:38:45 -0600 Subject: [PATCH] Added dining table structre and added new tests --- .vscode/launch.json | 23 +++- code/src/main.cpp | 97 ++++++++++++++++- code/src/waiting-state/chopstick.cpp | 2 +- code/src/waiting-state/diningTable.cpp | 63 +++++++++++ code/src/waiting-state/diningTable.h | 20 ++++ code/src/waiting-state/philosopher.cpp | 6 +- code/unittest/test-waiting-state.cpp | 143 +++++++++++++++---------- 7 files changed, 284 insertions(+), 70 deletions(-) create mode 100644 code/src/waiting-state/diningTable.cpp create mode 100644 code/src/waiting-state/diningTable.h diff --git a/.vscode/launch.json b/.vscode/launch.json index 516d663..7ca4ac2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,11 +4,30 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "name": "(gdb) Unittest Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/code/bin/unittest", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + }, { "name": "(gdb) Attach", "type": "cppdbg", "request": "attach", - "program": "${workspaceFolder}/code/bin/unittest", + "program": "${workspaceFolder}/code/bin/dining-philosophers", "processId": "${command:pickProcess}", "MIMode": "gdb", "setupCommands": [ @@ -23,7 +42,7 @@ "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/code/bin/unittest", + "program": "${workspaceFolder}/code/bin/dining-philosophers", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/code/src/main.cpp b/code/src/main.cpp index 04d0151..771ffbf 100644 --- a/code/src/main.cpp +++ b/code/src/main.cpp @@ -1,12 +1,99 @@ -#include "waiting-state/philosopher.h" -#include -#include +#include "waiting-state/diningTable.h" + #include +#include +#include +#include +#include /* read, write, pipe, _exit */ +#include using namespace std; -int main(int argc, char *argv[]) +/* Flag set by ‘--verbose’. */ +static int verbose_flag; + + + +void displayUsage() +{ + cout << + "-n/--number : Number 'n' of philosophers. \n" + "-h/--help: Show help\n"; + exit(EXIT_SUCCESS); +} + +int main (int argc, char **argv) { - return 0; + int c; + int n = 5; + + while (true) + { + static struct option long_options[] = + { + /* These options set a flag. */ + {"verbose", no_argument, &verbose_flag, 1}, + {"brief", no_argument, &verbose_flag, 0}, + /* These options don’t set a flag. + We distinguish them by their indices. */ + + {"number", required_argument, 0, 'n'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; + + /* getopt_long stores the option index here. */ + int option_index = 0; + + c = getopt_long (argc, argv, "hn:", + long_options, &option_index); + + + + /* Detect the end of the options. */ + if (c == -1) + break; + + switch (c) + { + case 0: + /* If this option set a flag, do nothing else now. */ + if (long_options[option_index].flag != 0) + break; + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case 'n': + n = atoi(optarg); + break; + case 'h': + case '?': + default: + displayUsage(); + abort (); + } + } + + /* Instead of reporting ‘--verbose’ + and ‘--brief’ as they are encountered, + we report the final status resulting from them. */ + if (verbose_flag) + puts ("verbose flag is set"); + + /* Print any remaining command line arguments (not options). */ + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + putchar ('\n'); + } + + WaitingPhilosopher::DiningTable::startDinner(n); + + exit (EXIT_SUCCESS); } \ No newline at end of file diff --git a/code/src/waiting-state/chopstick.cpp b/code/src/waiting-state/chopstick.cpp index 47d15df..6d1a7f5 100644 --- a/code/src/waiting-state/chopstick.cpp +++ b/code/src/waiting-state/chopstick.cpp @@ -53,7 +53,7 @@ Chopstick::Chopstick(int index) void Chopstick::putAway() { - int rc = semctl( m_semid, 1, IPC_RMID ); + int rc = semctl( m_semid, 0, IPC_RMID ); if (rc==-1) { std::string error = "ID: " + std::to_string(m_index) + " semctl() remove id failed\n"; diff --git a/code/src/waiting-state/diningTable.cpp b/code/src/waiting-state/diningTable.cpp new file mode 100644 index 0000000..88201b8 --- /dev/null +++ b/code/src/waiting-state/diningTable.cpp @@ -0,0 +1,63 @@ +#include +#include +#include + +#include +#include +#include +#include + +#include "diningTable.h" +#include "philosopher.h" +#include "chopstick.h" +#include "constants.h" + +using namespace WaitingPhilosopher; +using namespace std; + +void DiningTable::startDinner(int numberPhilosophers) +{ + Philosopher* philosophers = (Philosopher*)malloc(sizeof(Philosopher) * numberPhilosophers); + Chopstick* chopsticks = (Chopstick*)malloc(sizeof(Chopstick) * numberPhilosophers);; + pid_t pids[numberPhilosophers]; + + printf("\n------ Dining Philosophers ------\n\n\n"); + printf("%i philosophers dining\n\n", numberPhilosophers); + for (int i = 0; i < numberPhilosophers; i++) + { + philosophers[i] = Philosopher(i, numberPhilosophers); + chopsticks[i] = Chopstick(i); + } + + + for (int i = 0; i < numberPhilosophers; i++) + { + if ((pids[i] = fork()) < 0) + { + perror("fork"); + abort(); + } + else if (pids[i] == 0) + { + philosophers[i].dine(); + exit(0); + } + } + + int status; + pid_t pid; + int n = numberPhilosophers; + while (n > 0) + { + pid = wait(&status); + //printf("Child with PID %ld exited with status 0x%x.\n", (long)pid, status); + --n; // TODO(pts): Remove pid from the pids array. + } + + for (int i = 0; i < numberPhilosophers; i++) + { + chopsticks[i].putAway(); + } + + printf("\nFinished Diner\n"); +} \ No newline at end of file diff --git a/code/src/waiting-state/diningTable.h b/code/src/waiting-state/diningTable.h new file mode 100644 index 0000000..2f3c864 --- /dev/null +++ b/code/src/waiting-state/diningTable.h @@ -0,0 +1,20 @@ +#ifndef DININGTABLE_H_ +#define DININGTABLE_H_ + +// #ifdef __cplusplus +// extern "C" { +// #endif +#include + +namespace WaitingPhilosopher +{ + class DiningTable + { + public: + static void startDinner(int numberPhilosophers); + }; +} + +#endif /* DININGTABLE_H_ */ + +// EOF \ No newline at end of file diff --git a/code/src/waiting-state/philosopher.cpp b/code/src/waiting-state/philosopher.cpp index 09aae4e..c2a5ef5 100644 --- a/code/src/waiting-state/philosopher.cpp +++ b/code/src/waiting-state/philosopher.cpp @@ -65,7 +65,7 @@ void Philosopher::waitChopstick(int index) void Philosopher::pickupChopstick(int index) { - printf("ID: %i - pickup chopstick: %i\n",m_index,index); + printf("ID: %i - Pickup chopstick: %i\n",m_index,index); // std::cout<<"Me: "< 0) - { - pid = wait(&status); - printf("Child with PID %ld exited with status 0x%x.\n", (long)pid, status); - --n; // TODO(pts): Remove pid from the pids array. - } + aristotle.pickupChopstick(id); - for (int i = 0; i < numPh; i++) - { - chopsticks[i].putAway(); - } + semval = semctl( semId, 0, GETVAL , arg ); + ASSERT_EQ ( semval, 1 ); + + aristotle.pickupChopstick(id); + + semval = semctl( semId, 0, GETVAL , arg ); + ASSERT_EQ ( semval, 2 ); + + aristotle.putdownChopstick(id); + + semval = semctl( semId, 0, GETVAL , arg ); + ASSERT_EQ ( semval, 1 ); + + + testChopstick.putAway(); + + semKey = ftok(SEMKEYPATH,id); + ASSERT_FALSE( semKey == (key_t)-1 ); + + semId = semget( semKey, NUMSEMS, 0666); + ASSERT_TRUE ( semId == -1 ); +} + + +TEST_F(WaitingPhilosopherTest, DISABLED_evenPhilosophers) +{ + DiningTable::startDinner(6); +} + +TEST_F(WaitingPhilosopherTest, DISABLED_oddPhilosophers) +{ + DiningTable::startDinner(5); }