CS604P LABS (Merged File)
CS604P LABS (Merged File)
In order to practice the C code in Linux environment, you are required to install Virtual Box and
Ubuntu operating system on your systems using the guidelines given below.
Solution:
Following are the guidelines and helping material including required software and their
installations:
Step No.1
To install the Linux first you have to install Virtual Box visualization software in your Computer
system.
Follow the tutorial to download Virtual Box form the following link:
https://vulms.vu.edu.pk/Courses/CS604/Downloads/CS604-VirtualBox.mp4
(You can use VMware as well.)
Step No.2
Download Ubuntu Linux from the following link:
http://de.releases.ubuntu.com/16.10/ubuntu-16.10-desktop-i386.iso
Solution:
Write a program in C which will display your student id and name as output. Compile and
execute your program in Command prompt to display the output as shown below.
Lab 3
Write a program in C for inter-process communication between child and parent processes. You
have to use pipe() system calls for creating a pipe between parent and child processes. The
child will write the student id trough PIPE and parent will read the student id from pipe and
display it on screen. Parent will wait for child process until child write data to pipe. Compile
and execute your program in Command prompt to display the output as shown below.
Lab 4
Threads creation and termination
Write a program in C that will create two threads named as Thread 1 and Thread 2. You are
required to run these threads in parallel fashion and display the Thread IDs according to the
output as shown below. At the end, all threads will be terminated. Compile & run C program
on Linux Operating system.
Lab 5
Write a program in C to implement FSFS scheduling algorithm. Given the list of Processes and
their burst time, calculate waiting time and turnaround time for each process. Also calculate
average waiting time and average turnaround time. For example, the list of processes and their
CPU burst time are as follows:
Assume that all the processes arrive at time 0 in sequence P0, P1, P2 P3
Solution:
#include <stdio.h>
int main(){
int avgWTime = 0 ;
int avgtATime = 0 ;
wTime[0] = 0 ;
} // end of main()
Lab 6
Write a program in C to implement Round Robin scheduling algorithm. The time slice for each
process is 5 units. Given the list of Processes and their CPU burst time, calculate waiting time
and turnaround time for each process. You also have to calculate average waiting and average
turnaround time and display their values on screen.
For example, the list of processes and their CPU burst time are as follows:
Assume that all the processes arrive at time 0 in sequence P0, P1, P2 P3
Output of program:
Solution:
#include <stdio.h>
int main(){
int n = 4 ;
int avgWTime = 0, avgTTime = 0 ;
int timeSlice= 5 ;
int tSlice[4] ;
int bTime[4] ;
int tATime[4];
int wTime[4];
int count[4] ;
bTime[0] = 12 ;
bTime[1] =9 ;
bTime[2] = 4 ;
bTime[3] = 6 ;
int value[4] ;
int flag ;
int counter = 0;
do{
flag = 0 ;
for ( int i = 0 ; i<n; i++ ){
if (bTime[i] < timeSlice || bTime[i] == 0)
tSlice[i] = bTime[i];
else
tSlice[i] = timeSlice ;
for (int j = 0 ; j<tSlice[i]; j++ ){
bTime[i]-- ;
counter++ ;
}
tSlice[i] = bTime[i];
if(value[i] != 1)
{
count[i] = counter ;
}
}
bTime[0] = 12 ;
bTime[1] = 9 ;
bTime[2] = 4 ;
bTime[3] = 6 ;
printf("\n");
} // end of main()
Lab 7
In a program, the user will take size of buffer from user and then producer process will produce
items in buffer and consumer process will consume items from buffer and display its values on
screen.
#include<stdio.h>
int main()
{
int bufsize, in, out, produce = 0, consume = 0 , counter = 0;
in = 0; out = 0;
int buffer[bufsize] ;
char choice ;
do{
scanf("%c", &choice);
switch(choice){
case 'p':
if(counter == bufsize)
printf("Buffer is Full\n");
else { printf("Enter the value: ");
scanf("%d", &produce);
buffer[in] = produce;
in = (in+1)%bufsize;
counter++ ;
}
break ;
if(counter == 0)
printf("Buffer is Empty\n");
else {
consume = buffer[out];
printf("The consumed value is %d\n", consume);
out = (out+1)%bufsize;
counter-- ;
}
break ;
} // end of switch
}while( choice != 'q') ;
Students and teacher will communicate through google meet. Student will edit, compile and
run the C code for a given problem in Linux environment and share the screen with teacher.
Lab 8: Implementing Dining Philosophers Problem in C
Write a C program that solves Dining philosopher’s problem. Suppose there are five
Philosophers whose work is just thinking and eating. They sat at a round table for dinner. To
complete dinner each must need two chopsticks (or forks). But there are only five chopsticks
available (chopsticks always equal to number of philosophers) on table. They take in such a
manner that, first take left fork and next right fork. But problem is they try to take at same
time. Since they are trying at same time, Fork 1, 2, 3, 4, 5 taken by Philosopher 1, 2, 3, 4, 5
respectively (since they are left side of each). And each one tries to take right side Fork. But no
one found available Fork. Moreover, each one thinks that someone will release the Fork and
then I can eat. This continuous waiting leads to Deadlock situation.
To solve this deadlock situation, Last philosopher (any one can do this) first try to take right side
fork and then left side fork. i.e in our example 5th person tries to take 4th Fork instead of 5th
one. Since 4th Fork already taken by 4th the person, he gets nothing. But he left 5th Fork. Now
the first person will take this 5th Fork and complete dinner and make 1st and 5th available for
remaining people. Next 2nd person takes 1st fork and completes and releases 1st and 2nd. This
continues until all finishes dinner. In Operating System, this concept is used in process
synchronization. Same problem but instead of Philosophers processes are there and instead of
Forks, Resources are there. We follow above solution to avoid dead lock condition.
struct philosp{
int left;
int right;
}Philostatus[n];
if(otherFork== -1)
otherFork=(n-1);
ForkAvil[philID].taken = ForkAvil[otherFork].taken = 0;
printf("Philosopher %d released fork %d and fork %d\n",philID+1,philID+1,otherFork+1);
compltedPhilo++;
}
else if(Philostatus[philID].left==1 && Philostatus[philID].right==0){
if(philID==(n-1)){
if(ForkAvil[philID].taken==0){
ForkAvil[philID].taken = Philostatus[philID].right = 1;
printf("Fork %d taken by philosopher %d\n",philID+1,philID+1);
}else{
printf("Philosopher %d is waiting for fork %d\n",philID+1,philID+1);
}
}else{
int dupphilID = philID;
philID-=1;
if(philID== -1)
philID=(n-1);
if(ForkAvil[philID].taken == 0){
ForkAvil[philID].taken = Philostatus[dupphilID].right = 1;
printf("Fork %d taken by Philosopher %d\n",philID+1,dupphilID+1);
}else{
printf("Philosopher %d is waiting for Fork %d\n",dupphilID+1,philID+1);
}
}
}
else if(Philostatus[philID].left==0){ //nothing taken yet
if(philID==(n-1)){
if(ForkAvil[philID-1].taken==0){
ForkAvil[philID-1].taken = Philostatus[philID].left = 1;
printf("Fork %d taken by philosopher %d\n",philID,philID+1);
}else{
printf("Philosopher %d is waiting for fork %d\n",philID+1,philID);
}
}else{ //except last philosopher case
if(ForkAvil[philID].taken == 0){
ForkAvil[philID].taken = Philostatus[philID].left = 1;
printf("Fork %d taken by Philosopher %d\n",philID+1,philID+1);
}else{
printf("Philosopher %d is waiting for Fork %d\n",philID+1,philID+1);
}
}
}else{}
}
int main(){
for(i=0;i<n;i++)
ForkAvil[i].taken=Philostatus[i].left=Philostatus[i].right=0;
while(compltedPhilo<n){
for(i=0;i<n;i++)
goForDinner(i);
printf("\nTill now num of philosophers completed dinner are %d\n\n",compltedPhilo);
}
system("pause");
}
Lab 9: Implementing Banker’s Algorithm for Deadlock avoidance in C
In this algorithm, when a new process enters the system, it must declare the maximum number
of instances of each resource type that it may need, i.e., each process must a priori claim
maximum use of various system resources. This number may not exceed the total number of
instances of resources in the system, and there can be multiple instances of resources. When a
process requests a set of resources, the system must determine whether the allocation of these
resources will leave the system in a safe state. If it will, the resources are allocated; otherwise
the process must wait until some other process releases enough resources. We say that a
system is in a safe state if all of the processes in the system can be executed to termination in
some order; the order of process termination is called safe sequence. When a process gets all
its resources, it must use them and return them in a finite amount of time. Let n be the number
of processes in the system and m be the number of resource types. We need the following data
structures in the Banker’s algorithm:
int main()
{
printf("\nEnter number of processes: ");
scanf("%d", &processes);
printf("\nAllocated resources:");
for (i = 0; i < resources; i++)
{
printf("\t%d", allocation[i]);
}
printf("\nAvailable resources:");
for (i = 0; i < resources; i++)
{
printf("\t%d", available[i]);
}
printf("\n");
while (counter != 0)
{
safe = 0;
for (i = 0; i < processes; i++)
{
if (running[i])
{
exec = 1;
for (j = 0; j < resources; j++)
{
if (maximum_claim[i][j] - current[i][j] > available[j])
{
exec = 0;
break;
}
}
if (exec)
{
printf("\nProcess%d is executing\n", i + 1);
running[i] = 0;
counter--;
safe = 1;
printf("\n");
}
}
system(“pause”);
}
Students and teacher will communicate through Skype/Adobe Connect. Student will edit,
compile and run the C code for a given problem in Linux environment and share the screen with
teacher.
Lab 10: Logical to Physical Address Translation in C
#include<stdio.h>
#include<stdlib.h>
int main()
{
int seg, off, logAdd, phyAdd;
seg = seg*16;
phyAdd = (seg + off);
printf("\nThe 20-bit Physical Address: %x", phyAdd);
system("pause");
}
Students and teacher will communicate through Google meet. Student will edit, compile and
run the C code for a given problem in Linux environment and share the screen with teacher.
Lab 11: Calculating Paging Parameters and Paging Performance in C
Solution:
#include<stdlib.h>
#include <stdio.h>
#include <math.h>
int main()
{
double pages, mem, phyFrames, p, f , d, las, pas;
printf("Enter Logical Address Space Information");
printf("\nEnter number of pages: ");
scanf("%lf", &pages);
p = log2(pages);
printf("\nNo. of bits needed for p: %lf", ceil(p));
f = log2(phyFrames);
printf("\nNo. of bits needed for f: %lf", ceil(f));
d = log2(mem);
printf("\nNo. of bits needed for d: %lf", ceil(d));
las = p + d;
printf("\nLogical address size: %lf", las);
pas = f + d;
printf("\nPhysical address size: %lf", pas);
printf("\n\n\n");
system("pause");
}
Write a c program to calculate paging performance. The performance measure of paging is the
effective memory access time based upon several parameters.
#include<stdlib.h>
#include <stdio.h>
#include <math.h>
int main()
{
double Tmem, Ttlb, hRatio, tEffective, mRatio;
printf("Calculating Effective Memory Access Time");
printf("\n\n\n");
system("pause");
}
Lab 12: Demand Paging Performance Program in C
Write a c program to calculate demand paging performance. Demand paging can have a
significant effect on the performance of a computer system. To see why, let us compute the
effective access time for a demand paged memory. For most computer systems, the memory
access time, denoted ma now ranges from 10 to 200 nanoseconds. As long as we have no page
faults, the effective access time is equal to the memory access time. If, however a page fault
occurs, we must first read the relevant page from disk, and then access the desired word.
#include<stdlib.h>
#include <stdio.h>
int main()
printf("\nEnter p: ");
scanf("%lf", &p);
p = p / 100;
scanf("%lf", &pfo);
scanf("%lf", &pst);
scanf("%lf", &dirty);
scanf("%lf", &ro);
system("pause");
}
Lab 13: Implementing Least Recently Used (LRU) Page Replacement Algorithm in C
Write a c program to implement LRU Page Replacement algorithm. If we use the recent past as
an approximation of the near future, then we will replace the page that has not been used for
the longest period of time. Least Recently Used (LRU) page replacement algorithm basically
works on the concept that the pages that are heavily used in previous instructions are likely to
be used heavily in next instructions. The page that are used very less are likely to be used less in
future.
#include<stdio.h>
#include<stdlib.h>
int findLRU(int time[], int n){
int i, minimum = time[0], pos = 0;
for(i = 1; i < n; ++i){
if(time[i] < minimum){
minimum = time[i];
pos = i;
}
}
return pos;
}
int main() {
int no_of_frames, no_of_pages, frames[10], pages[30], counter = 0, time[10], flag1, flag2, i, j,
pos, faults = 0;
printf("Enter number of frames: ");
scanf("%d", &no_of_frames);
if(flag1 == 0){
for(j = 0; j < no_of_frames; ++j){
if(frames[j] == -1){
counter++;
faults++;
frames[j] = pages[i];
time[j] = counter;
flag2 = 1;
break;
}
}
}
if(flag2 == 0){
pos = findLRU(time, no_of_frames);
counter++;
faults++;
frames[pos] = pages[i];
time[pos] = counter;
}
printf("\n");
system("pause");
}
Lab 14: Demand Paging and Program Structure in C
Write a c program to declare and initialize two 2-Dimensional arrays (or matrices); one by
column-major order and other by row-major order. Demand paging is designed to be
transparent to the user program. However, in some cases system performance can be
improved if the programmer has an awareness of the underlying demand paging and execution
environment of the language used in the program.
#include<stdio.h>
#include<stdlib.h>
int main()
{
printf("Program to demonstrate Demand Paging Performance and Program Structure");
// Code 1: Column-major order causing 1024x1024 page faults
int A[1024][1024];
for (int j=0; j<1024; j++){
for (int i=0; i<1024; i++){
A[i][j] = 0;
}
}
printf("\n\nMatrix initialization in column-major order causing 1024x1024 page faults...");
Write a c program to calculate the Overhead of Bit Map (or Bit Vector) in Free-Space
Management. Frequently, the free space list is implemented as a bit map or bit vector. Each
block is represented by 1 bit. If the block is free, the bit is 1;if it is allocated, the bit is 0. This
approach is relatively simple and efficient in finding the first free block or n consecutive free
blocks on the disk.
#include<stdlib.h>
#include <stdio.h>
int main()
{
double blockSize, diskSize, overhead;
printf("Calculating Overhead of Bit-Map in Free-Space Management");
printf("\nEnter block size (in KB): ");
scanf("%lf", &blockSize);
diskSize = diskSize*1024*1024;
overhead = (diskSize / blockSize)/(8*1024);
Write the C program to create a basic simulation of a disk space management system.
The program should manage disk space allocation and de-allocation for files stored on
a simulated disk represented by an array. The system needs to allocate contiguous
blocks of free space for new files and mark them as allocated. Additionally, it should
be able to de-allocate space when files are deleted, marking the corresponding blocks
as free for reuse. The program should simulate file creation and deletion by allocating
and deallocating space accordingly, with print statements indicating the allocation and
de-allocation of disk blocks for each file operation.
Solution:
#include <stdio.h>
printf("Error: Not enough free space to allocate for file of size %d\n", fileSize);
}
int main() {
// Simulate file creation and deletion
allocateSpaceForFile(20);
allocateSpaceForFile(30);
deallocateSpaceForFile(0, 20);
allocateSpaceForFile(10);
return 0;
}