From 866fc8f181af2b4a7ba51a65b25ef06a0d15136c Mon Sep 17 00:00:00 2001 From: Diego Herrera Date: Thu, 7 Oct 2021 17:28:20 -0600 Subject: [PATCH] Initial implementation using Sys V semaphores --- .vscode/launch.json | 45 ++++++++ .vscode/settings.json | 52 +++++++++ code/kill-ipcs.sh | 22 ++++ code/makefile | 1 - code/src/constants.h | 21 ++++ code/src/main.cpp | 8 +- code/src/waiting-state/fork.cpp | 14 --- code/src/waiting-state/fork.h | 26 ----- code/src/waiting-state/philosopher.cpp | 142 ++++++++++++++++++++++++- code/src/waiting-state/philosopher.h | 13 ++- code/unittest/test-waiting-state.cpp | 79 +++++++++++++- 11 files changed, 369 insertions(+), 54 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100755 code/kill-ipcs.sh create mode 100644 code/src/constants.h delete mode 100644 code/src/waiting-state/fork.cpp delete mode 100644 code/src/waiting-state/fork.h diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..516d663 --- /dev/null +++ b/.vscode/launch.json @@ -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" + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..440fd4a --- /dev/null +++ b/.vscode/settings.json @@ -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" + } +} \ No newline at end of file diff --git a/code/kill-ipcs.sh b/code/kill-ipcs.sh new file mode 100755 index 0000000..f0146f7 --- /dev/null +++ b/code/kill-ipcs.sh @@ -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 \ No newline at end of file diff --git a/code/makefile b/code/makefile index a64da3d..4d31db8 100644 --- a/code/makefile +++ b/code/makefile @@ -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) diff --git a/code/src/constants.h b/code/src/constants.h new file mode 100644 index 0000000..3b56c62 --- /dev/null +++ b/code/src/constants.h @@ -0,0 +1,21 @@ +#ifndef CONSTANTS_H +#define CONSTANTS_H + +// #ifdef __cplusplus +// extern "C" { +// #endif +#include + +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 \ No newline at end of file diff --git a/code/src/main.cpp b/code/src/main.cpp index 3551fbb..04d0151 100644 --- a/code/src/main.cpp +++ b/code/src/main.cpp @@ -1,6 +1,12 @@ #include "waiting-state/philosopher.h" +#include +#include +#include -int main() + +using namespace std; + +int main(int argc, char *argv[]) { return 0; } \ No newline at end of file diff --git a/code/src/waiting-state/fork.cpp b/code/src/waiting-state/fork.cpp deleted file mode 100644 index f725c60..0000000 --- a/code/src/waiting-state/fork.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "fork.h" - -using namespace WaitingPhilosopher; - -Fork::Fork() -{ - -} - -bool Fork::isBeingUsed() -{ - return IsUsed; -} - diff --git a/code/src/waiting-state/fork.h b/code/src/waiting-state/fork.h deleted file mode 100644 index d49f296..0000000 --- a/code/src/waiting-state/fork.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef FORK_H_ -#define FORK_H_ - -// #ifdef __cplusplus -// extern "C" { -// #endif -#include - -namespace WaitingPhilosopher -{ - class Fork - { - public: - Fork(); - bool isBeingUsed(); - protected: - bool IsUsed = true; - - - - }; -} - -#endif /* FORK_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 3ac89c8..03d7e02 100644 --- a/code/src/waiting-state/philosopher.cpp +++ b/code/src/waiting-state/philosopher.cpp @@ -1,22 +1,156 @@ #include "philosopher.h" +#include "constants.h" + +#include +#include +#include + +#include + +#include 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: "< + +#include +#include + +#include +#include +#include + #include "waiting-state/philosopher.h" -#include "waiting-state/fork.h" +#include "constants.h" using namespace WaitingPhilosopher; using namespace std; +void deleteSemaphore(int id) +{ + key_t semkey = ftok(SEMKEYPATH,id); + if ( semkey == (key_t)-1 ) + { + std::cerr << "ID: "< 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 < numPh; i++) + { + deleteSemaphore(i); + } + }