Skip to main content

Implementing the Producer-Consumer Algorithm in C++

In this post, we implement a simulation of the Producer-Consumer Problem in C++ using a circular bounded buffer. This is one of the most classic synchronization problems in operating systems, modeling the coordination between a process that generates data (producer) and a process that consumes data (consumer) through a shared buffer of fixed capacity. What is the Producer-Consumer Problem? The Producer-Consumer problem (also called the Bounded Buffer problem) defines these rules: The producer generates items and places them into the buffer — but only if space is available. If the buffer is full, the producer must wait (sleep). The consumer retrieves and processes items from the buffer — but only if items exist. If the buffer is empty, the consumer must wait (sleep). Only one entity should access the buffer at a time (mutual exclusion). This simulation runs 20 steps. At each step, a random number determines whether the producer or consumer acts. A circular buffer is used so the array can be reused efficiently without shifting elements.

Implementation of Priority Scheduling Algorithm in C++

In this post, we implement the Priority Scheduling CPU scheduling algorithm in C++. Each process is assigned a priority number, and the process with the highest priority is scheduled first. This algorithm is used in real-time and embedded systems where certain tasks are more urgent than others and must preempt routine work. What is Priority Scheduling? In this implementation, a higher priority number means higher urgency (e.g., priority 5 executes before priority 1). The algorithm is non-preemptive — once a process starts, it runs to completion. All processes are assumed to arrive at time 0. The algorithm works by sorting processes in descending order of priority and then computing scheduling metrics in that order: Waiting Time (WT): WT[i] = WT[i-1] + BurstTime[i-1] (since all arrive at time 0) Turnaround Time (TT): TT[i] = WT[i] + BurstTime[i] The main concern with priority scheduling is starvation — low-priority processes may never get the CPU. The solution is aging: gradually increasing a process’s priority the longer it waits.

Implementation of LRU Page Replacement Algorithm in C++

In this post, we implement the LRU (Least Recently Used) Page Replacement Algorithm in C++. When a page fault occurs and all frames are occupied, LRU evicts the page that has not been used for the longest time. Unlike FIFO which only tracks load order, LRU tracks usage history, making it significantly more effective in practice. What is LRU Page Replacement? LRU exploits the principle of temporal locality — recently used pages are likely to be used again soon. By evicting the page that hasn’t been touched for the longest time, LRU keeps the most actively used pages in memory. Page Hit — Referenced page is already in a frame (its last-used time is implicitly updated). Page Fault — Referenced page is not in memory. On a fault with full frames, the frame whose page was accessed least recently is selected for replacement. LRU identification — For each frame, scan the page history backwards from the current reference to find the most recent access of that frame’s page. The frame with the oldest last-access is the LRU victim. LRU does not suffer from Bélady’s Anomaly (unlike FIFO) and closely approximates the optimal (OPT) algorithm.

Implementing First Fit Algorithm in C++

In this post, we implement the First Fit Memory Allocation Algorithm in C++. When a new process (job) needs memory, First Fit scans the list of available memory blocks from the beginning and allocates the first block that is large enough to hold the job. It is the fastest of the three classic memory placement strategies — First Fit, Best Fit, and Worst Fit. What is First Fit Memory Allocation? Memory is divided into fixed-size blocks (also called partitions). Each block can hold at most one job at a time. When a job arrives: Scan memory blocks from block 1 onwards. Allocate the first free block whose size ≥ job size. Mark that block as occupied. Stop scanning (no need to look at remaining blocks). If no block fits, the job remains unallocated. The leftover space inside an allocated block (block size − job size) is called internal fragmentation. Over time, First Fit tends to leave small, unusable gaps in the lower portion of memory (external fragmentation).

Symfony 2: Creating a Bundle

Note: This post covers Symfony 2, which reached end of life in November 2018. The bundle generator (app/console generate:bundle) and AppKernel.php/registerBundles() workflow described here were removed in Symfony 4. For modern Symfony, see the official Symfony documentation. This post is preserved for historical reference. As discussed in this and this post, Symfony 2 is a web application framework. In Symfony 2 we organize our code in form of bundles. You can think bundle as collection of all code. Say if your app has a front-end, a back-end and an API then you can create three different bundles one for your front-end, one for your back-end and one for API. This will allow your to manage code efficiently. Symfony 2 is flexible and it allows you to have as many as bundles you want in your app. Let's understand this bundle system in detail by creating a bundle.

Implementing FCFS Scheduling Algorithm in C++

In this post, we implement the First Come First Serve (FCFS) CPU scheduling algorithm in C++. FCFS is the simplest scheduling strategy — the process that arrives first in the ready queue gets the CPU first. It is non-preemptive: once a process starts, it runs to completion without interruption. What is FCFS Scheduling? FCFS works exactly like a real-world queue: the first person in line is served first. The CPU picks the first process from the ready queue, runs it completely, then picks the next. No reordering happens — processes execute strictly in arrival order. The key metrics computed are: Waiting Time (WT) — Time a process spends waiting before the CPU is allocated to it. Formula: WT[i] = WT[i-1] + BurstTime[i-1] - (ArrivalTime[i] - ArrivalTime[i-1]) Turnaround Time (TT) — Total time from arrival to completion. Formula: TT[i] = WT[i] + BurstTime[i] A well-known drawback is the Convoy Effect — a long process can block many short ones behind it, inflating average waiting time.

Implementing Best Fit Algorithm in C++

In this post, we implement the Best Fit Memory Allocation Algorithm in C++. Unlike First Fit which takes the first block large enough for a job, Best Fit searches through all free blocks and selects the one whose size is closest to the job’s size — the tightest possible fit. The goal is to minimize wasted space inside allocated blocks (internal fragmentation) and preserve large blocks for future large jobs. What is Best Fit Memory Allocation? Best Fit works by sorting memory blocks in ascending order of size before allocation. By scanning the sorted list and taking the first block that fits, we automatically pick the smallest block that still accommodates the job. This is the defining characteristic of Best Fit: among all free blocks that are large enough, it selects the one with the smallest size, leaving the rest of the available space in larger blocks undisturbed for future use. Sort all memory blocks in ascending order of size. For each job, scan the sorted blocks and allocate the first free block whose size ≥ job size. Because blocks are sorted by ascending size, the first fitting block is automatically the smallest one that fits — i.e., the best fit. After all allocations are done, re-sort blocks by their original block number so the output table is readable. Compared to First Fit, Best Fit produces less internal fragmentation per allocation because it picks the tightest available block. However, it tends to leave behind many tiny leftover fragments that are too small to be reused — a form of external fragmentation. It is also slower than First Fit because it must consider all blocks before allocating.

Implementing Midpoint Circle Algorithm in C++

The Midpoint Circle Algorithm (MPC) is an efficient way to draw a circle using raster graphics. It is an improved version of Bresenham’s circle drawing algorithm and avoids using floating-point calculations, making it faster for computer graphics. This blog post explains a C++ program that implements the Midpoint Circle Algorithm using the graphics.h library.

Implementing Midpoint Ellipse Algorithm in C++

Ellipses are fundamental shapes in computer graphics, widely used in various applications such as image processing, animation, and CAD systems. In this blog post, we'll explore how to draw an ellipse using the Midpoint Ellipse Algorithm in C++ with graphics.h. Introduction to Midpoint Ellipse Algorithm The Midpoint Ellipse Algorithm is an efficient way to generate an ellipse using only integer operations. It is based on the midpoint method, which determines the next pixel position by evaluating a decision parameter. This algorithm divides the ellipse into two regions: Region 1: The slope of the curve is less than 1. Region 2: The slope of the curve is greater than 1. Each region is processed separately to ensure a smooth curve. C++ Code Implementation Below is the C++ program that implements the Midpoint Ellipse Algorithm. It uses the graphics.h library, which is part of the Turbo C++ environment.

Implementing Flood Fill Algorithm in C++

The Flood Fill Algorithm fills a connected region on a raster display by replacing all pixels that share the same original colour as the seed pixel with a new fill colour. Unlike the Boundary Fill Algorithm — which stops at a specific boundary colour — Flood Fill continues spreading in all directions as long as the pixel matches the original seed colour. It is the underlying technique used by the “Paint Bucket” tool in image editors.