Question

In: Computer Science

1.- In this assignment you will implement a simulation of the interaction of user programs with...

1.- In this assignment you will implement a simulation of the interaction of user programs with the OS to execute an I/O operation on two different devices.

User programs:

User programs will communicate with DOIO (OS) to request an I/O operation. (This will simulate a system call)

User programs will give to DOIO three parameters: User id, device number (dev is a random number in the range 1 and 2 that represents device one or device two) and an address (addr is a random number in the range 1 and 20.) (addr is an integer that represents a track number in the hard drive).

User programs will pass the parameters to DOIO through three buffers of size one each (bufid, bufdev, and bufaddr).

Once the parameters are stored in the buffers, user programs executes a p(request_served[ “index” ]) operation to wait for the completion of the I/O operation. You will need a semaphore array request_served[5].

There will be five users running concurrently and each will execute 5 I/O operations.

DOIO:

DOIO will collect and id, device(dev), and address(addr) from bufid, bufdev, and bufaddr to assemble the IORB.

DOIO will check on device number to decide which one of the two devices will get the IORB.

Once the device has been selected, DOIO will store the IORB (id and addr) into the two buffers that represent the IORQ (iorqid and iorqaddr) of the selected device. Notice that you need separate buffers (one for each device: iorqid and iorqaddr and iorqid2 and iorqaddr2).

DOIO must wait to receive signals from Device drivers indicating that all request have been served. Then DOIO will shut down both Disks.

Device drivers (1 and 2):

Device drivers will collect an IORB (made up of id and addr) from iorqid and iorqaddr and then initiate the physical I/O operation on the hard drive it controls and wait for the I/O operation to be completed: p(operation_complete).

The device driver initiates the physical I/O operation by storing addr into a buffer of length one. The buffer name is “pio” (physical I/O).

When the I/O operation completes a signal is received, the Device driver will identify the User that issued the I/O request using the id, and will signal the semaphore “request_served” associated to the User.

When the last request has been served, both drivers have to signal DOIO to indicate that all requests have been handled and both drivers will emit a message: “Driver 1 (2) stops”

Disk (1 and 2):

The Disk processes simulates the access to a track in the hard drive.

The Disk process gets the addr from pio and stores it in a variable called “seek” and iterates in a dummy loop from 1 to “seek”.

Once out of the loop, disk will execute a v on the semaphore “operation_complete

Disk will operate continuously until DOIO shuts them down.

Note:  

Define all semaphores that you need according to the number of buffers used.

Each user will make 5 system calls to initiate I/O operations

DOIO will create 25 IORB

The sum of the I/O operations executed by drivers must add up 25. You will need a shared variable to control the total number of I/O operations because it is not known before hand the numbers of I/O operations initiated by each Device driver.

Once Drivers have served all request they have to signal DOIO.

Once DOIO receives signasl from Drivers indicating all request have been served. DOIO will shut down both Disks.   

Project Direction

You will write the program C-- based on the BACI interpreter that you used in programming project 1.

Test your solution

You must run and test your solution for correctness, as well as, comment on the code and the expected results. If this were a task for an employer, you would be expected to follow company policy, including naming, conventions, and syntax.

Project Submission

What to submit?

Submit the source code(.cm file) with comments and the output file (.txt) showing the results.

Example for the print out of results:

User 1 executes system call SIO or DOIO

DOIO assembles IORB and inserts it in IORQ for user 1

User 2 executes system call SIO or DOIO

Driver initiates I/O operation for user 1

User 3 executes system call SIO or DOIO

User 4 executes system call SIO or DOIO

DOIO assembles IORB and inserts it in IORQ for user 2

Disk Completes I/O operation (disk does not know what process initiated the I/O operation)

Driver signal user 1 (operation complete)

User 1 executes system call SIO or DOIO

DOIO assembles IORB and inserts it in IORQ

And so on…

Solutions

Expert Solution

List of variables and semaphores to be used in the program:

SEMAPHORES

  • User: fullUser,ioReq,mutexUser
  • Driver1:fullDriver1[DRIVERS],reqPend1[DRIVERS],mutexDriver1(BinSemaphore)
  • Driver2:fullDriver2[DRIVERS],reqPend2[DRIVERS],mutexDriver2(BinSemaphore)
  • Disk:fullDisk1[DRIVERS],physicalio1[DRIVERS],mutexDisk1,fullDisk2[DRIVERS],physicalio2[DRIVERS],mutexDisk2(BinSemaphore),reqService(BinSemaphore),opComplete1[DRIVERS],opComplete2[DRIVERS]

FUNCTIONS

  • void User(int id)
  • void Doio()
  • void Driver1(int id)
  • void Driver2(int id)
  • void Disk1(int id)
  • void Disk2(int id)

#include<stdlib.h>
#include<stdio.h>
#include<ctype.h>
#include <semaphore.h>
#include <sys/types.h>
#include <pthread.h>
#include <unistd.h>


const int COUNTER = 5;       //Number of I/O requests for each user
int TOTAL = 25;           //Total 25 IORB
int DRIVERS = 2;       //No of device drivers
int USERS = 5;           //Total number of I/O requests
//Total number of Drivers
//Number of Users //Semaphores for User


int
main ()
{
sem_t fullUser;
sem_t ioReq;
//binarysemaphore mutexUser; //User buffer at max
sem_t mutexUser;
sem_init (&mutexUser, 0, 1);   /* initialize mutex to 1 - binary semaphore */

//User buffer at empty
//User buffer protect //Semaphores for Driver 1
sem_t fullDriver1[DRIVERS];
sem_t reqPend[DRIVERS];
//binarysemAaphore mutexDriver1[DRIVERS]; //Driver 1 buffer at max
sem_t mutexDriver1;
/* Create the mutexDriver semaphore and initialize to DRIVERS buffer size */
sem_init (&mutexDriver1, 0, DRIVERS);

//Driver 1 buffer at empty
//Driver 1 buffer protect //Semaphores for Driver 2
sem_t fullDriver2[DRIVERS];
sem_t reqPend2[DRIVERS];
//binarysemaphore mutexDriver2[DRIVERS]; //Driver 2 buffer at max
sem_t mutexDriver2;
sem_init (&mutexDriver2, 0, DRIVERS);

//Driver 2 buffer at empty
//Driver 2 protect //Semaphores for Disk 1
sem_t fullDisk1[DRIVERS];
sem_t physicalio1[DRIVERS];
//binarysemaphore mutexDisk1[DRIVERS]; //Disk buffer at max
sem_t mutexDisk1;
sem_init (&mutexDisk1, 0, DRIVERS);

//Disk buffer at empty
//Disk buffer protect //Semaphores for Disk 2
sem_t physicalio2[DRIVERS];
sem_t fullDisk2[DRIVERS];
//binarysemaphore mutexDisk2[DRIVERS]; //Disk buffer at empty
sem_t mutexDisk2;
sem_init (&mutexDisk2, 0, DRIVERS);

//Disk buffer at max
//Disk buffer protect //Other semaphores
//binarysemaphore reqService[USERS];
sem_t reqService;
sem_init (&reqService, 0, USERS);

//binarysemaphore opComplete1[DRIVERS];
sem_t opComplete1;
sem_init (&opComplete1, 0, DRIVERS);

//binarysem opComplete2[DRIVERS];
sem_t opComplete2;
sem_init (&opComplete2, 0, DRIVERS);


//binarysem print; //I/O request print
sem_t print;
sem_init (&print, 0, 1);

//Disk1 protection
//Disk 2 protection
//Print protection
int idUser;
int addrUser;
int devUser;
int idIorq[DRIVERS];
int addrIorq[DRIVERS];
int pio[DRIVERS];
int countdriver = 0;
int countdisk = 0;       //User/Doio id buffer
//User/Doio address buffer
//User/Doio device buffer
//Doio/Driver user id buffer
//Doio/Driver address id buffer
//Driver/Disk
//Counter for Driver
//Counter for Disk

void User (int id)
{
int i, addr, dev;       //Local variables used
for (i = 0; i <= COUNTER; i++)
{
//Loop through the number of requests
   addr = rand () % 200 + 1;
//Generating random I/O information
   dev = rand () % 2;
//Generating random Driver assignment
   p (fullUser);
//Decrement available buffer locations between User and DOIO
   p (mutexUser);
//Exclusive access to I/O request idUser = id;
//Passing user id to shared resource
   addrUser = addr;
//Passing address to shared resource
   devUser = dev;
//Passing driver id to shared resource
   p (print);
//Gaining control of the printer
/*cout &lt;&lt; &quot;User &quot; &lt;&lt; id &lt;&lt; &quot;executes system call SIO or DOIO&quot; &lt;&lt; endl; */
   v (print);
   printf ("executes system call SIO or DOIO");
   v (mutexUser);       //Released control of the printer
//Release editting control of the I/O v(ioReq); //Inform DOIO that the request is p(reqService[id]); //Wait for completion of I/O request pending operation.
}
}

void Doio ()
{
int j, idIorb, addrIorb, devIorb;
for (j = 0; j <= TOTAL; j++)
{
   p (ioReq);
//sent a request
   p (mutexUser);
//request
   idIorb = idUser;
   addrIorb = addrUser;
   devIorb = devUser;
   v (mutexUser);
//I/O request
   v (fullUser);
//buffer locations between User and DOIO
// //Local variables used
//For loop that goes
//Checking to see if user
//Exclusive access to I/O
//Copying user ID into DOIO
//Copying address into DOIO
//Copying driver ID into DOIO
//Releasing editting control of
//Incrementing available Ending consuming process p(fullDriver1[devIorb]);
//Decrementing available buffer locations
   p (mutexDriver1[devIorb]);
//Exclusive access to I/O request
   idIorq[devIorb] = idIorb;
//Passing user to shared source
   addrIorq[devIorb] = addrIorb;
//Passing address information to shared resource
   v (mutexDriver1[devIorb]);
//Releasing editing control of I/O request
   v (reqPend[devIorb]);
//Inform Driver request is pending
   p (print);
//Gain control of printer
/*cout &lt;&lt; &quot;DOIO assembles IORB and inserts it into IORQ for User &quot; &lt;&lt;
idIorb &lt;&lt; endl;*/
   printf ("DOIO assembles IORB and inserts it into IORQ for User");
   v (print);
//Release control of printer
// Begin consuming process
   p (ioReq);
//request
   p (mutexUser);
//request
   idIorb = idUser;
   addrIorb = addrUser;
   devIorb = devUser;   //Checking to see if user sent a
//Exclusive access to I/O
//Copying user into DOIO
//Copying address into DOIO
//Copying driver ID into DOIO request v(mutexUser); //Releasing control of I/O v(fullUser);
//Incrementing available buffer locations
//Begin producing process
   p (fullDriver2[devIorb]);
//Decrementing available buffer location
   p (mutexDriver2[devIorb]);
//Exclusive access to I/O request
   idIorq[devIorb] = idIorb;
//Passing user into shared source
   addrIorq[devIorb] = addrIorb;
//Passing addr into shared source
/*cout &lt;&lt; &quot;DOIO assembles IORB and inserts it in IORQ2 for User &quot; &lt;&lt;
idIorb &lt;&lt; endl;*/
   v (mutexDriver2[devIorb]);
//Releasing control of I/O request
   v (reqPend2[devIorb]);
//Inform driver request is pending
}
}


void Driver1 (int id)
{
int idDriver, addrDriver, k;
//Local variables
p (reqPend[id]);
//Check to see if there is a request from DOIO
while (countdriver <= 25)
{
//Loop through the requests
   if (countdriver == 25)
   {
//Check for out of bounds
   v (reqPend2[k]);
   break;
   }
   p (mutexDriver1[id]);
//Gain exclusive editting access to IORQ
   idDriver = idIorq[id];
//Copy user ID into Driver
   addrDriver = addrIorq[id];
//Copy address into Driver
   v (mutexDriver1[id]);
//Release editting control of I/O request
   v (fullDriver1[id]);
//Increment available buffer location by 1
   p (print);
//Control of printer
/*cout &lt;&lt; &quot;Driver 1 initiates I/O operation for user &quot; &lt;&lt; idDriver &lt;&lt;
endl;*/
   printf ("Driver 1 initiates I/O operation for user");
   v (print);
//Release control of printer
   p (fullDisk1[id]);
//Decrement available buffer locations
   p (mutexDisk1[id]);
//Gain access to Disk request
   pio[id] = addrDriver;
//Pass adress to shared resource
   p (print);
/*cout &lt;&lt; &quot;Driver 1 signals User &quot; &lt;&lt; idDriver &lt;&lt; &quot;that the operation
is complete.&quot; &lt;&lt; endl;*/
   printf ("operation complete");
   countdriver++;
   v (print);
   v (mutexDisk1[id]);
//Release control of Disk request
   v (physicalio1[id]);
//Inform disk request is pending
   p (opComplete1[id]);
//Waiting for disk operation to complete
   v (reqService[idDriver]);
//Inform user request is complete } if ( countdriver == 25 ) {
   v (reqPend[k]);
   break;
}               //Check for out of bounds

}

void Driver2 (int id)
{
int idDriver2, addrDriver2, i = 0;
//Local variables
p (reqPend2[id]);
//Check to see if there is a request from DOIO
while (countdriver <= 25)
{
//Loop through the requests
   if (countdriver == 25)
   {
//Check for out of bounds
   v (reqPend[i]);
   break;
   }
   p (mutexDriver2[id]);
//Gain exclusive access to I/O request
   idDriver2 = idIorq[id];
//Copy user ID into Driver
   addrDriver2 = addrIorq[id];
//Copy address into Driver
   v (mutexDriver2[id]);
//Release control of Disk Request
   v (fullDriver2[id]);
//Increment available buffer location
   p (print);
//Access printer
/*cout &lt;&lt; &quot;Driver 2 initiates I/O operation for user &quot; &lt;&lt; idDriver2 &lt;&lt;
endl;*/
   v (print);
   printf ("Driver 2 initiates I/O operation for user");
//Release access to printer
   p (fullDisk2[id]);
//Decerement available buffer locations
   p (mutexDisk2[id]);
//Gain access to Disk 2 request
   pio[id] = addrDriver2;
//Pass address to a shared resource
   p (print);
/*cout &lt;&lt; &quot;Driver 2 signals User &quot; &lt;&lt; idDriver2 &lt;&lt; &quot;that the operation
is complete.&quot; &lt;&lt; endl;*/
   printf ("request served");
   countdriver++;
   v (print);
   v (mutexDisk2[id]);
//Release control of disk request
   v (physicalio2[id]);
//Inform disk 2 request is pending
   p (opComplete2[id]);
//Waiting for disk 2 to complete
   v (reqService[idDriver2]);
//Inform user the request is complete
   if (countdriver == 25)
   {
   v (reqPend[i]);
   break;
   }
}
}

void Disk1 (int id)
{
int i, seek;       //Check for out of while(countdisk &lt; 25){
p (physicalio1[id]);
//Decrement available buffer locations
p (mutexDisk1[id]);
//Gain exclusive access to I/O request
seek = pio[id];
//Grabbing the address from shared resource
v (mutexDisk1[id]);
//Releasing control of Disk 1
v (fullDisk1[id]);
//Increment available buffer location
for (i = 1; i <= seek; i++)
{
}
//Dummy loop that iterates from i to seek
p (print);
//Gain access to the printer
/*cout &lt;&lt; &quot;Disk 1 Completes I/O operation.&quot; &lt;&lt; endl;*/
v (print);
//Release acess to the printer.
countdisk++;
v (opComplete1[id]);
//Inform Driver operation is complete
}
}


void
Disk2 (int id)
{
int i, seek;           //Local variables while(countdisk &lt; 25){
//Loop through the requests
p (physicalio2[id]);
//Decrement available buffer locations
p (mutexDisk2[id]);
//Gain exclusive access to I/O request
seek = pio[id];
//Grabbing the address from shared resources
v (mutexDisk2[id]);
//Releasing control of Disk 2
v (fullDisk2[id]);
//Increment available buffer location
for (i = 1; i <= seek; i++)
{
}
//Dummy loop that iterates from i to seek
/*cout &lt;&lt; &quot;Disk 2 Completes I/O operation.&quot; &lt;&lt; endl;*/
printf ("Disk 2 Completes I/O operation") countdisk++;
v (opComplete2[id]);
//Inform Driver operation is complete
}
}


int z = 0;
initialsem (fullUser, 1);
initialsem (ioReq, 0);
initialsem (mutexUser, 1);
for (z = 0; z & lt; USERS; z++)
{
initialsem (reqService[z], 0);
}

for (z = 0; z <= DRIVERS; z++)
{
initialsem (fullDriver1[z], 1);
initialsem (reqPend[z], 0);
initialsem (mutexDriver1[z], 1);
initialsem (fullDriver2[z], 1);
initialsem (reqPend2[z], 0);
initialsem (mutexDriver1[z], 1);
initialsem (fullDisk1[z], 1);
initialsem (physicalio1[z], 0);
initialsem (mutexDisk1[z], 1);
initialsem (fullDisk2[z], 1);
initialsem (physicalio2[z], 0);
initialsem (mutexDisk2[z], 1);
initialsem (opComplete1[z], 0);
initialsem (opComplete2[z], 0);
}

initialsem (print, 1);
cobegin
{
User (0);
User (1);
User (2);
User (3);
User (4);
Doio ();
Driver1 (0);
Driver2 (0);
Disk1 (0);
Disk2 (0);
}

return 0;
}


Related Solutions

Assignment Implement Conway’s Game of Life. The Game of Life is a simple simulation that takes...
Assignment Implement Conway’s Game of Life. The Game of Life is a simple simulation that takes place in a grid of cells. Each cell can be either alive or dead, and it interacts with its neighbors (horizontally, vertically, or diagonally). In each iteration, a decision will be made to see if living cells stay alive, or if dead cells become alive. The algorithm is as follows: If a cell is alive: If it has less than two living neighbors, it...
Assignment Implement Conway’s Game of Life IN C The Game of Life is a simple simulation...
Assignment Implement Conway’s Game of Life IN C The Game of Life is a simple simulation that takes place in a grid of cells. Each cell can be either alive or dead, and it interacts with its neighbors (horizontally, vertically, or diagonally). In each iteration, a decision will be made to see if living cells stay alive, or if dead cells become alive. The algorithm is as follows: If a cell is alive: If it has less than two living...
Assignment Overview This assignment will give you practice with interactive programs and if/else statements. Part 1:...
Assignment Overview This assignment will give you practice with interactive programs and if/else statements. Part 1: User name Generator Write a program that prompts for and reads the user’s first and last name (separately). Then print a string composed of the first letter of the user’s first name, followed by the first five characters of the user’s last name, followed by a random number in the range 10 to 99. Assume that the last name is at least five letters...
You may use your programming of choice to implement and simulate. Please turn in the code, simulation, and a description of what is going on in the simulation.
You may use your programming of choice to implement and simulate. Please turn in the code, simulation, and a description of what is going on in the simulation.
PROGRAMMING LANGUAGE : JAVA Problem specification. In this assignment, you will create a simulation for a...
PROGRAMMING LANGUAGE : JAVA Problem specification. In this assignment, you will create a simulation for a CPU scheduler. The number of CPU’s and the list of processes and their info will be read from a text file. The output, of your simulator will display the execution of the processes on the different available CPU’s. The simulator should also display: -   The given info of each process -   CPU utilization - The average wait time - Turnaround time for each process...
1. Design and implement a program that reads a series of integers from the user and...
1. Design and implement a program that reads a series of integers from the user and continually prints their average after every reading. The input stops when the user enters “stop” as the input value. Read each input value as a string, then check if it is “stop” or not. If the string is not “stop”, then, attempt to convert it to an integer using the Integer.parseInt method. If this process throws a NumberFormatException, meaning that the input is not...
End user programs are designed for specific functions such as word processing or a game. You...
End user programs are designed for specific functions such as word processing or a game. You have installed a new piece of applications software onto a stand-alone PC. You then find that the printer attached to the PC fails to produce what can be seen on screen in that package. Explain clearly why this might happen.
In this assignment, you will implement a Polynomial linked list, the coefficients and exponents of the...
In this assignment, you will implement a Polynomial linked list, the coefficients and exponents of the polynomial are defined as a node. The following 2 classes should be defined.
For this computer assignment, you are to write a C++ program to implement a class for...
For this computer assignment, you are to write a C++ program to implement a class for binary trees. To deal with variety of data types, implement this class as a template. Most of the public member functions of the BinaryTree class call private member functions of the class (with the same name). These private member functions can be implemented as either recursive or non-recursive, but clearly, recursive versions of these functions are preferable because of their short and simple implementations...
For this computer assignment, you are to write a C++ program to implement a class for...
For this computer assignment, you are to write a C++ program to implement a class for binary trees. To deal with variety of data types, implement this class as a template. Most of the public member functions of the BinaryTree class call private member functions of the class (with the same name). These private member functions can be implemented as either recursive or non-recursive, but clearly, recursive versions of these functions are preferable because of their short and simple implementations...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT