#include #include #include #include #include #include #include #include #include "semp.h" /************************************************************************** * Authors: Gary Fleming, Amber McCloughan * Class: CIS452 - Operating Systems Concepts * Professor: Dr. Greg Wolffe * Date: 3/14/2019 * * Program that synchronizes shared memory between two processes. * Both processes swap memory back and forth, but a semaphore prevents * them from clobbering data. * * You must pass an argument to the program, which is the number of * times you want each process to swap the memory back and forth. ***************************************************************************/ // Size of shared memory segment. #define SIZE 16 /** * Main function of the reader program. Takes in * an argument, which is the number of times each * process will loop. * * @param argc, number of arguments. * @param argv, the actual arguments. */ int main(int argc, char *argv[]) { // Status for waiting on child. int status; /* The i for the for loop, the # of times looped, temp variable for swapping memory, and shared memory pointer. */ long int i, loop, temp, *shmPtr; // Shared memory ID. int shmId; // PID for forking. pid_t pid; // Getting loop # from program arguments. loop = atoi(argv[1]); // get value of loop variable (from command-line argument) // Getting shared memory segment. if ((shmId = shmget(IPC_PRIVATE, SIZE, IPC_CREAT | S_IRUSR | S_IWUSR)) < 0) { perror("i can't get no..\n"); exit(1); } // Attaching shared memory segment. if ((shmPtr = shmat(shmId, 0, 0)) == (void *)-1) { perror("can't attach\n"); exit(1); } // Initializing values for shared memory. shmPtr[0] = 0; shmPtr[1] = 1; // Creating semaphore. int semId = semp_init(1); // Forking if (!(pid = fork())) { // Child for (i = 0; i < loop; i++) { // Wait semp_wait(semId); temp = shmPtr[0]; // swap the contents of shmPtr[0] and shmPtr[1] shmPtr[0] = shmPtr[1]; shmPtr[1] = temp; // Signal semp_signal(semId); } // Detaching shared memory. if (shmdt(shmPtr) < 0) { perror("just can't let go\n"); exit(1); } // Child exits. exit(0); } else { // Parent for (i = 0; i < loop; i++) { // Wait semp_wait(semId); temp = shmPtr[1]; // swap the contents of shmPtr[1] and shmPtr[0] shmPtr[1] = shmPtr[0]; shmPtr[0] = temp; // Signal semp_signal(semId); } } // Waiting on child to exit. wait(&status); // Printing out the values. Should be 0 1. printf("values: %li\t%li\n", shmPtr[0], shmPtr[1]); // Detaching shared memory. if (shmdt(shmPtr) < 0) { perror("just can't let go\n"); exit(1); } // Flagging shared memory for deletion. if (shmctl(shmId, IPC_RMID, 0) < 0) { perror("can't deallocate\n"); exit(1); } // Deleting semaphore. semp_destroy(semId); // Goodbye. return 0; }