CS 3600 Operating Systems Homework 6
Problem A. Consider the following code example for allocating and releasing, which can be concurrently called by multiple processes to fork new processes.
#define MAX_PROCESSES 255 int number_of_processes = 0; // a shared variable
/* the implementation of fork() calls this function */ int allocate_process() { int new_pid;
if (number_of_processes == MAX_PROCESSES) return -1; else {
/* code to allocate necessary process resources */
++number_of_processes;
return new_pid;
}
}
/* the implementation of exit() calls this function */ void release_process() {
/* code to release process resources */
--number_of_processes;
}
Using the Semaphorestructure and its atomic wait() and signal() operations to solve a critical section (mutual exclusion) problem. To prevent race condition(s) and solve the critical section problem in the code given above,
(Hints: 1. The code here is NOT all the same as an example used in class; 2. In this problem, the Semaphore software tool needs to be used as a Binary Semaphore (Case 1) and the use of a Binary Semaphore (Case 1) to solve a critical section (mutual exclusion) problem is illustrated in the in-class lecture notes.)
- WRITE C statements to declare and initialize a Semaphorevariable named proc_S using the Semaphorestructure defined in Slide 3.25
- RE-WRITE the allocate_process() function by calling wait() and/or signal()defined in Slide 3.26
- RE-WRITE the release_process() function by calling wait() and/or signal() defined in Slide 3.26
Problem B. A file is to be shared among different processes, each of which owns a unique number. The file can be accessed simultaneously by several processes, subject to the following constraint: the sum of the unique numbers owned by the processes currently accessing the file must be less than a defined constant MAX_N. Complete access_file(), finish_access(), and initialization() as below to coordinate file access. (Hint: see an example in Slide 3.39, however, a loop, instead of an ifstatement, is needed in access_file() b/c an resumed process is not guaranteed to have a unique number that works.)
monitor file_access { int curr_sum; //sum of numbers owned by the processes currently accessing the file condition c; //allowing two operations wait() and signal() defined in Slide 3.33 void access_file(int my_num) {...} //called by a process to request file access void finish_access(int my_num) {...} //called by a process when completing file access void initialization() {...} //initializing variable(s)
}
Problem C. Solving the Bounded Buffer problem: Multiple Processes are producing and consuming full buffers by adding a newly produced full buffer to the head of a shared array-based list and removing a full buffer to be consumed from the tail of this shared list. a. using the structure given in Slide 3.25 and the information given in Slide 3.42, declare and initialize a binary semaphore variable named mutex, a semaphore variable named full, and a semaphore variable named empty,
- re-write the following produce() and consume() functions to implement the algorithm in Slides 3.42 through 3.44 to solve the racing conditions (Hint: are the variable counter and the while loop still needed? Most part of the solution is discussed in class.)
//buffer[] is an array of buffer pointers; next_produced points to a full buffer newly produced; // BUFFER_SIZE: the size of the array; next_consumed points to a full buffer for consuming.
void produce() {
/* produce an item pointed to by next_produced */ while (counter == BUFFER_SIZE)
; /*do nothing b/c all buffers have been produced*/ buffer[in] = next_produced; in = (in + 1) % BUFFER_SIZE; counter++;
} void consumer() { while (counter == 0)
; /* do nothing b/c no buffer for consuming */ next_consumed = buffer[out]; out = (out + 1) % BUFFER_SIZE;
//%: to loop back when reaching the end counter--;
/* consume the item in next consumed */
}