Please help me solve parts a, b, and c, it is confusing me and taking me forever because I don't know what to do.
Code in question:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
// A simple readers/writers program using a one-word shared memory.
#include <sys/types.h> // for pid_t
#include <unistd.h> // for fork
#include <stdio.h> // for printf
#include <sys/mman.h> // for mmap
#include <sys/wait.h> // for waitpid
#include <stdlib.h> // for exit
#define SIZE sizeof(int) // size of [int] integer
#define run_length 10 // number of iterations in test run
int main (void)
{
pid_t pid; // variable to record process id of child
caddr_t shared_memory; // shared memory base address
int i_parent, i_child; // index variables
int value; // value read by child
// set up shared memory segment
shared_memory = mmap(0, SIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_SHARED, -1, 0);
if (shared_memory == (caddr_t) -1) {
perror ("error in mmap while allocating shared memory\n");
exit (1);
}
if ((pid = fork()) < 0) {
// apply fork and check for error
perror ("error in fork");
exit (1);
}
if (0 == pid) {
// processing for child
printf("\033[0;31mThe child process begins.\033[0m\n");
for (i_child = 0; i_child < run_length; i_child++) {
// wait for memory to be updated
sleep(1);
value = *shared_memory;
printf("\033[0;31mChild's report: current value = %2d\033[0m\n", value);
}
printf("\033[0;31mThe child is done.\033[0m\n");
} else {
// processing for parent
printf("\033[0;32mThe parent process begins.\033[0m\n");
for (i_parent = 0; i_parent < run_length; i_parent++) {
// square into shared memory
*shared_memory = i_parent * i_parent;
printf("\033[0;32mParent's report: current value = %2d\033[0m\n", i_parent);
// wait for child to read value
sleep(1);
}
waitpid(pid, NULL, 0);
// deallocate shared memory
munmap (shared_memory, SIZE);
printf("\033[0;32mThe parent is done.\033[0m\n");
}
exit(0);
}
|
Review the code, compile (using gcc), and execute it a few times. Understand what is being done. Describe the program output you get, and explain briefly how it is produced.
Remove the sleep system call from the parent process, re-compile and re-execute. Explain the output produced.
Rather than rely upon sleep statements to synchronize the two processes, consider the use of spinlocks. In this approach, the parent will write to shared memory when the memory location contains the value -1, and the child will read when the memory location is not -1.
a.) Initialize the shared memory location in main memory to -1 before the fork operation. Note, why must this be done before the fork?
b.) Replace the sleep statement for the child by a spinlock that checks that the shared memory contains a nonnegative value. At the end of the child's loop, the shared memory location should be reset to -1.
c.) Remove the sleep statement from the parent at the end of the loop, and insert a spinlock at the beginning of the loop that checks that memory is -1. When this condition occurs, the parent may write the next nonnegative number to shared memory.
Describe the updated approach and output. Is this better?