Description
Problem Set #2
Total 4 points
(version: 1.0)
Note: This assignment weights a total of 4 points in the final marks of this course. However, just like each process has its own private virtual address space, this assignment also has its own virtual score space of 100 points, which is mapped to 4 points of physical marks. The below points for each question are given in the said virtual score space.
Question 1 – Synchronization (50 points)
(This question is related to ILO 2c – “describe the principles and techniques used by OS to support concurrency and synchronization control”.)
This is a solution (pseudocode) to the Readers-Writers problem given in the class.
sem_t semMutex, readMutex; void Reader(void) {
int readcount;
void init(void) { sem_init(&semMutex, 0, 1); sem_init(&readMutex,0, 1); readcount = 0;
}
void Writer(void) { sem_wait(&semMutex); do_writing(); sem_post(&semMutex);
}
}
sem_wait(&readMutex); readcount++; if (readcount == 1) sem_wait(&semMutex); sem_post(&readMutex);
do_reading();
sem_wait(&readMutex); readcount–; if (readcount == 0) sem_post(&semMutex); sem_post(&readMutex);
The above solution is implemented by using semaphores. Design another solution of the ReadersWriters problem by using condition variables and mutex locks. Write down your pseudo code to implement the Writer() and Reader() functions. Please include declaration and initialization of necessary variables, if any.
Question 2 – Synchronization (50 points)
(This question is related to ILO 2c – “describe the principles and techniques used by OS to support concurrency and synchronization control”.)
Consider the print spooler service provided by an Operating System.
When an application wants to print a file, it calls the printfile() system call, which results in placing a request in the next available slot of the print queue buffer. Assume the print queue buffer has N buffer slots; each can store an individual print request.
The kernel has K spooler threads running in the background. Each thread is responsible for processing a print request to generate an output file and placing the output file in the printer buffer. Assume the print buffer can only keep one output file at a time.
There is a printer thread running in the kernel space. When it detects that there is an output file in the print buffer, it will pass the file to the printer for printing and remove the file from the print buffer.
Write three functions that implement (1) the printfile() logic, (2) the spooler thread, and (3) the printer thread and use semaphores to coordinate the three threads in accessing the print queue buffer and the print buffer. Present the logic in C-like pseudocode statements.
Here are the data structures and utility functions relevant to the case.
/* this is the print queue buffer; each slot stores a request of type request_t */
request_t pqReqBuff[N];
/* this is for counting the number of requests in the print queue buffer */
int pqReqCount = 0;
/* this is the data type of the print buffer for temporary storing of the output file */
buffer_t pBuffer;
/* enqueue() – for adding a new request to the print queue buffer */
/* It updates the pqReqBuff array and pqReqCount variable, so MUST be called after getting the guard lock, i.e., should be called inside the critical section */
void enqueue(request_t req);
/* dequeue() – for getting (& removing) a request from the print queue buffer */
/* It updates the pqReqBuff array and pqReqCount variable, so MUST be called after getting the guard lock, i.e., should be called inside the critical section */
void dequeue(request_t *req);
/* process() – for processing the print request to generate the output file of type buffer_t; should be called outside the critical section */
void process(request_t req, buffer_t *output);
/* output() – for adding the output file to the printer buffer */
/* It updates the pBuffer variable, so MUST be called after getting the guard lock, i.e., should be called inside the critical section */
void output(buffer_t output);
/* retrieve() – for getting (& removing) the output file from the print buffer */
/* It updates the pBuffer variable, so MUST be called after getting the guard lock, i.e., should be called inside the critical section */
void retrieve(buffer_t *output);
/* printing() – for sending the output file to the hardware (printer); should be called outside the critical section */
void printing(buffer_t output);
(10 points) Declare and initialize the semaphores (sem_t) and any (global) variables used in this application. Note: sem_t semaphores are general semaphores; use sem_init() to initialize the semaphores.
// Declare the semaphores here
// Initialize the semaphores you declared here
(10 points) Implement the printfile() logic by completing the following function. Note: use sem_wait() and sem_post() to access the semaphores.
void printfile(request_t req) {
}
(20 points) Implement the spooler thread logic by completing the following function. Note: use sem_wait() and sem_post() to access the semaphores.
void Spooler() {
while (1) {
// for retrieving a request from the print queue buffer request_t req; buffer_t output; // for the output file
}
}
(10 points) Implement the printer thread logic by completing the following function. Note:
use sem_wait() and sem_post() to access the semaphores.
void Printer() { while (1) { buffer_t output; // for the output file
}
}
Reviews
There are no reviews yet.