KEMBAR78
Operating Systems Practical File | PDF
0% found this document useful (0 votes)
3 views29 pages

Operating Systems Practical File

The document provides a comparative overview of hardware and software requirements for various operating systems including UNIX, Linux, Windows XP, Windows 7, and Windows 8. It details processor, RAM, and hard disk space requirements, along with optional components for each OS. Additionally, it includes examples of C programs demonstrating UNIX system calls, CPU scheduling algorithms, and file storage allocation techniques.

Uploaded by

sundramthakur847
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
0% found this document useful (0 votes)
3 views29 pages

Operating Systems Practical File

The document provides a comparative overview of hardware and software requirements for various operating systems including UNIX, Linux, Windows XP, Windows 7, and Windows 8. It details processor, RAM, and hard disk space requirements, along with optional components for each OS. Additionally, it includes examples of C programs demonstrating UNIX system calls, CPU scheduling algorithms, and file storage allocation techniques.

Uploaded by

sundramthakur847
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
You are on page 1/ 29
AIML 2™ year 4" sem LAB ~I [BATCH I = 7 ‘Understanding the hardware and software requirements of various operating syst . )is essential for ensuring optimal performance and compat ity. Below is a comparative overview of the requirements for X. Linuy, Windows XP, Windows 7, and Windows 8: " NIX: dare Requirements © Processor: Minimum 1 GHz processor, * RAME Atleast 1 GB RAM. Mard Disk Space: Minimum 10 GB of free disk space. finsare Requirements: * UNIXcompatible operating systems such as Sun Sokiris, IBM AIX, or HP-UX. © Optional: Compiler and development tools, Optional: X Window System for a graphical user interface (GUD.— * _ Optignal: Networking tools for network communication. — = Linux: Hardware Requirements: * Processor: Minimum 1 GHz processor. RAM: Atleast I GB RAM (2 GB recommended for better performance), ‘© Hard Disk Spa Minimum 10 GB of free disk Space (20 GB recommended). Software Requirements: Linux distributions such as Ubuntu, Fe sdora, CentOS, of Debian. Optional: GUL pions: Compiler and development tots Optional: Neworking tools for network communication, Jos XI Hardare Requirements 1 RRGeeior Pentium 239 Mhz or faster (300 Me recommende), RAM: Minimum 6B RAM (128 MB recommended), s,, HaTd Disk Space: Atleast L.5 GB a fice disk one Software Requiremennse es Windows XP operating system, ‘ + Coan pena? gph eich WDDM der eninced graphic * Optional: Nenworking tools for ‘network communication, ‘ AWindows 7: * Mabe are Resuiremens %rocestor: | Gitzo faster processor. RAL J GB RAM (32-53 oF2 Gi RAM (4, 1, at Disk Space: 16 G8 G2-hit or Store Reremeng COR G2 We 20 (64-bit) oF ree disk space, Windons 7 opcraing system Phonak: Direc 9 graphics device as # Netrking ool for network communica ee eT BE GU Hohe are Wivemesus, : Mis uatt Dish Spove: 16 GiB Addit) os fe 2 Windus Wy ne © scanned with OKEN Scanner 5 Optional DirectX 9 graphies device with WDPM 1.0 or higher deer for GUE Features. # Optional: Networking tools for network communication! 1LUNINE Hardsvare Requirements an Solaris supports ocnor: UNIX operating stn can un on a vay hardreset, Por insta, SPARC processors wile IDM ATX designed for POWER arti RAM The memory eguremens vy depending onthe UNIX recom et GB oF RAM fr pial efomancss Mar Disk Space The dk se euenes lr ae on te UNIX tribunal compen For ‘example, HP-UX recommends a minimum of 10 GB'of free disk space for a standard installation, Software Requirements: hil ‘+ UNIX-Compatible Operating Systems: Examples inelude Sun Solaris, BM AIX, and HP-UX, Bach has is own set of hardware compatibility and requirements © Optionat Component s it and intended use. For example, IBM AIX © Compiler and Development Tools: These are essential fr software development. For example, GCC (GNU Compiler Collection) is widely used in UNIX environments. © X.Window System: Provides a graphical user interface. For instance, the X.Org Server is commonly used in UNIX systems. © Networking Tools: Uilities lke netstat, ssh, and fip facilitate network communication. 2.Linw Hardvare Requirements: © Processor: Linux supports a wide range of processors, from older 32-bit x86 to modem 64-bit arc AMD64 and ARM. © RAM: While minimal installations can run on $12 MB, distributions like Ubuntu recommend at least 2 GB for a smoother experience ‘© Hard Disk Space: A basic Linus installation ean require as litle as 2 GB, but distributions like Fedora or Ubuntu may reed more space, especially wi additional software packages. Software Requirements: ‘© Linux Distributions: Examples include Ubuntu, Fedora, CentOS, and Debian, Each offers different desktop ‘environments and package management systems. © Optional Components: ‘0 Graphical User Interface (GUD): Desktop environments like GNOME, KDE, or XFCE enance user interaction. © Compiler and Development Tools: Tools like GCC and make are essential For compiling software, ‘© Networking Tools: Utilities such as ifeonfig, ping, and wget are integral for network management. 2 3, Windows XP: Hardhvare Requirements: ‘© Processor: Intel Pentium Ill 233 MHlz or higher. ‘© RAM: Minimum of 64 MB; however, 128 MB is recommended for better performance. ‘© Hard Disk Space: Atleast 1.5 GB of free disk space, Softivare Requirements: ‘© Operating System: Windows XP Home Euition or Windows XP Professional © Optional Components: ; DirectX 9 Graphies Device: Necessary for enhanced grapes performance, especially fn gaming. ©. Networking Tools: Features like Inlet Connection Sharing and Rewote Desktop reute appropriate networking configurations. 4. Windows 7: Hardware Requirement © Processor: | Gllzor faster processor. ‘¢RAM:1 GB RAM for 32-bit or2 GB RAM for 61-bit systems, Hard Disk Spaces 16 GBB for 32-bit oF 20 GB for 64-bit system Software Requlrentents: © Operating Systems Windows 7 Starter, Hone Pre © Optional Component rn, Professional, Uti e. or Puterpeiseetons, © scanned with OKEN Scanner © DirectX 9 Graphics Device with WDDNE LO Driver: Reyuired for Acro Class interface ad other graphical Networking Toots Ineludes HomeGroup Far easy filesharing an onter networking titi, 5. Windows Mantware Requirements: + Process 1 GHz oF faster processor with support for PAL, NX, and 4 RAM:1 GI RAM for 32-bit or GI RAM for 64-bit systems Mara Disk Space: 16 GI for 32-bit oF 20 GI fir 64-bit ystems Software Requiremems + Operating System: Windows % or Windows 8 Pr editions. © Optional Components: on WDM 1.0 Dry need networking Features like improved Wie supp css forthe Windows 8 raphe inert i d VPN client. 6 ‘a © scanned with OKEN Scanner Program 2 rv Execute various UNIX system calls for i, Process management , ji. File management, : ili, Input/output System calls iv. Solution: Here’s a C program demonstrating various UNIX system calls related to: + i Process management File management + iii, Input/output system calls Each section includes basic yet illustrative system calls. E4Full C Program: UNIX System Call Demonstration Finclude finclude #include finclude finclude finclude include dnt main() { printf (" “\n") UNIX System Call Demonstration = // i. PROCESS MANAGEMENT printf ("\n--- Process Management -~-\n"); pid_t pid = fork(); // create a child process 4£ (pid < 0) { perror ("Fork failed"); exit (1)7 } else if (pid == 0) ( printf ("Child Process: PID = 4d\n", getpid())7 printf ("Child says: Hello fom child process!\n"); exit(0); // child exits } else ( Wait (NULL); // parent waits for child to finish printf("Parent Process: PID = $d\n", getpid())+ peint£ ("Parent says: Child process finished. \n"); © scanned with OKEN Scanner // 34, FILE MANAGEMENT printf ("\n--~ File Management ---\n"); int fd = open("demo.txt", O_CREAT | 0_WRONLY | 0 TRUNC, 0644); if (fd <0) { perror("File open error"); exit (1); ) const char *text = "This is a demo file written using system calls.\n"; write(fd, text, strlen(text)}; close( fa) ; // 433. INPUT/OUTPUT SYSTEM CALLS printf ("\n--- Input/Output System Calls ---\n"); char buffer[100); printf ("Enter some text: "); ssize_t bytesRead = read(STDIN_FILENO, buffer, sizeof (buffer)); buffer[bytesRead) = '\0'; // null-terminate input printf£("You entered: %s", buffer); return 0; CO Compile & Run the Program gcc unix_syscalls.c -o unix_syscalls -/unix_syscalls 0 Explanation of System Calls Used Category System Call) Purpose Process Management fork(), getpid(), wait () Create child, get PID, wait for child File Management open), weite(), close() Create/write to file VO System Calls read(),STOIN_FILENO Input from user using system-level read © scanned with OKEN Scanner Program 3 Implement CPU Scheduling Policies: i SUF, ii, Priority FCFS, iv. Multi-level Queue. Here's a complete C program that demonstrates CPU Scheduling Algorithms: i, Shortest Job First (SIF) ii, Priority Scheduling First-Come First-Serve (FCFS) iv. Multilevel Queue Scheduling Each algorithm is implemented separately for clarity. EZFull C Program: CPU Scheduling Algorithms Hinclude fdefine max 10 typedef struct ( int pid: int bt; // Burst Time int at; // Arrival Time int pri; // Priority int queue; // Queue number (for multilevel) ) Process; // Punction for FCFS Scheduling void ECFS(Process p{], int n) ( printf ("\n--- ECES Schedud int wt(n), tatinl; we[0] = 07 for (int i= 1; i < nj it) we{i) = we[i-1] + pli} ber for (int i= 0; £ < nj its) tatit] = welil + pii}.bty © scanned with OKEN Scanner print ("PID\EBT\EWT\LTAT\N") ; for (int i= 0; d < nz iv) printf("td\tid\tid\ttd\n", pli} pid, pli]-bt, weil, tat(il)s ) 7/ Function for SIF Scheduling void SJF(Process pl], int n) ( printf ("\n--~ SUP Scheduling Process temp; int wt{n], tat(n}; \n") J/ Sort based on Burst Time for (int i= 07 i < nei; i++) for (int j= itl; $< ny 444) if (pIj].bt < plil-bt) { temp = plil; pit) = pig] pj] = temps we[o} = for (int i= 1: i < ny itt) we[i] = wei-2] + pli-t).bty 0; A < mp itt) wed] + pli] .bts for (int i tatii) print ("PID\tBE\tHT\tTAT\n") ; for (int i= 0; i < nj itt) printg("éd\téd\ttd\ttd\n", p[i]-pid, p{i].bt, we(i], tat(i])+ ) // Bunction for Priority Scheduling void Priority(Process p[], int n) { printf ("\n--- Priority Scheduling -~-\n"); Process temp; int we(n), tatin}s J/ Sort based on Priority (lower number = higher priority) for (int i= 0; 4 #include #include #define MAX BLOCKS 100 © scanned with OKEN Scanner Ant disk[MAX BLOCKS}; // 0: free, 1: allocated Ide 77 Contiguous Allocation 1] aannnne Void contiguousAllocation() { int start, length, flag = 07 print£("\n[Contiguous Allocation] \n") 7 printf ("Enter starting block and length of file: scanf("id $d", kstart, glength): if (start + length > MAX_BLOCKS) ( print£("Allocation exceeds disk size.\n")i return; d - for (int i = start; i < start + length; i++) { if (disk[i] == 1) { flag = 1; break; d , a it (flag) { printf ("Contiguous blocks not available.\n"); } else ( for (int i = start; i < start + lengths i++) disk{i}] = 1s printé ("File allocated at blocks: Ve for (int i = start; i < start + length; i++) printé("*d ", i); printé ("\n"): ) WW arom // Yinked List Allocation UD wnenmn oo —— typedef struct Node { int block; Struct Node* next; } Node © void linkedListAllocation() ( “Ant n, blocks Node* head = NULL, *tenp = NULL, *newNode: printf ("\n{Linked List Allocation) \n")7 printé ("Enter number of blocks: "); seanf("sd", én)i for (int i= 07 i = MAX BLOCKS || disk{bLock} © scanned with OKEN Scanner printf ("Invalid or already allocated block.\n"); return ) disk{block] = 1; newNode = (Node*)malloc (sizeof (Node) ); newNode->block = block: newNode->next = NULL; if (head == NULL) head = newNode; else ‘temp->next = newNode; temp = newNiode; ) printf ("File allocated at blocks: "); temp = head; while (temp) ( printf("$d ", temp->block); temp = temp->next; d printé("\n"); // Free Linked list while (head) { temp = head; head = head->next; free (temp); ) 1 i= // Indexed Allocation Ml ~ void indexedAllocation() { int indexBlock, n, block; printé("\n[Indexed Allocation} \n"); printf ("Enter index block: ")7 scanf("td", GindexBlock) ; (Af (disk[indexBlock) == 1) ( print£ ("Index block already allocated. \n"); return; ) printf ("Enter number of blocks: " scanf("sd", &n)i int blocks{n]7 for (int {= 0; i < nz it) ( printé ("Enter block number td: " scan ("%d", Gblocks|1})7 bee © scanned with OKEN Scanner Sf (Dlocks|4] <0 11 blocks (1) > MAX_BLOCI printf("Block Ad is invalid or already all retur ’ disk[indexBlock) = for (int i= 0; i < np it) disk[blocks [iJ] printf ("File indexed at block td\n", indexBlock) ; printf ("Allocated data blocks: "); for (int i= 0; 4 < nz iss) printf("td ", blocks{i]}; printf ("\n") ; Uf wonnennn 17 Main Function a= int main() int choice; while (1) { printf£("\n--- File Storage Allocation Menu =--\n' printf£("l. Contiguous Allocation\n"); printf("2, Linked List Allocation\n"); printf ("3. Indexed Allocat {on\n’ print£("4. Exit\n"); printf ("Choose method: "} scanf("td", choice) switch (choice) ( ease 1: contiguousAllocation(); breaks case 2: linkedListAllocation(); break case 3: indexedAllocation(); breaks case 4: exit(0); default: printf ("Invalid choice!\n"); ) j return 0; 1 Compile & Run gee file allocation. -o file al +/file allocation LB ‘This simulation uses a 1D array to represent the disk (si si differently: aki blocks {if} == 1) ted.\n", blocks {lite "Ye ‘ach method allocates space © scanned with OKEN Scanner « Contiguous: Allocates blocks in a continuous segment. « Linked: Uses pointers (linked list). « Indexed: A single index block holds references to all file blocks. © scanned with OKEN Scanner Program 5 MV Implementation of contiguous allocation techniques: i. Worst-Fit ii. Best- Fit iii, First- Fit. Solution: Here is a C program that implements Contiguous Memory Allocation Techniques: Worst-Fit Best-Fit i. First-Fit These algorithms are applied to allocate memory blocks to incoming processes based on different strategies, $$ EAC Program: Contiguous Allocation (Worst, Best, First Fit) #include define MAX 20 void firstFit(int blocksize[], int m, int processSizef}, int n) { int allocation[n); for (int i= 0; i = processsize{i]) ( allocation{i] = 3; blockSize[j] -= processSize [i]; break; ) print£("\nFirst Fit Allocation:\n"); for (int i= 0; i ", i + 1, pri ssSize(1}): © scanned with OKEN Scanner 4£ (allocation{i} te =1) peqhIMEEC*BLOCK ¥d\nM, atlocatton{i1 + 112 printf ("Not Allocated\n® ) void bestFit(int blockSize(], int m, int processsize(], int n) { int allocationin]; for (int i= 0; 4 = processSize(i]) ( if (bestIdx == -1 || blockSize[j] < blockSize(bestidx! ) bestIdx ) if (bestIdx != -1) ( allocation[i] = bestidx; blockSize(bestIdx] -= processSize[1]; ) print£("\nBest Fit Allocation:\n"); for (int i= 07 i < ny itt) { printf ("Process td ($d KB) -> ", 4 +1, processSize(il)s if (allocation(i} 1) printf ("Block td\n", allocation{i] + 1); else printf ("Not Allocated\n"); ) 9 void worstFit (int blockSize[], int m, int processSize[], int n) { * int allocation(n]; for (int i= 0; 4 < nz i++) allocation{i] = -17 for (int i= 0; i < nz itt) ( int worstIdx = -1; for (int j = 0; 3 = processSize(il) { if (WorstIdx == -1 || blockSize(j} > blockSize{worst!ax}) worstIdx = 3; ) 4f (worstIdx != -1) ( allocation{i] = worstIdx; blockSize[worstIdx] -= processSize(1]; © scanned with OKEN Scanner print£("\nWorst Fit Allocation:\n"); for (int 4 i ", 4 + 1, processSize(il)s if (allocation[i] != -1) J om printf ("Block $d\n", allocation(i) + 1) else printf ("Not Allocated\n"); int main() { int blockSize(MAK], processSize[MAX] + int m,n; printf ("Enter number of memory blocks scanf("8d", m) printf ("Enter size of each memory block (in XB) :\n")i for (int i = 07 i < mp itt) { printf ("Block #d: ", i + 1)s scanf ("$d", eblockSize(i}); } print£("\nEnter number of processes: "J+ scant ("8d", &n)7 printé("Enter memory requirement of for (int i= 0; i < ns itt) ( printf ("Process td: ", i + 107 scanf("#d", sprocessSize[i])? each process (in KB):\n"); } int block1{MAX], block2(MAK], block3[MAK]+ for (int 4 = 0; i < mj itt) { block [i] = block2[1] = block3(4] = blockSize[i]i } firstFit (blockl, m, processSize, n)? bestFit (block2, m, processSize, n)i worstFit (block3, m, processSize, n)i return 0; 0 Sample Input Enter number of memory blocks: 5 Block 1: 100 Block 2: 500 Block 3/200 Block 4: 300 Block 5: 600 Enter number of processes: 4 Rennace 2 912 © scanned with OKEN Scanner Process 4: 426 0 Compile & Run gcc memory allocation.c -o memory allocation -/memory_ allocation eeteriemetde ae eS This program shows how each algorithm works: * First Fit: Allocates the first block that is big enough. ° Best Fit: Allocates the smallest sufficient block. * Worst Fit: Allocates the largest available block, © scanned with OKEN Scanner 0 C Program: Fragmentation Calculation Hinclude #define MAX 50 int main() { int blockCount, processCount; int blocks (MAX), processes[MAX], allocation (MAx] int i, 3¢ printf ("Enter number of memory blocks: "); scanf("8d", &blockCount) ; printf ("Enter size of each block:\n"); for (i = 0; i < blockCounts i++) ( printf("Block td: ", i + 1); scanf("td", sblocks[i]); y print£("\nEnter number of processes: "); scanf("éd", sprocessCount) ; printf ("Enter size of each process:\n"); for (i = 0; i < processCount; it+) { printf ("Process #d: ", i + 1); scanf("$d", sprocesses{i]}; } // First-Fit Allocation for (i = 0; i < processCount; itt) ( allocation{i] = -17 for (3 = 0; j < blockCount; j++) ( if (blocks[j] >= processes{i]}) { allocation[i] = 3; blocks[j] -= processes[i]; // reduce available block break; } // Calculate fragmentation int internalFragmentation = 0; for (i= 0; i < processCount; i++) ( if (allocation{i] != -1) internalFragmentation += blocks(allocation(ill: int externalFragmentation = 0; int unallocated » 07 for (i = 0) 4 < progessCount; i++) { if {allocation{i] == -1) ( unallocated++; ) © scanned with OKEN Scanner if (unallocated > 0) { for (i = 0; 4 < blockCount; i++) externalFragmentation 4= blocks (il; ) // Output allocation result printf ("\nProcess Allocation: \n") for (i = 07 i < processCount; i++) { printf£("Process &d (td KB) -> ", i + 1, processes(i]}; if (allocation[i) != -2) print£("Block $d\n", allocation[i] + 1); else : printf ("Not Allocated\n"); ) print£("\nfotal Internal Fragmentation: ¢d KB\n", internalfragmentation) ; if (unallocated > 0) printf("Total External Fragmentatiot externalFragmentation) ; else Sa KB\n", printf("No External Fragmentation (All processes allocated) \n' return 0; 0 Sample Input: Enter number of memory blocks: 4 Block 1: 100 Block 2: 500 Block 3: 200 Block 4: 300 Enter number of processes: 3 Process 1: 212 Process 2: 417 Process 3: 112 O Compile & Run gcc fragmentation.c -o fragmentation :/fragmentation ‘This program uses First-Fit strategy and shows how much memory is: + Wasted inside blocks (internal), Wasted outside due to fragmentation of free blocks (extemal). © scanned with OKEN Scanner Pi 7 rogram 7 Y > Implementation of compaction for the continually changing memory layout and calculate total movement of data, Hee program that simulates memory compaction —a process of rearranging memory so {fat all free memory isin one large contiguous block — and caleulates the total data moved during compaction, EZFeatures: + Simulates memory blocks (used + free), Simulates processes occupying memory (with starting address and size). 1 Compacts memory by moving all processes together to remove extemal fragmentation, * Caleulates total data movement during compaction. OC Program: Memory Compaction Simulation Hinclude fidefine MAX 20 ODF Greet exzact ¢ int pidy // Process 1D int start; // Start address int size; JI Menory size ) Process; int main() { int n, memorySize, totalMoved = 0; Process processes [MAX]; printf ("Enter total memory size; Scant ("td", Gmemcrysi ze) ; printf ("Enter number of processes: "); scant ("8d", én); // Input processes for (int 1 = 0; £ < nz 444) | Printf ("Enter Process ID, Start Address, and s fas dt ays (in kB) for Process © scanned with OKEN Scanner scan ("sdidid", gprocesses(s].pid, sprocosses(i) -start, sprocesses|i} size); ) // Sort processes based on their start address for (int i= 0; ion = 1; its) { for (int j= 0; 3 processes{j + 1].start) ( Process temp = processes (j]7 processes(j] = processes(} + 1]/ processes(j + 1] = temp; y printf ("\nBefore Compaction: \n"); for (int i= 0; i < ny its) { printé ("Process $d: Start = %d, Size = td\n", processes[i].pid, processes[i].start, processes[i] size) ; ) // Perform Compaction int currentStart = 07 for (int i= 0; i #include #define MAX 20 int main() { int p, rz // number of processes int rag{MAX] [MAX] = 10); // adja char nodeName[MAX][10); // node © scanned with OKEN Scanner prints (Enter number of procoaseat ")s scant ("2d", tpt printf ("Enter numbor of resources: ")y cits, oye int total = ptr 71 Naming nodes for for (int 4 int sprintf (nodeWame {i}, "Pid", 4 + 1) = 0; R1 > P2 > R2 — P1 (deadlock). 0 Sample Output: Resource Allocation Graph (Adjacency Matrix): Pi. Pe Al Re PIR), 0 1:, 0 P2470 0 O 1 Rigg 0:1 0. 0 Roe. 0. 0. 0 0 Additions You Can Make: Detect cycle in the graph (for deadlock detection). . Visualize using a graph-drawing tool or matrix plot. © scanned with OKEN Scanner Program 9 >» Implementation of Banker?s algorithm. Here's a C program to im; plement the Banker's A\ to avoid deadlock by ches Igorithm, which is use cking fora safe sequence of process execution. EiFeatures: * Accepts input for: Number of processes and resources, Allocation matrix (current resource allocation) Maximum matrix (maximum demand). © Available resources, * Computes the Need matrix, + Checks for a safe sequence using Banker's Algorithm, Reports whether the system is in a safe state or not. ° C Program: Banker's Algorithm #include include © scanned with OKEN Scanner #define MAX 10 int main() 4 int py my // n= number of processes, m= nunbor of resources int alloc {MAX} [MAX], max {MAXI [MAX], need MARL foe ee Sy arabe AK! Vy need {MAX} (MAXI; bool finish[MAX] = {false}; aint safeSeq[MAX], count = 0; printf("Enter number of processes: "); scanf("$d", én) i printf ("Enter number of resource type: scanf("8d", @m); printf ("Enter Allocation Matrix:\n"); for (int i= 0; i avail(3]) break; aim) 2 ee a thie process can be completed for (int k = 0; k < mz ke) avail[k] += alloc{il(k)s safeSeq{countt+] * 47 finish{i} = trues found = trues © scanned with OKEN Scanner ) if (! found) printf("\nSystem is NOT in a safe state return 1; (Deadlock possible) \n"); ) // Print safe sequence 4 printf ("\nSystem is in a SAFE state.\nSafe sequence is: "); ne for (int i = 0; i P3 -> P4 -> PO -> v2 Let me know if you'd like this with resource request simulation, GUI visualization, or C++/Python version. © scanned with OKEN Scanner

You might also like