Scene 1 of 100
`; }}, { title: "Classic Problem: Readers-Writers", text: "The Readers-Writers problem models access to a shared database. Multiple 'readers' can access the data simultaneously, but a 'writer' must have exclusive access.", viz: () => { /* static viz */ vizPanel.innerHTML = `

Readers-Writers Visualization: Many readers can enter, but a writer locks everyone out.

`; }}, { title: "Classic Problem: Dining Philosophers", text: "The Dining Philosophers problem is a classic example of deadlock. Five philosophers sit at a table with five chopsticks. Each needs two chopsticks to eat. If all pick up their left chopstick simultaneously, they all get stuck waiting for the right one, and no one can eat.", viz: () => { /* Generic placeholder for complex animation */ vizPanel.innerHTML = `

Dining Philosophers Animation: Illustrates deadlock when all philosophers grab their left chopstick.

`; }}, // Part 8: Deadlock (Scenes 84-90) { title: "What is Deadlock?", text: "In a multiprogramming environment, several processes may compete for a finite number of resources. A deadlock is a state where a set of blocked processes each holds a resource and is waiting to acquire a resource held by another process in the set.", viz: () => { vizPanel.innerHTML = `
P1 wants R2
โฎ‚
Resource
Conflict
โฎ€
P2 wants R1
`; }}, { title: "The Four Necessary Conditions", text: "A deadlock can arise if and only if four conditions hold simultaneously: Mutual Exclusion, Hold and Wait, No Preemption, and Circular Wait.", viz: () => { vizPanel.innerHTML = `
Mutual Exclusion
Hold and Wait
No Preemption
Circular Wait
`; anime({targets:'.cond-card', opacity:[0,1], scale:[0.5,1], delay:anime.stagger(100)}); }}, { title: "Resource Allocation Graph", text: "Deadlocks can be described more precisely using a directed graph called a system resource-allocation graph. A cycle in this graph is a necessary condition for a deadlock.", viz: () => { vizPanel.innerHTML = `
`; anime({targets: '.fade-in', opacity: [0, 1], duration: 1000}); } }, { title: "Deadlock Handling Strategies", text: "We can deal with the deadlock problem in one of three ways: prevent or avoid them by ensuring the system will never enter a deadlock state; allow the system to enter a deadlock state and then detect and recover from it; or ignore the problem and pretend that deadlocks never occur.", viz: () => { vizPanel.innerHTML = `
Prevention
Avoidance
Detection & Recovery
Ignorance (Ostrich Algorithm)
`; anime({targets:'.strat-card', opacity:[0,1], translateX:[-20,0], delay:anime.stagger(150)}); }}, { title: "Deadlock Prevention", text: "Deadlock prevention works by ensuring that at least one of the four necessary conditions cannot hold. For example, we could require processes to request all their resources at once (breaking 'Hold and Wait') or impose a total ordering of all resource types (breaking 'Circular Wait').", viz: () => { /* Static placeholder */ vizPanel.innerHTML = `

Preventing one of the four conditions breaks the cycle.

`; } }, { title: "Deadlock Avoidance", text: "Deadlock avoidance requires that the OS be given additional information in advance concerning which resources a process will request. The OS can then use algorithms like the Banker's Algorithm to ensure the system always stays in a 'safe state' where a deadlock is impossible.", viz: () => { vizPanel.innerHTML = `
Safe State
โž”
Unsafe State
โž”
Deadlock
`; }}, { title: "Deadlock Detection & Recovery", text: "If a system does not employ a prevention or avoidance algorithm, a deadlock may occur. It must then provide an algorithm that examines the state of the system to determine whether a deadlock has occurred and an algorithm to recover from the deadlock, typically by terminating processes or preempting resources.", viz: () => { vizPanel.innerHTML = `
1. Detect Deadlock Cycle
๐Ÿ”„
2. Break the Cycle (Recover)
`; }}, // Part 9: Memory Management (Scenes 91-95) { title: "Memory Management Basics", text: "For a program to be executed, it must be mapped to absolute addresses and loaded into memory. The memory management unit (MMU) of the OS is responsible for dynamically handling the allocation and deallocation of memory space.", viz: () => { vizPanel.innerHTML = `
Program on Disk
โž”
MMU
โž”
Physical Memory
`; }}, { title: "Address Binding", text: "The mapping from symbolic program addresses to physical memory addresses can happen at three different stages: Compile time, Load time, or Execution time. Execution time binding is the most flexible and is required for virtual memory.", viz: () => { vizPanel.innerHTML = `
Compile Time
Load Time
Execution Time
`; anime({targets:'.bind-time', opacity:[0,1], translateY:[20,0], delay: anime.stagger(200)}); }}, { title: "Logical vs Physical Address", text: "An address generated by the CPU is a logical address, whereas an address seen by the memory unit is a physical address. The Memory-Management Unit (MMU) is the hardware device that maps logical to physical addresses.", viz: () => { vizPanel.innerHTML = `
CPU โ†’ Logical Addr
โž”
MMU
โž”
Memory โ†’ Physical Addr
`; }}, { title: "Paging Explained", text: "Paging is a memory management scheme that permits a process's physical address space to be noncontiguous. It avoids external fragmentation by dividing logical memory into fixed-size blocks called 'pages' and physical memory into 'frames'.", viz: () => { /* complex animation placeholder */ vizPanel.innerHTML = `

Paging Animation: Shows logical pages mapped to physical frames via a page table.

`; } }, { title: "Segmentation Explained", text: "Segmentation is a memory-management scheme that supports the user's view of memory. A logical address space is a collection of segments. Each segment has a name and a length. Addresses specify both the segment name and the offset within the segment.", viz: () => { /* static placeholder */ vizPanel.innerHTML = `

Segmentation Diagram: Code, data, and stack segments mapped to physical memory.

`; } }, // Part 10: Virtual Memory & File Systems (Scenes 96-100) { title: "Virtual Memory Concept", text: "Virtual memory is a technique that allows the execution of processes that may not be completely in memory. This separation of user logical memory from physical memory gives programmers the illusion of a very large (virtual) memory.", viz: () => { vizPanel.innerHTML = `
Physical Memory
Virtual Memory
`; }}, { title: "Demand Paging", text: "Demand paging is the most common implementation of virtual memory. A page is brought into main memory only when it is needed, i.e., on 'demand'. An access to a page not in memory results in a 'page fault'.", viz: () => { vizPanel.innerHTML = `
Access Memory Address X...
PAGE FAULT!
Fetch page from disk...
`; anime({targets:'div > div', opacity:[0,1], translateY:[20,0], delay:anime.stagger(400)}); }}, { title: "Page Replacement Algorithms", text: "If there are no free frames when a page fault occurs, a page replacement algorithm selects a 'victim' frame to be paged out. Common algorithms include FIFO (First-In, First-Out) and LRU (Least Recently Used).", viz: () => { /* static placeholder */ vizPanel.innerHTML = `

Page Replacement Animation: Shows FIFO vs LRU choices.

`; }}, { title: "File System Concepts", text: "A file is a named collection of related information that is recorded on secondary storage. The file system provides the mechanism for online storage and access to both data and programs.", viz: () => { vizPanel.innerHTML = `
๐Ÿ“„ ๐Ÿ“ ๐Ÿ“‚
File System
`; }}, { title: "Course Complete", text: "Thank you for completing this interactive lesson on Operating Systems. You've covered the core concepts that power every modern computer.

โ€œTechnology is just a tool. In terms of getting the kids working together and motivating them, the teacher is the most important.โ€

- Bill Gates

", viz: () => { vizPanel.innerHTML = `

Congratulations!

You've reached the end.

`; anime({ targets: '.fade-in', opacity: [0, 1], translateY: [20, 0], delay: anime.stagger(200) }); } } ]; function renderScene(index) { if (index < 0 || index >= scenes.length) { return; } const scene = scenes[index]; const timeline = anime.timeline({ duration: 400, easing: 'easeOutExpo' }); timeline .add({ targets: '#text-panel, #viz-panel', opacity: 0, translateY: 10, complete: () => { // Update Text Panel textPanel.innerHTML = `

${scene.title}

${scene.text}
`; // Update Visualization Panel vizPanel.innerHTML = ''; if (scene.viz) { scene.viz(); } // Update Controls currentSceneIndex = index; sceneCounter.textContent = `Scene ${index + 1} of ${scenes.length}`; progressBar.style.width = `${((index + 1) / scenes.length) * 100}%`; prevBtn.disabled = index === 0; nextBtn.disabled = index === scenes.length - 1; } }) .add({ targets: '#text-panel, #viz-panel', opacity: 1, translateY: 0 }); } prevBtn.addEventListener('click', () => { if (currentSceneIndex > 0) { renderScene(currentSceneIndex - 1); } }); nextBtn.addEventListener('click', () => { if (currentSceneIndex < scenes.length - 1) { renderScene(currentSceneIndex + 1); } }); document.addEventListener('keydown', (e) => { if (e.key === 'ArrowRight') { nextBtn.click(); } else if (e.key === 'ArrowLeft') { prevBtn.click(); } }); // Initial render renderScene(0);