Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

(Done in C-- Based on the BACI Interpreter) In this assignment you will implemen

ID: 3600689 • Letter: #

Question

(Done in C-- Based on the BACI Interpreter)

In this assignment you will implement a simulation of the interaction of user programs with the OS to execute an I/O operation.

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 two parameters: User id 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 two buffers of size one each (bufid and bufaddr).

Once the parameters are stored in the buffers, user programs executes a P(request served) operation to wait for the completion of the I/O operation.

There will be one user running   and it will execute 5 I/O operations.

DOIO:

DOIO will collect an id and address(addr) from bufid and bufaddr to assemble the IORB.

DOIO will store the IORB (id and addr) into two buffers that represent the IORQ (iorqid and iorqaddr).

Device driver:

Device driver will collect an IORB (pair id and addr) from iorqid and iorqaddr and then initiates the physical I/O operation on the hard drive and wait for the I/O operation to be completed: P(operation complete).

The device driver initiate 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 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.

Disk:

The disk process 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”  

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

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

DOIO will create 5 IORB   

Project Direction

You will write a C-- program based on the BACI interpreter.

Example for the print out of results:

User 1 executes system call SIO or DOIO

DOIO assembles IORB and inserts it in IORQ

Driver initiates I/O operation for user 1

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…

Explanation / Answer

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;
int TOTAL = 25;
int DRIVERS = 2;   
int USERS = 5;   

int
main ()
{
sem_t fullUser;
sem_t ioReq;
//binarysemaphore mutexUser;
sem_t mutexUser;
sem_init (&mutexUser, 0, 1);

sem_t fullDriver1[DRIVERS];
sem_t reqPend[DRIVERS];
sem_t mutexDriver1;
sem_init (&mutexDriver1, 0, DRIVERS);

sem_t fullDriver2[DRIVERS];
sem_t reqPend2[DRIVERS];
//binarysemaphore mutexDriver2[DRIVERS];
sem_t mutexDriver2;
sem_init (&mutexDriver2, 0, DRIVERS);

sem_t fullDisk1[DRIVERS];
sem_t physicalio1[DRIVERS];
//binarysemaphore mutexDisk1[DRIVERS];
sem_t mutexDisk1;
sem_init (&mutexDisk1, 0, DRIVERS);

sem_t physicalio2[DRIVERS];
sem_t fullDisk2[DRIVERS];
//binarysemaphore mutexDisk2[DRIVERS];
sem_t mutexDisk2;
sem_init (&mutexDisk2, 0, DRIVERS);

//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;
sem_t print;
sem_init (&print, 0, 1);

int idUser;
int addrUser;
int devUser;
int idIorq[DRIVERS];
int addrIorq[DRIVERS];
int pio[DRIVERS];
int countdriver = 0;
int countdisk = 0;

void User (int id)
{
int i, addr, dev;
for (i = 0; i <= COUNTER; i++)
{
addr = rand () % 200 + 1;
dev = rand () % 2;
p (fullUser);
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);
p (mutexUser);

idIorb = idUser;
addrIorb = addrUser;
devIorb = devUser;
v (mutexUser);
v (fullUser);
p (mutexDriver1[devIorb])
idIorq[devIorb] = idIorb;
addrIorq[devIorb] = addrIorb;
v (mutexDriver1[devIorb]);
v (reqPend[devIorb]);
p (print);

/*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);
p (ioReq);
p (mutexUser);

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)
{

if (countdriver == 25)
{

v (reqPend[i]);
break;
}
p (mutexDriver2[id]);

idDriver2 = idIorq[id];

addrDriver2 = addrIorq[id];

v (mutexDriver2[id]);

v (fullDriver2[id]);

p (print);

v (print);
printf ("Driver 2 initiates I/O operation for user");

p (fullDisk2[id]);

p (mutexDisk2[id]);

pio[id] = addrDriver2;

p (print);
printf ("request served");
countdriver++;
v (print);
v (mutexDisk2[id]);
v (physicalio2[id]);
p (opComplete2[id]);
v (reqService[idDriver2]);
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]);
p (mutexDisk1[id]);
seek = pio[id];
v (mutexDisk1[id]);
v (fullDisk1[id]);
for (i = 1; i <= seek; i++)
{
}
p (print);
/*cout &lt;&lt; &quot;Disk 1 Completes I/O operation.&quot; &lt;&lt; endl;*/
v (print);
countdisk++;
v (opComplete1[id]);
}
}


void
Disk2 (int id)
{
int i, seek; //Local variables while(countdisk &lt; 25){
p (physicalio2[id]);
p (mutexDisk2[id]);
seek = pio[id];
v (mutexDisk2[id]);
v (fullDisk2[id]);
for (i = 1; i <= seek; i++)
{
}
printf ("Disk 2 Completes I/O operation") countdisk++;
v (opComplete2[id]);
}
}


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;
}