Operating SystemsOperating Systems

How a computer manages processes, memory, and files — with the classic exam problems fully worked out.Computer কীভাবে process, memory আর file manage করে — সব classic exam problem step-by-step solve করা আছে।

1. Processes and Threads1. Processes and Threads

An Operating System (OS) is the software that sits between your programs and the hardware. It does four big jobs: it manages the CPU (decides who runs), manages memory (decides who gets RAM), manages files and devices, and gives programs a safe way to talk to hardware through system calls.

A program is a passive file on disk (like a.out). A process is a program that is running. One program can create many processes. A process has: code (text section), data section (global variables), heap (dynamic memory), stack (function calls, local variables), and the current CPU register values.

Operating System (OS) হলো সেই software যা আপনার program আর hardware-এর মাঝখানে থাকে। এর চারটা বড় কাজ: CPU manage করা (কে চলবে ঠিক করা), memory manage করা (কে RAM পাবে), file আর device manage করা, আর system call-এর মাধ্যমে program-কে hardware-এর সাথে নিরাপদে কথা বলার সুযোগ দেওয়া।

Program হলো disk-এ রাখা একটা passive file (যেমন a.out)। Process হলো চলমান (running) program। একটা program থেকে অনেকগুলো process তৈরি হতে পারে। একটা process-এর থাকে: code (text section), data section (global variable), heap (dynamic memory), stack (function call, local variable), আর CPU register-এর বর্তমান মান।

Process Control Block (PCB)Process Control Block (PCB)

The OS keeps one PCB for each process. It is like the ID card + notebook of the process. It stores:

  • Process state — new, ready, running, waiting, or terminated.
  • Process ID (PID) — a unique number.
  • Program counter — address of the next instruction to run.
  • CPU registers — saved values of all registers.
  • CPU scheduling info — priority, pointers to scheduling queues.
  • Memory info — base/limit registers, page tables.
  • Accounting info — CPU time used, time limits.
  • I/O status — open files, devices in use.

OS প্রতিটা process-এর জন্য একটা করে PCB রাখে। এটা process-এর ID card + notebook-এর মতো। এতে থাকে:

  • Process state — new, ready, running, waiting, বা terminated।
  • Process ID (PID) — একটা unique number।
  • Program counter — পরের instruction-এর address।
  • CPU registers — সব register-এর save করা মান।
  • CPU scheduling info — priority, scheduling queue-এর pointer।
  • Memory info — base/limit register, page table।
  • Accounting info — কত CPU time ব্যবহার হয়েছে, time limit।
  • I/O status — খোলা file, ব্যবহার করা device।

Process StatesProcess States

A process moves through five states:

  • New — the process is being created.
  • Ready — it is loaded and waiting for the CPU.
  • Running — instructions are executing on the CPU.
  • Waiting (Blocked) — it is waiting for an event, like I/O to finish.
  • Terminated — it has finished.

একটা process পাঁচটা state-এর মধ্য দিয়ে যায়:

  • New — process তৈরি হচ্ছে।
  • Ready — load হয়ে গেছে, CPU-এর জন্য অপেক্ষা করছে।
  • Running — CPU-তে instruction চলছে।
  • Waiting (Blocked) — কোনো event-এর জন্য অপেক্ষা করছে, যেমন I/O শেষ হওয়া।
  • Terminated — কাজ শেষ।
new ready running terminated waiting admitted scheduler dispatch interrupt (preempt) exit I/O or event wait I/O or event done
Process state diagram: new → ready → running → terminated, with the waiting loop for I/O.Process state diagram: new → ready → running → terminated, আর I/O-এর জন্য waiting loop।
Note: A very common MCQ: "running → ready" happens because of an interrupt/time slice end (preemption). "running → waiting" happens because the process itself asks for I/O. A process never jumps from waiting directly to running — it must go through ready first.
Note: খুব common MCQ: "running → ready" হয় interrupt/time slice শেষ হলে (preemption)। "running → waiting" হয় process নিজে I/O চাইলে। Waiting থেকে সরাসরি running-এ যাওয়া যায় না — আগে ready-তে যেতে হয়।

Context SwitchContext Switch

When the CPU switches from process A to process B, the OS must save the state of A into A's PCB and load the state of B from B's PCB. This is a context switch. During the switch the CPU does no useful work, so it is pure overhead. Typical time: a few microseconds. More context switches = more wasted time.

CPU যখন process A থেকে process B-তে switch করে, তখন OS-কে A-এর state A-এর PCB-তে save করতে হয় আর B-এর state B-এর PCB থেকে load করতে হয়। এটাই context switch। Switch-এর সময় CPU কোনো কাজের কাজ করে না, তাই এটা পুরোটাই overhead। সাধারণত কয়েক microsecond লাগে। যত বেশি context switch, তত বেশি সময় নষ্ট।

Process vs ThreadProcess vs Thread

A thread is a lightweight unit of execution inside a process. Threads of the same process share the code, data, heap, and open files — but each thread has its own stack, program counter, and registers. Example: in a browser, one thread draws the page while another downloads images.

Thread হলো process-এর ভেতরের একটা lightweight execution unit। একই process-এর thread-গুলো code, data, heap আর open file share করে — কিন্তু প্রতিটা thread-এর নিজস্ব stack, program counter আর register থাকে। উদাহরণ: browser-এ একটা thread page আঁকে, আরেকটা image download করে।

Pointবিষয় Process Thread
WeightWeightHeavyweightHeavyweightLightweightLightweight
MemoryMemoryOwn address spaceনিজস্ব address spaceShares address space of the processProcess-এর address space share করে
Creation costCreation costSlow, expensiveধীর, ব্যয়বহুলFast, cheapদ্রুত, সস্তা
Context switchSlow (memory map changes)ধীর (memory map বদলায়)Fast (same address space)দ্রুত (একই address space)
CommunicationNeeds IPC (pipe, shared memory, message)IPC লাগে (pipe, shared memory, message)Just read/write shared variablesShared variable পড়া/লেখা যথেষ্ট
If one crashesএকটা crash করলেOthers surviveবাকিরা বেঁচে থাকেWhole process may dieপুরো process মরে যেতে পারে
Own itemsনিজস্ব জিনিসEverything (code, data, heap, stack, files)সব কিছু (code, data, heap, stack, files)Only stack, registers, program counterশুধু stack, register, program counter

User Threads vs Kernel ThreadsUser Threads vs Kernel Threads

  • User-level threads: managed by a library in user space. The kernel does not know about them. Creation and switching are very fast. Problem: if one thread makes a blocking system call, the whole process blocks.
  • Kernel-level threads: managed by the OS itself. Slower to create, but the kernel can schedule them on different CPU cores, and one blocked thread does not block the others.
  • Mapping models: many-to-one (many user threads on one kernel thread), one-to-one (Linux, Windows), many-to-many.
  • User-level thread: user space-এর একটা library manage করে। Kernel এদের কথা জানেই না। তৈরি আর switch খুব দ্রুত। সমস্যা: একটা thread blocking system call দিলে পুরো process block হয়ে যায়।
  • Kernel-level thread: OS নিজে manage করে। তৈরি করা ধীর, কিন্তু kernel এদের আলাদা আলাদা CPU core-এ চালাতে পারে, আর একটা block হলে বাকিরা চলতে পারে।
  • Mapping model: many-to-one (অনেক user thread এক kernel thread-এ), one-to-one (Linux, Windows), many-to-many

Multiprogramming vs Multitasking vs Multithreading (Real Exam!)Multiprogramming vs Multitasking vs Multithreading (Real Exam!)

These three words sound alike, but they mean different things. BUET asked to define and compare them (April 2017), so learn them as a set:

  • Multiprogramming: keep several jobs in memory at the same time. When the running job blocks (for example, it waits for I/O), the CPU switches to another job. The goal is throughput — the CPU is never idle. The switch happens only when a job blocks, not on a timer.
  • Multitasking (time-sharing): the CPU switches between tasks very fast using a timer (preemption), so every user or program feels the machine responds instantly. The goal is responsiveness. It is multiprogramming plus rapid preemptive switching.
  • Multithreading: many threads inside ONE process. All threads share the same address space (code, data, heap) but keep their own stack and registers. The goal is parallel work inside one program with cheap creation and cheap switching.

এই তিনটা শব্দ শুনতে একই রকম, কিন্তু মানে আলাদা। BUET এদের define আর compare করতে বলেছিল (April 2017), তাই একসাথে শিখে রাখুন:

  • Multiprogramming: একসাথে কয়েকটা job memory-তে রাখা হয়। চলমান job block হলে (যেমন I/O-এর অপেক্ষায়), CPU অন্য job-এ চলে যায়। লক্ষ্য throughput — CPU কখনো বসে থাকে না। Switch হয় শুধু job block হলে, timer-এ নয়।
  • Multitasking (time-sharing): CPU একটা timer দিয়ে খুব দ্রুত task বদলায় (preemption), ফলে প্রতিটা user বা program মনে করে machine সাথে সাথে সাড়া দিচ্ছে। লক্ষ্য responsiveness। এটা আসলে multiprogramming + দ্রুত preemptive switching।
  • Multithreading: একটা process-এর ভেতরে অনেক thread। সব thread একই address space (code, data, heap) share করে, কিন্তু নিজের stack আর register আলাদা রাখে। লক্ষ্য এক program-এর ভেতরে parallel কাজ — তৈরি আর switch দুটোই সস্তা।
Pointবিষয় Multiprogramming Multitasking Multithreading
Unit of workকাজের unit Whole jobs (processes) in memoryMemory-তে পুরো job (process) Tasks/processes of one or many usersএক বা অনেক user-এর task/process Threads inside ONE processএকটা process-এর ভেতরের thread
Main goalমূল লক্ষ্য Throughput (keep CPU busy)Throughput (CPU ব্যস্ত রাখা) Responsiveness (fast feel)Responsiveness (দ্রুত সাড়া) Parallelism inside one programএক program-এর ভেতরে parallelism
Switching triggerSwitch কখন হয় When the running job blocks (I/O wait)চলমান job block হলে (I/O wait) Timer interrupt — preemptive time sliceTimer interrupt — preemptive time slice Scheduler switches threads (cheap, same address space)Scheduler thread বদলায় (সস্তা, একই address space)
ExampleExample Old batch mainframe running jobs back to backপুরনো batch mainframe-এ পরপর job চলা Your PC running browser + music + editor "at once"আপনার PC-তে browser + গান + editor "একসাথে" চলা Browser: one thread draws, one downloadsBrowser: এক thread আঁকে, আরেকটা download করে
Real exam: BUET asked exactly this — "Define multitasking, multiprogramming and multithreading" — in April 2017. One-line memory trick: multiprogramming = many jobs in memory (switch on block); multitasking = fast timer switching (feel of parallel); multithreading = many threads in one process (shared address space).
Real exam: BUET ঠিক এটাই জিজ্ঞেস করেছিল — "Define multitasking, multiprogramming and multithreading" — April 2017-তে। এক লাইনে মনে রাখুন: multiprogramming = memory-তে অনেক job (block হলে switch); multitasking = timer দিয়ে দ্রুত switch (parallel-এর অনুভূতি); multithreading = এক process-এ অনেক thread (shared address space)।

fork() — creating a processfork() — process তৈরি করা

In UNIX/Linux, fork() creates a copy of the calling process. The copy is the child. fork() returns 0 to the child and the child's PID to the parent. Both continue running from the line right after fork().

UNIX/Linux-এ fork() calling process-এর একটা copy তৈরি করে। Copy-টা হলো childfork() child-কে 0 return করে আর parent-কে child-এর PID return করে। দুজনেই fork()-এর পরের লাইন থেকে চলতে থাকে।

#include <stdio.h>
#include <unistd.h>

int main() {
    fork();
    fork();
    printf("Hello\n");
    return 0;
}
Example: How many times is "Hello" printed?
After the 1st fork(): 2 processes. After the 2nd fork(): each of the 2 forks again → 4 processes. Each prints once → "Hello" prints 4 times.
General rule: \( n \) fork() calls in a row create \( 2^n \) processes, so the line prints \( 2^n \) times. Number of new child processes created = \( 2^n - 1 \).
Example: "Hello" কতবার print হবে?
১ম fork()-এর পর: 2টা process। ২য় fork()-এর পর: 2টার প্রত্যেকে আবার fork করে → 4টা process। প্রত্যেকে একবার print করে → "Hello" 4 বার print হয়
General rule: পরপর \( n \)টা fork() call দিলে \( 2^n \)টা process হয়, তাই লাইনটা \( 2^n \) বার print হয়। নতুন child process-এর সংখ্যা = \( 2^n - 1 \)।
Exam tip: BUET-style questions often put fork() inside an if or a loop. Draw the process tree on paper. Remember: fork() returns 0 in the child, >0 in the parent, and -1 on failure.
Exam tip: BUET-style প্রশ্নে প্রায়ই fork() কোনো if বা loop-এর ভেতরে থাকে। খাতায় process tree এঁকে ফেলুন। মনে রাখুন: fork() child-এ 0, parent-এ >0, আর fail করলে -1 return করে।

2. CPU Scheduling2. CPU Scheduling

Many processes wait in the ready queue, but the CPU can run only one at a time (per core). The CPU scheduler picks which process runs next. The goal is to keep the CPU busy and to make users happy.

Scheduling criteria (what we measure):

  • CPU utilization — keep the CPU as busy as possible (maximize).
  • Throughput — number of processes finished per unit time (maximize).
  • Turnaround time — finish time − arrival time. Total time a process spends in the system (minimize).
  • Waiting time — total time spent waiting in the ready queue = turnaround time − burst time (minimize).
  • Response time — time from arrival until the first time the process gets the CPU (minimize).

Preemptive vs non-preemptive: In non-preemptive scheduling, once a process gets the CPU it keeps it until it finishes or blocks. In preemptive scheduling, the OS can take the CPU away (for example, when the time slice ends or a shorter job arrives).

Ready queue-তে অনেক process অপেক্ষা করে, কিন্তু CPU একসাথে (প্রতি core-এ) একটাই চালাতে পারে। CPU scheduler ঠিক করে পরে কোনটা চলবে। লক্ষ্য: CPU-কে ব্যস্ত রাখা আর user-দের খুশি রাখা।

Scheduling criteria (আমরা কী মাপি):

  • CPU utilization — CPU-কে যতটা সম্ভব ব্যস্ত রাখা (maximize)।
  • Throughput — প্রতি unit time-এ কয়টা process শেষ হলো (maximize)।
  • Turnaround time — finish time − arrival time। System-এ থাকা মোট সময় (minimize)।
  • Waiting time — ready queue-তে অপেক্ষার মোট সময় = turnaround time − burst time (minimize)।
  • Response time — আসার পর থেকে প্রথমবার CPU পাওয়া পর্যন্ত সময় (minimize)।

Preemptive vs non-preemptive: Non-preemptive scheduling-এ process একবার CPU পেলে শেষ না হওয়া বা block না হওয়া পর্যন্ত রাখে। Preemptive scheduling-এ OS মাঝপথে CPU কেড়ে নিতে পারে (যেমন time slice শেষ হলে বা ছোট job এলে)।

\[ \text{Turnaround} = \text{Finish} - \text{Arrival}, \qquad \text{Waiting} = \text{Turnaround} - \text{Burst} \]

FCFS — First Come, First Served (non-preemptive)FCFS — First Come, First Served (non-preemptive)

Whoever arrives first runs first, like a queue at a shop. Simple, but a long job at the front makes everyone wait.

যে আগে আসে সে আগে চলে, দোকানের লাইনের মতো। সহজ, কিন্তু সামনে একটা লম্বা job থাকলে সবাইকে অপেক্ষা করতে হয়।

Example (FCFS): All arrive at time 0, in order P1, P2, P3.
Example (FCFS): সবাই time 0-তে আসে, order: P1, P2, P3।
ProcessBurst
P124
P23
P33

Gantt chart:

P1P2P3
0 → 2424 → 2727 → 30
ProcessFinishTurnaroundWaiting
P12424 − 0 = 2424 − 24 = 0
P22727 − 0 = 2727 − 3 = 24
P33030 − 0 = 3030 − 3 = 27

Average waiting = (0 + 24 + 27) / 3 = 17. Average turnaround = (24 + 27 + 30) / 3 = 27. If the order were P2, P3, P1, average waiting would be only (0 + 3 + 6)/3 = 3! This is the convoy effect: short processes get stuck behind one long process, like small cars behind a slow truck.

Average waiting = (0 + 24 + 27) / 3 = 17। Average turnaround = (24 + 27 + 30) / 3 = 27। Order যদি P2, P3, P1 হতো, average waiting হতো মাত্র (0 + 3 + 6)/3 = 3! এটাই convoy effect: ছোট process-গুলো একটা লম্বা process-এর পেছনে আটকে যায়, ধীর truck-এর পেছনে ছোট গাড়ির মতো।

SJF — Shortest Job First (non-preemptive)SJF — Shortest Job First (non-preemptive)

Pick the process with the smallest CPU burst. SJF is provably optimal for average waiting time — no other order can beat it. Problem: we usually do not know burst times in advance (we predict them), and long jobs can starve.

সবচেয়ে ছোট CPU burst-এর process-টা বেছে নেয়। Average waiting time-এর জন্য SJF প্রমাণিতভাবে optimal — অন্য কোনো order এর চেয়ে ভালো করতে পারে না। সমস্যা: burst time আগে থেকে জানা যায় না (predict করতে হয়), আর লম্বা job starve করতে পারে।

Example (SJF): All arrive at time 0.
Example (SJF): সবাই time 0-তে আসে।
ProcessBurst
P16
P28
P37
P43

Gantt chart (shortest first: P4, P1, P3, P2):

P4P1P3P2
0 → 33 → 99 → 1616 → 24
ProcessFinishTurnaroundWaiting
P1999 − 6 = 3
P2242424 − 8 = 16
P3161616 − 7 = 9
P4333 − 3 = 0

Average waiting = (3 + 16 + 9 + 0) / 4 = 7. Average turnaround = (9 + 24 + 16 + 3) / 4 = 13. FCFS in order P1..P4 would give average waiting 10.25 — SJF wins.

Average waiting = (3 + 16 + 9 + 0) / 4 = 7। Average turnaround = (9 + 24 + 16 + 3) / 4 = 13। P1..P4 order-এ FCFS দিলে average waiting হতো 10.25 — SJF-ই জিতল।

SRTF — Shortest Remaining Time First (preemptive SJF)SRTF — Shortest Remaining Time First (preemptive SJF)

Same idea as SJF, but preemptive: if a new process arrives with a burst shorter than the remaining time of the running process, the new one takes over.

SJF-এর মতোই, কিন্তু preemptive: নতুন কোনো process এলে, তার burst যদি চলমান process-এর remaining time-এর চেয়ে ছোট হয়, তাহলে নতুনটা CPU নিয়ে নেয়।

Example (SRTF):
Example (SRTF):
ProcessArrivalBurst
P108
P214
P329
P435

Step by step:

  • t=0: only P1. P1 runs (remaining 8).
  • t=1: P2 arrives (burst 4 < P1's remaining 7) → preempt. P2 runs.
  • t=2: P3 arrives (9 > P2's remaining 3) → no change.
  • t=3: P4 arrives (5 > P2's remaining 2) → no change.
  • t=5: P2 finishes. Remaining: P1=7, P3=9, P4=5 → P4 runs.
  • t=10: P4 finishes. Remaining: P1=7, P3=9 → P1 runs.
  • t=17: P1 finishes → P3 runs until t=26.

Step by step:

  • t=0: শুধু P1 আছে। P1 চলে (remaining 8)।
  • t=1: P2 আসে (burst 4 < P1-এর remaining 7) → preempt। P2 চলে।
  • t=2: P3 আসে (9 > P2-এর remaining 3) → পরিবর্তন নেই।
  • t=3: P4 আসে (5 > P2-এর remaining 2) → পরিবর্তন নেই।
  • t=5: P2 শেষ। Remaining: P1=7, P3=9, P4=5 → P4 চলে।
  • t=10: P4 শেষ। Remaining: P1=7, P3=9 → P1 চলে।
  • t=17: P1 শেষ → P3 চলে t=26 পর্যন্ত।

Gantt chart:

P1P2P4P1P3
0 → 11 → 55 → 1010 → 1717 → 26
ProcessFinishTurnaround = Finish − ArrivalWaiting = TAT − Burst
P11717 − 0 = 1717 − 8 = 9
P255 − 1 = 44 − 4 = 0
P32626 − 2 = 2424 − 9 = 15
P41010 − 3 = 77 − 5 = 2

Average waiting = (9 + 0 + 15 + 2) / 4 = 6.5. Average turnaround = (17 + 4 + 24 + 7) / 4 = 13.

Average waiting = (9 + 0 + 15 + 2) / 4 = 6.5। Average turnaround = (17 + 4 + 24 + 7) / 4 = 13

Priority SchedulingPriority Scheduling

Each process gets a priority number; the highest-priority process runs first (here, smaller number = higher priority). Can be preemptive or non-preemptive. Big problem: starvation — a low-priority process may wait forever. Fix: aging — slowly raise the priority of processes that wait a long time.

প্রতিটা process একটা priority number পায়; সবচেয়ে বেশি priority-র process আগে চলে (এখানে ছোট number = বেশি priority)। Preemptive বা non-preemptive দুটোই হতে পারে। বড় সমস্যা: starvation — কম priority-র process চিরকাল অপেক্ষা করতে পারে। সমাধান: aging — যারা অনেকক্ষণ অপেক্ষা করছে তাদের priority ধীরে ধীরে বাড়ানো।

Example (Priority, non-preemptive, all arrive at 0):
Example (Priority, non-preemptive, সবাই 0-তে আসে):
ProcessBurstPriority
P1103
P211
P324
P415
P552

Gantt chart (order P2, P5, P1, P3, P4):

P2P5P1P3P4
0 → 11 → 66 → 1616 → 1818 → 19

Waiting: P1 = 6, P2 = 0, P3 = 16, P4 = 18, P5 = 1. Average waiting = (6+0+16+18+1)/5 = 8.2.

Waiting: P1 = 6, P2 = 0, P3 = 16, P4 = 18, P5 = 1। Average waiting = (6+0+16+18+1)/5 = 8.2

Round Robin (RR, preemptive)Round Robin (RR, preemptive)

Every process gets a small fixed time quantum (e.g., 4 ms). If it does not finish in that time, it goes to the back of the ready queue. Great for time-sharing systems: everyone gets a fair turn, response time is good.

প্রতিটা process একটা ছোট নির্দিষ্ট time quantum পায় (যেমন 4 ms)। এর মধ্যে শেষ না হলে সে ready queue-এর পেছনে চলে যায়। Time-sharing system-এর জন্য দারুণ: সবাই fair সুযোগ পায়, response time ভালো।

Example (RR, quantum = 4, all arrive at 0): P1 = 24, P2 = 3, P3 = 3.
Example (RR, quantum = 4, সবাই 0-তে আসে): P1 = 24, P2 = 3, P3 = 3।

Gantt chart:

P1P2P3P1P1P1P1P1
0 → 44 → 77 → 1010 → 1414 → 1818 → 2222 → 2626 → 30

P2 and P3 finish inside their first quantum (they need only 3). After t=10 only P1 is left, so it runs quantum after quantum.

Waiting: P1 = 30 − 24 = 6 (it waited 4→10), P2 = 4, P3 = 7. Average waiting = (6 + 4 + 7)/3 = 5.67. Average turnaround = (30 + 7 + 10)/3 = 15.67.

P2 আর P3 প্রথম quantum-এর মধ্যেই শেষ (ওদের দরকার মাত্র 3)। t=10-এর পর শুধু P1 বাকি, তাই সে একের পর এক quantum পেয়ে চলে।

Waiting: P1 = 30 − 24 = 6 (সে 4→10 অপেক্ষা করেছে), P2 = 4, P3 = 7। Average waiting = (6 + 4 + 7)/3 = 5.67। Average turnaround = (30 + 7 + 10)/3 = 15.67

Exam tip (RR quantum effect): If the quantum is too big, RR becomes FCFS. If it is too small, too many context switches waste time. Rule of thumb: about 80% of CPU bursts should be shorter than the quantum. Also memorize: SJF is optimal for minimum average waiting time; SJF/SRTF/Priority can starve long or low-priority jobs; aging is the cure; RR never starves anyone.
Exam tip (RR quantum effect): Quantum খুব বড় হলে RR আসলে FCFS হয়ে যায়। খুব ছোট হলে অনেক বেশি context switch হয়ে সময় নষ্ট হয়। Rule of thumb: প্রায় 80% CPU burst quantum-এর চেয়ে ছোট হওয়া উচিত। আরও মুখস্থ রাখুন: minimum average waiting time-এর জন্য SJF optimal; SJF/SRTF/Priority-তে লম্বা বা কম priority-র job starve করতে পারে; সমাধান aging; RR-এ কেউ starve করে না

Multilevel QueueMultilevel Queue

The ready queue is split into several queues, e.g., foreground (interactive) using RR and background (batch) using FCFS. Each queue can have its own algorithm, and the queues themselves are scheduled (fixed priority, or time slices like 80% foreground / 20% background). A multilevel feedback queue also lets processes move between queues — a process that uses too much CPU drops to a lower queue; a process that waits too long moves up (this is aging in action).

Ready queue-কে কয়েকটা queue-তে ভাগ করা হয়, যেমন foreground (interactive) চলে RR দিয়ে আর background (batch) চলে FCFS দিয়ে। প্রতিটা queue-র নিজস্ব algorithm থাকতে পারে, আর queue-গুলোর মধ্যেও scheduling হয় (fixed priority, বা 80% foreground / 20% background-এর মতো time ভাগ)। Multilevel feedback queue-তে process queue বদলাতে পারে — বেশি CPU খেলে নিচের queue-তে নামে; বেশি অপেক্ষা করলে উপরে ওঠে (এটাই কার্যত aging)।

AlgorithmTypeTypeGoodভালো দিকBadখারাপ দিক
FCFSNon-preemptiveSimple, fair orderসহজ, fair orderConvoy effectConvoy effect
SJFNon-preemptiveOptimal average waitingOptimal average waitingNeeds future knowledge, starvationভবিষ্যৎ জানতে হয়, starvation
SRTFPreemptiveEven better averagesআরও ভালো averageMore switches, starvationবেশি switch, starvation
PriorityBoth possibleদুটোই সম্ভবImportant jobs firstজরুরি কাজ আগেStarvation (fix: aging)Starvation (সমাধান: aging)
Round RobinPreemptiveFair, good response timeFair, ভালো response timeQuantum choice is trickyQuantum বাছাই কঠিন

3. Synchronization3. Synchronization

Race ConditionRace Condition

When two or more processes/threads read and write shared data at the same time, the final result depends on the exact order of execution. This is a race condition.

Concrete example: Two threads both run counter++ once, starting from counter = 5. We expect 7. But counter++ is really three machine steps:

দুই বা ততোধিক process/thread যখন একই সময়ে shared data পড়ে আর লেখে, তখন শেষ ফলাফল নির্ভর করে execution-এর order-এর ওপর। এটাই race condition

Concrete example: দুইটা thread-ই একবার করে counter++ চালায়, শুরুতে counter = 5। আশা করি ফল হবে 7। কিন্তু counter++ আসলে তিনটা machine step:

register = counter    // read
register = register + 1
counter = register    // write
Example (bad interleaving):
  • T1: reads counter (5) into its register.
  • T2: reads counter (5) into its register. ← T1 has not written yet!
  • T1: adds 1 → 6, writes counter = 6.
  • T2: adds 1 → 6, writes counter = 6.
Final value = 6, not 7. One increment was lost. This is why we need synchronization.
Example (খারাপ interleaving):
  • T1: counter (5) নিজের register-এ পড়ে।
  • T2: counter (5) নিজের register-এ পড়ে। ← T1 তখনও লেখেনি!
  • T1: 1 যোগ করে → 6, counter = 6 লেখে।
  • T2: 1 যোগ করে → 6, counter = 6 লেখে।
শেষ মান = 6, 7 নয়। একটা increment হারিয়ে গেল। এজন্যই synchronization দরকার।

Critical Section ProblemCritical Section Problem

The critical section is the part of code where a process touches shared data. Only one process should be inside it at a time. A correct solution must satisfy three requirements:

  1. Mutual exclusion — at most one process in the critical section at any moment.
  2. Progress — if nobody is inside and someone wants in, the decision cannot be postponed forever; only processes trying to enter take part in the decision.
  3. Bounded waiting — after a process asks to enter, there is a limit on how many times others can enter before it does (no starvation).

Critical section হলো code-এর সেই অংশ যেখানে process shared data ধরে। একসাথে একটার বেশি process এর ভেতরে থাকা উচিত না। সঠিক সমাধানের তিনটা শর্ত মানতে হয়:

  1. Mutual exclusion — যেকোনো মুহূর্তে সর্বোচ্চ একটা process critical section-এ।
  2. Progress — ভেতরে কেউ নেই আর কেউ ঢুকতে চায়, তাহলে সিদ্ধান্ত চিরকাল ঝুলিয়ে রাখা যাবে না; শুধু যারা ঢুকতে চাইছে তারাই সিদ্ধান্তে অংশ নেবে।
  3. Bounded waiting — কেউ ঢুকতে চাওয়ার পর, তার আগে অন্যরা কতবার ঢুকতে পারবে তার একটা সীমা আছে (starvation নেই)।

Peterson's Solution (two processes)Peterson's Solution (দুই process)

A classic software-only solution for two processes (P0 and P1). It uses two shared variables: flag[2] ("I want to enter") and turn ("it is your turn"). Each process politely gives the turn to the other; whoever's turn it is enters. It satisfies all three requirements (on old simple hardware).

দুই process-এর (P0 আর P1) জন্য classic software-only সমাধান। দুইটা shared variable: flag[2] ("আমি ঢুকতে চাই") আর turn ("তোমার পালা")। প্রতিটা process ভদ্রভাবে অন্যকে পালা দিয়ে দেয়; যার পালা সে ঢোকে। এটা তিনটা শর্তই মানে (পুরনো simple hardware-এ)।

// Process Pi (the other one is Pj)
do {
    flag[i] = true;      // I want to enter
    turn = j;            // but you go first
    while (flag[j] && turn == j)
        ;                // busy wait
    /* critical section */
    flag[i] = false;     // I am out
    /* remainder section */
} while (true);

Mutex LocksMutex Locks

A mutex (mutual exclusion lock) is the simplest tool: acquire() before the critical section, release() after. If the lock is taken, others spin or sleep. A lock where waiting processes keep looping is called a spinlock — it wastes CPU but avoids context switches, so it is good for very short waits on multi-core machines.

Mutex (mutual exclusion lock) হলো সবচেয়ে সহজ tool: critical section-এর আগে acquire(), পরে release()। Lock নেওয়া থাকলে অন্যরা ঘুরতে থাকে বা ঘুমায়। যেখানে অপেক্ষমাণ process loop-এ ঘোরে সেটা spinlock — CPU নষ্ট করে কিন্তু context switch বাঁচায়, তাই multi-core machine-এ খুব ছোট অপেক্ষার জন্য ভালো।

SemaphoresSemaphores

A semaphore S is an integer changed only by two atomic operations:

  • wait(S) (also called P): decrement S; if S becomes negative, the caller blocks.
  • signal(S) (also called V): increment S; if any process was blocked, wake one up.

Binary semaphore: value only 0 or 1 — works like a mutex. Counting semaphore: value can be any number — counts available copies of a resource (e.g., 5 printers → start S at 5).

Semaphore S একটা integer যা শুধু দুইটা atomic operation দিয়ে বদলায়:

  • wait(S) (P-ও বলে): S কমায়; S negative হলে caller block হয়।
  • signal(S) (V-ও বলে): S বাড়ায়; কেউ blocked থাকলে একজনকে জাগায়।

Binary semaphore: মান শুধু 0 বা 1 — mutex-এর মতো কাজ করে। Counting semaphore: মান যেকোনো সংখ্যা — resource-এর available copy গোনে (যেমন 5টা printer → S শুরু হয় 5 থেকে)।

Producer–Consumer with SemaphoresProducer–Consumer with Semaphores

A producer puts items into a buffer of size N; a consumer takes them out. We use three semaphores: mutex = 1 (protects the buffer), empty = N (counts empty slots), full = 0 (counts filled slots).

Producer N size-এর একটা buffer-এ item রাখে; consumer সেগুলো নেয়। তিনটা semaphore ব্যবহার হয়: mutex = 1 (buffer পাহারা দেয়), empty = N (খালি slot গোনে), full = 0 (ভরা slot গোনে)।

// Producer                     // Consumer
do {                            do {
    produce item;                   wait(full);
    wait(empty);                    wait(mutex);
    wait(mutex);                    remove item from buffer;
    add item to buffer;             signal(mutex);
    signal(mutex);                  signal(empty);
    signal(full);                   consume item;
} while (true);                 } while (true);
Exam tip: The order matters: wait(empty) must come before wait(mutex). If you swap them, the producer can hold the mutex and then sleep waiting for an empty slot — the consumer can never get the mutex to make a slot empty → deadlock. MCQs love this trap.
Exam tip: Order গুরুত্বপূর্ণ: wait(empty) অবশ্যই wait(mutex)-এর আগে। উল্টে দিলে producer mutex ধরে রেখে খালি slot-এর অপেক্ষায় ঘুমাতে পারে — consumer আর mutex পাবে না, slot-ও খালি হবে না → deadlock। MCQ-তে এই trap খুব আসে।

MonitorsMonitors

Semaphores are easy to misuse (forget a signal, wrong order). A monitor is a high-level language construct: a class where only one process can be active inside at a time, automatically. It also has condition variables with x.wait() (sleep until signaled) and x.signal() (wake one waiting process). Java's synchronized keyword is a monitor idea.

Semaphore ভুলভাবে ব্যবহার করা সহজ (signal ভুলে যাওয়া, ভুল order)। Monitor হলো high-level language construct: এমন একটা class যার ভেতরে একসাথে শুধু একটা process active থাকতে পারে, automatic-ভাবে। এতে condition variable থাকে: x.wait() (signal না পাওয়া পর্যন্ত ঘুম) আর x.signal() (একজন অপেক্ষমাণকে জাগানো)। Java-র synchronized keyword monitor-এরই idea।

4. Deadlocks4. Deadlocks

A deadlock is a situation where a set of processes are all blocked, each waiting for a resource that another process in the set holds. Nobody can move — like two cars facing each other on a one-lane bridge, each waiting for the other to back up.

Deadlock হলো এমন অবস্থা যেখানে একদল process সবাই blocked, প্রত্যেকে এমন resource-এর অপেক্ষায় আছে যা দলের অন্য কেউ ধরে রেখেছে। কেউই নড়তে পারে না — এক লেনের সেতুতে মুখোমুখি দুই গাড়ির মতো, দুজনেই অপেক্ষা করছে অন্যজন পিছাবে বলে।

The 4 Coffman ConditionsThe 4 Coffman Conditions

Deadlock can happen only if all four hold at the same time:

  1. Mutual exclusion — at least one resource can be used by only one process at a time (e.g., a printer).
  2. Hold and wait — a process holds one resource while waiting for another.
  3. No preemption — a resource cannot be taken away by force; the holder must release it voluntarily.
  4. Circular wait — there is a cycle: P0 waits for P1's resource, P1 waits for P2's, ..., Pn waits for P0's.

Break any one condition and deadlock becomes impossible.

Deadlock তখনই হতে পারে যখন চারটা শর্তই একসাথে সত্য:

  1. Mutual exclusion — অন্তত একটা resource একসাথে একটা process-ই ব্যবহার করতে পারে (যেমন printer)।
  2. Hold and wait — একটা process একটা resource ধরে রেখে আরেকটার জন্য অপেক্ষা করে।
  3. No preemption — জোর করে resource কেড়ে নেওয়া যায় না; ধারককে নিজে ছাড়তে হয়।
  4. Circular wait — একটা cycle আছে: P0 অপেক্ষা করে P1-এর resource-এর জন্য, P1 করে P2-এর জন্য, ..., Pn করে P0-এর জন্য।

যেকোনো একটা শর্ত ভাঙলেই deadlock অসম্ভব।

Real exam (asked in multiple years!): BUET asked "state the four conditions necessary for deadlock" in October 2017 AND again in October 2018. Memorize all four NAMES exactly: mutual exclusion, hold and wait, no preemption, circular wait. Also be ready to give a one-line meaning of each — the names alone are only half the marks.
Real exam (একাধিক বছর এসেছে!): BUET "deadlock-এর জন্য প্রয়োজনীয় চারটা শর্ত লিখুন" জিজ্ঞেস করেছে October 2017-তে এবং আবার October 2018-তে। চারটা NAME হুবহু মুখস্থ রাখুন: mutual exclusion, hold and wait, no preemption, circular wait। প্রতিটার এক লাইনের মানেও বলতে পারতে হবে — শুধু নাম বললে অর্ধেক নম্বর।

Resource Allocation Graph (RAG)Resource Allocation Graph (RAG)

Circles are processes, squares are resources. An edge R → P means "R is assigned to P". An edge P → R means "P is requesting R".

  • No cycle → definitely no deadlock.
  • Cycle + one instance per resource → definitely deadlock.
  • Cycle + multiple instances → deadlock is possible, not certain.

বৃত্ত = process, বর্গ = resource। R → P edge মানে "R এখন P-এর কাছে"। P → R edge মানে "P R চাইছে"।

  • Cycle নেই → নিশ্চিতভাবে deadlock নেই।
  • Cycle আছে + প্রতি resource-এর একটাই instance → নিশ্চিত deadlock।
  • Cycle আছে + একাধিক instance → deadlock হতে পারে, নিশ্চিত না।
P1 P2 R1 R2 held by P1 requests R2 held by P2 requests R1
A cycle in the resource allocation graph: P1 holds R1 and wants R2; P2 holds R2 and wants R1 → deadlock.Resource allocation graph-এ cycle: P1-এর কাছে R1, সে চায় R2; P2-এর কাছে R2, সে চায় R1 → deadlock।

Handling StrategiesHandling Strategies

  • Prevention — design the system so one Coffman condition can never hold. E.g., order all resources with numbers and always request in increasing order (kills circular wait); request everything at once (kills hold and wait).
  • Avoidance — before granting a request, check that the system stays in a safe state (Banker's algorithm). Needs to know maximum needs in advance.
  • Detection & recovery — let deadlock happen, run a detection algorithm from time to time, then recover by killing a process or preempting resources.
  • Ignore it (Ostrich algorithm) — pretend it never happens. This is what most real OSes (Linux, Windows) actually do, because deadlocks are rare and the other methods are costly.
  • Prevention — system এমনভাবে design করা যেন একটা Coffman শর্ত কখনো সত্য না হয়। যেমন: সব resource-কে নম্বর দিয়ে সবসময় বাড়তি order-এ চাওয়া (circular wait শেষ); সব একবারে চাওয়া (hold and wait শেষ)।
  • Avoidance — request মঞ্জুর করার আগে দেখা যে system safe state-এ থাকবে কি না (Banker's algorithm)। আগে থেকে maximum need জানতে হয়।
  • Detection & recovery — deadlock হতে দাও, মাঝে মাঝে detection algorithm চালাও, তারপর কোনো process মেরে বা resource কেড়ে recover করো।
  • Ignore (Ostrich algorithm) — ভান করা যে এমন কিছু হয়ই না। বাস্তবে বেশিরভাগ OS (Linux, Windows) এটাই করে, কারণ deadlock বিরল আর বাকি পদ্ধতিগুলো ব্যয়বহুল।

Banker's Algorithm — full worked example (BUET favorite)Banker's Algorithm — full worked example (BUET favorite)

The system is in a safe state if there exists a safe sequence: an order in which every process can get its maximum need, finish, and return its resources. The algorithm:

  1. Compute Need = Max − Allocation for each process.
  2. Set Work = Available.
  3. Find an unfinished process with Need ≤ Work. Pretend it finishes: Work = Work + its Allocation. Mark it finished.
  4. Repeat. If all processes can finish → safe. If stuck → unsafe.

System safe state-এ আছে যদি একটা safe sequence থাকে: এমন একটা order যাতে প্রতিটা process তার maximum need পেয়ে, শেষ করে, resource ফেরত দিতে পারে। Algorithm:

  1. প্রতিটা process-এর জন্য Need = Max − Allocation বের করো।
  2. Work = Available ধরো।
  3. এমন একটা অসমাপ্ত process খোঁজো যার Need ≤ Work। ধরো সে শেষ করল: Work = Work + তার Allocation। তাকে finished mark করো।
  4. Repeat করো। সবাই শেষ করতে পারলে → safe। আটকে গেলে → unsafe।
Example: 5 processes, 3 resource types A (10 total), B (5), C (7). Current snapshot:
Example: 5টা process, 3 ধরনের resource: A (মোট 10), B (5), C (7)। বর্তমান অবস্থা:
ProcessAllocation (A B C)Max (A B C)Need = Max − Alloc
P00 1 07 5 37 4 3
P12 0 03 2 21 2 2
P23 0 29 0 26 0 0
P32 1 12 2 20 1 1
P40 0 24 3 34 3 1

Total allocated = (7, 2, 5), so Available = (10, 5, 7) − (7, 2, 5) = (3, 3, 2). Now run the safety check, Work = (3, 3, 2):

মোট allocated = (7, 2, 5), তাই Available = (10, 5, 7) − (7, 2, 5) = (3, 3, 2)। এবার safety check চালাই, Work = (3, 3, 2):

StepWorkCheckCheckResultResultNew Work = Work + Alloc
13 3 2P0 needs 7 4 3 ≤ 3 3 2?No — skipনা — skip
23 3 2P1 needs 1 2 2 ≤ 3 3 2?Yes — P1 runsহ্যাঁ — P1 চলে3 3 2 + 2 0 0 = 5 3 2
35 3 2P2 needs 6 0 0 ≤ 5 3 2?No — skipনা — skip
45 3 2P3 needs 0 1 1 ≤ 5 3 2?Yes — P3 runsহ্যাঁ — P3 চলে5 3 2 + 2 1 1 = 7 4 3
57 4 3P4 needs 4 3 1 ≤ 7 4 3?Yes — P4 runsহ্যাঁ — P4 চলে7 4 3 + 0 0 2 = 7 4 5
67 4 5P0 needs 7 4 3 ≤ 7 4 5?Yes — P0 runsহ্যাঁ — P0 চলে7 4 5 + 0 1 0 = 7 5 5
77 5 5P2 needs 6 0 0 ≤ 7 5 5?Yes — P2 runsহ্যাঁ — P2 চলে7 5 5 + 3 0 2 = 10 5 7

All processes can finish. Safe sequence: ⟨P1, P3, P4, P0, P2⟩ → the system is in a safe state. (Other safe sequences also exist, e.g., ⟨P1, P3, P4, P2, P0⟩ — any valid one is a correct answer.)

সব process শেষ করতে পারে। Safe sequence: ⟨P1, P3, P4, P0, P2⟩ → system safe state-এ আছে। (অন্য safe sequence-ও আছে, যেমন ⟨P1, P3, P4, P2, P0⟩ — যেকোনো valid sequence সঠিক উত্তর।)

Handling a new request (Request ≤ Need and Request ≤ Available must both hold): pretend to grant it — Available −= Request, Allocation += Request, Need −= Request — then run the safety check again. If the new state is safe, grant it for real; if not, roll back and make the process wait. Example: P1 requests (1, 0, 2). Check: (1,0,2) ≤ Need(1,2,2) ✓ and ≤ Available(3,3,2) ✓. After pretending: Available = (2,3,0), P1 Alloc = (3,0,2), P1 Need = (0,2,0). The safety check still finds ⟨P1, P3, P4, P0, P2⟩ → grant it.

নতুন request এলে (Request ≤ Need এবং Request ≤ Available দুটোই লাগবে): ধরে নাও দিলাম — Available −= Request, Allocation += Request, Need −= Request — তারপর আবার safety check চালাও। নতুন state safe হলে সত্যিই দাও; না হলে ফিরিয়ে নিয়ে process-কে অপেক্ষা করাও। Example: P1 চায় (1, 0, 2)। Check: (1,0,2) ≤ Need(1,2,2) ✓ এবং ≤ Available(3,3,2) ✓। ধরে নেওয়ার পর: Available = (2,3,0), P1 Alloc = (3,0,2), P1 Need = (0,2,0)। Safety check এখনও ⟨P1, P3, P4, P0, P2⟩ পায় → request মঞ্জুর।

Exam tip: Safe state ≠ deadlock-free forever. Safe means there is at least one order that avoids deadlock if the OS follows it. An unsafe state does not mean deadlock has happened — it means deadlock is now possible and the OS can no longer guarantee avoiding it. Also: always show the Work updates step by step in written answers — that is where the marks are.
Exam tip: Safe state মানেই চিরকাল deadlock-free না। Safe মানে অন্তত একটা order আছে যা মানলে deadlock এড়ানো যায়। Unsafe state মানেও deadlock হয়ে গেছে তা না — মানে এখন deadlock সম্ভব, OS আর guarantee দিতে পারছে না। আরও: written answer-এ Work-এর update step by step দেখাবেন — নম্বর ওখানেই।

5. Memory Management5. Memory Management

Logical vs Physical Address, MMULogical vs Physical Address, MMU

A logical (virtual) address is what the CPU generates — the address the program sees. A physical address is the real location in RAM. The MMU (Memory Management Unit) is hardware that translates logical → physical at run time. Simplest MMU: a relocation (base) register — physical = logical + base — and a limit register to stop the process from touching others' memory.

Logical (virtual) address হলো CPU যা generate করে — program যে address দেখে। Physical address হলো RAM-এর আসল জায়গা। MMU (Memory Management Unit) হলো hardware যা run time-এ logical → physical translate করে। সবচেয়ে সহজ MMU: relocation (base) register — physical = logical + base — আর limit register যা process-কে অন্যের memory ছুঁতে দেয় না।

Contiguous Allocation: First / Best / Worst FitContiguous Allocation: First / Best / Worst Fit

In contiguous allocation each process gets one continuous block. Free memory has "holes". Where do we put a new process?

  • First fit: the first hole that is big enough. Fast.
  • Best fit: the smallest hole that is big enough. Leaves tiny useless holes.
  • Worst fit: the largest hole. Leaves big leftover pieces.

In practice, first fit and best fit beat worst fit in both speed and memory use.

Contiguous allocation-এ প্রতিটা process একটানা একটা block পায়। Free memory-তে "hole" থাকে। নতুন process কোথায় বসাব?

  • First fit: প্রথম যে hole-এ জায়গা হয়। দ্রুত।
  • Best fit: জায়গা হয় এমন সবচেয়ে ছোট hole। ছোট ছোট অকেজো hole রেখে যায়।
  • Worst fit: সবচেয়ে বড় hole। বড় বড় leftover টুকরা রেখে যায়।

বাস্তবে speed আর memory ব্যবহারে first fit আর best fit — দুটোই worst fit-এর চেয়ে ভালো।

Example: Holes (in order): 100K, 500K, 200K, 300K, 600K. Processes arrive: 212K, 417K, 112K, 426K.
Example: Hole (order অনুযায়ী): 100K, 500K, 200K, 300K, 600K। Process আসে: 212K, 417K, 112K, 426K।
ProcessFirst fitBest fitWorst fit
212K500K hole (288K left)500K hole (288K বাকি)300K hole (88K left)300K hole (88K বাকি)600K hole (388K left)600K hole (388K বাকি)
417K600K hole (183K left)600K hole (183K বাকি)500K hole (83K left)500K hole (83K বাকি)500K hole (83K left)500K hole (83K বাকি)
112K288K hole (176K left)288K hole (176K বাকি)200K hole (88K left)200K hole (88K বাকি)388K hole (276K left)388K hole (276K বাকি)
426Kmust wait (no hole fits)অপেক্ষা করতে হয় (কোনো hole-এ হয় না)600K hole (174K left)600K hole (174K বাকি)must wait (no hole fits)অপেক্ষা করতে হয় (কোনো hole-এ হয় না)

Here only best fit places all four processes. This exact style of question appears in exams: trace each hole carefully and update leftover sizes.

এখানে শুধু best fit চারটা process-ই বসাতে পারে। Exam-এ ঠিক এই ধাঁচের প্রশ্ন আসে: প্রতিটা hole trace করে leftover size update করতে হয়।

FragmentationFragmentation

  • External fragmentation: total free memory is enough, but it is split into small non-contiguous holes, so a big request fails. Happens in contiguous allocation and segmentation. Fix: compaction (shuffle memory together) or use paging.
  • Internal fragmentation: memory is given in fixed-size blocks; the unused part inside a block is wasted. Happens in paging (last page is rarely full). Average waste ≈ half a page per process.
  • External fragmentation: মোট free memory যথেষ্ট, কিন্তু ছোট ছোট আলাদা hole-এ ভাগ হয়ে আছে, তাই বড় request fail করে। Contiguous allocation আর segmentation-এ হয়। সমাধান: compaction (memory একসাথে ঠেলে আনা) বা paging।
  • Internal fragmentation: Memory দেওয়া হয় fixed-size block-এ; block-এর ভেতরের অব্যবহৃত অংশ নষ্ট হয়। Paging-এ হয় (শেষ page প্রায়ই পুরো ভরে না)। গড় অপচয় ≈ process প্রতি আধা page।

PagingPaging

Paging removes external fragmentation. Logical memory is cut into fixed-size pages; physical memory is cut into same-size frames. Any page can go into any free frame — no need to be contiguous. A per-process page table maps page number → frame number.

Address translation: if the page size is \( 2^n \) bytes, the CPU splits a logical address into a page number p (high bits) and an offset d (low n bits):

Paging external fragmentation দূর করে। Logical memory-কে fixed-size page-এ কাটা হয়; physical memory-কে একই size-এর frame-এ। যেকোনো page যেকোনো খালি frame-এ যেতে পারে — একটানা হওয়ার দরকার নেই। প্রতিটা process-এর page table map করে: page number → frame number।

Address translation: page size যদি \( 2^n \) byte হয়, CPU logical address-কে ভাগ করে page number p (উপরের bit) আর offset d (নিচের n bit)-এ:

\[ p = \left\lfloor \frac{\text{address}}{\text{page size}} \right\rfloor, \quad d = \text{address} \bmod \text{page size}, \quad \text{physical} = \text{frame}(p) \times \text{page size} + d \]
Example (numeric address translation): Page size = 1 KB = 1024 bytes. Logical address = 3500.
  • Page number p = ⌊3500 / 1024⌋ = 3.
  • Offset d = 3500 mod 1024 = 3500 − 3×1024 = 3500 − 3072 = 428.
  • Suppose the page table says page 3 → frame 8. Then physical address = 8 × 1024 + 428 = 8620.
Binary view: with 1 KB pages the offset is the low 10 bits; the rest is the page number.
Example (numeric address translation): Page size = 1 KB = 1024 byte। Logical address = 3500।
  • Page number p = ⌊3500 / 1024⌋ = 3
  • Offset d = 3500 mod 1024 = 3500 − 3×1024 = 3500 − 3072 = 428
  • ধরুন page table বলে page 3 → frame 8। তাহলে physical address = 8 × 1024 + 428 = 8620
Binary-তে: 1 KB page হলে offset হলো নিচের 10 bit; বাকিটা page number।
Example (bit-level translation, 4 KB pages — asked October 2017 & April 2019): A system uses a 16-bit logical address and page size 4 KB = \( 2^{12} \) bytes.
  • Split the bits: offset needs 12 bits (because \( 4096 = 2^{12} \)). Remaining 16 − 12 = 4 bits for the page number. So there are \( 2^4 = 16 \) pages, each 4096 bytes.
  • Logical address = 0x3A7F (= 14975 decimal). In binary: 0011 1010 0111 1111.
  • Top 4 bits = 0011 → page number p = 3. Low 12 bits = 1010 0111 1111 = 0xA7F → offset d = 2687. Check: 14975 = 3×4096 + 2687. ✓
  • Page table lookup: suppose page 3 → frame 6.
  • Physical address = frame × page size + offset = 6 × 4096 + 2687 = 24576 + 2687 = 27263 (= 0x6A7F). Notice the offset bits never change — only the page-number bits are replaced by the frame number.
Second quick case: logical address 8500, page size 4 KB, page table: 0→5, 1→9, 2→2, 3→7. Then p = ⌊8500/4096⌋ = 2, d = 8500 − 8192 = 308, frame = 2 → physical = 2 × 4096 + 308 = 8500. (Here the frame number happened to equal the page number, so the address did not change — a favorite trick in exams!)
Example (bit-level translation, 4 KB page — October 2017 & April 2019-তে এসেছিল): একটা system-এ 16-bit logical address আর page size 4 KB = \( 2^{12} \) byte।
  • Bit ভাগ করুন: offset-এর জন্য 12 bit লাগে (কারণ \( 4096 = 2^{12} \))। বাকি 16 − 12 = 4 bit page number-এর জন্য। তাই page আছে \( 2^4 = 16 \)টা, প্রতিটা 4096 byte।
  • Logical address = 0x3A7F (= decimal 14975)। Binary-তে: 0011 1010 0111 1111
  • উপরের 4 bit = 0011 → page number p = 3। নিচের 12 bit = 1010 0111 1111 = 0xA7F → offset d = 2687। Check: 14975 = 3×4096 + 2687। ✓
  • Page table lookup: ধরুন page 3 → frame 6।
  • Physical address = frame × page size + offset = 6 × 4096 + 2687 = 24576 + 2687 = 27263 (= 0x6A7F)। লক্ষ করুন offset-এর bit কখনো বদলায় না — শুধু page-number-এর bit-গুলোর জায়গায় frame number বসে।
দ্বিতীয় দ্রুত case: logical address 8500, page size 4 KB, page table: 0→5, 1→9, 2→2, 3→7। তাহলে p = ⌊8500/4096⌋ = 2, d = 8500 − 8192 = 308, frame = 2 → physical = 2 × 4096 + 308 = 8500। (এখানে frame number ঘটনাক্রমে page number-এর সমান, তাই address বদলায়নি — exam-এর প্রিয় trick!)

Page Size Trade-offs — small vs large pagesPage Size Trade-offs — ছোট vs বড় page

Example (thinking through page size — asked April 2017): BUET asked: what are the problems and advantages of a SMALL page size?

Advantages of small pages:

  • Less internal fragmentation — the wasted space in the last page is on average half a page, so smaller page = less waste. Example: a 13 KB program with 4 KB pages wastes 3 KB in the last page; with 1 KB pages it wastes 0 KB.
  • Better fit to locality — memory is loaded in finer pieces, so only the bytes really needed come into RAM. Less useless data is loaded.

Problems of small pages:

  • Bigger page table — same address space / smaller page = MORE pages = more page table entries. Example: 32-bit space with 4 KB pages → \( 2^{20} \) entries; with 1 KB pages → \( 2^{22} \) entries (4× bigger table).
  • More TLB misses — the TLB has a fixed number of entries; each entry now covers less memory, so its "reach" shrinks and misses go up.
  • More page faults and more I/O overhead — bringing the same amount of data needs more separate page transfers, and each disk transfer has a fixed startup cost.

Large pages are the exact mirror: less table/TLB overhead and fewer faults, but more internal fragmentation and more useless data loaded per fault.

Example (page size নিয়ে ভাবা — April 2017-তে এসেছিল): BUET জিজ্ঞেস করেছিল: ছোট (SMALL) page size-এর সমস্যা আর সুবিধা কী?

ছোট page-এর সুবিধা:

  • Internal fragmentation কম — শেষ page-এ গড়ে আধা page নষ্ট হয়, তাই page ছোট হলে অপচয়ও কম। Example: 13 KB program-এ 4 KB page হলে শেষ page-এ 3 KB নষ্ট; 1 KB page হলে 0 KB।
  • Locality-র সাথে ভালো মেলে — memory ছোট ছোট টুকরায় load হয়, তাই সত্যিই যা দরকার শুধু সেটাই RAM-এ আসে। অদরকারি data কম load হয়।

ছোট page-এর সমস্যা:

  • Page table বড় হয় — একই address space / ছোট page = বেশি page = বেশি page table entry। Example: 32-bit space-এ 4 KB page → \( 2^{20} \) entry; 1 KB page → \( 2^{22} \) entry (4 গুণ বড় table)।
  • TLB miss বাড়ে — TLB-র entry সংখ্যা fixed; প্রতিটা entry এখন কম memory cover করে, তাই TLB-র "reach" কমে আর miss বাড়ে।
  • Page fault আর I/O overhead বাড়ে — একই পরিমাণ data আনতে বেশি সংখ্যক আলাদা page transfer লাগে, আর প্রতিটা disk transfer-এর একটা fixed startup খরচ আছে।

বড় page ঠিক এর উল্টো: table/TLB overhead কম, fault কম — কিন্তু internal fragmentation বেশি, আর প্রতি fault-এ অদরকারি data বেশি load হয়।

Pages in virtual address space mapped to frames in physical memory through a page table
Pages of the virtual address space map to frames of physical memory through the page table. Pages that are not in RAM live on disk.Virtual address space-এর page-গুলো page table-এর মাধ্যমে physical memory-র frame-এ map হয়। যে page RAM-এ নেই সেগুলো disk-এ থাকে।

TLB — Translation Lookaside BufferTLB — Translation Lookaside Buffer

The page table lives in RAM, so a plain paged access needs two memory accesses (one for the table, one for the data). The TLB is a small, very fast hardware cache of recent page → frame translations. TLB hit: translation is almost free. TLB miss: go to the page table in memory.

Effective Access Time (EAT): with hit ratio \( h \), memory time \( m \), TLB time \( \epsilon \): \( EAT = h(m + \epsilon) + (1-h)(2m + \epsilon) \). Example: m = 100 ns, ε ≈ 0, h = 0.9 → EAT = 0.9×100 + 0.1×200 = 110 ns.

Page table থাকে RAM-এ, তাই সাধারণ paged access-এ দুইবার memory access লাগে (একবার table, একবার data)। TLB হলো সাম্প্রতিক page → frame translation-এর ছোট, খুব দ্রুত hardware cache। TLB hit: translation প্রায় free। TLB miss: memory-র page table-এ যেতে হয়।

Effective Access Time (EAT): hit ratio \( h \), memory time \( m \), TLB time \( \epsilon \) হলে: \( EAT = h(m + \epsilon) + (1-h)(2m + \epsilon) \)। Example: m = 100 ns, ε ≈ 0, h = 0.9 → EAT = 0.9×100 + 0.1×200 = 110 ns

SegmentationSegmentation

Segmentation divides a program the way the programmer sees it: code segment, data segment, stack segment, etc. Segments have different sizes. An address is a pair (segment number, offset). The segment table stores each segment's base and limit; the hardware checks offset < limit, then physical = base + offset. Because segments are variable-size, segmentation suffers external fragmentation.

Segmentation program-কে ভাগ করে যেভাবে programmer দেখে: code segment, data segment, stack segment ইত্যাদি। Segment-গুলোর size আলাদা। Address হলো একটা জোড়া (segment number, offset)। Segment table-এ প্রতিটা segment-এর base আর limit থাকে; hardware check করে offset < limit, তারপর physical = base + offset। Segment variable-size বলে segmentation-এ external fragmentation হয়।

Pointবিষয়PagingSegmentation
Block sizeBlock sizeFixed (page)Fixed (page)Variable (segment)Variable (segment)
Viewদৃষ্টিভঙ্গিPhysical, invisible to programmerPhysical, programmer দেখে নাLogical, matches program structureLogical, program-এর গঠন অনুযায়ী
FragmentationInternalInternalExternalExternal
Table storesTable-এ থাকেFrame numbersFrame numberBase + limitBase + limit
Address formAddress-এর রূপ(page, offset)(segment, offset)
Exam tip: Fast calculation facts: number of pages = logical address space / page size; page table entries = number of pages. Example: 32-bit address, 4 KB pages → offset 12 bits, page number 20 bits → \( 2^{20} \) ≈ 1M page table entries. Questions on bit-splitting are very common.
Exam tip: দ্রুত হিসাবের fact: page সংখ্যা = logical address space / page size; page table entry = page সংখ্যা। Example: 32-bit address, 4 KB page → offset 12 bit, page number 20 bit → \( 2^{20} \) ≈ 1M page table entry। Bit ভাগ করার প্রশ্ন খুব common।

6. Virtual Memory6. Virtual Memory

Demand Paging and Page FaultsDemand Paging and Page Faults

Virtual memory lets a program be bigger than RAM. With demand paging, a page is loaded into RAM only when it is first used — "lazy loading". Each page table entry has a valid/invalid bit. Accessing an invalid page triggers a page fault. Steps of a page fault:

  1. The MMU finds the invalid bit and traps to the OS.
  2. The OS checks: is this a real invalid access (kill the process) or just a page not yet in RAM?
  3. Find a free frame (if none, run a page replacement algorithm to evict one; write it to disk if dirty).
  4. Read the wanted page from disk into the frame.
  5. Update the page table (valid bit = 1, frame number).
  6. Restart the instruction that faulted.

Virtual memory-র কারণে program RAM-এর চেয়ে বড় হতে পারে। Demand paging-এ কোনো page প্রথমবার ব্যবহারের সময়ই কেবল RAM-এ আনা হয় — "lazy loading"। প্রতিটা page table entry-তে valid/invalid bit থাকে। Invalid page access করলে page fault হয়। Page fault-এর ধাপ:

  1. MMU invalid bit পেয়ে OS-কে trap করে।
  2. OS check করে: এটা কি সত্যিই invalid access (process kill) নাকি page শুধু RAM-এ নেই?
  3. খালি frame খোঁজে (না থাকলে page replacement algorithm চালিয়ে একটা বের করে; dirty হলে disk-এ লেখে)।
  4. দরকারি page disk থেকে frame-এ পড়ে।
  5. Page table update করে (valid bit = 1, frame number)।
  6. যে instruction-এ fault হয়েছিল সেটা আবার চালায়।

Effective access time with faults: if page fault rate is \( p \), memory access is \( m \), and fault service takes \( F \): \( EAT = (1-p) \times m + p \times F \). Faults are millions of times slower than RAM, so even a tiny \( p \) hurts a lot.

Fault সহ effective access time: page fault rate \( p \), memory access \( m \), fault service time \( F \) হলে: \( EAT = (1-p) \times m + p \times F \)। Fault RAM-এর চেয়ে লাখো গুণ ধীর, তাই খুব ছোট \( p \)-ও অনেক ক্ষতি করে।

Page Replacement — worked examples (BUET favorite)Page Replacement — worked examples (BUET favorite)

We use the classic reference string 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 with 3 frames. In the tables below, each column is one reference; F marks a page fault, H a hit. Frames show their contents after the reference.

Classic reference string 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 আর 3 frame ব্যবহার করব। নিচের table-এ প্রতিটা column একটা reference; F মানে page fault, H মানে hit। Frame-এ reference-এর পরের অবস্থা দেখানো হয়েছে।

FIFO (First-In, First-Out)

Evict the page that has been in memory the longest (the oldest arrival).

যে page সবচেয়ে আগে memory-তে এসেছে (oldest) তাকে বের করে দাও।

Ref70120304230321201701
F177722224440000000777
F20000333222221111100
F3111100033333322221
F/HFFFFHFFFFFFHHFHFHFFF

FIFO: 15 page faults (5 hits).

FIFO: 15 page fault (5 hit)।

Optimal (OPT)

Evict the page that will not be used for the longest time in the future. It gives the minimum possible faults, but it needs future knowledge — so it is only a benchmark to compare against.

যে page ভবিষ্যতে সবচেয়ে দেরিতে ব্যবহার হবে তাকে বের করো। এতে সবচেয়ে কম fault হয়, কিন্তু ভবিষ্যৎ জানতে হয় — তাই এটা শুধু তুলনার benchmark।

Ref70120304230321201701
F177722222222222222777
F20000000000000000000
F3111334433331111111
F/HFFFFHFHFHFHHHFHHHFHH

Optimal: 9 page faults. (At reference 4 we evict 1 because 0 and 2 are needed sooner; at reference 3 we evict 4 because it is never used again.)

Optimal: 9 page fault। (Reference 4-এ 1-কে বের করি কারণ 0 আর 2 আগে লাগবে; reference 3-এ 4-কে বের করি কারণ সে আর কখনো লাগবে না।)

LRU (Least Recently Used)

Evict the page that was not used for the longest time in the past. LRU uses history as a guess of the future. It is close to Optimal and never suffers Belady's anomaly (it is a "stack algorithm").

যে page অতীতে সবচেয়ে দীর্ঘ সময় ব্যবহার হয়নি তাকে বের করো। LRU অতীতকে ভবিষ্যতের অনুমান হিসেবে ব্যবহার করে। এটা Optimal-এর কাছাকাছি আর কখনো Belady's anomaly-তে ভোগে না ("stack algorithm")।

Ref70120304230321201701
F177722224440001111111
F20000000033333300000
F3111333222222222777
F/HFFFFHFHFFFFHHFHFHFHH

LRU: 12 page faults. Summary on this string with 3 frames: Optimal 9 < LRU 12 < FIFO 15.

LRU: 12 page fault। এই string-এ 3 frame-এ সারসংক্ষেপ: Optimal 9 < LRU 12 < FIFO 15।

Exam tip (LRU vs FIFO trick): FIFO evicts by arrival time; LRU evicts by last use time. A hit changes NOTHING in FIFO, but in LRU a hit makes that page "most recent" — this is where students lose marks. Always write the recency order beside each column for LRU. And count the first fills of empty frames as faults too (compulsory faults).
Exam tip (LRU vs FIFO trick): FIFO বের করে arrival time দেখে; LRU বের করে শেষ ব্যবহারের time দেখে। FIFO-তে hit হলে কিছুই বদলায় না, কিন্তু LRU-তে hit হলে সেই page "most recent" হয়ে যায় — এখানেই students নম্বর হারায়। LRU-তে প্রতি column-এর পাশে recency order লিখে রাখুন। আর খালি frame প্রথমবার ভরাটাও fault হিসেবে গুনবেন (compulsory fault)।

Belady's AnomalyBelady's Anomaly

Normally more frames → fewer faults. But with FIFO, sometimes more frames give MORE faults. Classic string: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5 — FIFO gives 9 faults with 3 frames but 10 faults with 4 frames. LRU and Optimal never show this anomaly.

সাধারণত frame বাড়লে fault কমে। কিন্তু FIFO-তে কখনো কখনো frame বাড়ালে fault-ও বাড়ে। Classic string: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5 — FIFO-তে 3 frame-এ 9 fault কিন্তু 4 frame-এ 10 fault। LRU আর Optimal-এ এই anomaly কখনো হয় না।

Thrashing and the Working SetThrashing and the Working Set

Thrashing: when a process does not have enough frames, it faults constantly — the system spends more time swapping pages than doing real work. CPU utilization drops, the OS thinks it should add more processes, and things get even worse.

Working set model: the working set is the set of pages a process used in the last \( \Delta \) references (its current "locality"). Give each process at least its working-set size of frames. If the total demand of all processes exceeds the number of frames, suspend some process — that prevents thrashing.

Thrashing: কোনো process যথেষ্ট frame না পেলে সে অনবরত fault করে — system আসল কাজের চেয়ে page swap-এই বেশি সময় দেয়। CPU utilization কমে যায়, OS ভাবে আরও process আনা দরকার, আর অবস্থা আরও খারাপ হয়।

Working set model: শেষ \( \Delta \)টা reference-এ process যে page-গুলো ব্যবহার করেছে সেটাই তার working set (বর্তমান "locality")। প্রতিটা process-কে অন্তত তার working-set size-এর frame দাও। সবার মোট চাহিদা frame সংখ্যার বেশি হলে কোনো process suspend করো — তাতেই thrashing আটকায়।

degree of multiprogramming → CPU utilization → thrashing starts
Adding processes helps CPU utilization — until memory runs out. Then thrashing begins and utilization crashes.Process বাড়ালে CPU utilization বাড়ে — যতক্ষণ না memory শেষ হয়। তারপর thrashing শুরু হয় আর utilization ধসে পড়ে।

7. File Systems7. File Systems

Files: Attributes and OperationsFiles: Attributes and Operations

A file is a named collection of related data on storage. Typical attributes: name, identifier (a unique number), type, location on disk, size, protection (who can read/write/execute), timestamps (created/modified/accessed), owner. These attributes are stored in the directory / inode, not inside the file data.

Basic operations: create, open, read, write, seek (reposition), delete, truncate, close. The OS keeps an open-file table with the current position pointer for each open file.

File হলো storage-এ রাখা নামওয়ালা একগুচ্ছ related data। সাধারণ attribute: name, identifier (একটা unique number), type, disk-এ location, size, protection (কে read/write/execute করতে পারবে), timestamp (created/modified/accessed), owner। এই attribute-গুলো থাকে directory / inode-এ, file-এর data-র ভেতরে না।

Basic operation: create, open, read, write, seek (অবস্থান বদলানো), delete, truncate, close। OS একটা open-file table রাখে যাতে প্রতিটা খোলা file-এর current position pointer থাকে।

Directory StructuresDirectory Structures

  • Single-level: all files in one directory. Naming clashes, no grouping.
  • Two-level: one directory per user. Users are separated, but no sub-grouping.
  • Tree: directories inside directories — what Windows/Linux use. Absolute path (from root, e.g. /home/user/a.txt) vs relative path (from the current directory).
  • Acyclic graph: a tree plus shared files/directories via links (UNIX hard links, symbolic links). Must be careful about cycles and deletion.
  • Single-level: সব file এক directory-তে। নাম নিয়ে সংঘর্ষ, কোনো grouping নেই।
  • Two-level: প্রতি user-এর একটা directory। User আলাদা, কিন্তু ভেতরে sub-grouping নেই।
  • Tree: Directory-র ভেতরে directory — Windows/Linux এটাই ব্যবহার করে। Absolute path (root থেকে, যেমন /home/user/a.txt) vs relative path (current directory থেকে)।
  • Acyclic graph: Tree + link দিয়ে shared file/directory (UNIX hard link, symbolic link)। Cycle আর deletion নিয়ে সাবধান থাকতে হয়।

Allocation MethodsAllocation Methods

How do we place a file's blocks on disk?

  • Contiguous: the file occupies consecutive blocks. Directory stores (start, length).
  • Linked: each block stores a pointer to the next block. Directory stores (first, last). FAT (File Allocation Table) is a smarter version: all the "next" pointers live in one table in memory.
  • Indexed: one index block holds the addresses of all data blocks. Directory points to the index block.

File-এর block-গুলো disk-এ কীভাবে রাখব?

  • Contiguous: File পাশাপাশি block-এ থাকে। Directory-তে থাকে (start, length)।
  • Linked: প্রতিটা block-এ পরের block-এর pointer থাকে। Directory-তে থাকে (first, last)। FAT (File Allocation Table) এর চালাক version: সব "next" pointer memory-র এক table-এ থাকে।
  • Indexed: একটা index block-এ সব data block-এর address থাকে। Directory index block-কে point করে।
Pointবিষয়ContiguousLinkedIndexed
Random (direct) accessRandom (direct) access Excellentচমৎকার Very bad (must walk the chain)খুব খারাপ (chain ধরে হাঁটতে হয়) Good (one index lookup)ভালো (একটা index lookup)
External fragmentationExternal fragmentation Yes — the big problemহ্যাঁ — বড় সমস্যা Noনেই Noনেই
File growthFile বড় হওয়া Hard (may need to move the file)কঠিন (file সরাতে হতে পারে) Easy (add a block anywhere)সহজ (যেকোনো জায়গায় block যোগ) Easy up to index limitsIndex-এর সীমা পর্যন্ত সহজ
OverheadOverhead None per blockBlock প্রতি নেই Pointer in every block; bad reliability (one lost pointer breaks the chain)প্রতি block-এ pointer; reliability খারাপ (একটা pointer হারালে chain ভাঙে) Extra index block per fileFile প্রতি বাড়তি index block
Used byব্যবহার করে CD-ROMs, old systemsCD-ROM, পুরনো system FAT (MS-DOS) UNIX inode, ext familyUNIX inode, ext family

The inode IdeaThe inode Idea

UNIX uses inodes: one inode per file stores the attributes plus a mixed index — typically 12 direct pointers (to data blocks), 1 single indirect (points to a block full of pointers), 1 double indirect, and 1 triple indirect. Small files are fast (direct pointers), and huge files are still possible (indirect levels).

UNIX inode ব্যবহার করে: প্রতি file-এর একটা inode-এ attribute + একটা মিশ্র index থাকে — সাধারণত 12টা direct pointer (data block-এ), 1টা single indirect (pointer-ভরা একটা block-কে point করে), 1টা double indirect, আর 1টা triple indirect। ছোট file দ্রুত (direct pointer), আবার বিশাল file-ও সম্ভব (indirect level)।

Example (max file size): Block size = 1 KB, pointer size = 4 bytes → one block holds 1024/4 = 256 pointers.
  • Direct: 12 × 1 KB = 12 KB
  • Single indirect: 256 × 1 KB = 256 KB
  • Double indirect: 256 × 256 × 1 KB = 64 MB
  • Triple indirect: 256 × 256 × 256 × 1 KB = 16 GB
Max file size ≈ 12 KB + 256 KB + 64 MB + 16 GB. This calculation is a favorite written question.
Example (max file size): Block size = 1 KB, pointer size = 4 byte → এক block-এ 1024/4 = 256টা pointer।
  • Direct: 12 × 1 KB = 12 KB
  • Single indirect: 256 × 1 KB = 256 KB
  • Double indirect: 256 × 256 × 1 KB = 64 MB
  • Triple indirect: 256 × 256 × 256 × 1 KB = 16 GB
Max file size ≈ 12 KB + 256 KB + 64 MB + 16 GB। এই হিসাবটা written প্রশ্নে খুব প্রিয়।

Free Space ManagementFree Space Management

  • Bit map (bit vector): one bit per block — 1 = free, 0 = used (or the opposite). Easy to find n consecutive free blocks; needs extra memory. Example: a 1 TB disk with 4 KB blocks needs 228 bits = 32 MB of bitmap.
  • Linked list: free blocks are chained together. No wasted space, but slow to traverse and hard to grab contiguous runs.
  • Grouping / counting: store addresses of many free blocks in one block, or store (start, count) pairs for runs of free blocks.
  • Bit map (bit vector): প্রতি block-এ এক bit — 1 = free, 0 = used (বা উল্টো)। পরপর n-টা free block খোঁজা সহজ; বাড়তি memory লাগে। Example: 4 KB block-এর 1 TB disk-এ লাগে 228 bit = 32 MB bitmap।
  • Linked list: Free block-গুলো chain করা থাকে। জায়গা নষ্ট হয় না, কিন্তু traverse ধীর আর পরপর block পাওয়া কঠিন।
  • Grouping / counting: এক block-এ অনেক free block-এর address রাখা, বা free run-এর (start, count) জোড়া রাখা।

Journaling (briefly)Journaling (সংক্ষেপে)

If power fails in the middle of a file operation, the file system can be left half-updated (metadata pointing to garbage). A journaling file system (ext4, NTFS) first writes the planned changes to a journal (log), then applies them, then marks them done. After a crash, the OS replays or discards journal entries — recovery takes seconds instead of a full disk scan (like old fsck).

File operation-এর মাঝখানে power চলে গেলে file system আধা-update অবস্থায় থাকতে পারে (metadata আবর্জনা point করছে)। Journaling file system (ext4, NTFS) আগে পরিকল্পিত change-গুলো একটা journal (log)-এ লেখে, তারপর apply করে, তারপর done mark করে। Crash-এর পর OS journal entry-গুলো replay বা বাদ দেয় — পুরো disk scan (পুরনো fsck)-এর বদলে কয়েক second-এ recovery হয়।

Exam tip: Match method to property fast: FAT = linked allocation with the pointers moved into a table; inode = indexed allocation; contiguous = best for sequential AND direct access but suffers external fragmentation; linked = no external fragmentation but terrible direct access.
Exam tip: দ্রুত মিলিয়ে ফেলুন: FAT = linked allocation, pointer-গুলো table-এ সরানো; inode = indexed allocation; contiguous = sequential আর direct access দুটোতেই সেরা কিন্তু external fragmentation-এ ভোগে; linked = external fragmentation নেই কিন্তু direct access খুব খারাপ।

Practice Questions (Admission Style)Practice Questions (Admission Style)

Q1. Which of the following is NOT a process state?
  • (a) Ready
  • (b) Running
  • (c) Compiled
  • (d) Waiting
Q1. নিচের কোনটা process state নয়?
  • (a) Ready
  • (b) Running
  • (c) Compiled
  • (d) Waiting
Show Answerউত্তর দেখুন
Answer: (c) — The five process states are new, ready, running, waiting, and terminated. "Compiled" describes a program file, not a running process.
Answer: (c) — পাঁচটা process state হলো new, ready, running, waiting আর terminated। "Compiled" একটা program file-এর কথা বলে, চলমান process-এর না।
Q2. Which information is stored in the PCB (Process Control Block)?
  • (a) Program counter and CPU registers
  • (b) Source code of the program
  • (c) The compiler used
  • (d) The monitor resolution
Q2. PCB (Process Control Block)-তে কোন তথ্য থাকে?
  • (a) Program counter আর CPU register
  • (b) Program-এর source code
  • (c) কোন compiler ব্যবহার হয়েছে
  • (d) Monitor-এর resolution
Show Answerউত্তর দেখুন
Answer: (a) — The PCB stores the process state, PID, program counter, register values, scheduling info, memory info, accounting info, and I/O status. Source code lives on disk, not in the PCB.
Answer: (a) — PCB-তে থাকে process state, PID, program counter, register-এর মান, scheduling info, memory info, accounting info আর I/O status। Source code থাকে disk-এ, PCB-তে না।
Q3. A program calls fork() three times in a row and then prints "Hi". How many times is "Hi" printed?
  • (a) 3
  • (b) 4
  • (c) 8
  • (d) 6
Q3. একটা program পরপর তিনবার fork() call করে তারপর "Hi" print করে। "Hi" কতবার print হবে?
  • (a) 3
  • (b) 4
  • (c) 8
  • (d) 6
Show Answerউত্তর দেখুন
Answer: (c) — Each fork doubles the number of processes: 1 → 2 → 4 → 8. So \( 2^3 = 8 \) processes each print once. (Number of new children created = 8 − 1 = 7.)
Answer: (c) — প্রতিটা fork process সংখ্যা দ্বিগুণ করে: 1 → 2 → 4 → 8। তাই \( 2^3 = 8 \)টা process প্রত্যেকে একবার print করে। (নতুন child তৈরি হয়েছে = 8 − 1 = 7টা।)
Q4. The convoy effect is a problem of which scheduling algorithm?
  • (a) Round Robin
  • (b) FCFS
  • (c) SJF
  • (d) Multilevel feedback queue
Q4. Convoy effect কোন scheduling algorithm-এর সমস্যা?
  • (a) Round Robin
  • (b) FCFS
  • (c) SJF
  • (d) Multilevel feedback queue
Show Answerউত্তর দেখুন
Answer: (b) — In FCFS, one long CPU-bound process at the front makes all the short processes wait behind it, like cars behind a slow truck. Preemptive algorithms like RR avoid this.
Answer: (b) — FCFS-এ সামনে থাকা একটা লম্বা CPU-bound process-এর পেছনে সব ছোট process আটকে থাকে, ধীর truck-এর পেছনে গাড়ির মতো। RR-এর মতো preemptive algorithm এটা এড়ায়।
Q5. (Written) For the table below, compute the average waiting time and average turnaround time for (i) FCFS and (ii) non-preemptive SJF.
P1: arrival 0, burst 5  |  P2: arrival 1, burst 3  |  P3: arrival 2, burst 8  |  P4: arrival 3, burst 6.
Q5. (Written) নিচের table-এর জন্য (i) FCFS এবং (ii) non-preemptive SJF-এ average waiting time আর average turnaround time বের করুন।
P1: arrival 0, burst 5  |  P2: arrival 1, burst 3  |  P3: arrival 2, burst 8  |  P4: arrival 3, burst 6।
Show Answerউত্তর দেখুন
Answer:

(i) FCFS — order of arrival P1, P2, P3, P4. Gantt: P1 (0→5), P2 (5→8), P3 (8→16), P4 (16→22).

  • Turnaround: P1 = 5−0 = 5, P2 = 8−1 = 7, P3 = 16−2 = 14, P4 = 22−3 = 19. Average TAT = (5+7+14+19)/4 = 11.25.
  • Waiting = TAT − burst: P1 = 0, P2 = 4, P3 = 6, P4 = 13. Average waiting = (0+4+6+13)/4 = 5.75.

(ii) SJF (non-preemptive) — at t=0 only P1 is there, so P1 runs 0→5. At t=5 the waiting jobs are P2 (3), P3 (8), P4 (6): pick shortest → P2 (5→8), then P4 (8→14), then P3 (14→22).

  • Turnaround: P1 = 5, P2 = 7, P4 = 11, P3 = 20. Average TAT = (5+7+20+11)/4 = 10.75.
  • Waiting: P1 = 0, P2 = 4, P4 = 5, P3 = 12. Average waiting = (0+4+12+5)/4 = 5.25.

SJF gives a smaller average waiting time, as expected.

Answer:

(i) FCFS — arrival order P1, P2, P3, P4। Gantt: P1 (0→5), P2 (5→8), P3 (8→16), P4 (16→22)।

  • Turnaround: P1 = 5−0 = 5, P2 = 8−1 = 7, P3 = 16−2 = 14, P4 = 22−3 = 19। Average TAT = (5+7+14+19)/4 = 11.25
  • Waiting = TAT − burst: P1 = 0, P2 = 4, P3 = 6, P4 = 13। Average waiting = (0+4+6+13)/4 = 5.75

(ii) SJF (non-preemptive) — t=0-তে শুধু P1 আছে, তাই P1 চলে 0→5। t=5-এ অপেক্ষায় P2 (3), P3 (8), P4 (6): সবচেয়ে ছোট → P2 (5→8), তারপর P4 (8→14), তারপর P3 (14→22)।

  • Turnaround: P1 = 5, P2 = 7, P4 = 11, P3 = 20। Average TAT = (5+7+20+11)/4 = 10.75
  • Waiting: P1 = 0, P2 = 4, P4 = 5, P3 = 12। Average waiting = (0+4+12+5)/4 = 5.25

প্রত্যাশা মতোই SJF-এ average waiting time কম।

Q6. (Written) Run Round Robin with time quantum = 2 on: P1 (arrival 0, burst 4), P2 (arrival 0, burst 5), P3 (arrival 0, burst 3). Draw the Gantt chart and compute the average waiting time.
Q6. (Written) Time quantum = 2 নিয়ে Round Robin চালান: P1 (arrival 0, burst 4), P2 (arrival 0, burst 5), P3 (arrival 0, burst 3)। Gantt chart আঁকুন আর average waiting time বের করুন।
Show Answerউত্তর দেখুন
Answer:

Queue starts [P1, P2, P3]. Trace, 2 units at a time (a process re-joins the back of the queue if it still has work):

  • 0→2: P1 (P1 left 2) — queue [P2, P3, P1]
  • 2→4: P2 (P2 left 3) — queue [P3, P1, P2]
  • 4→6: P3 (P3 left 1) — queue [P1, P2, P3]
  • 6→8: P1 finishes at 8 — queue [P2, P3]
  • 8→10: P2 (P2 left 1) — queue [P3, P2]
  • 10→11: P3 finishes at 11 — queue [P2]
  • 11→12: P2 finishes at 12.

Gantt: | P1 0–2 | P2 2–4 | P3 4–6 | P1 6–8 | P2 8–10 | P3 10–11 | P2 11–12 |

Turnaround: P1 = 8, P2 = 12, P3 = 11. Waiting = TAT − burst: P1 = 8−4 = 4, P2 = 12−5 = 7, P3 = 11−3 = 8. Average waiting = (4+7+8)/3 = 6.33. Average turnaround = (8+12+11)/3 = 10.33.

Answer:

Queue শুরুতে [P1, P2, P3]। প্রতি 2 unit করে trace (কাজ বাকি থাকলে process queue-এর পেছনে ফিরে যায়):

  • 0→2: P1 (P1-এর বাকি 2) — queue [P2, P3, P1]
  • 2→4: P2 (P2-এর বাকি 3) — queue [P3, P1, P2]
  • 4→6: P3 (P3-এর বাকি 1) — queue [P1, P2, P3]
  • 6→8: P1 শেষ 8-এ — queue [P2, P3]
  • 8→10: P2 (P2-এর বাকি 1) — queue [P3, P2]
  • 10→11: P3 শেষ 11-এ — queue [P2]
  • 11→12: P2 শেষ 12-এ।

Gantt: | P1 0–2 | P2 2–4 | P3 4–6 | P1 6–8 | P2 8–10 | P3 10–11 | P2 11–12 |

Turnaround: P1 = 8, P2 = 12, P3 = 11। Waiting = TAT − burst: P1 = 8−4 = 4, P2 = 12−5 = 7, P3 = 11−3 = 8। Average waiting = (4+7+8)/3 = 6.33। Average turnaround = (8+12+11)/3 = 10.33।

Q7. Which scheduling algorithm can never cause starvation?
  • (a) SJF
  • (b) Priority scheduling
  • (c) Round Robin
  • (d) SRTF
Q7. কোন scheduling algorithm-এ কখনো starvation হয় না?
  • (a) SJF
  • (b) Priority scheduling
  • (c) Round Robin
  • (d) SRTF
Show Answerউত্তর দেখুন
Answer: (c) — In Round Robin every process in the queue gets a quantum in turn, so everyone makes progress. In SJF/SRTF a long job can starve if short jobs keep arriving; in priority scheduling a low-priority job can starve (aging is the fix).
Answer: (c) — Round Robin-এ queue-এর প্রতিটা process পালাক্রমে quantum পায়, তাই সবাই এগোয়। SJF/SRTF-এ ছোট job আসতেই থাকলে লম্বা job starve করে; priority scheduling-এ কম priority-র job starve করে (সমাধান aging)।
Q8. A counting semaphore is initialized to 10. Then 6 wait() and 4 signal() operations are performed. What is the final value?
  • (a) 6
  • (b) 8
  • (c) 10
  • (d) 12
Q8. একটা counting semaphore-এর শুরুর মান 10। এরপর 6টা wait() আর 4টা signal() operation হলো। শেষ মান কত?
  • (a) 6
  • (b) 8
  • (c) 10
  • (d) 12
Show Answerউত্তর দেখুন
Answer: (b) — Each wait() decrements by 1, each signal() increments by 1. Final value = 10 − 6 + 4 = 8. (Since the value never went below 0 here, no process blocked.)
Answer: (b) — প্রতিটা wait() মান 1 কমায়, প্রতিটা signal() 1 বাড়ায়। শেষ মান = 10 − 6 + 4 = 8। (এখানে মান কখনো 0-এর নিচে যায়নি, তাই কোনো process block হয়নি।)
Q9. (Written) Two threads T1 and T2 each execute counter++ once, with counter = 5 initially. Explain, using the machine-level steps, how the final value can be 6 instead of 7, and name two tools that fix this.
Q9. (Written) দুইটা thread T1 আর T2 প্রত্যেকে একবার করে counter++ চালায়, শুরুতে counter = 5। Machine-level step দিয়ে ব্যাখ্যা করুন কীভাবে শেষ মান 7-এর বদলে 6 হতে পারে, আর এটা ঠিক করার দুইটা tool-এর নাম বলুন।
Show Answerউত্তর দেখুন
Answer:

counter++ = read, add 1, write (three steps). Bad interleaving: T1 reads 5 → T2 reads 5 (before T1 writes) → T1 writes 6 → T2 writes 6. One increment is lost, so the result is 6. This is a race condition: the result depends on execution order over shared data.

Fixes: put counter++ in a critical section using a mutex lock or a binary semaphore (wait before, signal after). A monitor or an atomic instruction (like test-and-set based locks) also works.

Answer:

counter++ = read, 1 যোগ, write (তিন step)। খারাপ interleaving: T1 পড়ে 5 → T2 পড়ে 5 (T1 লেখার আগেই) → T1 লেখে 6 → T2 লেখে 6। একটা increment হারিয়ে যায়, ফল 6। এটাই race condition: shared data-র ওপর ফলাফল execution order-এর ওপর নির্ভর করে।

সমাধান: counter++-কে critical section-এ রাখুন — mutex lock বা binary semaphore দিয়ে (আগে wait, পরে signal)। Monitor বা atomic instruction (যেমন test-and-set ভিত্তিক lock)-ও কাজ করে।

Q10. Which of the following is NOT one of the four Coffman conditions for deadlock?
  • (a) Mutual exclusion
  • (b) Hold and wait
  • (c) Preemption
  • (d) Circular wait
Q10. নিচের কোনটা deadlock-এর চারটা Coffman condition-এর একটা নয়?
  • (a) Mutual exclusion
  • (b) Hold and wait
  • (c) Preemption
  • (d) Circular wait
Show Answerউত্তর দেখুন
Answer: (c) — The condition is NO preemption (resources cannot be taken by force). "Preemption" itself actually helps break deadlock. The four conditions: mutual exclusion, hold and wait, no preemption, circular wait.
Answer: (c) — শর্তটা হলো NO preemption (জোর করে resource নেওয়া যায় না)। "Preemption" নিজে বরং deadlock ভাঙতে সাহায্য করে। চারটা শর্ত: mutual exclusion, hold and wait, no preemption, circular wait।
Q11. (Written) A system has 3 resource types A (9 total), B (3), C (6). The snapshot is:
P0: Allocation (1,0,0), Max (3,2,2) | P1: Allocation (6,1,2), Max (6,1,3) | P2: Allocation (2,1,1), Max (3,1,4) | P3: Allocation (0,0,2), Max (4,2,2).
(i) Compute the Need matrix and Available. (ii) Is the system in a safe state? If yes, give a safe sequence with full working.
Q11. (Written) একটা system-এ 3 ধরনের resource: A (মোট 9), B (3), C (6)। অবস্থা:
P0: Allocation (1,0,0), Max (3,2,2) | P1: Allocation (6,1,2), Max (6,1,3) | P2: Allocation (2,1,1), Max (3,1,4) | P3: Allocation (0,0,2), Max (4,2,2)।
(i) Need matrix আর Available বের করুন। (ii) System কি safe state-এ আছে? হলে পুরো হিসাবসহ একটা safe sequence দিন।
Show Answerউত্তর দেখুন
Answer:

(i) Need = Max − Allocation: P0 = (2,2,2), P1 = (0,0,1), P2 = (1,0,3), P3 = (4,2,0).
Total allocated = (1+6+2+0, 0+1+1+0, 0+2+1+2) = (9,2,5). Available = (9,3,6) − (9,2,5) = (0,1,1).

(ii) Safety check, Work = (0,1,1):

  • P0 needs (2,2,2) ≤ (0,1,1)? No. P1 needs (0,0,1) ≤ (0,1,1)? Yes → P1 finishes. Work = (0,1,1) + (6,1,2) = (6,2,3).
  • P0 needs (2,2,2) ≤ (6,2,3)? Yes → P0 finishes. Work = (6,2,3) + (1,0,0) = (7,2,3).
  • P2 needs (1,0,3) ≤ (7,2,3)? Yes → P2 finishes. Work = (7,2,3) + (2,1,1) = (9,3,4).
  • P3 needs (4,2,0) ≤ (9,3,4)? Yes → P3 finishes. Work = (9,3,4) + (0,0,2) = (9,3,6) = total.

All processes can finish → the system is safe. Safe sequence: ⟨P1, P0, P2, P3⟩.

Answer:

(i) Need = Max − Allocation: P0 = (2,2,2), P1 = (0,0,1), P2 = (1,0,3), P3 = (4,2,0)।
মোট allocated = (9,2,5)। Available = (9,3,6) − (9,2,5) = (0,1,1)

(ii) Safety check, Work = (0,1,1):

  • P0-এর দরকার (2,2,2) ≤ (0,1,1)? না। P1-এর দরকার (0,0,1) ≤ (0,1,1)? হ্যাঁ → P1 শেষ। Work = (0,1,1) + (6,1,2) = (6,2,3)।
  • P0-এর দরকার (2,2,2) ≤ (6,2,3)? হ্যাঁ → P0 শেষ। Work = (6,2,3) + (1,0,0) = (7,2,3)।
  • P2-এর দরকার (1,0,3) ≤ (7,2,3)? হ্যাঁ → P2 শেষ। Work = (7,2,3) + (2,1,1) = (9,3,4)।
  • P3-এর দরকার (4,2,0) ≤ (9,3,4)? হ্যাঁ → P3 শেষ। Work = (9,3,4) + (0,0,2) = (9,3,6) = মোট।

সব process শেষ করতে পারে → system safe। Safe sequence: ⟨P1, P0, P2, P3⟩

Q12. (Written) For the reference string 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5 with 3 frames, count the page faults for (i) FIFO and (ii) LRU. Which one performs better here?
Q12. (Written) Reference string 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5 আর 3 frame-এর জন্য (i) FIFO এবং (ii) LRU-তে page fault গুনুন। এখানে কোনটা ভালো করে?
Show Answerউত্তর দেখুন
Answer:

(i) FIFO (evict oldest arrival):

  • 1F [1], 2F [1,2], 3F [1,2,3], 4F evict 1 → [2,3,4], 1F evict 2 → [3,4,1], 2F evict 3 → [4,1,2], 5F evict 4 → [1,2,5], 1 hit, 2 hit, 3F evict 1 → [2,5,3], 4F evict 2 → [5,3,4], 5 hit.

FIFO faults = 9 (3 hits).

(ii) LRU (evict least recently used):

  • 1F, 2F, 3F, 4F evict 1 → [2,3,4], 1F evict 2 → [3,4,1], 2F evict 3 → [4,1,2], 5F evict 4 → [1,2,5], 1 hit, 2 hit, 3F evict 5 (1 and 2 were just used) → [1,2,3], 4F evict 1 → [2,3,4], 5F evict 2 → [3,4,5].

LRU faults = 10.

Here FIFO (9) beats LRU (10) — a good reminder that LRU is usually better but not always. (This is also the classic Belady string: FIFO with 4 frames gives 10 faults, more than with 3 frames.)

Answer:

(i) FIFO (oldest-কে বের করো):

  • 1F [1], 2F [1,2], 3F [1,2,3], 4F 1 বাদ → [2,3,4], 1F 2 বাদ → [3,4,1], 2F 3 বাদ → [4,1,2], 5F 4 বাদ → [1,2,5], 1 hit, 2 hit, 3F 1 বাদ → [2,5,3], 4F 2 বাদ → [5,3,4], 5 hit।

FIFO fault = 9 (3 hit)।

(ii) LRU (least recently used-কে বের করো):

  • 1F, 2F, 3F, 4F 1 বাদ → [2,3,4], 1F 2 বাদ → [3,4,1], 2F 3 বাদ → [4,1,2], 5F 4 বাদ → [1,2,5], 1 hit, 2 hit, 3F 5 বাদ (1 আর 2 এইমাত্র ব্যবহার হয়েছে) → [1,2,3], 4F 1 বাদ → [2,3,4], 5F 2 বাদ → [3,4,5]।

LRU fault = 10

এখানে FIFO (9) LRU (10)-কে হারায় — মনে রাখুন: LRU সাধারণত ভালো, কিন্তু সবসময় না। (এটাই classic Belady string: FIFO-তে 4 frame দিলে 10 fault হয়, 3 frame-এর চেয়ে বেশি।)

Q13. Page size is 1 KB. For the logical address 2500, what are the page number and offset?
  • (a) page 2, offset 452
  • (b) page 3, offset 428
  • (c) page 2, offset 500
  • (d) page 1, offset 476
Q13. Page size 1 KB। Logical address 2500-এর page number আর offset কত?
  • (a) page 2, offset 452
  • (b) page 3, offset 428
  • (c) page 2, offset 500
  • (d) page 1, offset 476
Show Answerউত্তর দেখুন
Answer: (a) — Page = ⌊2500 / 1024⌋ = 2. Offset = 2500 − 2×1024 = 2500 − 2048 = 452. (If the page table maps page 2 → frame f, the physical address is f×1024 + 452.)
Answer: (a) — Page = ⌊2500 / 1024⌋ = 2। Offset = 2500 − 2×1024 = 2500 − 2048 = 452। (Page table page 2 → frame f দিলে physical address = f×1024 + 452।)
Q14. (Written) What is thrashing? Why does adding more processes make it worse instead of better? How does the working set model prevent it?
Q14. (Written) Thrashing কী? আরও process যোগ করলে ভালো না হয়ে আরও খারাপ হয় কেন? Working set model কীভাবে এটা আটকায়?
Show Answerউত্তর দেখুন
Answer:

Thrashing = a process (or the whole system) spends more time servicing page faults (swapping pages in and out) than doing real work, because processes do not have enough frames for their current locality.

Why more processes hurt: when CPU utilization drops (everyone is waiting on disk), the OS thinks the CPU is idle and admits more processes. Each new process takes frames away from the others, so everyone's fault rate rises even more — a vicious cycle.

Working set fix: measure each process's working set (pages used in the last Δ references). Give each process at least that many frames. If the sum of all working sets exceeds available frames, suspend a process instead of admitting more. Demand never exceeds supply, so thrashing cannot start.

Answer:

Thrashing = কোনো process (বা পুরো system) আসল কাজের চেয়ে page fault সামলাতে (page আনা-নেওয়ায়) বেশি সময় দেয়, কারণ process-গুলো তাদের বর্তমান locality-র জন্য যথেষ্ট frame পায়নি।

বেশি process কেন ক্ষতিকর: CPU utilization কমলে (সবাই disk-এর অপেক্ষায়), OS ভাবে CPU খালি, তাই আরও process ঢোকায়। প্রতিটা নতুন process অন্যদের frame কেড়ে নেয়, ফলে সবার fault rate আরও বাড়ে — একটা দুষ্টচক্র।

Working set সমাধান: প্রতিটা process-এর working set মাপো (শেষ Δ reference-এ ব্যবহৃত page)। প্রত্যেককে অন্তত ততগুলো frame দাও। সব working set-এর যোগফল available frame-এর বেশি হলে নতুন ঢোকানোর বদলে একটা process suspend করো। চাহিদা কখনো জোগান ছাড়ায় না, তাই thrashing শুরুই হতে পারে না।

Q15. (Written, hard) A UNIX-style inode has 12 direct pointers, 1 single indirect, 1 double indirect, and 1 triple indirect pointer. Block size = 2 KB, each block pointer = 4 bytes. (i) How many pointers fit in one block? (ii) Compute the maximum file size contribution of each level and the total.
Q15. (Written, কঠিন) একটা UNIX-style inode-এ 12টা direct pointer, 1টা single indirect, 1টা double indirect আর 1টা triple indirect pointer আছে। Block size = 2 KB, প্রতিটা block pointer = 4 byte। (i) এক block-এ কয়টা pointer ধরে? (ii) প্রতিটা level-এর maximum file size-এ অবদান আর মোট হিসাব করুন।
Show Answerউত্তর দেখুন
Answer:

(i) Pointers per block = 2048 / 4 = 512.

(ii)

  • Direct: 12 × 2 KB = 24 KB.
  • Single indirect: 512 pointers × 2 KB = 1024 KB = 1 MB.
  • Double indirect: 512 × 512 × 2 KB = 262144 × 2 KB = 512 MB.
  • Triple indirect: 512 × 512 × 512 × 2 KB = 256 GB.

Total max file size = 24 KB + 1 MB + 512 MB + 256 GB ≈ 256.5 GB. Method to remember: each indirect level multiplies by (pointers per block) = block size / pointer size.

Answer:

(i) প্রতি block-এ pointer = 2048 / 4 = 512টা

(ii)

  • Direct: 12 × 2 KB = 24 KB
  • Single indirect: 512 pointer × 2 KB = 1024 KB = 1 MB
  • Double indirect: 512 × 512 × 2 KB = 262144 × 2 KB = 512 MB
  • Triple indirect: 512 × 512 × 512 × 2 KB = 256 GB

মোট max file size = 24 KB + 1 MB + 512 MB + 256 GB ≈ 256.5 GB। মনে রাখার নিয়ম: প্রতিটা indirect level-এ (প্রতি block-এর pointer সংখ্যা) = block size / pointer size দিয়ে গুণ হয়।

Q16. (Written, Real exam style — April 2017) Define multiprogramming, multitasking, and multithreading. For each, state (i) the unit of work, (ii) the main goal, and (iii) what triggers a switch. Give one example of each.
Q16. (Written, Real exam style — April 2017) Multiprogramming, multitasking আর multithreading define করুন। প্রতিটার জন্য লিখুন: (i) কাজের unit, (ii) মূল লক্ষ্য, (iii) switch কীসে ঘটে। প্রতিটার একটা করে example দিন।
Show Answerউত্তর দেখুন
Answer:

Multiprogramming: several jobs are kept in memory at the same time. When the running job blocks (waits for I/O), the CPU switches to another ready job. (i) Unit: whole processes/jobs. (ii) Goal: throughput — never let the CPU sit idle. (iii) Switch trigger: the running job blocks (no timer). Example: an old batch mainframe that runs job B while job A waits for the card reader.

Multitasking (time-sharing): the CPU switches between tasks very rapidly using a timer interrupt (preemption), giving each a small time slice. (i) Unit: tasks/processes of one or many users. (ii) Goal: responsiveness — the machine feels instant to everyone. (iii) Switch trigger: the time slice ends (preemptive), or the task blocks. Example: your PC "simultaneously" running a browser, a music player, and an editor.

Multithreading: one process contains many threads that all share the same address space (code, data, heap, open files) but have their own stack, registers, and program counter. (i) Unit: threads inside ONE process. (ii) Goal: parallel work inside a single program, with cheap creation and cheap context switches. (iii) Switch trigger: the scheduler switches threads — fast, because the address space does not change. Example: a browser where one thread renders the page while another downloads images.

One-line contrast: multiprogramming = many jobs in memory (switch on block); multitasking = multiprogramming + rapid timer-based preemption; multithreading = many execution units inside one process sharing memory.

Answer:

Multiprogramming: একসাথে কয়েকটা job memory-তে রাখা হয়। চলমান job block হলে (I/O-এর অপেক্ষায়), CPU অন্য ready job-এ চলে যায়। (i) Unit: পুরো process/job। (ii) লক্ষ্য: throughput — CPU-কে কখনো বসিয়ে না রাখা। (iii) Switch: চলমান job block হলে (timer নেই)। Example: পুরনো batch mainframe — job A card reader-এর অপেক্ষায় থাকলে job B চলে।

Multitasking (time-sharing): CPU একটা timer interrupt দিয়ে (preemption) খুব দ্রুত task বদলায়, প্রত্যেকে ছোট time slice পায়। (i) Unit: এক বা অনেক user-এর task/process। (ii) লক্ষ্য: responsiveness — সবার কাছে machine instant মনে হয়। (iii) Switch: time slice শেষ হলে (preemptive), বা task block হলে। Example: আপনার PC-তে "একসাথে" browser, গান আর editor চলা।

Multithreading: একটা process-এর ভেতরে অনেক thread — সবাই একই address space (code, data, heap, open file) share করে, কিন্তু নিজের stack, register আর program counter আলাদা। (i) Unit: এক process-এর ভেতরের thread। (ii) লক্ষ্য: এক program-এর ভেতরে parallel কাজ, সস্তা creation আর সস্তা context switch। (iii) Switch: scheduler thread বদলায় — দ্রুত, কারণ address space বদলায় না। Example: browser-এ এক thread page আঁকে, আরেকটা image download করে।

এক লাইনে পার্থক্য: multiprogramming = memory-তে অনেক job (block হলে switch); multitasking = multiprogramming + timer দিয়ে দ্রুত preemption; multithreading = এক process-এর ভেতরে অনেক execution unit, memory shared।

Q17. (Written, Real exam style — October 2017 & April 2019) A system has a 16-bit logical address and page size 4 KB. The page table is: page 0 → frame 9, page 1 → frame 4, page 2 → frame 11, page 3 → frame 6. (i) How many bits are used for the page number and how many for the offset? (ii) For logical address 13500, find the page number, the offset, and the physical address. (iii) What is the maximum number of pages this process can have?
Q17. (Written, Real exam style — October 2017 & April 2019) একটা system-এ 16-bit logical address আর page size 4 KB। Page table: page 0 → frame 9, page 1 → frame 4, page 2 → frame 11, page 3 → frame 6। (i) Page number-এ কত bit আর offset-এ কত bit? (ii) Logical address 13500-এর page number, offset আর physical address বের করুন। (iii) এই process সর্বোচ্চ কয়টা page পেতে পারে?
Show Answerউত্তর দেখুন
Answer:

(i) Page size = 4 KB = \( 2^{12} \) bytes → offset = 12 bits. Page number = 16 − 12 = 4 bits.

(ii) Step by step:

  • Page number p = ⌊13500 / 4096⌋ = 3 (because 3 × 4096 = 12288 ≤ 13500 < 16384).
  • Offset d = 13500 − 12288 = 1212.
  • Page table: page 3 → frame 6.
  • Physical address = frame × page size + offset = 6 × 4096 + 1212 = 24576 + 1212 = 25788.

(iii) Page number has 4 bits → maximum \( 2^4 = \) 16 pages (page 0 to page 15). Total logical space = 16 × 4 KB = 64 KB = \( 2^{16} \) bytes — consistent with the 16-bit address.

Answer:

(i) Page size = 4 KB = \( 2^{12} \) byte → offset = 12 bit। Page number = 16 − 12 = 4 bit

(ii) Step by step:

  • Page number p = ⌊13500 / 4096⌋ = 3 (কারণ 3 × 4096 = 12288 ≤ 13500 < 16384)।
  • Offset d = 13500 − 12288 = 1212
  • Page table: page 3 → frame 6
  • Physical address = frame × page size + offset = 6 × 4096 + 1212 = 24576 + 1212 = 25788

(iii) Page number 4 bit → সর্বোচ্চ \( 2^4 = \) 16টা page (page 0 থেকে page 15)। মোট logical space = 16 × 4 KB = 64 KB = \( 2^{16} \) byte — 16-bit address-এর সাথে মিলে যায়।