Skip to content

Latest commit

 

History

18 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Adaptive CPU Scheduler Simulator (C++)

A multithreaded C++ simulation of a single-core CPU scheduler that combines:

  • dynamic time slicing,
  • shortest-remaining-time selection,
  • and anti-starvation fairness.

This project is designed as a compact systems-programming artifact you can showcase on a resume to demonstrate:

  • OS scheduling fundamentals,
  • thread synchronization with mutexes and condition variables,
  • deterministic event logging,
  • and performance-oriented design tradeoffs.

Why this project is useful

Real systems software depends on scheduling decisions that balance throughput, responsiveness, and fairness. This simulator demonstrates those tradeoffs in a way that is easy to inspect and modify.

Skills this showcases

  • Operating Systems concepts: process arrival, burst/remaining time, waiting time, starvation avoidance.
  • Concurrent programming in C++: std::thread, std::mutex, std::condition_variable, shared-state coordination.
  • Algorithmic decision logic: dynamic quantum and tie-breaking under contention.
  • Engineering communication: structured logs and reproducible input/output files.

Practical relevance

  • Useful as a teaching/learning simulator for scheduling strategies.
  • Useful as a base project for experimenting with alternative policies (e.g., fixed RR, FCFS, aging, MLFQ).
  • Useful portfolio piece for internships and entry-level systems/software roles.

Core scheduling model

Inputs

The simulator reads processes from input.txt. Each line is:

<arrival_time> <burst_time>

Example:

0 10
2 5
4 8

Execution policy

At each scheduling cycle:

  1. Build the set of ready processes (arrived and not finished).

  2. Prioritize processes that have never run before (fairness guard).

  3. Within the selected candidate set, choose by:

    • shortest remaining time,
    • then earlier arrival time,
    • then smaller process ID.
  4. Compute quantum as:

    ceil(0.10 * remaining_time), minimum 1.

  5. Run selected process for min(quantum, remaining_time).

Waiting time

After completion, waiting time is computed using the standard formula:

waiting_time = finish_time - arrival_time - burst_time


Architecture

  • One scheduler thread decides who runs next.
  • One thread per process simulates process execution.
  • Shared state is protected by a mutex.
  • Two condition variables coordinate handoff:
    • scheduler → process wake-up,
    • process → scheduler completion notification.

This enforces a strict single-CPU simulation where only one process executes at a time.

Visual walkthrough

1) Thread-level architecture

Scheduler architecture diagram

The scheduler thread dispatches exactly one process at a time, while all threads synchronize through a mutex + condition-variable handshake.

2) Timeline behavior ("round robin with a twist")

Scheduling timeline diagram

This visualization highlights the hybrid policy:

  • cyclic CPU handoff behavior,
  • fairness boost for ready processes that have never run,
  • shortest-remaining-time choice inside each candidate group,
  • dynamic quantum (10% of remaining time, minimum 1).

If images do not render in your Git host preview, open them directly:

3) Mermaid diagram (text-rendered fallback)

flowchart TD
    S[Scheduler Thread] -->|cv_process notify| P1[Process Threads]
    P1 -->|cv_scheduler notify| S
    S --> M[(Shared State + Mutex)]
    P1 --> M
Loading
flowchart LR
    A[Ready Queue] --> B{Any unstarted ready process?}
    B -- Yes --> C[Pick shortest remaining among unstarted]
    B -- No --> D[Pick shortest remaining among started]
    C --> E["Quantum = ceil(0.10 * remaining), min 1"]
    D --> E
    E --> F[Run selected process for one slice]
    F --> A
Loading

Build and run

Requirements

  • C++ compiler with C++11+ thread support (e.g., g++)
  • POSIX-like shell environment

Commands

g++ main.cpp -pthread -o scheduler
./scheduler

The program expects input.txt in the same directory.

Output

Execution logs and final waiting times are written to:

  • terminal output
  • output.txt

Example output events

  • Time X, Process N, Started
  • Time X, Process N, Resumed
  • Time X, Process N, Paused
  • Time X, Process N, Finished
  • Final waiting times per process

Design insights (from implementation report)

During development and validation, a few key insights emerged:

  • The hybrid policy improves completion behavior for short jobs compared to pure round robin.
  • Fairness is guaranteed by prioritizing not-yet-started ready processes, reducing starvation risk.
  • Correct single-CPU simulation required strict synchronization between scheduler and worker threads.
  • The approach is intentionally more complex than fixed-quantum RR, but gives better control over fairness/efficiency tradeoffs.

Suggested roadmap

  • Add metrics summary (average waiting/turnaround/response time).
  • Add policy plug-ins to compare multiple schedulers in one run.
  • Add CLI flags for quantum strategy and logging verbosity.
  • Add automated tests and sample workloads for regression checks.

Project structure

.
├── main.cpp
├── input.txt
├── output.txt
├── README.md
└── docs/
    ├── ARCHITECTURE.md
    └── assets/
        ├── scheduler-architecture.svg
        └── scheduling-timeline.svg
    └── ARCHITECTURE.md

License

Use this project as a personal/portfolio learning artifact. If you plan to publish publicly, consider adding an explicit open-source license (e.g., MIT).

About

Operating Systems in C++

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages