Skip to content

Commit

Permalink
Partially working solution
Browse files Browse the repository at this point in the history
  • Loading branch information
Diego Herrera committed Oct 8, 2021
1 parent 63d981c commit e36ee5a
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 91 deletions.
62 changes: 62 additions & 0 deletions code/src/waiting-state/chopstick.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "chopstick.h"
#include "constants.h"

#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>

#include <iostream>

#include <unistd.h>

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());
}
}
25 changes: 25 additions & 0 deletions code/src/waiting-state/chopstick.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef CHOPSTICK_H_
#define CHOPSTICK_H_

// #ifdef __cplusplus
// extern "C" {
// #endif
#include <string>

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
131 changes: 50 additions & 81 deletions code/src/waiting-state/philosopher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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: "<<m_index<<" semctl() remove id failed\n";
// }
}

void Philosopher::think()
{
{
printf("ID: %i - Thinking\n",m_index);
}


void Philosopher::eat()
{

int neighbor1 = (m_index + 1) % m_numPhilosophers ;
int neighbor2 = (m_index - 1 + m_numPhilosophers) % m_numPhilosophers;
printf("ID: %i - Eating\n",m_index);
usleep(500);
printf("ID: %i - Done eating\n",m_index);
}

printf("ID: %i, N1: %i, N2: %i\n",m_index,neighbor1,neighbor2);
void Philosopher::dine()
{

int chopstick1 = m_index;
int chopstick2 = (m_index + 1) % m_numPhilosophers ;

waitNeighbor(neighbor1);
waitNeighbor(neighbor2);
printf("ID: %i - Right Chopstick: %i, Left Chopstick: %i\n",m_index,chopstick1,chopstick2);

semaphoreOperation(m_index, 1);
think();

printf("ID: %i - Eating\n",m_index);
// std::cout<<"Me: "<<m_index<<" Eating"<<std::endl;
waitChopstick(chopstick1);
pickupChopstick(chopstick1);
waitChopstick(chopstick2);
pickupChopstick(chopstick2);

eat();

putdownChopstick(chopstick1);
putdownChopstick(chopstick2);


usleep(500);
semaphoreOperation(m_index, -1);
printf("ID: %i - Done\n",m_index);
printf("ID: %i - Done\n",m_index);
// std::cout<<"Me: "<<m_index<<" Done"<<std::endl;
}

void Philosopher::waitNeighbor(int index)
void Philosopher::waitChopstick(int index)
{
printf("ID: %i - Waiting for neighbor: %i\n",m_index,index);
// std::cout<<"Me: "<<m_index<<"Waiting for neighbor: "<<index<<std::endl;
printf("ID: %i - Waiting for chopstick: %i\n",m_index,index);
// std::cout<<"Me: "<<m_index<<"Waiting for chopstick: "<<index<<std::endl;
semaphoreOperation(index, 0);

}

void Philosopher::pickupChopstick(int index)
{
printf("ID: %i - pickup chopstick: %i\n",m_index,index);
// std::cout<<"Me: "<<m_index<<"Waiting for chopstick: "<<index<<std::endl;
semaphoreOperation(index, 1);

}

void Philosopher::putdownChopstick(int index)
{
printf("ID: %i - putdown chopstick: %i\n",m_index,index);
// std::cout<<"Me: "<<m_index<<"Waiting for chopstick: "<<index<<std::endl;
semaphoreOperation(index, -1);

}

void Philosopher::semaphoreOperation(int index, short action)
{
printf("ID: %i - Operation on semaphore: %i - OpCode: %i\n",m_index, index, action);
// std::cout<<"Me: "<<m_index<<"Waiting for neighbor: "<<index<<std::endl;
// printf("ID: %i - Operation on semaphore: %i - OpCode: %i\n",m_index, index, action);
// std::cout<<"Me: "<<m_index<<"Waiting for chopstick: "<<index<<std::endl;
int semId;
key_t semKey;
struct sembuf operations = {.sem_num = 0, .sem_op = action, .sem_flg = 0};



/* 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. */
// Generate an IPC key for the semaphore set
semKey = ftok(SEMKEYPATH,index);
if ( m_semkey == (key_t)-1 )
{
Expand Down Expand Up @@ -150,7 +118,8 @@ void Philosopher::semaphoreOperation(int index, short action)
perror(error.c_str());
}

printf("ID: %i - Comleted Operation on semaphore: %i - OpCode: %i\n",m_index, index, action);
// printf("ID: %i - Comleted Operation on semaphore: %i - OpCode: %i\n",m_index, index, action);

}


7 changes: 4 additions & 3 deletions code/src/waiting-state/philosopher.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ namespace WaitingPhilosopher
{
public:
Philosopher(int index, int numPhilosophers);
~Philosopher();
void dine();
void think();
void eat();
void waitChopstick(int index);
void pickupChopstick(int index);
void putdownChopstick(int index);
protected:
int m_index;
int m_semid;
int m_numPhilosophers;
key_t m_semkey;

void waitNeighbor(int index);
void semaphoreOperation(int index, short action);


Expand Down
14 changes: 7 additions & 7 deletions code/unittest/test-waiting-state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <sys/shm.h>

#include "waiting-state/philosopher.h"
#include "waiting-state/chopstick.h"
#include "constants.h"

using namespace WaitingPhilosopher;
Expand Down Expand Up @@ -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);
}


Expand All @@ -86,7 +89,7 @@ TEST_F(WaitingPhilosopherTest, evenPhilosophers)
}
else if (pids[i] == 0)
{
philosophers[i].eat();
philosophers[i].dine();
exit(0);
}
}
Expand All @@ -103,10 +106,7 @@ TEST_F(WaitingPhilosopherTest, evenPhilosophers)

for (int i = 0; i < numPh; i++)
{
deleteSemaphore(i);
chopsticks[i].putAway();
}



}

0 comments on commit e36ee5a

Please sign in to comment.