#include #include #include #include #include #include #include #include #include /************************************************************************** * 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 the child. int status; /* The i for the for loop, the # of times looped, temp variable for swapping memory, and shared memory pointers. */ 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 the 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; // Getting semaphore. int semId = semget(IPC_PRIVATE, 1, 00600); // Initializing semaphore to 1. semctl(semId, 0, SETVAL, 1); // Operation for locking the semaphore (subtract 1) struct sembuf lock = {0, -1, SEM_UNDO}; // Operating for unlocking the semaphore (add 1) struct sembuf unlock = {0, 1, SEM_UNDO}; // Forking if (!(pid = fork())) { // Child for (i = 0; i < loop; i++) { // Wait semop(semId, &lock, 1); temp = shmPtr[0]; // swap the contents of shmPtr[0] and shmPtr[1] shmPtr[0] = shmPtr[1]; shmPtr[1] = temp; // Signal semop(semId, &unlock, 1); } // 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 semop(semId, &lock, 1); temp = shmPtr[1]; // swap the contents of shmPtr[1] and shmPtr[0] shmPtr[1] = shmPtr[0]; shmPtr[0] = temp; // Signal semop(semId, &unlock, 1); } } // Waiting on the 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. semctl(semId, 0, IPC_RMID); // Goodbye. return 0; }