A Deep Dive into Operating Systems
Madhav Ganesan
Posted on December 1, 2024
An operating system is software that manages a computer’s hardware. A computer system can be divided into four components: the hardware, the operating system, the application programs, and a user.
The hardware — the central processing unit (CPU), the memory, and the input/output (I/O) devices—provides the basic computing resources for the system
The operating system controls the hardware and coordinates its use among the various application programs for the various users.
The operating system (OS) acts as the manager of the computer's resources
Since bare hardware alone is not particularly easy to use, application programs are developed. These programs require certain common operations, such as those controlling the I/O devices.
The common functions of controlling and allocating resources are then brought together into one piece of software: the operating system.
Kernel View
It is the core component of an operating system. It has complete control over everything that occurs in the system. It manages hardware, system resources, and the execution of programs.
Monolithic Kernel
It is a single large process running entirely in a single address space. It provides high performance due to direct communication between components. They are simpler to design.
Examples: Linux, early versions of UNIX.
Microkernel
It minimizes the amount of code running in kernel mode by moving most of the OS services, such as device drivers and file systems, into user space. The kernel itself only handles basic tasks like inter-process communication (IPC) and low-level hardware interaction.
Greater modularity and easier maintenance since services are separated from the kernel.
Examples: MINIX, QNX, L4
Hybrid Kernel
It combines aspects of both monolithic and microkernel architectures. It aims to provide the performance of a monolithic kernel while maintaining some modularity by allowing certain services to run in user space.
Examples: Windows NT, macOS
Responsibilites
Process Management
Memory Management
Device Management
File System Management
System Calls:
User View
Moore's law
In the 1960s, Gordon Moore, co-founder of Intel, predicted that the number of transistors on an integrated circuit would double approximately every 18 months, leading to an exponential increase in computing power and a decrease in cost per transistor.
Operating System Components
Kernel:
System Programs:
System programs are utilities and tools that assist users in interacting with the OS and managing system resources but are not part of the kernel.
Ex. CLI, file management tools (e.g., ls, cp), and system configuration tools.
Application Programs:
Application programs are designed for end-users to perform specific tasks
Ex. Microsoft word, Google chrome
Computer-System Organization
CPU (Central Processing Unit):
It executes instructions and processes data. It is the core component responsible for computation and task management.
WMIC (Windows Management Instrumentation Command-line) is a command-line utility in Windows that provides a way to query and manage system information and configuration data.
wmic cpu get name, maxclockspeed, numberofcores,numberoflogicalprocessors,threadcount,systemname
Device Controllers:
It is a hardware component that manages and controls the operation of a specific type of peripheral device (e.g., disk drives, USB ports, graphics cards). It acts as an intermediary between the CPU and the peripheral device.
wmic path Win32_PnPEntity get Name, DeviceID
*Device Drivers: *
It is a software component that provides the operating system and applications with a way to interact with a hardware device through a standardized interface. It translates general commands from the OS into device-specific operations understood by the device controller.
driverquery //list all the installed drivers
wmic driver get name, description
*Memory Controller: *
It manages access to the system's memory (RAM) and ensures that both the CPU and various device controllers can access memory in an orderly and synchronized manner.
Bus
It is a communication system that connects various components within a computer, including the CPU, memory, and device controllers.
Interrupts
These are signals sent to the CPU to alert it to events that require immediate attention.
Working:
1) When a device needs attention, the device controller sends an interrupt signal to the CPU, typically via the system bus.
2) Upon receiving an interrupt, the CPU stops its current task and transfers execution to a fixed location in memory where the interrupt service routine (ISR) is located.
3) The ISR executes and handles the event that caused the interrupt. After completing the ISR, the CPU restores the previous state and resumes the interrupted computation.
Interrupt Management:
A table of pointers (interrupt vector) is used to manage interrupts. This table stores the addresses of various ISR routines. Each entry in the table corresponds to an interrupt request number.
Storage
Memory Types
Main Memory (RAM): (Volatile)
It is used to store programs and data that are actively/ directly being used by the CPU.
Bootstrap Program:
It is the initial program executed when a computer is powered on, which loads the operating system into RAM. It is stored in non-volatile memory since RAM is volatile.
Storage Hierarchy
Primary Storage/ Physical memory (Volatile):
Registers
Cache Memory
Main Memory (RAM)
Secondary Storage (Non-Volatile):
Hard Disk Drives (HDDs) (Mechanical storage)
Solid-State Drives (SSDs) (Electrical storage)
Optical Discs and Magnetic Tapes
Cache Memory
It is integrated into or close to the CPU. It is a small, high-speed storage area located within the CPU or between the CPU and main memory. It stores copies of frequently accessed data from main memory to reduce latency and improve performance. It typically includes multiple levels (L1, L2, and sometimes L3), with each level being larger but slower than the previous one.
Registers
It is a small, fast storage location within a CPU used to hold data temporarily during processing. They can be accessed within a single clock cycle. Registers built into each CPU core are typically designed for extremely fast access, often within a single CPU clock cycle.
Types of registers
General-Purpose Registers (GPRs):
These registers are used for a variety of operations and can hold data, addresses, or intermediate results.
Special-Purpose Registers:
Program Counter (PC): Holds the address of the next instruction to be executed. It helps the CPU keep track of instruction flow.
Instruction Register (IR): Contains the current instruction being executed.
Stack Pointer (SP): Points to the current top of the stack, which is used for managing function calls and local variables.
Base Pointer (BP): Used to point to the base of the stack frame, which helps in accessing function parameters and local variables.
Status Register / Flags Register: Contains flags that provide information about the status of the CPU (e.g., carry, zero, overflow flags).
Index Registers:
Used to store indexes for array and table accesses. They are often used in addressing modes for effective address calculation.
Random Access Memory (RAM)
It is a type of volatile memory used by the CPU to store data that is actively being used or processed, providing fast access to this data.
Types of RAM:
DRAM (Dynamic RAM)
It stores each bit of data in a separate capacitor within an integrated circuit. Because capacitors leak charge, the stored data must be refreshed periodically. It is less expensive and slower than SRAM.
SRAM (Static RAM)
It uses flip-flops to store each bit of data, which does not need to be refreshed like DRAM.
Ex. Cache memory
ROM (Read-Only Memory)
It is non-volatile memory used to store firmware and system software that does not need to be changed frequently.
Types of ROM:
PROM (Programmable ROM)
It can be programmed once after manufacturing, and it is permanently stored. The programming process is done using special equipment.
EPROM (Erasable Programmable ROM)
It be erased by exposing it to ultraviolet (UV) light and then reprogrammed.
Ex. Used in systems where firmware updates are occasionally necessary.
EEPROM (Electrically Erasable Programmable ROM)
It can be erased and reprogrammed using electrical charge, without needing UV light.
Ex. Used for storing small amounts of data that may need to be updated periodically, such as BIOS settings or configuration data.
Hard Disk Drives (HDDs)
It is a type of non-volatile storage, that is slower than SSD due to mechanical moving parts and offers higher storage capacity.
Ex. Commonly used for storing large amounts of data, including operating systems, applications, and user files
Solid State Drives (SSDs)
It is a type of non-volatile storage, which is faster than HDD and offers lower storage capacities
Ex. It is used for data storage where speed is crucial, such as for high-performance computing tasks, gaming, and tasks requiring high-speed data access.
wmic diskdrive get model,serialNumber,size,mediaType
Thread
A thread is the smallest unit of execution within a process. It is a lightweight, independently executing sequence of instructions that can run concurrently with other threads within the same process.
Thread Components:
Program Counter: Keeps track of the next instruction to be executed.
Registers: Hold intermediate data and addresses during execution.
Stack: Manages function calls, local variables, and return addresses specific to the thread.
Thread ID: Uniquely identifies the thread within the process.
Terms
Multiprogramming – Multiprogramming is known as keeping multiple programs in the main memory at the same time ready for execution.
Multiprocessing – A computer using more than one CPU at a time.
Multitasking – Multitasking is nothing but multiprogramming with a Round-robin scheduling algorithm.
Multithreading is an extension of multitasking.
Virtualization
It is a technology that allows multiple virtual instances, such as virtual machines (VMs), to run on a single physical machine.
Types of Virtualization
Full Virtualization:
It creates complete virtual environment that is isolated from the host system. Each virtual machine (VM) appears to have its own complete operating system and hardware. The guest operating system is not aware that it is running in a virtualized environment.
Paravirtualization:
Guest operating system to be aware of the virtual environment. This allows the guest OS to communicate directly with the hypervisor, bypassing some of the overhead associated with full virtualization.
Process
Each process operates within its allocated memory space and is protected from other processes and the operating system, two key mechanisms are employed: base and limit registers.
Base Register
It holds the smallest legal physical memory address that a process can access.
Limit Register
It specifies the size of the memory range that the process can access.
Logical Address Space
The address generated by the CPU during a program's execution. This is the address that the program uses and is considered the virtual address
Physical Address Space
The actual address in physical memory (RAM) where the data or instructions are stored. This is the address seen by the memory unit.
Memory Management Unit (MMU): Hardware component responsible for translating logical (virtual) addresses into physical addresses.
Zombie process
It is a process that has completed execution but still has an entry in the process table. These processes are often harmless but can accumulate and waste system resources.
CPU Scheduling Algorithms
First-Come, First-Served (FCFS)
The processes are executed in the order they arrive, with each process running to completion without preemption.
Advantages:
Disadvantages:
Processes may experience poor average waiting times and the Convoy Effect if a long process delays shorter ones. Additionally, in busy systems, processes may suffer starvation if continually arriving processes keep the CPU occupied with lengthy tasks.
Shortest Job Next (SJN) / Shortest Job First (SJF)
It schedules processes with the shortest burst time next. It includes two variations: Non-Preemptive, where a process runs to completion once started, and Preemptive (Shortest Remaining Time First - SRTF), where the CPU can be preempted by a new process with a shorter remaining time.
Disadvantages:
Requires knowing or predicting burst times, which is often impractical, and can lead to starvation of longer processes if shorter processes continuously arrive.
Round Robin (RR)
It assigns each process a fixed time slice or quantum for execution. If a process doesn't complete within its time slice, it is preempted and moved to the end of the queue, with the CPU then given to the next process in line.
Advantages:
No Starvation
Disadvantages:
Frequent context switching can reduce performance if the time slice is too short, and if the time slice is too long, overall performance may degrade.
Priority Scheduling
It allocates the CPU to the process with the highest priority. Priorities can be either static or dynamic, and the scheduling can be preemptive, where higher priority processes can preempt lower ones, or non-preemptive, where a process runs to completion once started.
Disadvantages:
Lower priority processes experiences starvation
Multi-Level Queue (MLQ)
It divides processes into different queues based on criteria like priority or type, with each queue using its own scheduling algorithm. The CPU is allocated according to the scheduling policy of the respective queue.
Multi-Level Feedback Queue (MLFQ)
It dynamically adjusts process queues based on behavior and CPU usage, moving processes between queues to optimize performance. For instance, CPU-intensive processes may be demoted to lower-priority queues, while less demanding ones can be promoted.
Convoy Effect
It is an effect in which shorter processes are stuck waiting behind a long process that is currently executing. Because the long process occupies the CPU for an extended period, all the shorter processes queued behind it experience increased waiting times.
Context Switching
It involves saving the state of a currently running process and loading the state of another process, allowing the CPU to manage multiple processes efficiently and enable multitasking. During a context switch, the state of the currently running process is saved into a process control block (PCB) or task control block (TCB).
Critical Section
It is a section of code that accesses a shared resource and must not be executed by more than one thread or process at a time to prevent data inconsistency or corruption. Synchronization mechanisms, such as mutexes, semaphores, or locks, are used to manage access to the critical section and avoid issues like race conditions.
Mutex (mutual exclusion)
It is a synchronization primitive used to control access to a shared resource in concurrent programming. It ensures that only one thread or process can access the critical section of code or shared resource at a time.
Lock: A thread or process must acquire the mutex by locking it before entering the critical section. If the mutex is already locked by another thread, the requesting thread will be blocked until the mutex is available.
Unlock: After completing its operations on the shared resource, the thread unlocks the mutex, allowing other threads to acquire it and access the critical section.
Semaphore
It is a variable/abstract data type/synchronization tool that provides a way for processes or threads to signal each other about the availability of resources or the progress of tasks.
Types of Semaphores
1) Binary Semaphore (Mutex):
It can be either 0 or 1. It ensures mutual exclusion meaning that only one process or thread can access a critical section of code or resource at a time.
Operations are wait() attempts to acquire the semaphore and signal() releases the semaphore by setting its value back to 1, potentially unblocking a waiting process or thread.
2) Counting Semaphore:
It can be any non-negative integer. It manages access to a resource pool where multiple instances are available. For example, if a resource pool has 5 identical resources, the semaphore can be initialized to 5.
wait() - When a process or thread needs access to a resource, it performs this operation on the semaphore.
signal() - When a process or thread is finished using a resource, it performs this operation on the semaphore.
Classic Problems of Synchronization
The Dining Philosophers Problem
Five philosophers are seated around a table, each with a fork to their left and right. To eat, a philosopher needs both forks. The challenge is to design a protocol that prevents deadlock (where no philosopher can eat because they're all waiting for the other fork) and ensures that each philosopher eventually gets a chance to eat.
semaphore waiter = 1;
semaphore forks[5] = {1, 1, 1, 1, 1}; // Each fork is available
procedure philosopher(i):
while true:
think();
wait(waiter); // Request permission to pick up forks
wait(forks[i]); // Try to acquire left fork
wait(forks[(i+1) % 5]); // Try to acquire right fork
signal(waiter); // Release the waiter
eat();
signal(forks[i]); // Release left fork
signal(forks[(i+1) % 5]); // Release right fork
Each philosopher must request permission from the waiter before picking up both forks. The waiter only allows fork acquisition if both forks are available. Philosophers release the forks and signal the waiter when done eating, ensuring that only one philosopher can pick up forks at a time and avoiding deadlock. This approach prevents indefinite waiting and ensures fair access to the shared resources.
The Producer-Consumer Problem
The Readers-Writers Problem
The Sleeping Barber Problem
Deadlock
It occurs when a set of threads or processes are in a state where each thread is waiting for a resource held by another thread, causing a situation where none of them can proceed.
Necessary Conditions for Deadlock
Mutual Exclusion: At least one resource must be held in a non-sharable mode, meaning only one thread can use the resource at a time. If another thread requests the same resource, it must wait until the resource is released.
Hold and Wait: A thread must be holding at least one resource while waiting to acquire additional resources held by other threads.
No Preemption: Resources cannot be forcibly taken from a thread; they can only be released voluntarily by the thread holding them.
Circular Wait: There must be a circular chain of threads where each thread is waiting for a resource held by the next thread in the chain.
Resource Allocation graph
Deadlock Prevention
Mutual Exclusion: Cannot be avoided for non-sharable resources.
Hold and Wait: Can be managed by requesting all resources at once or releasing all held resources before requesting new ones.
No Preemption: Can be addressed by allowing resource preemption, though this is complex for certain resources.
Circular Wait: Can be prevented by enforcing a resource ordering or hierarchy.
Deadlock Avoidance
Banker's Algorithm
It ensures that the system remains in a safe state and avoids deadlocks by evaluating resource allocation requests carefully.
Deadlock Detection
Priority inversion
It is a problem in real-time and multitasking systems where a lower-priority task holds a resource needed by a higher-priority task, causing the higher-priority task to be indirectly preempted by even lower-priority tasks.
Priority Inheritance
It is a technique used to mitigate priority inversion by temporarily raising the priority of a lower-priority task holding a resource needed by a higher-priority task. This ensures that the higher-priority task is not delayed by other tasks and helps maintain system responsiveness.
Memory leaks
It occurs when a program allocates memory but fails to release it after use, causing the memory to remain occupied and unavailable for other processes. This can lead to reduced system performance and eventual system crashes as available memory becomes exhausted.
Memory Management
Contiguous Memory Allocation
It is a method of memory management where each process occupies a single contiguous block of memory. This means that all the memory required by a process is allocated in a single, continuous segment of physical memory.
Memory Management Stratergies
Compaction
It is the process of rearranging the contents of memory to consolidate free memory into a single contiguous block. This helps alleviate external fragmentation by creating larger blocks of free memory that can accommodate new processes or data.
Paging
It is a memory management technique that divides the process's address space into fixed-size blocks called pages, and physical memory into blocks of the same size called frames. This allows for non-contiguous memory allocation, meaning that processes do not need to be loaded into a contiguous block of physical memory.
Example:
Page Reference String: 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3
Number of Frames: 3
Page Replacement Algorithm
First-In-First-Out (FIFO)
Pages are added in the order they are referenced, and when a page fault occurs, the oldest page is removed (no matter it is more or less recently accessed)
Least Recently Used (LRU)
The least recently used page is removed on a page fault.
Optimal Page Replacement
Replace the page that won’t be used for the longest time in the future.
Clock (Second Chance)
Pages are organized in a circular queue, and each page has a reference bit. If a page fault occurs, it checks the reference bit; if it’s 1, it gives the page a second chance (sets bit to 0) and moves to the next.
Least Frequently Used (LFU)
Replace the page with the lowest access count.
Problems
FIFO: Belady's Anomaly
LRU: Complex bookkeeping
Optimal Page Replacement: Impractical without future knowledge
Clock (Second Chance): Inefficiency with poorly tuned reference bit strategy
LFU: Ineffective with changing access patterns
Demand Paging
It is a memory management technique where pages are only loaded into physical memory when they are actually needed. This means that a page is not loaded into memory until the CPU tries to access it, causing a page fault.
Segmentation
It divides memory into segments based on the logical divisions of a process, such as code, data, and stack. Each segment can grow independently and be allocated in different areas of physical memory.
Fragmentation (Problem)
It refers to the inefficient use of memory that can occur as a result of allocating and freeing memory in a system. It involves the breakdown of memory into smaller, non-contiguous blocks over time.
Types of Fragmentation
Internal Fragmentation
It occurs when a process is allocated more memory than it actually needs, leaving unused space within the allocated partition
External Fragmentation
It refers to the condition where free memory is split into small, non-contiguous blocks over time, making it difficult to allocate a large contiguous block of memory even though the total free memory might be sufficient.
This happens as processes are loaded and removed from memory, creating holes of various sizes scattered throughout memory. Over time, these holes can become too small to satisfy new memory requests, even though the total free memory may be adequate.
Thrashing
It occurs when the operating system spends the majority of its time swapping pages in and out of physical memory rather than executing processes. This excessive paging activity leads to very high disk I/O operations and poor CPU utilization.
Aging
It is a technique used in operating systems, particularly in the context of memory management and page replacement algorithms, to prevent processes from being indefinitely delayed or starved. Aging helps to ensure that all processes eventually get a chance to execute, even if they have been waiting for a long time.
Direct Memory Access (DMA)
It is a technology that enhances system efficiency by allowing peripherals to access the main memory directly, bypassing the CPU. This is particularly useful for large data transfers, as it reduces the CPU's workload and speeds up the process.
Thermal throttling
It is a mechanism used in computers and electronic devices to prevent overheating and ensure stable operation when the system's temperature exceeds a certain threshold. This process involves automatically reducing the performance of the CPU, GPU, or other components to lower the temperature and avoid potential damage.
RAID (Redundant Array of Independent Disks)
It is a technology used to enhance the performance and reliability of data storage systems by combining multiple physical hard drives into a single logical unit.
RAID 0 (Striping):
It splits data evenly across multiple disks without redundancy.
RAID 1 (Mirroring):
It duplicates the same data on two or more disks.
RAID 5 (Striping with Parity):
It distributes data and parity (error-checking information) across all disks.
RAID 6 (Striping with Double Parity)
It similar to RAID 5 but with an additional layer of parity, allowing for two disks to fail without data loss
Virtual Memory
It allows processes to be larger than physical memory. Programs do not need to fit entirely into RAM to execute, as parts of the program can be loaded and unloaded as needed.
Translation Lookaside Buffer (TLB)
It is a specialized cache used in virtual memory systems to accelerate the translation of virtual addresses to physical addresses.
Stay Connected!
If you enjoyed this post, don’t forget to follow me on social media for more updates and insights:
Twitter: madhavganesan
Instagram: madhavganesan
LinkedIn: madhavganesan
Posted on December 1, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.