Skip to content

Commit

Permalink
Initial implementation using Sys V semaphores
Browse files Browse the repository at this point in the history
  • Loading branch information
Diego Herrera committed Oct 7, 2021
1 parent 1c15a71 commit 866fc8f
Show file tree
Hide file tree
Showing 11 changed files with 369 additions and 54 deletions.
45 changes: 45 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "${workspaceFolder}/code/bin/unittest",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/code/bin/unittest",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing -gdb-set follow-fork-mode child",
"ignoreFailures": true
},
{
"text": "-gdb-set follow-fork-mode child"
}
]
}
]
}
52 changes: 52 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"files.associations": {
"*.tcc": "cpp",
"limits": "cpp",
"type_traits": "cpp",
"iostream": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"map": "cpp",
"set": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"new": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"typeinfo": "cpp"
}
}
22 changes: 22 additions & 0 deletions code/kill-ipcs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

ME=`whoami`

IPCS_S=`ipcs -s | egrep "0x[0-9a-f]+ [0-9]+" | grep $ME | cut -f2 -d" "`
IPCS_M=`ipcs -m | egrep "0x[0-9a-f]+ [0-9]+" | grep $ME | cut -f2 -d" "`
IPCS_Q=`ipcs -q | egrep "0x[0-9a-f]+ [0-9]+" | grep $ME | cut -f2 -d" "`


for id in $IPCS_M; do
ipcrm -m $id;
done

for id in $IPCS_S; do
ipcrm -s $id;
done

for id in $IPCS_Q; do
ipcrm -q $id;
done

ipcs
1 change: 0 additions & 1 deletion code/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ $(OUTFILE): $(OBJFILES)
$(CXX) -o $(BINDIR)/$@ $^ $(CXXFLAGS) $(LDFLAGS) $(LDLIBS)

$(TESTFILE): $(TESTOBJFILES)
echo $(TESTOBJFILES)
mkdir -p $(BINDIR)
$(CXX) -o $(BINDIR)/$@ $^ $(CXXFLAGS) $(LDFLAGS) $(TSTLIBS)

Expand Down
21 changes: 21 additions & 0 deletions code/src/constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef CONSTANTS_H
#define CONSTANTS_H

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

namespace WaitingPhilosopher
{
#define SEMKEYPATH "/tmp/dinPh" /* Path used on ftok for semget key */
#define SHMKEYPATH SEMKEYPATH /* Path used on ftok for shmget key */
#define OUTPUTPATH "/tmp/" /* Path used on ftok for semget key */

#define NUMSEMS 1
#define SIZEOFSHMSEG 2048
}

#endif /* PHILOSOPHER_H_ */

// EOF
8 changes: 7 additions & 1 deletion code/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#include "waiting-state/philosopher.h"
#include <iostream>
#include <unistd.h>
#include <stdio.h>

int main()

using namespace std;

int main(int argc, char *argv[])
{
return 0;
}
14 changes: 0 additions & 14 deletions code/src/waiting-state/fork.cpp

This file was deleted.

26 changes: 0 additions & 26 deletions code/src/waiting-state/fork.h

This file was deleted.

142 changes: 138 additions & 4 deletions code/src/waiting-state/philosopher.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,156 @@
#include "philosopher.h"
#include "constants.h"

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

#include <iostream>

#include <unistd.h>

using namespace WaitingPhilosopher;

Philosopher::Philosopher()
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());

}



}

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()
{
}

void Philosopher::wait()

void Philosopher::eat()
{

int neighbor1 = (m_index + 1) % m_numPhilosophers ;
int neighbor2 = (m_index - 1 + m_numPhilosophers) % m_numPhilosophers;

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

waitNeighbor(neighbor1);
waitNeighbor(neighbor2);

semaphoreOperation(m_index, 1);

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

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

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

}

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;
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. */
semKey = ftok(SEMKEYPATH,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());
//return -1;
}

/* Get the already created semaphore ID associated with key. */
/* If the semaphore set does not exist, then it will not be */
/* created, and an error will occur. */
semId = semget( semKey, NUMSEMS, 0666);
if ( semId == -1 )
{
std::string error = "ID: " + std::to_string(m_index) + " semget() failed\n";
perror(error.c_str());
// return -1;
}

// operations[0].sem_num = 0; /* Operate on the first sem */
// operations[0].sem_op = action; /* Wait for the value to be=0 */
// operations[0].sem_flg = 0; /* Allow a wait to occur */

int rc = semop( semId, &operations, 1 );
if (rc == -1)
{
std::string error = "ID: " + std::to_string(m_index) + " semop() failed\n";
perror(error.c_str());
}

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

}

}
13 changes: 10 additions & 3 deletions code/src/waiting-state/philosopher.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@ namespace WaitingPhilosopher
class Philosopher
{
public:
Philosopher();
Philosopher(int index, int numPhilosophers);
~Philosopher();
void think();
void wait();
void eat();
protected:
bool waitingState = true;
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
Loading

0 comments on commit 866fc8f

Please sign in to comment.