Question

Consider the C program (twoupdate) to demonstrate race condition. In this assignment, we will implement Peterson's...

Consider the C program (twoupdate) to demonstrate race condition. In this assignment, we will implement Peterson's algorithm to ensure mutual exclusion in the respective critical sections of the two processes, and thereby eliminate the race condition.

In order to implement Peterson's Algorithm, the two processes should share a boolean array calledflagwith two components and an integer variable called turn, all initialized suitably. We will create and access these shared variables using UNIX system calls relating to shared memory – shmget, shmat, shmdtandshmctl. The necessary include files and function prototypes for these system calls are as follows:

#include

#include

       #include

int shmget(key_t key, size_t size, int shmflag);

       void *shmat(int shmid, const void *shmaddr, int shmflag);

       int *shmdt(const void *shmaddr);

       int shmctl(int shmid, int cmd, struct shmid_ds *buf);

Spool out the man files for these system calls and study them carefully.

First create an include file called sharevar.h as shown. The file sharevar.h contains necessary constant and type definitions to create the shared memory segment for this assignment. In order to create a shared memory segment, the processes must first agree on a unique key.  

Study the attached listing of the files named sharevar.h and twoupdate.c, which show the use of these system calls. There is no need to modify twoupdate.c. But you have to suitably modify process0.c and process1.c. Both processes should make shmget, shmat and shmdt system calls in their respective main functions. Further, the lockfile and unlockfile functions in these two processes should implement the Peterson's algorithm. But, note that the shmctl to remove the shared memory segment should be called only by twoupdate.c. Be sure to create the file data with an integer 0 in it before you run the program every time. If the program works correctly, the final value left in the file should be the same every time the program is run, as long as the count for update is not changed.

Create a script output with a listing of all source files – sharevar.h, twoupdate.c, process0.c, and process1.c. Show the output of four or five runs of twoupdate for small values of count, say below 30. If you use a C Shell script file for repeated testing, provide a listing of the same. Exit from script.

Warning: Do not edit the source file inside the script. The control characters will create a messy script output. Edit out the print statements in both processes and recompile them.

Warning: The program runs for this part may take several minutes. Create a new script file with three runs of twoupdate for count = 1000, 5000, and 10000, as further proof of proper file access coordination between the two processes. Cleary we do not want lengthy printouts. Hence, we have edited out the print statements inside process0.c and process1.c.

BELOW IS THE CODE for twoupdate.c, sharevar.h, process0.c (process1.c is just a copy).

//twoupdate.c

#include

#include

#include

#include

#include

#include "sharevar.h"

/*Variables needed for shared memory segment*/

/*Set up as external variables for programming ease*/

int shmid;

syncvars *shmptr;

int main (int argc, char *argv[])

{

   FILE *fp; int initial, final; int status;

   /*Check for command line arguments*/

   if (argc != 3)

   {

      printf("usage: %s filename count\n", argv[0]);

      return -1;

   }

   /*Determine initial value in file before update*/

   fp = fopen(argv[1], "r");

   fscanf(fp, "%d", &initial);

   fclose(fp);

   /*Create a shared memory segment for the given key*/

   /*provided one does not exist already*/

   shmid = shmget(SHMKEY, sizeof(syncvars), PERMS | IPC_CREAT);

   /*Attach the shared memory segment to this process*/

   shmptr = (syncvars *) shmat(shmid, (void *) NULL, 0);

   /*Initialize the shared memory for Peterson's Algorithm*/

   shmptr->flag[0] = FALSE;

   shmptr->flag[1] = FALSE;

   shmptr->turn = 0;

   /*Launch the two processes*/

   if (fork() == 0) {

      execlp("process0", "process0", argv[1], argv[2], (char *) NULL);

   }

   if (fork() == 0) {

      execlp("process1", "process1", argv[1], argv[2], (char *) NULL);

   }        

   /*Wait for the two processes to terminate*/

   wait(&status); wait(&status);

   /*Detach the shared memory segment*/

   shmdt((void *) shmptr);

   /*Remove the shared memory segment*/

   shmctl(shmid, IPC_RMID, (struct shmid_ds *) NULL);

   /*Determine final value in file after update*/

   fp = fopen(argv[1], "r");

   fscanf(fp, "%d", &final);

   fclose(fp);

   /*Print value in file before and after two-process update*/

   printf("\n\n****Initial value in file %d\n\n", initial);

   printf("****Final value in file %d\n\n", final);

return 0;

}

//sharevar.h

/*Constant and type definitions needed for creating the*/

/*shared memory segment to implement Peterson's Algorithm*/

#define PERMS 0666 /*Access rights*/

#define SHMKEY ((key_t) 800123456) /*Use your Banner ID#*/

#define FALSE 0

#define TRUE 1

typedef struct {

   int flag[2];

   int turn;

} syncvars;  

//process0.c

#include

#include

#include

#include

#include

#include

#include

void waste_time(void);

#define MAXSIZE 80

int main(int argc, char *argv[])

{

   /*Uses UNIX input/output system calls for file access */

   /*for no reason other than educational value*/

   /*function prototype for file access*/

   void fileaccess (int fd, int count);

   int fd, count;

   /*Check for command line arguments*/

   if (argc != 3) {

      printf("usage: process0 filename count\n");

      return -1;

   }

   count = atoi(argv[2]);

   /*Open file and update*/

   fd = open(argv[1], O_RDWR, 0);  

   fileaccess(fd, count);

  

   return 0;

}

/*Access the file with the given fd and increment*/

/*the only integer value in that file count times*/

void fileaccess(int fd, int count)

{

   /*function prototypes for locking and unlocking file*/

   void lockfile (void);

   void unlockfile (void);

   int i, k, value; pid_t pid;

   char buff[MAXSIZE];

   /*Initialize the seed for random number generator*/

   srand(time(NULL));

   pid = getpid();

   for (i = 0; i < count; i++)

   {

      lockfile();                  /*lock the file*/

      /*Read value from file*/

      lseek(fd, 0L, 0);

      k = read(fd, buff, MAXSIZE); buff[k] = '\0';

      sscanf(buff, "%d\n", &value);

      /*Increment value*/

      value++;

     

      /*Slow down*/

      waste_time();

      /*Write back into file*/

      sprintf(buff, "%10d\n", value);

      lseek(fd, 0L, 0);

      k = strlen(buff); write(fd, buff, k);

      printf("pid = %d, new value = %d\n", pid, value);

      unlockfile();                /*unlock the file*/

   }

}

void waste_time (void)

{

   /*Slow down; waste time in loop*/

   int randNum = rand() % 100000; int x;

   for (x = 0; x < randNum; x++) {

   }

}

void lockfile(void)

{

}

void unlockfile(void)

{

}

Thanks so much for your help!!

Homework Answers

Answer #1

process1.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>

#include "sharevar.h"

#define MAXSIZE 80

void fileaccess(int fd, int count);

int shmid;
syncvars *shmptr;

int main(int argc, char *argv[])
{
   int fd, count;
   if(argc != 3){
      printf("usage: process1 filename count\n");
      return -1;
   }
   count = atoi(argv[2]);

   fd = open(argv[1], O_RDWR, 0);
   fileaccess(fd, count);

   return 0;
}

void fileaccess(int fd, int count){
   void lockfile (void);
   void unlockfile (void);

   int i, k, value; pid_t pid;
   char buff[MAXSIZE];

   shmid = shmget(SHMKEY, sizeof(syncvars), PERMS | IPC_CREAT);
   shmptr = (syncvars *) shmat(shmid, (void *) NULL, 0);

   pid = getpid();

   for(i = 0; i < count; i++){
      lockfile();
      while(shmptr->turn == 0 && shmptr->flag[0] == TRUE );

      //critical stuff
      lseek(fd, 0L, 0);
      k = read(fd, buff, MAXSIZE); buff[k] = '\0';
      sscanf(buff, "%d\n", &value);
      value++;

      sprintf(buff, "%10d\n", value);
      lseek(fd, 0l, 0);
      k = strlen(buff); write(fd, buff, k);
      printf("pid = %d, new value = %d\n", pid, value);
      unlockfile();
   }
}

void lockfile (void){
   shmptr->flag[1] = TRUE;
   shmptr->turn = 0;
}

void unlockfile (void){
   shmptr->flag[1] = FALSE;
}

twoupdate.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include "sharevar.h"

/*Variables needed for shared memory segment*/
/*Set up as external variables for programming ease*/
int shmid;
syncvars *shmptr;

int main(int argc, char *argv[]){
   FILE *fp; int initial, final; int status;

   /*Check for command line arguments*/
   if(argc != 3){
       printf("usage: %s filename count\n", argv[0]);
       return -1;
   }

   /*Deterime initial value in the file before update*/
   fp = fopen(argv[1], "r");
   fscanf(fp, "%d", &initial);
   fclose(fp);

   /*Create a shared memory segmenmt for the given key*/
   /*provided one does not exist already*/
   shmid = shmget(SHMKEY, sizeof(syncvars), PERMS | IPC_CREAT);
   /*Attach the shared memory segment to this process.*/
   shmptr = (syncvars *) shmat(shmid, (void *) NULL, 0);

   /*Initialize the shared memory for Peterson's Algorithm*/
   shmptr->flag[0] = FALSE;
   shmptr->flag[1] = FALSE;
   shmptr->turn = 0;

   /*Launch the two processes*/
   if(fork() == 0){
       execlp("process0", "process0", argv[1], argv[2], (char *) NULL);
   }
   if(fork() == 0){
       execlp("process1", "process1", argv[1], argv[2], (char *) NULL);
   }
   /*Wait for the two processes to terminate*/
   wait(&status); wait(&status);

   /*Detatch the shared memory segment*/
   shmdt((void *) shmptr);
   /*Remove the shared memory segment*/
   shmctl(shmid, IPC_RMID, (struct shmid_ds *) NULL);

   /*Determine the file value in file after update*/
   fp = fopen(argv[1], "r");
   fscanf(fp, "%d", &final);
   fclose(fp);

   /*Print value in file before and after two-process update*/
   printf("\n\n****Initial value in file %d\n\n", initial);
   printf("****Final value in file %d\n\n", final);

   return 0;
}

sharevar.h

/*Constant and type definitions needed for creating the*/
/*shared memory segment to implement Peterson's Algorithm*/
#define PERMS 0666 /*Acess rights*/
#define SHMKEY ((key_t) 800650198)
#define FALSE 0
#define TRUE 1
typedef struct {
   int flag[2];
   int turn;
} syncvars;

Know the answer?
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for?
Ask your own homework help question
Similar Questions
LANGUAGE C The codes below reads another .c or .txt file. Then, it will read the...
LANGUAGE C The codes below reads another .c or .txt file. Then, it will read the contents of every line and store the contents into a string array. Example: .c file that is to be read: #include <stdio.h> int main(){    printf("Hello World");    return ; } _______________(END OF THE FILE)_______________ Therefore, the code will read the contents above and store the contents in every line into an array, such that.... array[0] = "#include <stdio.h>\n" array[1] = "\n" array[2] ="int...
CS4315 Operating Systems Lab 2: Linux Processes This lab assignment contains three questions. To submit this...
CS4315 Operating Systems Lab 2: Linux Processes This lab assignment contains three questions. To submit this lab assignment, please use a Word document to include the screenshots and write your answer. 1. Run the following C program, and submit a screenshot of the result. #include <sys/types.h> #include <stdio.h> #include <unistd.h> int main( ) { pid_t pid; if ( (pid = fork()) == 0 ) { printf (“I am the child, my pid = %d and my parent pid = %d\n”,...
Compile and run the following code and presuming your executable is in a.out, run this command...
Compile and run the following code and presuming your executable is in a.out, run this command from the shell prompt: ./a.out ; echo "Parent Terminated Normally with a return value of $?" Explain, in your own words, why you see the screen output you do and how that output relates to both the content of the program AND the nature of the shell command used to invoke it. Hint: This has everything to do with how processes “communicate” their exit...
Using the C programming language implement Heapsort in the manner described in class. Here is some...
Using the C programming language implement Heapsort in the manner described in class. Here is some example code to use as a guideline. Remember, you need only implement the sort algorithm, both the comparison and main functions have been provided. /* * * after splitting this file into the five source files: * * srt.h, main.c, srtbubb.c, srtinsr.c, srtmerg.c * * compile using the command: * * gcc -std=c99 -DRAND -DPRNT -DTYPE=(float | double) -D(BUBB | HEAP | INSR |...
For a C program hangman game: Create the function int setup_game [int setup_game ( Game *g,...
For a C program hangman game: Create the function int setup_game [int setup_game ( Game *g, char wordlist[][MAX_WORD_LENGTH], int numwords)] for a C program hangman game. (The existing code for other functions and the program is below, along with what the function needs to do) What int setup_game needs to do setup_game() does exactly what the name suggests. It sets up a new game of hangman. This means that it picks a random word from the supplied wordlist array and...
C Program Write a program to count the frequency of each alphabet letter (A-Z a-z, total...
C Program Write a program to count the frequency of each alphabet letter (A-Z a-z, total 52 case sensitive) and five special characters (‘.’, ‘,’, ‘:’, ‘;’ and ‘!’) in all the .txt files under a given directory. The program should include a header count.h, alphabetcount.c to count the frequency of alphabet letters; and specialcharcount.c to count the frequency of special characters. Please only add code to where it says //ADDCODEHERE and keep function names the same. I have also...
Please answer the following C question: Read the following files called array-utils5A.c and array-utils5A.h. Build an...
Please answer the following C question: Read the following files called array-utils5A.c and array-utils5A.h. Build an executable with gcc -Wall -DUNIT_TESTS=1 array-utils5A.c The definitions for is_reverse_sorted and all_different are both defective. Rewrite the definitions so that they are correct. The definition for is_alternating is missing. Write a correct definition for that function, and add unit tests for it, using the unit tests for is_reverse_sorted and all_different as models. Please explain the logic errors present in in the definition of is_reverse_sorted...
This is C programming assignment. The objective of this homework is to give you practice using...
This is C programming assignment. The objective of this homework is to give you practice using make files to compose an executable file from a set of source files and adding additional functions to an existing set of code. This assignment will give you an appreciation for the ease with which well designed software can be extended. For this assignment, you will use both the static and dynamic assignment versions of the matrix software. Using each version, do the following:...
"C language" Take this code and make the minor modification necessary to create a circular linked...
"C language" Take this code and make the minor modification necessary to create a circular linked list (Hint: Store a pointer to the first node in the next pointer of the last node.) Demonstrate that this is working by traversing the list until the first pointer is encountered 3 times. Next redefine the node structure to include a back pointer. This will enable your program to move from front to back and then from back to front. It is not...
C CODE PLZ! All instructions are in sections of code #include <stdio.h> /* TODO: Define 3...
C CODE PLZ! All instructions are in sections of code #include <stdio.h> /* TODO: Define 3 functions input, gcd and lcm in such a way that the main function below compiles correctly and has the correct behavior. The input function prompts the user to enter a non-negative integer. If the user enters a negative integer, the function prints a "sorry" statement and prompts the user again. It keeps on prompting until the user enters a non-negative number. The input function...
ADVERTISEMENT
Need Online Homework Help?

Get Answers For Free
Most questions answered within 1 hours.

Ask a Question
ADVERTISEMENT