56
CS 2257 - Operating Systems Laboratory CS 2257 OPERATING SYSTEMS LAB 0 0 3 2 (Common to CSE & IT) (Implement the following on LINUX or other Unix like platform. Use C for high level language implementation) 1. Write programs using the following system calls of UNIX operating system: fork, exec, getpid, exit, wait, close, stat, opendir, readdir 2. Write programs using the I/O system calls of UNIX operating system (open, read, write, etc) 3. Write C programs to simulate UNIX commands like ls, grep, etc. 4. Given the list of processes, their CPU burst times and arrival times, display/print the Gantt chart for FCFS and SJF. For each of the scheduling policies, compute and print the average waiting time and average turnaround time. (2 sessions) 5. Given the list of processes, their CPU burst times and arrival times, display/print the Gantt chart for Priority and Round robin. For each of the scheduling policies, compute and print the average waiting time and average turnaround time. (2 sessions) 6. Developing Application using Inter Process communication (using shared memory, pipes or message queues) 7. Implement the Producer – Consumer problem using semaphores (using UNIX system calls). 8. Implement some memory management schemes – I 9. Implement some memory management schemes – II 10. Implement any file allocation technique (Linked, Indexed or Contiguous) Example for exercises 8 & 9 : 1 Lab Manual Meenakshi College of Engineering, Chennai

38451142-CS2257 (1)

Embed Size (px)

Citation preview

Page 1: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

CS 2257 OPERATING SYSTEMS LAB 0 0 3 2 (Common to CSE & IT)

(Implement the following on LINUX or other Unix like platform. Use C for high level language implementation)

1. Write programs using the following system calls of UNIX operating system:fork, exec, getpid, exit, wait, close, stat, opendir, readdir

2. Write programs using the I/O system calls of UNIX operating system (open, read, write, etc)

3. Write C programs to simulate UNIX commands like ls, grep, etc.

4. Given the list of processes, their CPU burst times and arrival times, display/print the Gantt chart for FCFS and SJF. For each of the scheduling policies, compute and print the average waiting time and average turnaround time. (2 sessions)

5. Given the list of processes, their CPU burst times and arrival times, display/print the Gantt chart for Priority and Round robin. For each of the scheduling policies, compute and print the average waiting time and average turnaround time. (2 sessions)

6. Developing Application using Inter Process communication (using shared memory, pipes or message queues)

7. Implement the Producer – Consumer problem using semaphores (using UNIX system calls).

8. Implement some memory management schemes – I

9. Implement some memory management schemes – II

10. Implement any file allocation technique (Linked, Indexed or Contiguous)

Example for exercises 8 & 9 :

Free space is maintained as a linked list of nodes with each node having the starting byte address and the ending byte address of a free block. Each memory request consists of the process-id and the amount of storage space required in bytes. Allocated memory space is again maintained as a linked list of nodes with each node having the process-id, starting byte address and the ending byte address of the allocated space. When a process finishes (taken as input) the appropriate node from the allocated list should be deleted andthis free disk space should be added to the free space list. [Care should be taken to merge contiguous free blocks into one single block. This results in deleting more than one node from the free space list and changing the start and end address in the appropriate node]. For allocation use first fit, worst fit and best fit.

TOTAL: 45

1Lab Manual Meenakshi College of Engineering, Chennai

Page 2: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

Hardware and Software required for a batch of 30 students.

HARDWARE:

30 Personal Computers

SOFTWARE:

Linux:

Ubuntu / OpenSUSE / Fedora / Red Hat / Debian / Mint OS Linux could be loaded in individual PCs.

(OR)A single server could be loaded with Linux and connected from the individual PCs.

2Lab Manual Meenakshi College of Engineering, Chennai

Page 3: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

1. Process , Directory & File Management system calls

Aim :

To write C programs for the fork, exec, getpid, exit, wait, stat, opendir, readdir system calls of UNIX operating system.

Description

A system call is just what its name implies - a request for the operating system to do something on behalf of the user's program. The system calls are functions used in the kernel itself. To the programmer, the system call appears as a normal C function call. However since a system call executes code in the kernel, there must be a mechanism to change the mode of a process from user mode to kernel mode. The C compiler uses a predefined library of functions (the C library)that have the names of the system calls. The library functions typically invoke an instruction that changes the process execution mode to kernel mode and causes the kernel to start executing code for system calls. The instruction that causes the mode change is often referred to as an "operating system trap" which is a software generated interrupt. The library routines execute in user mode, but the system call interface is a special case of an interrupt handler. The library functions pass the kernel a unique number per system call in a machine dependent way

getpid, getppid To get the process and parent process identification number.

General Syntax: pid_t getpid(void); pid_t getppid(void);

Description

getpid returns the process ID of the current process. (This is often used by routines that generate unique temporary file names.) getppid returns the process ID of the parent of the current process.

fork()

causes the UNIX system to create a new process, called the "child process", with a new process ID. The contents of the child process are identical to the contents of the parent process.

The prototype for the fork() system call is:

int fork()

3Lab Manual Meenakshi College of Engineering, Chennai

Page 4: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

The new process inherits several characteristics of the old process. Among the characteristics inherited are:

The environment. All signal settings. The set user ID and set group ID status. The time left until an alarm clock signal. The current working directory and the root directory. The file creation mask as established with umask().

The child process begins executing and the parent process continues executing at the return from the fork() system call. This is difficult to understand at first because you only call fork() once, yet it returns twice -- once per process. To differentiate which process is which, fork() returns zero in the child process and non-zero (the child's process ID) in the parent process.

exec system call

The UNIX system calls that transform a executable binary file into a process are the "exec" family of system calls. The prototypes for these calls are:

int execl(file_name, arg0 [, arg1, ..., argn], NULL) char *file_name, *arg0, *arg1, ..., *argn;

wait()

You can control the execution of child processes by calling wait() in the parent. wait() forces the parent to suspend execution until the child is finished. wait() returns the process ID of a child process that finished. If the child finishes before the parent gets around to calling wait(), then when wait() is called by the parent, it will return immediately with the child's process ID. (It is possible to have more that one child process by simply calling fork() more than once.). The prototype for the wait() system call is:

int wait(status) int *status;

where status is a pointer to an integer where the UNIX system stores the value returned by the child process. wait() returns the process ID of the process that ended.

exit()

The exit() system call ends a process and returns a value to it parent. The prototype for the exit() system call is:

void exit(status) int status;where status is an integer between 0 and 255.

4Lab Manual Meenakshi College of Engineering, Chennai

Page 5: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

Note: since wait() returns the exit status multiplied by 256 (contained in the upper 8 bits), the status value is shifted right 8 bits (divided by 256) to obtain the correct value.

File Status

stat() ,fstat() , lstat()

The i-node data structure holds all the information about a file except the file's name and its contents. Sometimes your programs need to use the information in the i-node structure to do some job. You can access this information with the stat(), lstat() and fstat() system calls.

opendir - open a directory

SYNOPSIS #include <sys/types.h> #include <dirent.h>

DIR *opendir(const char *name);

DESCRIPTION The opendir() function opens a directory stream corresponding to the directory name, and returns a pointer to the directory stream. The stream is positioned at the first entry in the directory.

RETURN VALUE The opendir() function returns a pointer to the directory stream or NULL if an error occurred.

readdir - read directory entry

readdir reads one dirent structure from the directory pointed at by fd into the memory area pointed to by dirp. The parameter count is ignored; at most one dirent structure is read.

int readdir(unsigned int fd, struct dirent *dirp, unsigned int count);

closedir - close a directory int closedir(DIR *dir);

DESCRIPTION The closedir() function closes the directory stream associated with dir. The directory stream descriptor dir is not available after this call.

5Lab Manual Meenakshi College of Engineering, Chennai

Page 6: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

Exercises:

/* 1. Program to print the process id */

Algorithm:1. Include necessary header files for using systems calls.2. Make necessary declaration.3. Get the process identification number and parent process identification number using

getpid() and getppid() system calls4. Display the process id’s

#include <sys/types.h>#include <unistd.h>#include<stdio.h>

main(){int pid,ppid;pid=getpid();ppid=getppid();

printf("\n Process Id is %d\n",pid);printf("\n Parent Process Id is %d\n",ppid);}OUTPUTprocess ID is 5198parent process ID is 5129

/* 2. Program using fork system call */#include <sys/types.h>#include <unistd.h>#include<stdio.h>

main(){printf("\n This is to demonstrate the fork()");fork();printf("\nAfter fork()");}OUTPUTthis is to demonstrate fork() after fork()

/* 3. fork and pid */#include <sys/types.h>#include <unistd.h>#include<stdio.h>

main()

6Lab Manual Meenakshi College of Engineering, Chennai

Page 7: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

{int pid;pid=fork();if(pid==0){printf("\n I am the child, my process ID is %d ",getpid());printf("\n I am the child's parent process ID is %d ",getppid());}else{printf("\n I am the parent, my process ID is %d ",getpid());printf("\n I am the parent's parent process ID is %d ",getppid());}}OUTPUTi am the parent, my process ID is 5273i am the parent's parent,process ID is 5129I am the child, my process ID is 5274I am the child's parent, process ID is 1

/* 4. orphan process */#include <sys/types.h>#include <unistd.h>#include<stdio.h>

main(){int pid;pid=fork();if(pid==0){printf("\n I am the child, my process ID is %d ",getpid());printf("\n I am the child's parent process ID is %d ",getppid());sleep(10);printf("\n I am the child, my process ID is %d ",getpid());printf("\n I am the child's parent process ID is %d ",getppid());

}else{printf("\n I am the parent, my process ID is %d ",getpid());printf("\n I am the parent's parent process ID is %d ",getppid());}}OUTPUT

I am the child, my process ID is 5301 I am the parent, my process id is 5300

7Lab Manual Meenakshi College of Engineering, Chennai

Page 8: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

I am the parent's parent, my process ID is 5129[it2-21@localhost ~]$ I am thechild's parent, my process ID is 5300 I am the child, my process Id is 5301 I am the child's parent, my process ID is 1

/* 5. exec system call */#include <sys/types.h>#include<stdio.h>#include <unistd.h>main(){ execl("/bin/ls", "/bin/ls", "-r", "-t", "-l", (char *) 0);}OUTPUTtotal 384-rw-rw-r-- 1 it2-21 it2-21 359 Oct 14 08:24 pol.cpp-rw-rw-r-- 1 it2-21 it2-21 200 Dec 8 11:35 forks.c-rw-rw-r-- 1 it2-21 it2-21 102 Dec 14 10:48 exec1.c-rw-rw-r-- 1 it2-21 it2-21 283 Dec 14 11:06 wait.c-rw-rw-r-- 1 it2-21 it2-21 246 Dec 14 11:22 exit.c-rw-rw-r-- 1 it2-21 it2-21 214 Dec 14 11:25 exit1.c-rw-rw-r-- 1 it2-21 it2-21 393 Dec 14 12:12 opre.c-rw-rw-r-- 1 it2-21 it2-21 367 Dec 14 12:13 fileinfo.c-rw-rw-r-- 1 it2-21 it2-21 0 Dec 14 12:20 read.cpp-rw-rw-r-- 1 it2-21 it2-21 1786 Dec 18 09:50 poly.cpp-rw-rw-r-- 1 it2-21 it2-21 153 Dec 21 11:31 op.c-rw-rw-r-- 1 it2-21 it2-21 0 Dec 21 11:32 buf,c-rw-rw-r-- 1 it2-21 it2-21 197 Dec 21 11:32 buf.c---------x 1 it2-21 it2-21 0 Dec 21 11:33 fn

/* 6. exec system call */#include <unistd.h>#include <sys/types.h>#include<stdio.h>

main(){ execl("/bin/date", "date", NULL);}OUTPUTMon Jan 11 11:08:50 UTC 2010

8Lab Manual Meenakshi College of Engineering, Chennai

Page 9: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

/* 7. wait system call *//* process synchronization */#include <sys/types.h>#include <unistd.h>#include<stdio.h>

main(){int pid,i=0;printf("\n Ready to fork");pid=fork();if(pid==0){printf("\n Child starts ");for(i=0;i<1000;i++);

printf("\n Child ends ");}else{wait(0);for(i=0;i<1000;i++);

printf("\n Parent process ends ");}}OUTPUTready to fork child starts child ends ready to fork parent process ends

/* 8. Program using exit system call */ #include <sys/types.h>#include <unistd.h>#include<stdio.h>main(){int p;p=fork();if(p==0){printf("\n Child created ");exit(0);printf("\n Process ended ");

9Lab Manual Meenakshi College of Engineering, Chennai

Page 10: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

}if(p<0){printf("\n Cannnot create child ");exit(-1);printf("\n Process ended ");}}OUTPUTchild created

/* 9. Program using exit and wait system call */

#include <sys/types.h>#include <unistd.h>#include<stdddio.h>main(){

unsigned int status;

if ( fork () == 0 ) { /* == 0 means in child */ scanf ("%d", &status); exit (status); } else { /* != 0 means in parent */ wait (&status); printf("child exit status = %d\n", status > 8); } }OUTPUTchild exit status=1

/* 10. Program using lstat() system call */#include<stdio.h>#include<sys/stat.h>main(int argc,char **argv){

struct stat statbuf;if(lstat(argv[1],&statbuf)==-1)printf("Error : cannot find file information ");else{printf("\n File %s ", argv[1]);printf("\n Inode number %d",statbuf.st_ino);printf("\n UID %d",statbuf.st_uid);

10Lab Manual Meenakshi College of Engineering, Chennai

Page 11: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

printf("\n GID %d",statbuf.st_gid);printf("\n File size in bytes %d",statbuf.st_size);}}OUTPUT./a.out opre.c file opre.cI node number 1387260UID 998GID 999file size in bytes 393

/* 11. Program using opendir and readdir system call */#include<stdio.h>#include <sys/types.h>#include <dirent.h>

int main(int argc, char *argv[]){ DIR *dp; struct dirent *dirp; if (argc != 2) { printf("a single argument (the directory name) is required\n"); exit(1); }

if ( (dp = opendir(argv[1])) == NULL) { printf("can't open %s\n",argv[1]); exit(1); }

while ( (dirp = readdir(dp)) != NULL) printf("%s %d\n",dirp->d_name,dirp->d_ino); closedir(dp); exit(0);}OUTPUT./a.out grep.c 1387273simu.c 1387274a.out 1387265. 1387247hi 1387233.. 1387211rem.c 1387276

Result :

Thus C program was written programs using the fork, exec, getpid, exit, wait, stat, opendir, readdir system calls of UNIX operating system.

11Lab Manual Meenakshi College of Engineering, Chennai

Page 12: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

2. File realated system call – open(), read(), write()

Aim : To write a C program using open(), read(), write and close system calls.

Description open()

open() lets you open a file for reading, writing, or reading and writing. The prototype for the open() system call is:

int open(char *file_name, int option_flags int [, mode])where file_name is a pointer to the character string that names the file, option_flags represent the type of channel, and mode defines the file's access permissions if the file is being created.

read() write()

The read() system call does all input and the write() system call does all output.When used together, they provide all the tools necessary to do input and output sequentially.

Both read() and write() take three arguments. Their prototypes are:

int read(int file_descriptor, char * buffer_pointer,unsigned transfer_size)int write(int file_descriptor,char * buffer_pointer, unsigned transfer_size)

where file_descriptor identifies the I/O channel, buffer_pointer points to the area in memory where the data is stored for a read() or where the data is taken for a write(), and transfer_size defines the maximum number of characters transferred between the file and the buffer. read() and write() return the number of bytes transferred.

close()To close a channel, use the close() system call. The prototype for the close() system call is:int close(int file_descriptor)where file_descriptor identifies a currently open channel. close() fails if file_descriptor does not identify a currently open channel.

Exercises /* 1. using creat system call */

#include <stdio.h> #include <sys/types.h> /* defines types used by sys/stat.h */ #include <sys/stat.h> /* defines S_IREAD & S_IWRITE */

int main() { int fd; fd = creat("datafile.dat", S_IREAD | S_IWRITE); if (fd == -1) printf("Error in opening datafile.dat\n"); else

12Lab Manual Meenakshi College of Engineering, Chennai

Page 13: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

{ printf("datafile.dat opened for read/write access\n"); printf("datafile.dat is currently empty\n"); } close(fd); exit (0); }

/* 2. using open, write system call */#include<fcntl.h>#include<unistd.h>main(){int fd,i;fd=open("test",O_CREAT|O_RDWR|O_APPEND,0666);for(i=0;i<100;i++)write(fd,"A",1);close(fd);}OUTPUT:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

/* 3. using - open ,read and write system calls *//* reading a content from file and displaying it to monitor */#include<stdio.h>#include<fcntl.h>main(){char buf[100],fn[10];int fd,n;printf("Enter file name ");scanf("%s",fn);fd=open(fn,O_RDONLY);n=read(fd,buf,100);n=write(1,buf,n);//write to monitor close(fd);}OUTPUTenter file name open.c#include<stdio.h>#include<fcntl.h>main(){char buf[1000],fn1[10],fn2[10];int fd1,fd2,n;

13Lab Manual Meenakshi College of Engineering, Chennai

Page 14: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

/* 4. using - write system calls writing line of text the file */#include<stdio.h>#include<fcntl.h>#include<string.h>main(){char buf[100],fn[10];int fd,n;printf("Enter file name ");scanf("%s",fn);printf("\nEnter text ");gets(buf);fd=open(fn,O_CREAT|0666);n=write(fd,buf,strlen(buf));//write fileclose(fd);}OUTPUT:enter file name open.center textHI !HInclude<stdio.h>#include<fcntl.h>main(){char buf[1000],fn1[10],fn2[10]; …… }

/* 5. using - open ,read and write system calls file copy operation*/#include<stdio.h>#include<fcntl.h>main(){char buf[1000],fn1[10],fn2[10];int fd1,fd2,n;printf("Enter source file name ");scanf("%s",fn1);printf("Enter destination file name ");scanf("%s",fn2);fd1=open(fn1,O_RDONLY);n=read(fd1,buf,1000);fd2=open(fn2,O_CREAT|0666);n=write(fd2,buf,n);//write fileclose(fd1);close(fd2);}

14Lab Manual Meenakshi College of Engineering, Chennai

Page 15: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

OUTPUTenter source file name write.c enter destination file name read.c

#include<stdio.h>#include<fcntl.h>#include<string.h>main(){char buf[100],fn[10];int fd,n;printf("enter file name");scanf("%s",fn);printf("\n enter text\n");scanf("%s",buf);fd=open(fn,O_CREAT|O_WRONLY,0666);n=write(fd,buf,strlen(buf));close(fd);}

Result : Thus C program was written using open(), read(), write() and close() system calls.

15Lab Manual Meenakshi College of Engineering, Chennai

Page 16: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

3. Simulation of Unix CommandsAim :

To write a C program to simulate basic Unix commands like ls,grep, cp,rm

Description :

UNIX commands can be simulated in the high level language using Unix system calls and APIs available in the language. In addition, programming language construct can also be used to avail the UNIX commands.

Exercises :1. Siumulation of ls command

Algorithm :1. Include necessary header files for manipulating directory.2. Declare and initialize required objects.3. Read the directory name form the user4. Open the directory using opendir() system call and report error if the directory is

not available5. Read the entry available in the directory6. Display the directory entry (ie., name of the file or sub directory.7. Repeat the step 6 and 7 until all the entries were read.

/* 1. Siumulation of ls command */#include<dirent.h>#include<stdio.h>main(){char dirname[10];DIR *p;struct dirent *d;printf("Enter directory name ");scanf("%s",dirname);p=opendir(dirname);if(p==NULL){perror("Cannot find dir.");exit(-1);}while(d=readdir(p))printf("%s\n",d->d_name);}OUTPUT:enter directory name iii...f2f1

16Lab Manual Meenakshi College of Engineering, Chennai

Page 17: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

2. Simulation of grep command.Algorithm :

1. Include necessary header files2. Make necessary declarations3. Read the file name from the user and open the file in the read only mode.4. Read the pattern from the user.5. Read a line of string from the file and search the pattern in that line.6. If pattern is available, print the line.7. Repeat the step 4 to 6 till the end of the file.

/* 2. Simulation of grep command */#include<stdio.h>#include<string.h>main(){char fn[10],pat[10],temp[200];FILE *fp;printf("\n Enter file name : ");scanf("%s",fn);printf("Enter the pattern to be searched : ");scanf("%s",pat);fp=fopen(fn,"r");while(!feof(fp)){fgets(temp,1000,fp);if(strstr(temp,pat))printf("%s",temp);}fclose(fp);}OUTPUT:enter file name: file4enter the pattern to be searched: rollroll no percentage grade

3. Simulation of cp command Algorithm:

1. Include required header file2. Make necessary declarations3. Read the source and destination file names from the user.4. Using read() system call, read the content of the file to the buffer.5. Uing write() system call, write the buffer content to the destination file.6. Close the opened files.

17Lab Manual Meenakshi College of Engineering, Chennai

Page 18: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

/* using - open ,read and write system calls file copy operation*/#include<stdio.h>#include<fcntl.h>main(){char buf[1000],fn1[10],fn2[10];int fd1,fd2,n;printf("Enter source file name ");scanf("%s",fn1);printf("Enter destination file name ");scanf("%s",fn2);fd1=open(fn1,O_RDONLY);n=read(fd1,buf,1000);fd2=open(fn2,O_CREAT|0666);n=write(fd2,buf,n);//write fileclose(fd1);close(fd1);}

OUTPUT:enter source file namels.center destination file namefile8[it2-20@localhost ~]$ cat file8#include<dirent.h>#include<stdio.h>main(){char dirname[10];DIR *p;struct dirent *d;printf("enter directory name");scanf("%s",dirname);p=opendir(dirname);if(p==NULL){perror("cannot find directory");exit(-1);}while(d=readdir(p))printf("%s\n",d->d_name);}

18Lab Manual Meenakshi College of Engineering, Chennai

Page 19: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

/* 4. to remove file or dir. */Algorithm:

1. Include required header file2. Make necessary declarations3. Read the file name from the user.4. Using remove () system call remove the file from the user.

#include<stdio.h>#include<fcntl.h>main(){char fn[10];printf("Enter source file name ");scanf("%s",fn);if(remove(fn)==0)printf("\nFile/Dir removed");elseprintf("\nCannot be removed");}OUTPUT: enter source file namefile10

file/directory removed

Result :Thus C program was written to simulate some Unix Commands

19Lab Manual Meenakshi College of Engineering, Chennai

Page 20: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

4. Process Scheduling – FCFS, SJF

Aim :To write C program to simulate FCFS and SJF scheduling algorithms.

CPU/Process Scheduling

The assignment of physical processors to processes allows processors to accomplish work. The problem of determining when processors should be assigned and to which processes is called processor scheduling or CPU scheduling.

When more than one process is runable, the operating system must decide which one first. The part of the operating system concerned with this decision is called the scheduler, and algorithm it uses is called the scheduling algorithm.

First-Come-First-Served (FCFS) Scheduling

Other names of this algorithm are:

● First-In-First-Out (FIFO) ● Run-to-Completion ● Run-Until-Done

Perhaps,  First-Come-First-Served algorithm is the simplest scheduling algorithm is the simplest scheduling algorithm. Processes are dispatched according to their arrival time on the ready queue. Being a nonpreemptive discipline, once a process has a CPU, it runs to completion. The FCFS scheduling is fair in the formal sense or human sense of fairness but it is unfair in the sense that long jobs make short jobs wait and unimportant jobs make important jobs wait.

FCFS is more predictable than most of other schemes since it offers time. FCFS scheme is not useful in scheduling interactive users because it cannot guarantee good response time. The code for FCFS scheduling  is simple to write and understand. One of the major drawback of this scheme is that the average time is often quite long.

Shortest-Job-First (SJF) Scheduling

Other name of this algorithm is Shortest-Process-Next (SPN).

Shortest-Job-First (SJF) is a non-preemptive discipline in which waiting job (or process) with the smallest estimated run-time-to-completion is run next. In other words, when CPU is available, it is assigned to the process that has smallest next CPU burst.

The SJF scheduling is especially appropriate for batch jobs for which the run times are known in advance. Since the SJF scheduling algorithm gives the minimum average time for a given set of processes, it is probably optimal.

The SJF algorithm favors short jobs (or processors) at the expense of longer ones.

The obvious problem with SJF scheme is that it requires precise knowledge of how long a job or process will run, and this information is not usually available.

The best SJF algorithm can do is to rely on user estimates of run times.

In the production environment where the same jobs run regularly, it may be possible to

20Lab Manual Meenakshi College of Engineering, Chennai

Page 21: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

provide reasonable estimate of run time, based on the past performance of the process. But in the development environment users rarely know how their program will execute.

Like FCFS, SJF is non preemptive therefore, it is not useful in timesharing environment in which reasonable response time must be guaranteed.

FCFS SCHEDULING

#include<stdio.h>struct process{ char pName[10]; int ex_time,wt_time,st_time,end_time;}p[10];main(){ int n,i,j,k; float avgwaittime=0.0,avgTurnAroundTime=0.0; float totalWaitTime=0.0; int totalExecTime=0,totalTurnAroundTime=0; printf("\n enter number of process"); scanf("%d",&n); p[0].st_time=0; p[0].wt_time=0; printf("\n enter process name"); scanf("%s",p[i].pName); printf("enter Burst time"); scanf("%d",&p[i].ex_time); if(i==0) p[i].end_time=p[i].ex_time; else { p[i].wt_time=p[i-1].end_time; p[i].st_time=p[i-1].end_time; p[i].end_time=p[i].st_time+p[i].ex_time; } } for(j=0;j<n;j++) { totalExecTime+=p[j].ex_time; totalWaitTime+=p[j].wt_time; } totalTurnAroundTime=totalExecTime+totalWaitTime; avgwaittime=(float)totalWaitTime/n;

avgTurnAroundTime=(float)totalTurnAroundTime/n; printf("\n\n Name Burst Start End Wait Time\n"); for(k=0;k<n;k++) printf("\n%s \t%d \t%d \t%d \t%d",p[k].pName,p[k].ex_time,p[k].st_time,p[k].end_time,p[k].wt_time); printf("\nAverage Waiting Time %f",avgwaittime);

21Lab Manual Meenakshi College of Engineering, Chennai

Page 22: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

printf("\n Average Turn Around Time %f",avgTurnAroundTime);}

SAMPLE INPUT/ OUTPUT:

enter number of process 5

enter process name p1enter Burst time3

enter process name p2enter Burst time2

enter process name p3enter Burst time1

enter process name p4enter Burst time4

enter process namep5enter Burst time2

Name Burst Start End Wait Time

p1 3 0 3 0 p2 2 3 5 3 p3 1 5 6 5 p4 4 6 10 6 p5 2 10 12 10Average Waiting Time 4.800000 Average Turn Around Time 7.200000

Shortest Job First Scheduling

#include<stdio.h>struct process{ char pname[10]; int ex_time,wt_time,st_time,end_time;}p[10],temp;main(){ int n,i,j,k; float avgwaittime=0.0,avgturnaroundtime=0.0; float totalwaittime=0.0;

22Lab Manual Meenakshi College of Engineering, Chennai

Page 23: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

int totalexectime=0,totalturnaroundtime=0; printf("\n enter the number of process"); scanf("%d",&n); p[0].st_time=0; p[0].wt_time=0; for(i=0;i<n;i++){ printf("\n enter process name"); scanf("%s",p[i].pname); printf("enter burst time"); scanf("%d",&p[i].ex_time);}for(i=0;i<n;i++)for(j=0;j<n;j++){ temp=p[i];p[i]=p[j];p[j]=temp;}}p[0].wt_time=0;p[0].st_time=0;p[0].end_time=p[0].ex_time;for(j=0;j<n;j++){ if(j>0)

{ p[j].wt_time=p[j-1].end_time; p[j].st_time=p[j-1].end_time; p[j].end_time=p[j].st_time+p[j].ex_time;} totalexectime+=p[j].ex_time; totalwaittime+=p[j].wt_time;}avgwaittime=(float)totalwaittime/n;totalturnaroundtime=totalexectime+totalwaittime;avgturnaroundtime=(float)totalturnaroundtime/n;printf("\n\nname brust start endwaittime\n");for(k=0;k<n;k++)printf("\n%s\t%d\t%d\t%d\t%d",p[k].pname,p[k].ex_time,p[k].st_time,p[k].end_time,p[k].wt_time);printf("\naverage waiting time %f",avgwaittime);printf("\n average turnaroundtime %f",avgturnaroundtime);}

23Lab Manual Meenakshi College of Engineering, Chennai

Page 24: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

SAMPLE INPUT / OUTPUT:enter the number of process4 enter process namep1 enter burst time3 enter process namep2 enter burst time6 enter process namep3 enter burst time4 enter process namep4 enter burst time2

name burst start end waittime

p4 2 0 2 0 p1 3 2 5 2 p3 4 5 9 5 p2 6 9 15 9 average waiting time 4.000000 average turnaroundtime 7.750000

Result :Thus C program was written for simulating FCFS and SJF scheduling algorithms.

24Lab Manual Meenakshi College of Engineering, Chennai

Page 25: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

5. CPU SCHEDULING PRIPORITY, ROUND ROBIN

Aim :To write a C program for simulating Priority and Round Robin scheduling algorithms.

Priority Scheduling

The basic idea is straightforward: each process is assigned a priority, and priority is allowed to run. Equal-Priority processes are scheduled in FCFS order. The shortest-Job-First (SJF) algorithm is a special case of general priority scheduling algorithm.

An SJF algorithm is simply a priority algorithm where the priority is the inverse of the (predicted) next CPU burst. That is, the longer the CPU burst, the lower the priority and vice versa.

Priority can be defined either internally or externally. Internally defined priorities use some measurable quantities or qualities to compute priority of a process.

Examples of Internal priorities are

● Time limits. ● Memory requirements. ● File requirements,

    for example, number of open files. ● CPU Vs I/O requirements.

Externally defined priorities are set by criteria that are external to operating system such as

● The importance of process. ● Type or amount of funds being paid for computer use. ● The department sponsoring the work. ● Politics.

Priority scheduling can be either preemptive or non preemptive

● A preemptive priority algorithm will preemptive the CPU if the priority of the newly arrival process is higher than the priority of the currently running process.

● A non-preemptive priority algorithm will simply put the new process at the head of the ready queue.

A major problem with priority scheduling is indefinite blocking or starvation. A solution to the problem of indefinite blockage of the low-priority process is aging. Aging is a technique of gradually increasing the priority of processes that wait in the system for a long period of time.

Round Robin Scheduling

One of the oldest, simplest, fairest and most widely used algorithm is round robin (RR).

In the round robin scheduling, processes are dispatched in a FIFO manner but are given a limited amount of CPU time called a time-slice or a quantum.

If a process does not complete before its CPU-time expires, the CPU is preempted and given to the next process waiting in a queue. The preempted process is then placed at the back of

25Lab Manual Meenakshi College of Engineering, Chennai

Page 26: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

the ready list.

Round Robin Scheduling is preemptive (at the end of time-slice) therefore it is effective in time-sharing environments in which the system needs to guarantee reasonable response times for interactive users.

The only interesting issue with round robin scheme is the length of the quantum. Setting the quantum too short causes too many context switches and lower the CPU efficiency. On the other hand, setting the quantum too long may cause poor response time and appoximates FCFS.

In any event, the average waiting time under round robin scheduling is often quite long.

Priority Scheduling #include<stdio.h>

struct process{char pname[10];int ex_time,wt_time,st_time,end_time,turn_time,priority;}p[10],temp;main(){int n,i,j,k;float avgwaittime=0.0,avgturnaroundtime=0.0;float totalwaittime=0.0;int totalexectime=0,totalturnaroundtime=0;printf("\nenter number of process");scanf("%d",&n);p[0].st_time=0;p[0].wt_time=0;for(i=0;i<n;i++){printf("\nenter process name");scanf("%s",p[i].pname);printf("\nenter process priority 0 with highest priority");scanf("%d",&p[i].priority);printf("enter burst time");scanf("%d",&p[i].ex_time);}for(i=0;i<n;i++)for(j=0;j<n;j++){if(p[i].priority<p[j].priority){temp=p[i];p[i]=p[j];p[j]=temp;}}

26Lab Manual Meenakshi College of Engineering, Chennai

Page 27: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

if(j==0){p[j].wt_time=0;p[j].st_time=0;p[j].end_time=p[j].ex_time;p[j].turn_time=p[j].ex_time+p[j].wt_time;}if(j>0){p[j].wt_time=p[j-1].end_time;p[j].st_time=p[j-1].end_time;p[j].end_time=p[j].st_time+p[j].ex_time;p[j].turn_time=p[j].ex_time+p[j].wt_time;}totalexectime+=p[j].ex_time;totalwaittime+=p[j].wt_time;totalturnaroundtime+=p[j].turn_time;}avgwaittime=(float)totalwaittime/n;avgturnaroundtime=(float)totalturnaroundtime/n;printf("\n\nname burst start end waittime\n");for(k=0;k<n;k++)printf("\n%s\t%d\t%d\t%d\t%d\t%d",p[k].pname,p[k].ex_time,p[k].st_time,p[k].end_time,p[k].wt_time); 37,1 87%printf("\naveragewaitingtime%f",avgwaittime);printf("\naverageturnaroundtime%f",avgturnaroundtime);}

OUTPUt:

Enter the number of processes 4

Enter process name p1Enter process priority 0 with highest priority 2Enter burst time 3

Enter process name p2

Enter process priority 0 with highest priority 4Enter burst time 6

Enter process name p3Enter process priority 0 with highest priority 1Enter burst time4

Enter process name p4Enter process priority 0 with highest priority3Enter burst time2

27Lab Manual Meenakshi College of Engineering, Chennai

Page 28: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

name burst start end waittime

p3 4 0 4 0p1 3 4 7 4p4 2 7 9 7p2 6 9 15 9

average waiting time 5.000000 average turnaroundtime 8.750000

// ROUND ROBIN SCHEDULING#include<stdio.h>struct process {char PName[10];int ex_time,wt_time,st_time,end_time,turn_time;int rem_time,completed_time;}p[10],temp;int quant_time;main(){int n,i,j,k;float avgWaitTime=0.0,avgTurnAroundTime=0.0;float totalWaitTime=0.0;int totalExecTime=0,totalTurnAroundTime=0;int fs,fe;printf("\nEnter number of process");scanf("%d",&n);

for(i=0;i<n;i++){printf("\nEnter process name");scanf("%s",p[i].PName);printf("Enter Burst time ");scanf("%d",&p[i].ex_time);p[i].rem_time=p[i].ex_time;p[i].completed_time=0;}printf("\nEnter quantum time ");scanf("%d",&quant_time);printf("\n name start end busrt rem compl");/* for first process start and the wait time to be 0 */j=0;fs=p[j].st_time=0;p[j].wt_time=0;if(p[j].ex_time>quant_time){ p[j].end_time=quant_time;p[j].completed_time=quant_time;}

28Lab Manual Meenakshi College of Engineering, Chennai

Page 29: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

else{p[j].end_time=p[j].ex_time;p[j].completed_time=p[j].ex_time;

p[j].wt_time=p[j].end_time-p[j].rem_time;p[j].turn_time=p[j].wt_time+p[j].ex_time;}p[j].rem_time=p[j].ex_time-p[j].completed_time;printf("\n%s\t%d\t%d\t%d\t%d\t%d",p[j].PName,p[j].st_time,p[j].end_time,p[j].ex_time,p[j].rem_time,p[j].completed_time);

fe=p[j].end_time;j++;while(j<n){p[j].st_time=fe;if(p[j].rem_time>quant_time){p[j].end_time=p[j].st_time+quant_time;p[j].rem_time-=quant_time;p[j].completed_time+=quant_time;fe+=quant_time;printf("\n%s\t%d\t%d\t%d\t%d\t%d",p[j].PName,p[j].st_time,p[j].end_time,p[j].ex_time,p[j].rem_time,p[j].completed_time);}else if(p[j].rem_time>0){p[j].end_time=p[j].st_time+p[j].rem_time;p[j].wt_time=fe-p[j].completed_time;p[j].completed_time+=p[j].rem_time;p[j].turn_time=p[j].wt_time+p[j].ex_time;fe+=p[j].rem_time;p[j].rem_time=0;

printf("\n%s\t%d\t%d\t%d\t%d\t%d",p[j].PName,p[j].st_time,p[j].end_time,p[j].ex_time,p[j].rem_time,p[j].completed_time);}j++;if(j==n){for(k=0;k<n;k++){if(p[k].rem_time>0) /*break for the inner for loop */ { j=k;break; }}if(k>n) /* breaks from the outer while loop */break;}}

29Lab Manual Meenakshi College of Engineering, Chennai

Page 30: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

printf("\n Process Name Waiting Time Turn Around Time"); for(i=0;i<n;i++){ printf("\n%s\t\t%d\t\t%d",p[i].PName,p[i].wt_time,p[i].turn_time); totalWaitTime+=p[i].wt_time; totalTurnAroundTime+=p[i].turn_time;}avgWaitTime=(float)totalWaitTime/n;avgTurnAroundTime=(float)totalTurnAroundTime/n;printf("\nAverage waiting time %f",avgWaitTime);printf("\nAverage turn around time %f",avgTurnAroundTime);}

OUTPUT: enter number of process4

enter process name p1enter burst time 3

enter process namep2enter burst time6

enter process namep3enter burst time4

enter process namep4enter burst time2

enter quantum time2

name start end burst rem comp p1 0 2 3 1 2 p2 2 4 6 4 2 p3 4 6 4 2 2 p4 6 8 2 0 2 p1 8 9 3 0 3 p2 9 11 6 2 4 p3 11 13 4 0 4p2 13 15 6 0 6 processname waitingtime turnaroundtime p1 6 9 p2 9 15 p3 9 13 p4 6 8 average waiting time7.500000 average turn around time 11.250000

Result :Thus C program was written for simulating FCFS and SJF scheduling algorithms.

30Lab Manual Meenakshi College of Engineering, Chennai

Page 31: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

6. Inter Process communication (using shared memory, pipes or message queues

Aim To write a C program to implement inter-process communication using pipes, shared memory and message queues.

Description

The Linux IPC (Inter-process communication) facilities provide a method for multiple processes to communicate with one another.

The types of inter process communication are:

1. Signals - Sent by other processes or the kernel to a specific process to indicate various conditions.

2. Pipes - Unnamed pipes set up by the shell normally with the "|" character to route output from one program to the input of another.

3. FIFOS - Named pipes operating on the basis of first data in, first data out. 4. Message queues - Message queues are a mechanism set up to allow one or more

processes to write messages that can be read by one or more other processes. 5. Semaphores - Counters that are used to control access to shared resources. These

counters are used as a locking mechanism to prevent more than one process from using the resource at a time.

6. Shared memory - The mapping of a memory area to be shared by multiple processes.

Message queues, semaphores, and shared memory can be accessed by the processes if they have access permission to the resource as set up by the object's creator. The process must pass an identifier to the kernel to be able to get the access.

PIPES

The Linux IPC (Inter-process communication) facilities provide a method for multiple processes to communicate with one another. There are several methods of IPC available to Linux.Simply put, a pipe is a method of connecting the standard output of one process to the standard input of another. Pipes are the eldest of the IPC tools, having been around since the earliest incarnations of the UNIX operating system. They provide a method of one-way communications (hence the term half-duplex) between processes.

To create a simple pipe with C, we make use of the pipe() system call. It takes a single argument, which is an array of two integers, and if successful, the array will contain two new file descriptors to be used for the pipeline. After creating a pipe, the process typically spawns a new process (remember the child inherits open file descriptors).

PROTOTYPE: int pipe( int fd[2] ); RETURNS: 0 on success -1 on error

31Lab Manual Meenakshi College of Engineering, Chennai

Page 32: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

NOTES: fd[0] is set up for reading, fd[1] is set up for writing

Shared Memory

Shared memory allows one or more processes to communicate via memory that appears in all of their virtual address spaces. The pages of the virtual memory is referenced by page table entries in each of the sharing processes' page tables. It does not have to be at the same address in all of the processes' virtual memory.

SYNOPSIS #include <sys/ipc.h> #include <sys/shm.h>

shmget - allocates a shared memory segment int shmget(key_t key, size_t size, int shmflg); shmget() returns the identifier of the shared memory segment associ- ated with the value of the argument key.

void *shmat(int shmid, const void *shmaddr, int shmflg); The function shmat attaches the shared memory segment identified by shmid to the address space of the calling process. The attaching address is specified by shmaddr with one of the following criteria: int shmdt(const void *shmaddr);

The function shmdt detaches the shared memory segment located at the address specified by shmaddr from the address space of the calling process.

Message Queues

Message queues can be best described as an internal linked list within the kernel's addressing space. Messages can be sent to the queue in order and retrieved from the queue in several different ways. Each message queue (of course) is uniquely identified by an IPC identifier.

Message queues allow one or more processes to write messages, which will be read by one or more reading processes. Linux maintains a list of message queues, the msgque vector; each element of which points to a msqid_ds data structure that fully describes the message queue. When message queues are created a new msqid_ds data structure is allocated from system memory and inserted into the vector.

NAME

msgget - get a message queue identifier

SYNOPSIS

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgget(key_t key, int msgflg);

32Lab Manual Meenakshi College of Engineering, Chennai

Page 33: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

DESCRIPTION

The function returns the message queue identifier associated with the value of the key argument.

MSGSND & MSGRCV

To send or receive a message, the calling process allocates a structure of the following general form:

struct msgbuf {

long mtype; /* message type, must be > 0 */

char mtext[1]; /* message data */

};

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);

The msgsnd system call appends a copy of the message pointed to by msgp to the message queue whose identifier is specified by msqid.

ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msg-

typ, int msgflg);

The system call msgrcv reads a message from the message queue specified by msqid into the msgbuf pointed to by the msgp argument, removing the read message from the queue.

Exercise Programs :

/* 1. IPC USING PIPES */

#include<stdio.h>main(){int fd[2],child;char a[10];printf("\nEnter the string to enter into the pipe ");scanf("%s",a);pipe(fd);child=fork();if(!child){

33Lab Manual Meenakshi College of Engineering, Chennai

Page 34: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

close(fd[0]);write(fd[1],a,5);wait(0);}else{close(fd[1]);read(fd[0],a,5);printf("\nThe string received from the pipe is %s\n",a);}return 0;}OUTPUT: enter the string to enter into the pipe hello the string received from the pipe is hello

/* 2. IPC USING SHARED MEMEORY */#include<stdio.h>#include<sys/shm.h>#include<sys/ipc.h>

main(){int child, shmid,i;char *shmptr;child=fork();

if(!child){shmid=shmget(2041,32,0666|IPC_CREAT);shmptr=shmat(shmid,0,0);

printf("\nParent writing.........\n");for(i=0;i<10;i++){shmptr[i]='a'+i;putchar(shmptr[i]);}printf("\n%s",shmptr);wait(NULL);}else{shmid=shmget(2041,32,0666|IPC_CREAT);shmptr=shmat(shmid,0,0);printf("\nReading from child.........\n");for(i=0;i<10;i++)putchar(shmptr[i]);

34Lab Manual Meenakshi College of Engineering, Chennai

Page 35: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

shmdt(NULL);shmctl(shmid,IPC_RMID,NULL);}return 0;}OUTPUT: parent writing... reading from child...abcdefghijabcdefghij abcdefghij

/* 3. a. IPC USING MESSAGE QUEUES - SEND MESSAGE */#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <stdio.h>#include <string.h>

#define MSGSZ 128

/* Declare the message structure. */

typedef struct msgbuf { long mtype; char mtext[MSGSZ]; } message_buf;

main(){ int msqid; int msgflg = IPC_CREAT | 0666; key_t key; message_buf sbuf; size_t buf_length;

/* Get the message queue id for the "name" 1234, which was created by * the server. */ key = 1234; msqid = msgget(key, msgflg );

/* We'll send message type 1 */ sbuf.mtype = 1; (void) strcpy(sbuf.mtext, "Did you get this?"); buf_length = strlen(sbuf.mtext) ; /* Send a message. */ msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT);

35Lab Manual Meenakshi College of Engineering, Chennai

Page 36: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

printf("Message: \"%s\" Sent\n", sbuf.mtext);}OUTPUT:message:"did you get there?" sent

/*3 .b. IPC USING MESSAGE QUEUES - RECEIVE MESSAGE */ #include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <stdio.h>#define MSGSZ 128

/* Declare the message structure. */

typedef struct msgbuf { long mtype; char mtext[MSGSZ];} message_buf;

main(){ int msqid; key_t key; message_buf rbuf;

/* Get the message queue id for the "name" 1234, which was created by the server. */ key = 1234;

msqid = msgget(key, 0666); /* Receive an answer of message type 1 */ msgrcv(msqid, &rbuf, MSGSZ, 1, 0); /*Print the answer. */ printf("%s\n", rbuf.mtext); exit(0);}OUTPUT:message:"did you get there?" received

Result :Thus C program was program written to implement IPC using pipes, shared memory and message queues.

36Lab Manual Meenakshi College of Engineering, Chennai

Page 37: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

7. Producer – Consumer problem using semaphoresAim :To write a C program to implement producer consumer problem using semaphore.

Semaphores

Semaphore is a location in memory whose value can be tested and set by more than one process. The test and set operation is, so far as each process is concerned, uninterruptible or atomic; once started nothing can stop it. The result of the test and set operation is the addition of the current value of the semaphore and the set value, which can be positive or negative. Depending on the result of the test and set operation one process may have to sleep until the semphore's value is changed by another process. Semaphores can be used to implement critical regions, areas of critical code that only one process at a time should be executing.

Say you had many cooperating processes reading records from and writing records to a single data file. You would want that file access to be strictly coordinated. You could use a semaphore with an initial value of 1 and, around the file operating code, put two semaphore operations, the first to test and decrement the semaphore's value and the second to test and increment it. The first process to access the file would try to decrement the semaphore's value and it would succeed, the semaphore's value now being 0. This process can now go ahead and use the data file but if another process wishing to use it now tries to decrement the semaphore's value it would fail as the result would be -1. That process will be suspended until the first process has finished with the data file. When the first process has finished with the data file it will increment the semaphore's value, making it 1 again. Now the waiting process can be woken and this time its attempt to increment the semaphore will succeed.

A semaphore is represented by an anonymous structure including the following members:

unsigned short semval; /* semaphore value */ unsigned short semzcnt; /* # waiting for zero */ unsigned short semncnt; /* # waiting for increase */ pid_t sempid; /* process that did last op */

The function semop performs operations on selected members of the semaphore set indicated by semid. Each of the nsops elements in the array pointed to by sops specifies an operation to be performed on a semaphore by a struct sembuf including the following members:

unsigned short sem_num; /* semaphore number */ short sem_op; /* semaphore operation */ short sem_flg; /* operation flags */ #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h>

int semop(int semid, struct sembuf *sops, unsigned nsops);SEMGET:

semget - get a semaphore set identifier

SYNOPSIS #include <sys/types.h>

37Lab Manual Meenakshi College of Engineering, Chennai

Page 38: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

#include <sys/ipc.h> #include <sys/sem.h>

int semget(key_t key, int nsems, int semflg);

DESCRIPTION This function returns the semaphore set identifier associated with the argument key.

semctl - semaphore control operations

SYNOPSIS #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h>

int semctl(int semid, int semnum, int cmd, ...);

DESCRIPTION The function semctl performs the control operation specified by cmd on the semaphore set identified by semid, or on the semnum-th semaphore of that set. (Semaphores are numbered starting at 0.)

/* program to demonstrate a basic producer-consumer implementation. */

#include <stdio.h> /* standard I/O routines. */#include <stdlib.h> /* rand() and srand() functions */#include <unistd.h> /* fork(), etc. */#include <time.h> /* nanosleep(), etc. */#include <sys/types.h> /* various type definitions. */#include <sys/ipc.h> /* general SysV IPC structures */#include <sys/sem.h> /* semaphore functions and structs. */

#define NUM_LOOPS 10 /* number of loops to perform. */

int main(int argc, char* argv[]){ int sem_set_id; /* ID of the semaphore set. */ int child_pid; /* PID of our child process. */ int i; /* counter for loop operation. */ struct sembuf sem_op; /* structure for semaphore ops. */ int rc; /* return value of system calls. */ struct timespec delay; /* used for wasting time. */

/* create a private semaphore set with one semaphore in it, */ /* with access only to the owner. */ sem_set_id = semget(IPC_PRIVATE, 1, 0600); printf("semaphore set created, semaphore set id '%d'.\n", sem_set_id); rc = semctl(sem_set_id, 0, SETVAL, 0); /* fork-off a child process, and start a producer/consumer job. */

38Lab Manual Meenakshi College of Engineering, Chennai

Page 39: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

child_pid = fork(); switch (child_pid) {

case 0: /* child process here */ for (i=0; i<NUM_LOOPS; i++) {

/* block on the semaphore, unless it's value is non-negative. */sem_op.sem_num = 0;sem_op.sem_op = -1;sem_op.sem_flg = 0;semop(sem_set_id, &sem_op, 1);printf("consumer: '%d'\n", i);fflush(stdout);

} break;default: /* parent process here */ for (i=0; i<NUM_LOOPS; i++) {

printf("producer: '%d'\n", i);fflush(stdout);/* increase the value of the semaphore by 1. */sem_op.sem_num = 0;sem_op.sem_op = 1;sem_op.sem_flg = 0;semop(sem_set_id, &sem_op, 1);

/* pause execution for a little bit, to allow the *//* child process to run and handle some requests. *//* this is done about 25% of the time. */if (rand() > 3*(RAND_MAX/4)) {

delay.tv_sec = 0; delay.tv_nsec = 10; nanosleep(&delay, NULL);

} } break;

}

return 0;}OUTPUT:Semaphore set created ,semaphore set id '2588751'Producer:0Consumer:0Producer:1Producer:2Consumer:1Consumer:2Producer:3Consumer:3Producer:4Consumer:4Producer:5

39Lab Manual Meenakshi College of Engineering, Chennai

Page 40: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

Producer:6Producer:7Consumer:5Consumer:6Consumer:7Producer:8Producer:9Consumer:8Consumer:9

Result :Thus C program was written to implement producer consumer problem using semaphores.

40Lab Manual Meenakshi College of Engineering, Chennai

Page 41: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

8. Memory Management Scheme – I

( First Fit and Best Fit Memory Allocation Strategies )

Aim :

To implement memory allocation algorithms first fit and best fit.

Description :

In an environment that supports dynamic memory allocation, the memory manager must keep a record of the usage of each allocatable block of memory. This record could be kept by using almost any data structure that implements linked lists. An obvious implementation is to define a free list of block descriptors, with each descriptor containing a pointer to the next descriptor, a pointer to the block, and the length of the block. The memory manager keeps a free list pointer and inserts entries into the list in some order conducive to its allocation strategy. A number of strategies are used to allocate space to the processes that are competing for memory.

Best Fit

The allocator places a process in the smallest block of unallocated memory in which it will fit.

Problems:

It requires an expensive search of the entire free list to find the best hole. More importantly, it leads to the creation of lots of little holes that are not big enough

to satisfy any requests. This situation is called fragmentation, and is a problem for all memory-management strategies, although it is particularly bad for best-fit.

Solution: One way to avoid making little holes is to give the client a bigger block than it asked for. For example, we might round all requests up to the next larger multiple of 64 bytes. That doesn't make the fragmentation go away, it just hides it.

Unusable space in the form of holes is called external fragmentation Unusable space in the form of holes is called external fragmentation

Worst Fit

The memory manager places process in the largest block of unallocated memory available. The idea is that this placement will create the largest hole after the allocations, thus increasing the possibility that, compared to best fit, another process can use the hole created as a result of external fragmentation.

First Fit

41Lab Manual Meenakshi College of Engineering, Chennai

Page 42: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

Another strategy is first fit, which simply scans the free list until a large enough hole is found. Despite the name, first-fit is generally better than best-fit because it leads to less fragmentation.

Problems:

Small holes tend to accumulate near the beginning of the free list, making the memory allocator search farther and farther each time.

Solution: Next Fit

Next Fit

The first fit approach tends to fragment the blocks near the beginning of the list without considering blocks further down the list. Next fit is a variant of the first-fit strategy. The problem of small holes accumulating is solved with next fit algorithm, which starts each search where the last one left off, wrapping around to the beginning when the end of the list is reached (a form of one-way elevator)

Result: Thus C program was written to implement first fit and best fit allocation strategies.

9. Memory Management Scheme – II

( Paging and Page replacement algorithm – FIFO)Aim : To write a C program for implementing paging scheme and FIFO page replacement algorithm

Paging

Basic idea: allocate physical memory to processes in fixed size chunks called page frames. Present abstraction to application of a single linear address space. Inside machine, break address space of application up into fixed size chunks called pages. Pages and page frames are same size. Store pages in page frames. When process generates an address, dynamically translate to the physical page frame which holds data for that page.

So, a virtual address now consists of two pieces: a page number and an offset within that page. Page sizes are typically powers of 2; this simplifies extraction of page numbers and offsets. To access a piece of data at a given address, system automatically does the following:

o Extracts page number. o Extracts offset. o Translate page number to physical page frame id.

42Lab Manual Meenakshi College of Engineering, Chennai

Page 43: 38451142-CS2257 (1)

CS 2257 - Operating Systems Laboratory

o Accesses data at offset in physical page frame.

First-In, First-Out (FIFO)First-in, first-out is as easy to implement as Random Replacement, andalthough its performance is equally unreliable or worse, claims , itsbehavior does follow a predictable pattern. Rather than choosing a victimpage at random, the oldest page (or first-in) is the first to be removed.Conceptually compares FIFO to a limited size queue, with items beingadded to the queue at the tail. When the queue fills (all of the physicalmemory has been allocated), the first page to enter is pushed out of head ofthe queue. Similar to Random Replacement, FIFO blatantly ignores trends,and although it produces less page faults, still does not take advantage oflocality trends unless by coincidence as pages move along the queue .

43Lab Manual Meenakshi College of Engineering, Chennai