EXPERIMENT 2

 First Come First Serve (FCFS) 

First Come First Serve CPU Scheduling Algorithm shortly known as FCFS is the first algorithm of CPU Process Scheduling Algorithm. In First Come First Serve Algorithm what we do is to allow the process to execute in linear manner.

This means that whichever process enters process enters the ready queue first is executed first. This shows that First Come First Serve Algorithm follows First In First Out (FIFO) principle

Example:  

/*

 * FCFS Scheduling Program in C

 */

#include <stdio.h>

int main()

{

    int pid[15];

    int bt[15];

    int n;

    printf("Enter the number of processes: ");

    scanf("%d",&n);

 

    printf("Enter process id of all the processes: ");

    for(int i=0;i<n;i++)

    {

        scanf("%d",&pid[i]);

    }

 

    printf("Enter burst time of all the processes: ");

    for(int i=0;i<n;i++)

    {

        scanf("%d",&bt[i]);

    }

    int i, wt[n];

    wt[0]=0;

 

    //for calculating waiting time of each process

    for(i=1; i<n; i++)

    {

        wt[i]= bt[i-1]+ wt[i-1];

    }


    printf("Process ID     Burst Time     Waiting Time     TurnAround Time\n");

    float twt=0.0;

    float tat= 0.0;

    for(i=0; i<n; i++)

    {

        printf("%d\t\t", pid[i]);

        printf("%d\t\t", bt[i]);

        printf("%d\t\t", wt[i]);

 

        //calculating and printing turnaround time of each process

        printf("%d\t\t", bt[i]+wt[i]);

        printf("\n");

 

        //for calculating total waiting time

        twt += wt[i];

 

        //for calculating total turnaround time

        tat += (wt[i]+bt[i]);

    }

    float att,awt;

 

    //for calculating average waiting time

    awt = twt/n;

 

    //for calculating average turnaround time

    att = tat/n;

    printf("Avg. waiting time= %f\n",awt);

    printf("Avg. turnaround time= %f",att);

}


Program Explanation

1. Initialize two array pid[] and bt[] of size 15.
2. Ask the user for number of processes n.
3. Ask the user for process id and burst time for all n processes and store them into pid[] and bt[] respectively.
4. Calculate waiting time of each process by the formula wt[i] = wt[i-1] + bt[i-1].
5. Print Process Id, Burst Time, waiting time and Turnaround time of each process in tabular manner.
6. Calculate and print turnaround time of each process = bt[i] + wt[i].
7. Add waiting time of all the processes and store it in the variable twt.
8. Add turnaround time of all the processes and store it in the variable tat.
9. Calculate average waiting time as awt = twt/n.
10. Calculate average turnaround time as att = tat/n;
11. Print average waiting time and average turnaround time.
12. Exit.



 Shortest Job First (SJF)
The shortest job first (SJF) or shortest job next, is a scheduling policy that selects the waiting process with the smallest execution time to execute next. SJN, also known as Shortest Job Next (SJN), can be preemptive or Non-Preemptive.


CODE:

/*
 * C Program to Implement SJF Scheduling
 */
 
#include<stdio.h>
int main()
{
    int bt[20],p[20],wt[20],tat[20],i,j,n,total=0,totalT=0,pos,temp;
    float avg_wt,avg_tat;
    printf("Enter number of process:");
    scanf("%d",&n);
 
    printf("\nEnter Burst Time:\n");
    for(i=0;i<n;i++)
    {
        printf("p%d:",i+1);
        scanf("%d",&bt[i]);
        p[i]=i+1;
    }
 
    //sorting of burst times
    for(i=0;i<n;i++)
    {
        pos=i;
        for(j=i+1;j<n;j++)
        {
            if(bt[j]<bt[pos])
                pos=j;
        }
 
        temp=bt[i];
        bt[i]=bt[pos];
        bt[pos]=temp;
 
        temp=p[i];
        p[i]=p[pos];
        p[pos]=temp;
    }
 
    wt[0]=0;
 
    //finding the waiting time of all the processes
    for(i=1;i<n;i++)
    {
        wt[i]=0;
        for(j=0;j<i;j++)
             //individual WT by adding BT of all previous completed processes
            wt[i]+=bt[j];
 
        //total waiting time
        total+=wt[i];   
    }
 
    //average waiting time
    avg_wt=(float)total/n;  
 
    printf("\nProcess\t Burst Time \tWaiting Time\tTurnaround Time");
    for(i=0;i<n;i++)
    {
        //turnaround time of individual processes
        tat[i]=bt[i]+wt[i]; 
 
        //total turnaround time
        totalT+=tat[i];      
        printf("\np%d\t\t %d\t\t %d\t\t\t%d",p[i],bt[i],wt[i],tat[i]);
    }
 
    //average turnaround time
    avg_tat=(float)totalT/n;     
    printf("\n\nAverage Waiting Time=%f",avg_wt);
    printf("\nAverage Turnaround Time=%f",avg_tat);
}
  
Program Explanation

1. Initialize two array pid[] and bt[] of size 20.
2. Ask the user for number of processes n.
3. Ask the user for process id and burst time for all n processes and store them into pid[] and bt[] respectively.
4. Sort all the processes according to their burst time.
5. Assign waiting time = 0 to the smallest process.
6. Calculate waiting time of each process by using two loops and adding all the burst time of previously completed processes.
7. Print Process Id, Burst Time, waiting time and Turnaround time of each process in tabular manner.
8. Calculate and print turnaround time of each process = bt[i] + wt[i].
9. Add waiting time of all the processes and store it in the variable total.
10. Add turnaround time of all the processes and store it in the variable totalT.
11. Calculate average waiting time as avg_wt = total/n.
12. Calculate average turnaround time as avg_tat = totalT/n;
13. Print average waiting time and average turnaround time.
14. Exit.


 EXPERIMENT 3

The Dining Philosopher Problem – The Dining Philosopher Problem states that K philosophers seated around a circular table with one chopstick between each pair of philosophers. There is one chopstick between each philosopher. A philosopher may eat if he can pick up the two chopsticks adjacent to him. One chopstick may be picked up by any one of its adjacent followers but not both. 


Semaphore Solution to Dining Philosopher –
Each philosopher is represented by the following pseudocode: 
 

process P[i]
 while true do
   {  THINK;
      PICKUP(CHOPSTICK[i], CHOPSTICK[i+1 mod 5]);
      EAT;
      PUTDOWN(CHOPSTICK[i], CHOPSTICK[i+1 mod 5])
   }

There are three states of the philosopher: THINKING, HUNGRY, and EATING. Here there are two semaphores: Mutex and a semaphore array for the philosophers. Mutex is used such that no two philosophers may access the pickup or putdown at the same time. The array is used to control the behavior of each philosopher. But, semaphores can result in deadlock due to programming errors.


CODE:

#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
 
#define N 5
#define THINKING 2
#define HUNGRY 1
#define EATING 0
#define LEFT (phnum + 4) % N
#define RIGHT (phnum + 1) % N
 
int state[N];
int phil[N] = { 0, 1, 2, 3, 4 };
 
sem_t mutex;
sem_t S[N];
 
void test(int phnum)
{
    if (state[phnum] == HUNGRY
        && state[LEFT] != EATING
        && state[RIGHT] != EATING) {
        // state that eating
        state[phnum] = EATING;
 
        sleep(2);
 
        printf("Philosopher %d takes fork %d and %d\n",
                      phnum + 1, LEFT + 1, phnum + 1);
 
        printf("Philosopher %d is Eating\n", phnum + 1);
 
        // sem_post(&S[phnum]) has no effect
        // during takefork
        // used to wake up hungry philosophers
        // during putfork
        sem_post(&S[phnum]);
    }
}
 
// take up chopsticks
void take_fork(int phnum)
{
 
    sem_wait(&mutex);
 
    // state that hungry
    state[phnum] = HUNGRY;
 
    printf("Philosopher %d is Hungry\n", phnum + 1);
 
    // eat if neighbours are not eating
    test(phnum);
 
    sem_post(&mutex);
 
    // if unable to eat wait to be signalled
    sem_wait(&S[phnum]);
 
    sleep(1);
}
 
// put down chopsticks
void put_fork(int phnum)
{
 
    sem_wait(&mutex);
 
    // state that thinking
    state[phnum] = THINKING;
 
    printf("Philosopher %d putting fork %d and %d down\n",
           phnum + 1, LEFT + 1, phnum + 1);
    printf("Philosopher %d is thinking\n", phnum + 1);
 
    test(LEFT);
    test(RIGHT);
 
    sem_post(&mutex);
}
 
void* philosopher(void* num)
{
 
    while (1) {
 
        int* i = num;
 
        sleep(1);
 
        take_fork(*i);
 
        sleep(0);
 
        put_fork(*i);
    }
}
 
int main()
{
 
    int i;
    pthread_t thread_id[N];
 
    // initialize the semaphores
    sem_init(&mutex, 0, 1);
 
    for (i = 0; i < N; i++)
 
        sem_init(&S[i], 0, 0);
 
    for (i = 0; i < N; i++) {
 
        // create philosopher processes
        pthread_create(&thread_id[i], NULL,
                       philosopher, &phil[i]);
 
        printf("Philosopher %d is thinking\n", i + 1);
    }
 
    for (i = 0; i < N; i++)
 
        pthread_join(thread_id[i], NULL);
}

 EXPERIMENT 4

Why the Banker's Algorithm is called that?

The reason the banker's algorithm is so titled is because it is employed in the banking sector to determine whether or not to authorize a loan to an individual. Assume a bank has n account holders, each of whom has an individual balance of S. When someone requests for a loan, the bank first deducts the loan amount from the total amount of money it possesses, and only approves the loan if the balance is more than S. It is done because the bank can simply do it if every account holder shows up to get their money.

In other words, the bank would never arrange its funds in a way that would prevent it from meeting the demands of all of its clients. The bank would strive to maintain safety at all times.

CODE:

  1. // Banker's Algorithm  
  2. #include <stdio.h>  
  3. int main()  
  4. {  
  5.     // P0, P1, P2, P3, P4 are the Process names here  
  6.   
  7.     int n, m, i, j, k;  
  8.     n = 5;                         // Number of processes  
  9.     m = 3;                         // Number of resources  
  10.     int alloc[5][3] = {{0, 1, 0},  // P0 // Allocation Matrix  
  11.                        {2, 0, 0},  // P1  
  12.                        {3, 0, 2},  // P2  
  13.                        {2, 1, 1},  // P3  
  14.                        {0, 0, 2}}; // P4  
  15.   
  16.     int max[5][3] = {{7, 5, 3},  // P0 // MAX Matrix  
  17.                      {3, 2, 2},  // P1  
  18.                      {9, 0, 2},  // P2  
  19.                      {2, 2, 2},  // P3  
  20.                      {4, 3, 3}}; // P4  
  21.   
  22.     int avail[3] = {3, 3, 2}; // Available Resources  
  23.   
  24.     int f[n], ans[n], ind = 0;  
  25.     for (k = 0; k < n; k++)  
  26.     {  
  27.         f[k] = 0;  
  28.     }  
  29.     int need[n][m];  
  30.     for (i = 0; i < n; i++)  
  31.     {  
  32.         for (j = 0; j < m; j++)  
  33.             need[i][j] = max[i][j] - alloc[i][j];  
  34.     }  
  35.     int y = 0;  
  36.     for (k = 0; k < 5; k++)  
  37.     {  
  38.         for (i = 0; i < n; i++)  
  39.         {  
  40.             if (f[i] == 0)  
  41.             {  
  42.                 int flag = 0;  
  43.                 for (j = 0; j < m; j++)  
  44.                 {  
  45.                     if (need[i][j] > avail[j])  
  46.                     {  
  47.                         flag = 1;  
  48.                         break;  
  49.                     }  
  50.                 }  
  51.                 if (flag == 0)  
  52.                 {  
  53.                     ans[ind++] = i;  
  54.                     for (y = 0; y < m; y++)  
  55.                         avail[y] += alloc[i][y];  
  56.                     f[i] = 1;  
  57.                 }  
  58.             }  
  59.         }  
  60.     }  
  61.     int flag = 1;  
  62.     for (int i = 0; i < n; i++)  
  63.     {  
  64.         if (f[i] == 0)  
  65.         {  
  66.             flag = 0;  
  67.             printf("The following system is not safe");  
  68.             break;  
  69.         }  
  70.     }  
  71.     if (flag == 1)  
  72.     {  
  73.         printf("Following is the SAFE Sequence\n");  
  74.         for (i = 0; i < n - 1; i++)  
  75.             printf(" P%d ->", ans[i]);  
  76.         printf(" P%d", ans[n - 1]);  
  77.     }  
  78.     return (0);  
  79. }  


 EXPERIMENT 5

FIFO

The simplest algorithm for replacing pages is this one. The operating system maintains a queue for all of the memory pages in this method, with the oldest page at the front of the queue. The first page in the queue is chosen for removal when a page has to be replaced.


Implementation

Let the amount of pages that memory can store serve as the capacity. Set, the current collection of memory pages, shall be.

  1. 1. Begin turning the pages.  
  2. i) If the set can hold no more pages.  
  3. a) Add pages one at a time into the collection until it is full or all requests for pages have been fulfilled.  
  4. b) Maintain the pages in the queue simultaneously to carry out FIFO.  
  5. b) Increased page error  
  6. ii) Other  
  7. Do nothing if the current page is included in the collection.  
  8. If not, either a) the current page in the string should be substituted for the first page in the queue since it was the first to be placed into memory, or b) the first page in the queue should be removed.  
  9. b) Add the currently viewing page to the queue.  
  10. d) Page faults that increase.  
  11. 2. Return page errors.  

code : 

  1. #include < stdio.h >  
  2. int main()  
  3. {  
  4.     int incomingStream[] = {4 , 1 , 2 , 4 , 5};  
  5.     int pageFaults = 0;  
  6.     int frames = 3;  
  7.     int m, n, s, pages;   
  8.     pages = sizeof(incomingStream)/sizeof(incomingStream[0]);   
  9.     printf(" Incoming \ t Frame 1 \ t Frame 2 \ t Frame 3 ");  
  10.     int temp[ frames ];  
  11.     for(m = 0; m < frames; m++)  
  12.     {  
  13.         temp[m] = -1;  
  14.     }  
  15.     for(m = 0; m < pages; m++)  
  16.     {  
  17.         s = 0;   
  18.         for(n = 0; n < frames; n++)  
  19.         {  
  20.             if(incomingStream[m] == temp[n])  
  21.             {  
  22.                 s++;  
  23.                 pageFaults--;  
  24.             }  
  25.         }  
  26.         pageFaults++;  
  27.         if((pageFaults <= frames) && (s == 0))  
  28.         {  
  29.             temp[m] = incomingStream[m];  
  30.         }  
  31.         else if(s == 0)  
  32.         {  
  33.             temp[(pageFaults - 1) % frames] = incomingStream[m];  
  34.         }  
  35.         printf("\n");  
  36.         printf("%d\t\t\t",incomingStream[m]);  
  37.         for(n = 0; n < frames; n++)  
  38.         {  
  39.             if(temp[n] != -1)  
  40.                 printf(" %d\t\t\t", temp[n]);  
  41.             else  
  42.                 printf(" - \t\t\t");  
  43.         }  
  44.     }  
  45.     printf("\nTotal Page Faults:\t%d\n", pageFaults);  
  46.     return 0;  
  47. }  


In Least Recently Used (LRU) algorithm is a Greedy algorithm where the page to be replaced is least recently used. The idea is based on locality of reference, the least recently used page is not likely 
Let say the page reference string 7 0 1 2 0 3 0 4 2 3 0 3 2 . Initially we have 4 page slots empty. 
Initially all slots are empty, so when 7 0 1 2 are allocated to the empty slots —> 4 Page faults 
0 is already there so —> 0 Page fault. 
when 3 came it will take the place of 7 because it is least recently used —>1 Page fault 
0 is already in memory so —> 0 Page fault
4 will takes place of 1 —> 1 Page Fault 
Now for the further page reference string —> 0 Page fault because they are already available in the memory.



CODE:
//C++ implementation of above algorithm
#include<bits/stdc++.h>
using namespace std;
 
// Function to find page faults using indexes
int pageFaults(int pages[], int n, int capacity)
{
    // To represent set of current pages. We use
    // an unordered_set so that we quickly check
    // if a page is present in set or not
    unordered_set<int> s;
 
    // To store least recently used indexes
    // of pages.
    unordered_map<int, int> indexes;
 
    // Start from initial page
    int page_faults = 0;
    for (int i=0; i<n; i++)
    {
        // Check if the set can hold more pages
        if (s.size() < capacity)
        {
            // Insert it into set if not present
            // already which represents page fault
            if (s.find(pages[i])==s.end())
            {
                s.insert(pages[i]);
 
                // increment page fault
                page_faults++;
            }
 
            // Store the recently used index of
            // each page
            indexes[pages[i]] = i;
        }
 
        // If the set is full then need to perform lru
        // i.e. remove the least recently used page
        // and insert the current page
        else
        {
            // Check if current page is not already
            // present in the set
            if (s.find(pages[i]) == s.end())
            {
                // Find the least recently used pages
                // that is present in the set
                int lru = INT_MAX, val;
                for (auto it=s.begin(); it!=s.end(); it++)
                {
                    if (indexes[*it] < lru)
                    {
                        lru = indexes[*it];
                        val = *it;
                    }
                }
 
                // Remove the indexes page
                s.erase(val);
 
                // insert the current page
                s.insert(pages[i]);
 
                // Increment page faults
                page_faults++;
            }
 
            // Update the current page index
            indexes[pages[i]] = i;
        }
    }
 
    return page_faults;
}
 
// Driver code
int main()
{
    int pages[] = {7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2};
    int n = sizeof(pages)/sizeof(pages[0]);
    int capacity = 4;
    cout << pageFaults(pages, n, capacity);
    return 0;
}


 EXPERIMENT 6

FIRST FIT:

#include <stdio.h>

void implimentFirstFit(int blockSize[], int blocks, int processSize[], int processes)
{
    // This will store the block id of the allocated block to a process
    int allocate[processes];
    int occupied[blocks];

    // initially assigning -1 to all allocation indexes
    // means nothing is allocated currently
    for(int i = 0; i < processes; i++)
	{
		allocate[i] = -1;
	}
	
	for(int i = 0; i < blocks; i++){
        occupied[i] = 0;
    }
	
    // take each process one by one and find
    // first block that can accomodate it
    for (int i = 0; i < processes; i++)
    {
        for (int j = 0; j < blocks; j++) 
        { 
        if (!occupied[j] && blockSize[j] >= processSize[i])
            {
                // allocate block j to p[i] process
                allocate[i] = j;
                occupied[j] = 1;
 
                break;
            }
        }
    }

    printf("\nProcess No.\tProcess Size\tBlock no.\n");
    for (int i = 0; i < processes; i++)
    {
        printf("%d \t\t\t %d \t\t\t", i+1, processSize[i]);
        if (allocate[i] != -1)
            printf("%d\n",allocate[i] + 1);
        else
            printf("Not Allocated\n");
    }
}

void main()
{
    int blockSize[] = {30, 5, 10};
    int processSize[] = {10, 6, 9};
    int m = sizeof(blockSize)/sizeof(blockSize[0]);
    int n = sizeof(processSize)/sizeof(processSize[0]);
    
    implimentFirstFit(blockSize, m, processSize, n);
}

Best Fit:

#include <stdio.h>

void implimentBestFit(int blockSize[], int blocks, int processSize[], int proccesses)
{
    // This will store the block id of the allocated block to a process
    int allocation[proccesses];
    int occupied[blocks];
    
    // initially assigning -1 to all allocation indexes
    // means nothing is allocated currently
    for(int i = 0; i < proccesses; i++){
        allocation[i] = -1;
    }
    
    for(int i = 0; i < blocks; i++){
        occupied[i] = 0;
    }
 
    // pick each process and find suitable blocks
    // according to its size ad assign to it
    for (int i = 0; i < proccesses; i++)
    {
        
        int indexPlaced = -1;
        for (int j = 0; j < blocks; j++) { 
            if (blockSize[j] >= processSize[i] && !occupied[j])
            {
                // place it at the first block fit to accomodate process
                if (indexPlaced == -1)
                    indexPlaced = j;
                    
                // if any future block is smalller than the current block where
                // process is placed, change the block and thus indexPlaced
		// this reduces the wastage thus best fit
                else if (blockSize[j] < blockSize[indexPlaced])
                    indexPlaced = j;
            }
        }
 
        // If we were successfully able to find block for the process
        if (indexPlaced != -1)
        {
            // allocate this block j to process p[i]
            allocation[i] = indexPlaced;
            
            // make the status of the block as occupied
            occupied[indexPlaced] = 1;
        }
    }
 
    printf("\nProcess No.\tProcess Size\tBlock no.\n");
    for (int i = 0; i < proccesses; i++)
    {
        printf("%d \t\t\t %d \t\t\t", i+1, processSize[i]);
        if (allocation[i] != -1)
            printf("%d\n",allocation[i] + 1);
        else
            printf("Not Allocated\n");
    }
}
 
// Driver code
int main()
{
    int blockSize[] = {100, 50, 30, 120, 35};
    int processSize[] = {40, 10, 30, 60};
    int blocks = sizeof(blockSize)/sizeof(blockSize[0]);
    int proccesses = sizeof(processSize)/sizeof(processSize[0]);
 
    implimentBestFit(blockSize, blocks, processSize, proccesses);
 
    return 0 ;
}

worst fit:
#include <stdio.h>

void implimentWorstFit(int blockSize[], int blocks, int processSize[], int processes)
{
    // This will store the block id of the allocated block to a process
    int allocation[processes];
    int occupied[blocks];
    
    // initially assigning -1 to all allocation indexes
    // means nothing is allocated currently
    for(int i = 0; i < processes; i++){
        allocation[i] = -1;
    }
    
    for(int i = 0; i < blocks; i++){
        occupied[i] = 0;
    }
 
    // pick each process and find suitable blocks
    // according to its size ad assign to it
    for (int i=0; i < processes; i++)
    {
	int indexPlaced = -1;
	for(int j = 0; j < blocks; j++)
	{
	    // if not occupied and block size is large enough
	    if(blockSize[j] >= processSize[i] && !occupied[j])
            {
                // place it at the first block fit to accomodate process
                if (indexPlaced == -1)
                    indexPlaced = j;
                    
                // if any future block is larger than the current block where
                // process is placed, change the block and thus indexPlaced
                else if (blockSize[indexPlaced] < blockSize[j])
                    indexPlaced = j;
            }
        }
 
        // If we were successfully able to find block for the process
        if (indexPlaced != -1)
        {
            // allocate this block j to process p[i]
            allocation[i] = indexPlaced;
            
            // make the status of the block as occupied
            occupied[indexPlaced] = 1;
 
            // Reduce available memory for the block
            blockSize[indexPlaced] -= processSize[i];
        }
    }
 
    printf("\nProcess No.\tProcess Size\tBlock no.\n");
    for (int i = 0; i < processes; i++)
    {
        printf("%d \t\t\t %d \t\t\t", i+1, processSize[i]);
        if (allocation[i] != -1)
            printf("%d\n",allocation[i] + 1);
        else
            printf("Not Allocated\n");
    }
}
 
// Driver code
int main()
{
    int blockSize[] = {100, 50, 30, 120, 35};
    int processSize[] = {40, 10, 30, 60};
    int blocks = sizeof(blockSize)/sizeof(blockSize[0]);
    int processes = sizeof(processSize)/sizeof(processSize[0]);
 
    implimentWorstFit(blockSize, blocks, processSize, processes);
 
    return 0;
}


EXPERIMENT 7
\
FCFS is the simplest disk scheduling algorithm. As the name suggests, this algorithm entertains requests in the order they arrive in the disk queue. The algorithm looks very fair and there is no starvation (all requests are serviced sequentially) but generally, it does not provide the fastest service.

Algorithm: 

Let Request array represents an array storing indexes of tracks that have been requested in ascending order of their time of arrival. ‘head’ is the position of disk head.
Let us one by one take the tracks in default order and calculate the absolute distance of the track from the head.
Increment the total seek count with this distance.
Currently serviced track position now becomes the new head position.
Go to step 2 until all tracks in request array have not been serviced.

code:
// C++ program to demonstrate
// FCFS Disk Scheduling algorithm
#include <stdio.h>
#include <math.h>
 
int size = 8;
 
void FCFS(int arr[],int head)
{
    int seek_count = 0;
      int cur_track, distance;
   
    for(int i=0;i<size;i++)
       {
        cur_track = arr[i];
       
          // calculate absolute distance
        distance = fabs(head - cur_track);
       
          // increase the total count
        seek_count += distance;
       
          // accessed track is now new head
        head = cur_track;
    }
   
    printf("Total number of seek operations: %d\n",seek_count);
       
      // Seek sequence would be the same
    // as request array sequence
    printf("Seek Sequence is\n");
   
      for (int i = 0; i < size; i++) {
        printf("%d\n",arr[i]);
    }
}
 
//Driver code
int main()
{
      // request array
    int arr[8] = { 176, 79, 34, 60, 92, 11, 41, 114 };
      int head = 50;
     
    FCFS(arr,head);
   
    return 0;
}


Shortest Seek Time First (SSTF) – 
Basic idea is the tracks which are closer to current disk head position should be serviced first in order to minimise the seek operations.

Advantages of Shortest Seek Time First (SSTF) – 

Better performance than FCFS scheduling algorithm.
It provides better throughput.
This algorithm is used in Batch Processing system where throughput is more important.
It has less average response and waiting time.

Disadvantages of Shortest Seek Time First (SSTF) – 

Starvation is possible for some requests as it favours easy to reach request and ignores the far away processes.
There is lack of predictability because of high variance of response time.
Switching direction slows things down.

Algorithm – 

Let Request array represents an array storing indexes of tracks that have been requested. ‘head’ is the position of disk head.
Find the positive distance of all tracks in the request array from head.
Find a track from requested array which has not been accessed/serviced yet and has minimum distance from head.
Increment the total seek count with this distance.
Currently serviced track position now becomes the new head position.
Go to step 2 until all tracks in request array have not been serviced.

CODE:
// C++ program for implementation of
// SSTF disk scheduling
#include <bits/stdc++.h>
using namespace std;
 
// Calculates difference of each 
// track number with the head position
void calculatedifference(int request[], int head,
                         int diff[][2], int n)
{
    for(int i = 0; i < n; i++)
    {
        diff[i][0] = abs(head - request[i]);
    }
}
 
// Find unaccessed track which is
// at minimum distance from head
int findMIN(int diff[][2], int n)
{
    int index = -1;
    int minimum = 1e9;
   
    for(int i = 0; i < n; i++)
    {
        if (!diff[i][1] && minimum > diff[i][0])
        {
            minimum = diff[i][0];
            index = i;
        }
    }
    return index;
}
 
void shortestSeekTimeFirst(int request[],
                           int head, int n)
{
    if (n == 0)
    {
        return;
    }
     
    // Create array of objects of class node   
    int diff[n][2] = { { 0, 0 } };
     
    // Count total number of seek operation  
    int seekcount = 0;
     
    // Stores sequence in which disk access is done
    int seeksequence[n + 1] = {0};
     
    for(int i = 0; i < n; i++)
    {
        seeksequence[i] = head;
        calculatedifference(request, head, diff, n);
        int index = findMIN(diff, n);
        diff[index][1] = 1;
         
        // Increase the total count
        seekcount += diff[index][0];
         
        // Accessed track is now new head
        head = request[index];
    }
    seeksequence[n] = head;
     
    cout << "Total number of seek operations = "
         << seekcount << endl;
    cout << "Seek sequence is : " << "\n";
     
    // Print the sequence
    for(int i = 0; i <= n; i++)
    {
        cout << seeksequence[i] << "\n";
    }
}
 
// Driver code
int main()
{
    int n = 8;
    int proc[n] = { 176, 79, 34, 60, 92, 11, 41, 114 };
     
    shortestSeekTimeFirst(proc, 50, n);
     
    return 0;
}