Skip to content

Instantly share code, notes, and snippets.

@KyleJohnstonNet
Last active January 5, 2018 01:57
Show Gist options
  • Save KyleJohnstonNet/91f1e546cc19297b71aa6c7e10f2b3e6 to your computer and use it in GitHub Desktop.
Save KyleJohnstonNet/91f1e546cc19297b71aa6c7e10f2b3e6 to your computer and use it in GitHub Desktop.
// COSC 3360
// Dr. Jehan-Francois Paris
// Spring 2016
// The University of Houston
// Assignment 3
// Kyle Johnston
// kjjohnston@uh.edu
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string>
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <dirent.h>
using namespace std;
int main(int argc, char const *argv[]) {
//Base variables
string family, name;
int arrivalTime, stayTime, balance;
int numberOfProcesses = 0;
bool waitingForNumbers;
pid_t pid;
//Shared Memory
long memoryKeyM, memoryKeyC;
int memorySidM, memorySidC;
int *nMontagues, *nCapulets;
memoryKeyM = rand();
memoryKeyC = rand();
memorySidM = shmget(memoryKeyM, sizeof(int), 0600 | IPC_CREAT);
memorySidC = shmget(memoryKeyC, sizeof(int), 0600 | IPC_CREAT);
if (memoryKeyM == -1) {
perror("Cannot get shared segment for Montagues");
exit(3);
}
if (memoryKeyC == -1) {
perror("Cannot get shared segment for Capulets");
exit(3);
}
nMontagues = (int *) shmat(memorySidM, NULL, 0);
nCapulets = (int *) shmat(memorySidC, NULL, 0);
if (nMontagues == NULL) {
perror("Cannot get address of shared segment for the Montagues");
exit(24);
}
if (nCapulets == NULL) {
perror("Cannot get address of shared segment for the Capulets");
exit(24);
}
*nMontagues = *nCapulets = 0;
//Semaphores for Mutual Exclusion on Shared Memory
sem_t *montague, *capulet, *numbers;
char semMontague[] = "KyleJohnston-Montague";
char semCapulet[] = "KyleJohnston-Capulet";
char semNumbers[] = "KyleJohnston-Numbers";
int semValue;
montague = sem_open(semMontague, O_CREAT, 0600, 1);
capulet = sem_open(semCapulet, O_CREAT, 0600, 1);
numbers = sem_open(semNumbers, O_CREAT, 0600, 0);
sem_post(montague);
sem_post(capulet);
sem_post(numbers);
if (montague == SEM_FAILED) {
perror("Unable to create the montague semaphore.");
sem_unlink(semMontague);
exit(1);
}
if (capulet == SEM_FAILED) {
perror("Unable to create the capulet semaphore.");
sem_unlink(semCapulet);
exit(1);
}
//Loop, reading input and creating child processes from it.
while (cin >> family >> name >> arrivalTime >> stayTime) {
//cout <<"Family: "<<family<<" \tName: "<<name<<"\t\tEntry Time: "<<arrivalTime<<" \tStay Time: "<<stayTime<<endl;
numberOfProcesses++;
pid = fork();
if (pid == 0) { //If 0 this is the child process
sleep(arrivalTime);
cout<<name<<" "<<family<<" arrives at time "<<arrivalTime<<"."<<endl;
//cout<<"There are now "<<*nMontagues<<" Montague(s) and "<<*nCapulets<<" Capulet(s) in the piazza."<<endl;
//Try to Enter
//Queue by family
if (family == "Montague") {
//sem_getvalue(montague, &semValue);
//cout<<"\t\t"<<name<<" "<<family<<" is waiting in the Montague queue, which currently has a value of "<<semValue<<endl;
sem_wait(montague);
//cout<<"\t\t"<<name<<" "<<family<<" has reached the front of the Montauge queue"<<endl;
} else if (family == "Capulet") {
//sem_getvalue(montague, &semValue);
//cout<<"\t\t"<<name<<" "<<family<<" is waiting in the Capulet queue, which currently has a value of "<<semValue<<endl;
sem_wait(capulet);
//cout<<"\t\t"<<name<<" "<<family<<" has reached the front of the Capulet queue"<<endl;
} else {
cout<<"Family: "<<family<<" is not recognized."<<endl;
_exit(0);
}
//cout<<name<<" "<<family<<" is trying to enter the piazza."<<endl;
//Wait till ballance allows entry
waitingForNumbers = true;
while (true) {
sem_wait(numbers);
balance = *nMontagues - *nCapulets;
//cout<<"\t\t"<<name<<" "<<family<<" checks the ballance: "<<balance<<endl;
if (family == "Montague" && balance <= 0) {
*nMontagues += 1;
waitingForNumbers = false;
} else if (family == "Capulet" && balance >= 0) {
*nCapulets += 1;
waitingForNumbers = false;
}
if (!waitingForNumbers) {
break;
}
sem_post(numbers);
}
cout<<name<<" "<<family<<" enters the piazza."<<endl<<"There are now "<<*nMontagues<<" Montague(s) and "<<*nCapulets<<" Capulet(s) in the piazza."<<endl;
sem_post(numbers);
if (family == "Montague") {
sem_post(montague);
} else if (family == "Capulet") {
sem_post(capulet);
}
sleep(stayTime);
//cout<<name<<" "<<family<<" wants to leave the piazza."<<endl;
//Wait till the ballance allows exiting
waitingForNumbers = true;
while (true) {
sem_wait(numbers);
balance = *nMontagues - *nCapulets;
//cout<<name<<" "<<family<<" checks the balance "<<balance<<endl;
if (family == "Montague" && balance >= 0) {
*nMontagues -= 1;
waitingForNumbers = false;
} else if (family == "Capulet" && balance <= 0) {
*nCapulets -= 1;
waitingForNumbers = false;
}
if (!waitingForNumbers) {
break;
}
sem_post(numbers);
}
cout<<name<<" "<<family<<" leaves the piazza."<<endl<<"There are now "<<*nMontagues<<" Montague(s) and "<<*nCapulets<<" Capulet(s) in the piazza."<<endl;
sem_post(numbers);
_exit(0);
}
}
while (numberOfProcesses>0) {
wait(0);
numberOfProcesses--;
}
sem_unlink(semMontague);
sem_unlink(semCapulet);
sem_unlink(semNumbers);
shmdt(nMontagues);
shmdt(nCapulets);
shmctl(memorySidM, 0, IPC_RMID);
shmctl(memorySidC, 0, IPC_RMID);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment