feat: Add English documentation, switch license to MIT, and include JOSS paper.
This commit is contained in:
1 parent
571d8e51d2
commit
cb05314232
10 files changed
+646
-4
No files matched your search
@@ -0,0 +1,164 @@
|
||||
# Scheduling Algorithms
|
||||
|
||||
*Também disponível em: [🇧🇷 Português](./algorithms.md)*
|
||||
|
||||
This document describes in detail the scheduling algorithms implemented in PSS. For each algorithm, the operating principle, parameters, tie-breaking rules, and educational examples are presented.
|
||||
|
||||
---
|
||||
|
||||
## General Rules
|
||||
|
||||
- **Time unit:** the simulator operates in discrete *ticks*. Each tick represents 1 CPU time unit.
|
||||
- **Bursts:** each process has an alternating sequence of bursts: `CPU → I/O → CPU → ...`, always starting with CPU.
|
||||
- **Tie-breaking:** when two processes are tied on the algorithm's selection criterion, priority goes to the one that arrived first (`arrivalTime`). As a second tie-breaker, `id` is used in lexicographic order.
|
||||
- **Context Switch:** if configured (≥ 1 tick), an overhead is inserted every time the CPU switches processes.
|
||||
|
||||
---
|
||||
|
||||
## FCFS — First Come, First Served
|
||||
|
||||
**Type:** Non-preemptive
|
||||
|
||||
### How it works
|
||||
|
||||
Perhaps the most intuitive algorithm: the process that arrived first is served first. The Ready queue is sorted by `arrivalTime`. Once a process occupies the CPU, it stays there until its current CPU burst is complete — no interruptions.
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
P1: arrival=0, CPU: 4 ticks
|
||||
P2: arrival=1, CPU: 3 ticks
|
||||
P3: arrival=2, CPU: 1 tick
|
||||
|
||||
Gantt: | P1 P1 P1 P1 | P2 P2 P2 | P3 |
|
||||
Tick: 0 1 2 3 4 5 6 7
|
||||
```
|
||||
|
||||
| Process | Turnaround | Waiting |
|
||||
|---------|:----------:|:-------:|
|
||||
| P1 | 4 | 0 |
|
||||
| P2 | 6 | 3 |
|
||||
| P3 | 6 | 5 |
|
||||
|
||||
### Note: Convoy Effect
|
||||
|
||||
If a long process arrives before several short ones, the short ones wait a long time — even though the CPU could be serving them. This phenomenon is called the **Convoy Effect** and is one of the main drawbacks of FCFS. Try the `convoy_effect` preset to visualize it.
|
||||
|
||||
---
|
||||
|
||||
## SJF — Shortest Job First (Non-Preemptive)
|
||||
|
||||
**Type:** Non-preemptive
|
||||
|
||||
### How it works
|
||||
|
||||
When selecting the next process, SJF chooses the one with the **shortest remaining CPU burst** in the Ready queue. Once on the CPU, the process is not interrupted until its burst is complete.
|
||||
|
||||
SJF is optimal for minimizing average waiting time, but has a practical drawback: in real systems, future burst durations are unknown. In the simulator, you define bursts explicitly, so SJF can be applied perfectly.
|
||||
|
||||
### Parameters
|
||||
|
||||
No additional parameters.
|
||||
|
||||
---
|
||||
|
||||
## SRTF — Shortest Remaining Time First (Preemptive SJF)
|
||||
|
||||
**Type:** Preemptive
|
||||
|
||||
### How it works
|
||||
|
||||
Preemptive version of SJF. At each tick, the scheduler checks whether any process in the Ready queue has a **shorter** remaining burst than the currently running process. If so, a preemption occurs: the current process is returned to the Ready queue, and the new candidate takes the CPU.
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
P1: arrival=0, CPU: 8 ticks
|
||||
P2: arrival=1, CPU: 4 ticks
|
||||
|
||||
Tick 0: P1 starts (remaining=8)
|
||||
Tick 1: P2 arrives (remaining=4 < 7) → preemption!
|
||||
Tick 5: P2 finishes → P1 resumes (remaining=7)
|
||||
Tick 12: P1 finishes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Round Robin (RR)
|
||||
|
||||
**Type:** Preemptive
|
||||
**Parameter:** `quantum` (time slice, default: 2)
|
||||
|
||||
### How it works
|
||||
|
||||
The Ready queue is treated as a circular queue. Each process receives at most `quantum` consecutive CPU ticks. If the process still has remaining burst at the end of the quantum, it goes back to the **end** of the Ready queue and waits its turn.
|
||||
|
||||
I/O bursts **do not** consume quantum — the process voluntarily leaves the CPU when initiating I/O.
|
||||
|
||||
### Trade-off
|
||||
|
||||
The smaller the quantum, the fairer the time-sharing, but the higher the context switch overhead. The larger the quantum, the more RR behaves like FCFS.
|
||||
|
||||
---
|
||||
|
||||
## Priority Scheduling (Non-Preemptive and Preemptive)
|
||||
|
||||
**Type:** Non-preemptive or Preemptive (select in the panel)
|
||||
**Parameters:** Aging (optional) + aging interval
|
||||
|
||||
### How it works
|
||||
|
||||
Each process has a priority from `1` (highest) to `10` (lowest). The scheduler always selects the highest-priority process in the Ready queue.
|
||||
|
||||
- **Non-preemptive:** once on the CPU, the process completes its burst without interruption.
|
||||
- **Preemptive:** if a higher-priority process arrives, the current one is immediately preempted.
|
||||
|
||||
### Starvation and Aging
|
||||
|
||||
The classic problem with Priority Scheduling is **starvation**: low-priority processes may *never* receive the CPU if high-priority processes keep arriving.
|
||||
|
||||
The solution is **aging**: every `agingInterval` ticks a process spends in the Ready queue, its priority is incremented by 1 (i.e., the numeric value decreases), down to a minimum of `1`. Over time, even low-priority processes reach the head of the queue.
|
||||
|
||||
Try the `starvation` and `aging_fix` presets to see this difference.
|
||||
|
||||
---
|
||||
|
||||
## HRRN — Highest Response Ratio Next
|
||||
|
||||
**Type:** Non-preemptive
|
||||
|
||||
### How it works
|
||||
|
||||
HRRN tries to be fairer than SJF by taking the process's waiting time into account. At each selection, the **Response Ratio** of each process in the Ready queue is computed:
|
||||
|
||||
```
|
||||
ratio = (waitingTime + burstTime) / burstTime
|
||||
```
|
||||
|
||||
The process with the **highest ratio** is selected. This naturally increases the priority of processes that have been waiting a long time, preventing starvation.
|
||||
|
||||
| Situation | Effect on ratio |
|
||||
|-----------|----------------|
|
||||
| Process with short burst | high ratio from the start |
|
||||
| Process that has been waiting a long time | ratio grows over time |
|
||||
| Process with long burst + little wait | low ratio |
|
||||
|
||||
---
|
||||
|
||||
## Multilevel Queue
|
||||
|
||||
**Type:** Preemptive
|
||||
**Parameters:** number of queues, quantum per queue
|
||||
|
||||
### How it works
|
||||
|
||||
Processes are distributed across multiple queues with different priorities. Each queue has its own Round Robin quantum. Higher-priority queues are always served first — a lower-priority queue only receives CPU if all queues above it are empty.
|
||||
|
||||
This allows different classes of processes to be treated distinctly: for example, interactive processes in high-priority queues (small quantum) and batch processes in low-priority queues (larger quantum).
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- Silberschatz, A., Galvin, P. B., & Gagne, G. — *Operating System Concepts*, 10th edition
|
||||
- Tanenbaum, A. S. — *Modern Operating Systems*, 4th edition
|
||||
@@ -1,5 +1,7 @@
|
||||
# 📐 Algoritmos de Escalonamento
|
||||
|
||||
*Also available in: [🇺🇸 English](./algorithms.en.md)*
|
||||
|
||||
Este documento descreve em detalhes os algoritmos de escalonamento implementados no PSS. Para cada algoritmo são apresentados o princípio de funcionamento, parâmetros, regras de desempate e exemplos didáticos.
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
# Metrics
|
||||
|
||||
*Também disponível em: [🇧🇷 Português](./metrics.md)*
|
||||
|
||||
PSS automatically computes a set of metrics at the end (or during) the simulation. This document explains each metric, its formula, what it represents, and how to read it in the charts.
|
||||
|
||||
---
|
||||
|
||||
## Per-Process Metrics
|
||||
|
||||
These metrics are computed individually for each simulated process.
|
||||
|
||||
| Metric | Formula | What it means |
|
||||
|--------|---------|----------------|
|
||||
| **Arrival Time** | `arrivalTime` | Tick at which the process first entered the Ready queue |
|
||||
| **First CPU Tick** | `startTick` | Tick at which the process first used the CPU |
|
||||
| **Finish Time** | `finishTick` | Tick at which the process completed its execution |
|
||||
| **Response Time** | `startTick − arrivalTime` | How long the process waited before receiving the CPU for the first time |
|
||||
| **Turnaround Time** | `finishTick − arrivalTime` | Total lifetime of the process (arrival → completion) |
|
||||
| **Waiting Time** | `turnaround − cpuTime − ioTime` | Total time spent in the Ready queue (doing nothing useful) |
|
||||
| **CPU Time** | Σ ticks in Running state | Total CPU actually consumed |
|
||||
| **I/O Time** | Σ ticks in Waiting state | Total time waiting for I/O devices |
|
||||
| **CPU Utilization** | `cpuTime / turnaround × 100` | Percentage of the turnaround time the process was actually using the CPU |
|
||||
| **Bound Type** | see below | Classification of the process as CPU Bound, I/O Bound, or Balanced |
|
||||
|
||||
### Table visualization
|
||||
|
||||
In the **Per Process** tab, each row displays inline horizontal mini progress bars next to the numeric values. The bars are proportional to the **largest value of the same metric among all processes**, enabling immediate visual comparison:
|
||||
|
||||
| Column | Bar color |
|
||||
|--------|-----------|
|
||||
| Response Time | Amber |
|
||||
| Turnaround Time | Blue |
|
||||
| Waiting Time | Orange |
|
||||
| CPU Time | Emerald |
|
||||
| I/O Time | Cyan |
|
||||
| CPU Utilization | Violet → Blue gradient |
|
||||
|
||||
---
|
||||
|
||||
## Global Metrics
|
||||
|
||||
Computed over the complete set of processes in the simulation.
|
||||
|
||||
| Metric | Formula |
|
||||
|--------|---------|
|
||||
| **Avg Response Time** | Average of all processes' response times |
|
||||
| **Avg Turnaround Time** | Average of all turnaround times |
|
||||
| **Avg Waiting Time** | Average of all waiting times |
|
||||
| **CPU Throughput** | `completed processes / total simulation time` |
|
||||
| **CPU Utilization (global)** | `Σ Running ticks / total time × 100` |
|
||||
| **Total Simulation Time** | Tick of the last completion event |
|
||||
|
||||
In the **Global** tab, each time card (Response, Turnaround, Waiting) displays a bar proportional to the **total simulation time**, indicating "how much of that total time the average process spends in that state". The CPU Utilization bar uses an amber → green gradient to indicate utilization health.
|
||||
|
||||
---
|
||||
|
||||
## CPU Bound vs. I/O Bound Classification
|
||||
|
||||
At the end of the simulation, each process is automatically classified based on the proportion of time spent on CPU and I/O:
|
||||
|
||||
```
|
||||
cpuRatio = cpuTime / (cpuTime + ioTime)
|
||||
ioRatio = ioTime / (cpuTime + ioTime)
|
||||
|
||||
cpuRatio ≥ 0.65 → CPU Bound
|
||||
ioRatio ≥ 0.65 → I/O Bound
|
||||
otherwise → Balanced
|
||||
```
|
||||
|
||||
- **CPU Bound:** the process spends most of its time using the processor.
|
||||
- **I/O Bound:** the process spends most of its time waiting for I/O devices.
|
||||
- **Balanced:** the process uses CPU and I/O in a balanced way.
|
||||
|
||||
> **In the process list:** estimate computed from the declared bursts (before simulation).
|
||||
> **In the metrics table:** classification computed from the actual recorded times.
|
||||
|
||||
---
|
||||
|
||||
## Charts ("Chart" tab)
|
||||
|
||||
### Comparative Profile — Radar Chart
|
||||
|
||||
Displayed when there are **2 or more processes**. Each axis represents a time dimension, normalized from 0–100% relative to the largest value in that dimension among all processes:
|
||||
|
||||
| Axis | Meaning |
|
||||
|------|---------|
|
||||
| **Turnaround** | Relative total lifetime |
|
||||
| **Response** | Relative time to first CPU |
|
||||
| **Waiting** | Relative time in the Ready queue |
|
||||
| **CPU Time** | Relative CPU usage |
|
||||
| **I/O Time** | Relative I/O usage |
|
||||
|
||||
Each process is drawn as a colored polygon (the color configured for the process). Wider polygons indicate processes with larger times in the corresponding dimensions. The radar chart is ideal for identifying **profile differences** between processes — for example, a CPU Bound process will have a much larger CPU Time axis than I/O Time.
|
||||
|
||||
### Per-Process Breakdown — Stacked Bar Chart
|
||||
|
||||
Always displayed. Each bar represents a process, with stacked segments:
|
||||
|
||||
- **Amber** — Waiting Time
|
||||
- **Green** — CPU Time
|
||||
- **Cyan** — I/O Time
|
||||
|
||||
The total height of each bar equals the **Turnaround Time** of the process.
|
||||
|
||||
---
|
||||
|
||||
## Example
|
||||
|
||||
Consider three processes with the following bursts:
|
||||
|
||||
| Process | Bursts | cpuTime | ioTime | cpuRatio | Classification |
|
||||
|---------|--------|:-------:|:------:|:--------:|:--------------:|
|
||||
| P1 | CPU:8, IO:1, CPU:1 | 9 | 1 | 90% | CPU Bound |
|
||||
| P2 | CPU:1, IO:8, CPU:1 | 2 | 8 | 20% | I/O Bound |
|
||||
| P3 | CPU:4, IO:2, CPU:4 | 8 | 2 | 80% | CPU Bound |
|
||||
@@ -1,5 +1,7 @@
|
||||
# 📏 Métricas
|
||||
|
||||
*Also available in: [🇺🇸 English](./metrics.en.md)*
|
||||
|
||||
O PSS calcula automaticamente um conjunto de métricas ao final (ou durante) a simulação. Este documento explica cada métrica, sua fórmula, o que ela representa e como lê-la nos gráficos.
|
||||
|
||||
---
|
||||
|
||||
Reference in new issue
Block a user