Assignment 09: Disk Scheduling Operations
I. Objective & Theoretical Framework
One of the core responsibilities of an operating system is to utilize hardware efficiently. For magnetic disk drives, meeting this responsibility entails minimizing access time and maximizing disk bandwidth. Both metrics can be significantly improved by managing the execution order of pending disk I/O requests. This process is called disk scheduling.
You will program simulations for three prominent disk scheduling algorithms:
- First-Come, First-Served (FCFS): The simplest form of scheduling. It is intrinsically fair, but it generally does not provide the fastest service.
- SCAN (The Elevator Algorithm): The disk arm starts at one end and moves towards the other end, servicing requests as it reaches each cylinder until it gets to the other end of the disk. At the other end, the direction of head movement is reversed, and servicing continues as the head continuously scans back and forth.
- C-SCAN (Circular SCAN): A variant of SCAN designed to provide a more uniform wait time. Like SCAN, C-SCAN moves the head from one end of the disk to the other, servicing requests. However, when the head reaches the other end, it immediately returns to the beginning of the disk without servicing any requests on the return trip.
II. Prerequisite Knowledge & Resources
- Mathematical Operations: You will require absolute value calculations to determine track differences (seek distance). You may include
<stdlib.h>for theabs()function or write a manual conversion constraint (e.g.,if (val < 0) val = val * (-1);). - Array Sorting: The SCAN and C-SCAN algorithms require you to sort the incoming track requests in ascending order before you can logically split them into “left” and “right” directional arrays.
III. Starter Code & Partial Implementations
The following skeleton demonstrates the logic for FCFS disk scheduling. It calculates the header movements required to traverse a given array of track requests.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int t[20], n, i, tohm[20], tot = 0;
float avhm;
clock_t start, end;
double cpu_time_used;
// --- I/O OPERATIONS (OUTSIDE TIMER) ---
printf("Enter the number of tracks: ");
scanf("%d", &n);
printf("Enter the tracks to be traversed: ");
for(i = 1; i <= n; i++) {
scanf("%d", &t[i]);
}
printf("Enter the initial position of the read/write head: ");
scanf("%d", &t[0]);
// --- CORE ALGORITHM LOGIC (INSIDE TIMER) ---
start = clock();
for(i = 0; i < n; i++) {
tohm[i] = t[i+1] - t[i];
if(tohm[i] < 0) {
tohm[i] = tohm[i] * (-1); // Convert to absolute value
}
tot += tohm[i];
}
avhm = (float)tot / n;
end = clock();
// ------------------------------------------
cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
// --- OUTPUT OPERATIONS (OUTSIDE TIMER) ---
printf("\nTracks traversed\tDifference between tracks\n");
for(i = 0; i < n; i++) {
printf("%d\t\t\t%d\n", t[i+1], tohm[i]);
}
printf("\nAverage header movements: %f\n", avhm);
printf("Algorithm Execution Time: %f seconds\n", cpu_time_used);
return 0;
}
IV. Step-by-Step Task List
FCFS Evaluation: Complete and execute the FCFS starter code. Test it with a variety of track sequences to observe how highly erratic requests cause massive seek overhead.
SCAN Implementation: Create a new program. Prompt the user for the number of tracks, the initial head position, and the array of requests.
Sort the request array in ascending order.
Locate where the initial head position falls within the sorted array.
Traverse the array towards the
0track (or the maximum track, depending on your chosen initial direction), calculating distances, then reverse direction and process the remaining requests.
- C-SCAN Implementation: Create a new program for C-SCAN. Prompt the user for the total disk boundaries (e.g., 0 to 199). Implement the logic so that when the head reaches the maximum boundary, it calculates the jump back to
0, but does not service requests during that jump, before continuing its sweep.
V. Common Pitfalls & Debugging Strategies
Disk Boundary Insertion: For SCAN and C-SCAN, a common failure is forgetting to insert the absolute disk boundaries (e.g.,
0andtot-1) into your array of requests. The read/write head must travel to the absolute end of the disk before reversing (SCAN) or looping (C-SCAN), even if there is no specific file request at that exact boundary.Array Index Out of Bounds: When dynamically splitting the sorted requests into two separate traversal arrays, pay close attention to your loop terminating conditions to avoid reading uninitialized memory.
VI. Real-World Case Study
It is a common misconception that disk scheduling algorithms are obsolete in the era of Solid State Drives (SSDs) because flash memory has no moving read/write head and thus a physical “seek time” of zero. However, operating system I/O schedulers (such as the Linux BFQ or Kyber schedulers) still utilize variants of these elevator algorithms. Instead of optimizing physical arm movement, they optimize for flash page erasure block cycles, grouping logical block addresses together to maximize parallel data channel bandwidth and minimize wear on the NAND flash gates.
VII. Advanced Variant Tasks
- SSTF (Shortest Seek Time First): Write a C program to implement the SSTF algorithm. Instead of sweeping back and forth, the head should always jump to the unserviced track that is closest to its current position. Compare the average head movements against FCFS and SCAN.
- LOOK & C-LOOK Algorithms: Implement the LOOK and C-LOOK algorithms. These are identical to SCAN and C-SCAN, except the head only goes as far as the last request in a given direction, rather than traveling all the way to the absolute physical edge of the disk.
VIII. Resources & Further Reading
- OSTEP - Hard Disk Drives: Read Chapter 37: Hard Disk Drives (PDF). This chapter mathematically breaks down seek time and rotational delay, and illustrates the logic behind SCAN, C-SCAN, and SSTF.
- Linux I/O Schedulers: For an advanced real-world connection, research the Linux BFQ (Budget Fair Queueing) and Kyber I/O schedulers. Notice how modern OS kernels have evolved beyond basic elevator algorithms to prioritize flash-memory bandwidth over physical head movement.