diff --git a/code/src/waiting-state/chopstick.cpp b/code/src/waiting-state/chopstick.cpp new file mode 100644 index 0000000..47d15df --- /dev/null +++ b/code/src/waiting-state/chopstick.cpp @@ -0,0 +1,62 @@ +#include "chopstick.h" +#include "constants.h" + +#include +#include +#include + +#include + +#include + +using namespace WaitingPhilosopher; + +Chopstick::Chopstick(int index) +{ + int rc= 0; + m_index = index; + + /* Generate an IPC key for the semaphore set and the shared */ + /* memory segment. Typically, an application specific path and */ + /* id would be used to generate the IPC key. */ + m_semkey = ftok(SEMKEYPATH,m_index); + if ( m_semkey == (key_t)-1 ) + { + std::string error = "ID: " + std::to_string(m_index) + " ftok() for sem failed\n"; + perror(error.c_str()); + abort(); + } + + + /* Create a semaphore set using the IPC key. The number of */ + /* semaphores in the set is two. If a semaphore set already */ + /* exists for the key, return an error. The specified permissions*/ + /* give everyone read/write access to the semaphore set. */ + + m_semid = semget( m_semkey, NUMSEMS, 0666 | IPC_CREAT | IPC_EXCL ); + if ( m_semid == -1 ) + { + std::string error = "ID: " + std::to_string(m_index) + " semget() failed\n"; + perror(error.c_str()); + abort(); + } + + // Initialize the semaphore in the set to 0 + rc = semctl( m_semid, 0, SETVAL, 0); + if(rc == -1) + { + std::string error = "ID: " + std::to_string(m_index) + " semctl() initialization failed\n"; + perror(error.c_str()); + + } +} + +void Chopstick::putAway() +{ + int rc = semctl( m_semid, 1, IPC_RMID ); + if (rc==-1) + { + std::string error = "ID: " + std::to_string(m_index) + " semctl() remove id failed\n"; + perror(error.c_str()); + } +} diff --git a/code/src/waiting-state/chopstick.h b/code/src/waiting-state/chopstick.h new file mode 100644 index 0000000..ecf45e4 --- /dev/null +++ b/code/src/waiting-state/chopstick.h @@ -0,0 +1,25 @@ +#ifndef CHOPSTICK_H_ +#define CHOPSTICK_H_ + +// #ifdef __cplusplus +// extern "C" { +// #endif +#include + +namespace WaitingPhilosopher +{ + class Chopstick + { + public: + Chopstick(int index); + void putAway(); + protected: + int m_index; + int m_semid; + key_t m_semkey; + }; +} + +#endif /* CHOPSTICK_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 03d7e02..09aae4e 100644 --- a/code/src/waiting-state/philosopher.cpp +++ b/code/src/waiting-state/philosopher.cpp @@ -13,113 +13,81 @@ using namespace WaitingPhilosopher; Philosopher::Philosopher(int index, int numPhilosophers) { - int rc= 0; - m_index = index; - m_numPhilosophers = numPhilosophers; - - /* Generate an IPC key for the semaphore set and the shared */ - /* memory segment. Typically, an application specific path and */ - /* id would be used to generate the IPC key. */ - m_semkey = ftok(SEMKEYPATH,m_index); - if ( m_semkey == (key_t)-1 ) - { - std::string error = "ID: " + std::to_string(m_index) + " ftok() for sem failed\n"; - perror(error.c_str()); - abort(); - } - - - /* Create a semaphore set using the IPC key. The number of */ - /* semaphores in the set is two. If a semaphore set already */ - /* exists for the key, return an error. The specified permissions*/ - /* give everyone read/write access to the semaphore set. */ - - m_semid = semget( m_semkey, NUMSEMS, 0666 | IPC_CREAT | IPC_EXCL ); - if ( m_semid == -1 ) - { - std::string error = "ID: " + std::to_string(m_index) + " semget() failed\n"; - perror(error.c_str()); - abort(); - } - - /* Initialize the first semaphore in the set to 0 and the */ - /* second semaphore in the set to 0. */ - /* */ - /* The first semaphore in the sem set means: */ - /* '1' -- The shared memory segment is being used. */ - /* '0' -- The shared memory segment is freed. */ - - /* The '1' on this command is a no-op, because the SETALL command*/ - /* is used. */ - rc = semctl( m_semid, 0, SETVAL, 0); - if(rc == -1) - { - std::string error = "ID: " + std::to_string(m_index) + " semctl() initialization failed\n"; - perror(error.c_str()); - - } - - - + m_index = index; + m_numPhilosophers = numPhilosophers; } -Philosopher::~Philosopher() -{ - // int rc = semctl( m_semid, 1, IPC_RMID ); - // if (rc==-1) - // { - // std::cerr <<"ID: "< #include "waiting-state/philosopher.h" +#include "waiting-state/chopstick.h" #include "constants.h" using namespace WaitingPhilosopher; @@ -66,14 +67,16 @@ class WaitingPhilosopherTest : public testing::Test TEST_F(WaitingPhilosopherTest, evenPhilosophers) { - int numPh = 3; + int numPh = 5; Philosopher* philosophers = (Philosopher*)malloc(sizeof(Philosopher) * numPh); + Chopstick* chopsticks = (Chopstick*)malloc(sizeof(Chopstick) * numPh);; pid_t pids[numPh]; for (int i = 0; i < numPh; i++) { - philosophers[i] = Philosopher(i, numPh); + philosophers[i] = Philosopher(i, numPh); + chopsticks[i] = Chopstick(i); } @@ -86,7 +89,7 @@ TEST_F(WaitingPhilosopherTest, evenPhilosophers) } else if (pids[i] == 0) { - philosophers[i].eat(); + philosophers[i].dine(); exit(0); } } @@ -103,10 +106,7 @@ TEST_F(WaitingPhilosopherTest, evenPhilosophers) for (int i = 0; i < numPh; i++) { - deleteSemaphore(i); + chopsticks[i].putAway(); } - - - }