feat: add MLFQ scheduling algorithm and thread scheduler
- Implemented MLFQ (Multilevel Feedback Queue) algorithm with dynamic priority levels and quantum management. - Created unit tests for MLFQ algorithm covering initialization, demotion, selection, priority boost, preemption, and quantum expiration. - Developed a ThreadScheduler class supporting FCFS, RR, and PRIORITY scheduling policies for intra-process thread management. - Added unit tests for ThreadScheduler to validate thread selection and quantum expiration logic.
This commit is contained in:
1 parent
532c14e382
commit
5761dfe70a
34 files changed
+3789
-334
No files matched your search
+101
-1
@@ -147,7 +147,7 @@ The process with the **highest ratio** is selected. This naturally increases the
|
||||
|
||||
## Multilevel Queue
|
||||
|
||||
**Type:** Preemptive
|
||||
**Type:** Preemptive
|
||||
**Parameters:** number of queues, quantum per queue
|
||||
|
||||
### How it works
|
||||
@@ -158,6 +158,106 @@ This allows different classes of processes to be treated distinctly: for example
|
||||
|
||||
---
|
||||
|
||||
## MLFQ (Multilevel Feedback Queue)
|
||||
|
||||
**Type:** Preemptive
|
||||
**Parameters:** number of queues, quantum per queue (default: [2, 4, 8]), boost interval
|
||||
|
||||
### How it works
|
||||
|
||||
MLFQ is an extension of the Multilevel Queue that allows **processes to move between queues** based on their observed runtime behavior — eliminating the need to know burst durations in advance.
|
||||
|
||||
#### Movement rules
|
||||
|
||||
| Event | Action |
|
||||
|-------|--------|
|
||||
| Newly arrived process | Enters **queue 0** (highest priority) |
|
||||
| Process exhausts the quantum of its current queue | **Demoted** to the next queue (lower priority) |
|
||||
| Process returns from I/O | Stays in the **same queue** (cooperative behavior is rewarded) |
|
||||
| Boost tick (configurable interval) | **All** processes are moved to queue 0 |
|
||||
|
||||
#### Why is MLFQ efficient?
|
||||
|
||||
- Interactive processes (I/O Bound) naturally stay in high-priority queues because they leave the CPU before exhausting the quantum.
|
||||
- Batch processes (CPU Bound) progressively migrate to lower-priority queues where they receive larger quantums.
|
||||
- The periodic boost prevents starvation: even processes that fell to lower queues eventually return to the top.
|
||||
|
||||
#### Example with 3 queues (quantums: 2, 4, 8)
|
||||
|
||||
```
|
||||
Process A (CPU Bound, burst=12):
|
||||
Queue 0 → uses 2 ticks, demoted → Queue 1
|
||||
Queue 1 → uses 4 ticks, demoted → Queue 2
|
||||
Queue 2 → uses remaining 6 ticks (quantum=8, not exhausted)
|
||||
|
||||
Process B (I/O Bound, burst=1 CPU + I/O + burst=1 CPU):
|
||||
Queue 0 → uses 1 tick → goes to I/O → returns to Queue 0
|
||||
→ always stays in the highest-priority queue
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
| Parameter | Default | Description |
|
||||
|-----------|---------|-------------|
|
||||
| Number of queues | 3 | Number of priority queues |
|
||||
| Quantum per queue | [2, 4, 8] | Time slice for each queue |
|
||||
| Boost interval | 20 ticks | Every N ticks, all processes move up to queue 0 |
|
||||
|
||||
---
|
||||
|
||||
## Thread Models
|
||||
|
||||
PSS supports **thread** simulation within processes, implementing the three classical models described in Operating Systems textbooks.
|
||||
|
||||
### General Concepts
|
||||
|
||||
- A process can have **N user threads**, each with its own burst sequence (CPU and I/O).
|
||||
- The scheduling policy among threads within the same process is configurable: **FCFS**, **Round Robin**, or **Priority**.
|
||||
- The thread model determines how user threads map to kernel threads.
|
||||
|
||||
### MANY_TO_ONE (N:1)
|
||||
|
||||
**N user threads → 1 kernel thread**
|
||||
|
||||
- Only one thread can use the CPU at a time within the process.
|
||||
- If any thread initiates I/O, **the entire process blocks** (the kernel thread is stuck).
|
||||
- No real parallelism; very simple to implement.
|
||||
- Simulated by the `many_to_one` presets.
|
||||
|
||||
### ONE_TO_ONE (1:1)
|
||||
|
||||
**Each user thread → 1 dedicated kernel thread**
|
||||
|
||||
- Threads block **independently**: if Thread A does I/O, Threads B and C remain in the Ready queue.
|
||||
- The process only terminates when **all** threads have terminated.
|
||||
- The process blocks only when all threads are simultaneously in I/O.
|
||||
- Simulated by the `one_to_one` presets.
|
||||
|
||||
### MANY_TO_MANY (N:M)
|
||||
|
||||
**N user threads → M kernel threads (M ≤ N)**
|
||||
|
||||
- The number of kernel threads (`kernelThreadCount`) is configurable.
|
||||
- If all M kernel slots are occupied, additional user threads wait in the **kernel wait queue** (`KernelWait`).
|
||||
- Combines flexibility with resource control: more active threads than N:1 but less overhead than 1:1.
|
||||
- Simulated by the `many_to_many` presets.
|
||||
|
||||
### Intra-Process Policy
|
||||
|
||||
Defines how the scheduler selects the next thread when multiple threads are Ready within the same process:
|
||||
|
||||
| Policy | Behavior |
|
||||
|--------|----------|
|
||||
| **FCFS** | The oldest thread in the Ready queue is selected |
|
||||
| **Round Robin (RR)** | Each thread receives `threadQuantum` ticks; when exhausted, it goes to the end of the queue |
|
||||
| **Priority** | The highest-priority thread is selected; immediate preemption if a higher-priority thread becomes ready |
|
||||
|
||||
### Gantt Chart with Threads
|
||||
|
||||
When a process has threads, the Gantt chart displays **sub-rows** below the process row, one per thread, with colors derived from the process color (40° hue shift per thread). The state of each thread (New, Ready, Running, Waiting, Terminated) is colored using the same CSS variables as process states.
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- Silberschatz, A., Galvin, P. B., & Gagne, G., *Operating System Concepts*, 10th edition.
|
||||
|
||||
Reference in new issue
Block a user