C: simulating round-robin scheduling
Give each job a fixed time slice in turn and compute the turnaround time of each.
#include <stdio.h>
int main(void) {
int remaining[] = {5, 3, 1};
int finish[] = {0, 0, 0};
int jobs = 3;
int quantum = 2;
int clock = 0;
int unfinished = jobs;
while (unfinished > 0) {
for (int i = 0; i < jobs; i++) {
if (remaining[i] == 0) {
continue;
}
int run = remaining[i] < quantum ? remaining[i] : quantum;
clock += run;
remaining[i] -= run;
printf("t=%d P%d ran %d\n", clock, i + 1, run);
if (remaining[i] == 0) {
finish[i] = clock;
unfinished--;
}
}
}
double total = 0;
for (int i = 0; i < jobs; i++) {
printf("P%d turnaround %d\n", i + 1, finish[i]);
total += finish[i];
}
printf("average turnaround %.2f\n", total / jobs);
return 0;
}t=2 P1 ran 2 t=4 P2 ran 2 t=5 P3 ran 1 t=7 P1 ran 2 t=8 P2 ran 1 t=9 P1 ran 1 P1 turnaround 9 P2 turnaround 8 P3 turnaround 5 average turnaround 7.33
Explanation
Round-robin scheduling runs each ready process for at most one quantum and then moves on to the next, cycling until all are done. A process that has not finished waits for its next turn, so no job can monopolize the CPU. The turnaround time of a job is its completion time minus its arrival time.
All jobs arrive at time 0 here. The simulation keeps the remaining burst of each job and a clock. It walks through the jobs in a cycle, runs each unfinished one for min(quantum, remaining), and records when a job's remaining time reaches zero. A smaller quantum is more responsive but costs more context switches.
Explore the dry run
#include <stdio.h> int main(void) { int remaining[] = {5, 3, 1}; int finish[] = {0, 0, 0}; int jobs = 3; int quantum = 2; int clock = 0; int unfinished = jobs; while (unfinished > 0) { for (int i = 0; i < jobs; i++) { if (remaining[i] == 0) { continue; } int run = remaining[i] < quantum ? remaining[i] : quantum; clock += run; remaining[i] -= run; printf("t=%d P%d ran %d\n", clock, i + 1, run); if (remaining[i] == 0) { finish[i] = clock; unfinished--; } } } double total = 0; for (int i = 0; i < jobs; i++) { printf("P%d turnaround %d\n", i + 1, finish[i]); total += finish[i]; } printf("average turnaround %.2f\n", total / jobs); return 0;}Follow the example
Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.
View the complete dry-run table
| Step / line | What happens | State after step | Output so far |
|---|---|---|---|
| A job runs for a full quantum, or less if it needs less. | — | — | |
| The clock advances by the time actually used. | — | — | |
| P1 and P2 each take two units first, then P3 finishes in one. | — | t=2 P1 ran 2 t=4 P2 ran 2 t=5 P3 ran 1 t=7 P1 ran 2 t=8 P2 ran 1 t=9 P1 ran 1 | |
| Record the completion time when the remaining burst reaches zero. | — | t=2 P1 ran 2 t=4 P2 ran 2 t=5 P3 ran 1 t=7 P1 ran 2 t=8 P2 ran 1 t=9 P1 ran 1 | |
| (9 + 8 + 5) / 3 = 7.33. | — | t=2 P1 ran 2 t=4 P2 ran 2 t=5 P3 ran 1 t=7 P1 ran 2 t=8 P2 ran 1 t=9 P1 ran 1 P1 turnaround 9 P2 turnaround 8 P3 turnaround 5 average turnaround 7.33 |
Cost and common mistakes
Each slice costs O(1). The number of slices is the sum of ceil(burst / quantum) over all jobs.
- This model ignores the time spent on context switches, which makes tiny quanta look better than they are.
- With all jobs arriving at time 0, turnaround equals completion time. With later arrivals, subtract the arrival time.
- A quantum much larger than any burst makes round-robin behave like first-come, first-served.
Try it yourself
How many time slices does this schedule use?
Reveal answer and reasoning
Six slices: P1 uses 3, P2 uses 2, and P3 uses 1.