Initial commit.
This commit is contained in:
commit
f8fd4e7269
|
@ -0,0 +1,143 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/sem.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 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;
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
#include "semp.h"
|
||||||
|
#include <sys/sem.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.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;
|
||||||
|
}
|
|
@ -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
|
Loading…
Reference in New Issue