From f8fd4e7269d662982f2cd838adf6420b0a7cb2ee Mon Sep 17 00:00:00 2001 From: Amber Date: Sun, 21 Feb 2021 21:22:37 -0500 Subject: [PATCH] Initial commit. --- extra-credit.c | 143 ++++++++++++++++++++++++++++++++++++ programming-assignment.c | 152 +++++++++++++++++++++++++++++++++++++++ semp.c | 72 +++++++++++++++++++ semp.h | 50 +++++++++++++ 4 files changed, 417 insertions(+) create mode 100644 extra-credit.c create mode 100644 programming-assignment.c create mode 100644 semp.c create mode 100644 semp.h diff --git a/extra-credit.c b/extra-credit.c new file mode 100644 index 0000000..06a2f38 --- /dev/null +++ b/extra-credit.c @@ -0,0 +1,143 @@ +#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; +} \ No newline at end of file diff --git a/programming-assignment.c b/programming-assignment.c new file mode 100644 index 0000000..fb5798f --- /dev/null +++ b/programming-assignment.c @@ -0,0 +1,152 @@ +#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; +} \ No newline at end of file diff --git a/semp.c b/semp.c new file mode 100644 index 0000000..bd75071 --- /dev/null +++ b/semp.c @@ -0,0 +1,72 @@ +#include "semp.h" +#include + +/************************************************************************** + * Authors: Gary Fleming, Amber McCloughan + * Class: CIS452 - Operating Systems Concepts + * Professor: Dr. Greg Wolffe + * Date: 3/14/2019 + * + * Library of functions for synchronization + * using semaphores. Includes the classic + * wait() and signal() functions, as well as + * functions for initializing and deleting + * semaphores. + * + * @see semp.h for function definitions. +***************************************************************************/ + +/** + * Initialize a semaphore. The ID for using the other + * functions is returned by the function. + * + * @param value, the value to initialize the semaphore to. + * @return semId, the ID of the semaphore. + */ +int semp_init(int value) +{ + int semId = semget(IPC_PRIVATE, 1, 00600); + semctl(semId, 0, SETVAL, value); + + return semId; +} + +/** + * Attempts to wait on the semaphore. Subtracts 1 from + * the internal value of the semaphore. + * + * @param semId, the ID of the semaphore. + * @return 0 if there were no errors. + */ +int semp_wait(int semId) +{ + struct sembuf lock = {0, -1, SEM_UNDO}; + semop(semId, &lock, 1); + return 0; +} + +/** + * Signals the semaphore. Adds 1 to the internal value + * of the semaphore. + * + * @param semId, the ID of the semaphore. + * @return 0 if there were no errors. + */ +int semp_signal(int semId) +{ + struct sembuf unlock = {0, 1, SEM_UNDO}; + semop(semId, &unlock, 1); + return 0; +} + +/** + * Deletes the semaphore. + * + * @param semId, the ID of the semaphore. + * @return 0 if there were no errors. + */ +int semp_destroy(int semId) +{ + semctl(semId, 0, IPC_RMID); + return 0; +} \ No newline at end of file diff --git a/semp.h b/semp.h new file mode 100644 index 0000000..a843ba4 --- /dev/null +++ b/semp.h @@ -0,0 +1,50 @@ +#ifndef LAB_SEMP_H +#define LAB_SEMP_H + +/************************************************************************** + * Authors: Gary Fleming, Amber McCloughan + * Class: CIS452 - Operating Systems Concepts + * Professor: Dr. Greg Wolffe + * Date: 3/14/2019 + * + * Library of functions for synchronization + * using semaphores. Includes the classic + * wait() and signal() functions, as well as + * functions for initializing and deleting + * semaphores. + * + * @see semp.c for function implementations. +***************************************************************************/ + +/** + * Initialize a semaphore. The ID for using the other + * functions should be returned by the function. + * + * @param value, the value to initialize the semaphore to. + */ +int semp_init(int value); + +/** + * Attempts to wait on the semaphore. Subtracts 1 from + * the internal value of the semaphore. + * + * @param semId, the ID of the semaphore. + */ +int semp_wait(int semId); + +/** + * Signals the semaphore. Adds 1 to the internal value + * of the semaphore. + * + * @param semId, the ID of the semaphore. + */ +int semp_signal(int semId); + +/** + * Deletes the semaphore. + * + * @param semId, the ID of the semaphore. + */ +int semp_destroy(int semId); + +#endif \ No newline at end of file