OS LAB MANUAL
OS LAB MANUAL
Comma
Slot: E11+E12+C14.
1. File Management Commands
Description
Example
nd
Date: 11/12/24
ls Lists files and directories. ls -l (detailed view).
cp Copies files or directories. cp file1.txt file2.txt.
mv Moves or renames files or mv file1.txt
directories. newname.txt.
rm Removes files or directories. rm file1.txt.
touch Creates an empty file. touch newfile.txt.
2. Piping (|):
Common Symbols:
Symb Description Example
1
ol
> Redirect output (overwrite ls > filelist.txt
file).
>> Redirect output (append to echo "Hello" >> filelist.txt
file).
< Redirect input from a file. sort < unsorted.txt
` ` Pipe output of one command to
another.
2> Redirect error output. ls non_existent_file 2> error.txt
2
Command Description Type
3
BELOW ARE SOME MORE COMMANDS FOR THE WINDOWS
4
5
EXPERIMENT 2
Process Creation and Management
Aim: A program to create a clone.
Whenever a program gets a fork statement than at the same instance clone is created
and starts executing from there only, both the process is parent and child.
CODE:
#include<stdio.h>
#include<unistd.h>
int main(){
fork();
printf("HELLO WORLD -> My PID is %d\n",getpid());
return 0;
}
OUTPUT:
CODE:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
6
// create a new program
pid_t pid = fork();
// error handling
if (pid < 0)
{
// fork failed
printf("forkfailed");
return 1;
}
else if (pid == 0)
{
// child process
printf("child process\n");
printf("child process ID: %d\n", getpid());
printf("Parent process ID: %d\n", getppid());
}
else
{
// parent process
printf("parent process\n");
printf("parent process ID: %d\n", getpid());
printf("child process id: %d\n", pid);
}
return 0;
}
OUTPUT:
The fork system create a new process by duplicating the calling process after calling fork.
7
Aim: Implement the parent-child process relationship
and demonstrate process termination.
CODE:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
pid_t pid = fork();
if (pid < 0)
{
// fork failed
printf("forkfailed");
return 1;
}
else if (pid == 0)
{
// child process
printf("child process\n");
printf("child process ID: %d\n", getpid());
printf("Parent process ID: %d\n", getppid());
printf("child process will terminate now\n");
exit(0);
}
else
{
// parent process
printf("parent process\n");
printf("parent process ID: %d\n", getpid());
printf("waiting for child process to terminate...\n");
int status;
wait(&status); // Wait for the child process to terminate
if (WIFEXITED(status))
{
printf("CHILD PROCESS TERMINATED WITH EXIT STATUS: %d\n",
WEXITSTATUS(status));
}
else
{
8
printf("Child process did not terminate successfully\n");
}
printf("Parent process will terminate now\n");
}
return 0;
}
OUTPUT:
1. In this program the child process prints its PID and its parent’s PID then
terminates.
2. The parent process wait for the child to finish , checks its exit status and then
continues to its termination.
CODE:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork(); // Create a child process
if (pid < 0) {
9
// Error occurred
perror("fork failed");
return 1;
}
if (pid == 0) {
// Child process
printf("Child process: PID = %d\n", getpid());
execl("/bin/ls", "ls", "-l", NULL); // Replace current process with "ls" command
// This line will not be executed unless execl fails
printf("After exec()\n");
} else {
// Parent process
int status;
wait(&status); // Wait for the child to finish
if (WIFEXITED(status)) {
printf("Parent process: Child exited with status %d\n", WEXITSTATUS(status));
}
printf("Parent process: PID = %d\n", getpid());
}
return 0;
}
In Unix-like systems, processes are identified by unique Process IDs (PIDs). The
parent process can create child processes using fork(), and the child process can
use getpid() to get its own PID. After a child process terminates, the parent can
use wait() to check the status of the child process, such as whether it exited
normally or if there was an error.
Key Functions:
fork(): Creates a new child process. Returns 0 in the child process, and the child’s
PID in the parent.
getpid(): Returns the PID of the calling process.
wait(): Makes the parent process wait for the child to terminate and returns the
child's exit status.
WIFEXITED(status): Checks if the child terminated normally.
WEXITSTATUS(status): Retrieves the child's exit status.
CODE:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork(); // Create a child process
10
if (pid < 0) {
// Error occurred
perror("fork failed");
return 1;
}
if (pid == 0) {
// Child process
printf("Child process: PID = %d\n", getpid());
// Simulate some work
printf("Child process is doing work...\n");
_exit(0); // Exit the child process with status 0 (success)
} else {
// Parent process
int status;
wait(&status); // Wait for the child process to finish
printf("Parent process: PID = %d\n", getpid());
if (WIFEXITED(status)) {
// Check if the child exited normally
printf("Child exited with status %d\n", WEXITSTATUS(status));
} else {
printf("Child process did not exit normally\n");
}
}
return 0;
}
11
EXPERIMENT 3
CPU Scheduling Algorithms
1. AIM: WRITE A C PROGRAM TO STIMULTE FCFS(FIRST
COME FIRST SERVE) SCHEDULING ALGORITHM
CODE:
#include <stdio.h>
struct Process {
int id;
int arrivalTime;
int burstTime;
int waitingTime;
int turnaroundTime;
};
float totalWaitingTime = 0;
float totalTurnaroundTime = 0;
12
printf("\nProcess ID\tArrival Time\tBurst Time\tWaiting Time\tTurnaround Time\n");
for (int i = 0; i < n; i++) {
totalWaitingTime += proc[i].waitingTime;
totalTurnaroundTime += proc[i].turnaroundTime;
printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\n",
proc[i].id, proc[i].arrivalTime, proc[i].burstTime,
proc[i].waitingTime, proc[i].turnaroundTime);
}
printf("\nAverage Waiting Time: %.2f", totalWaitingTime / n);
printf("\nAverage Turnaround Time: %.2f\n", totalTurnaroundTime / n);
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
struct Process proc[n];
findavgTime(proc, n);
return 0;
}
OUTPUT:
13
2. AIM: WRITE A C PROGRAM TO IMPLEMENT
SHORTEST JOB FIRST SCHEDULING WITH AND
WITHOUT PREEMTION
1.PREEMTIVE
CODE:
#include <stdio.h>
struct Process {
int id;
int arrivalTime;
int burstTime;
int remainingTime;
int waitingTime;
int turnaroundTime;
};
14
while (complete < n) {
minIndex = -1;
int minBurst = 9999;
if (minIndex != -1) {
proc[minIndex].remainingTime--;
t++;
if (proc[minIndex].remainingTime == 0) {
proc[minIndex].turnaroundTime = t - proc[minIndex].arrivalTime;
proc[minIndex].waitingTime = proc[minIndex].turnaroundTime -
proc[minIndex].burstTime;
totalWaitingTime += proc[minIndex].waitingTime;
totalTurnaroundTime += proc[minIndex].turnaroundTime;
complete++;
}
} else {
t++; // No process is ready, increment time
}
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
sortProcesses(proc, n);
findAvgTime(proc, n);
return 0;
}
OUTPUT:
16
17
1. NON PREEMTIVE
CODE:
#include <stdio.h>
struct Process {
int id;
int arrivalTime;
int burstTime;
int waitingTime;
int turnaroundTime;
};
float totalWaitingTime = 0;
float totalTurnaroundTime = 0;
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
sortProcesses(proc, n);
findAvgTime(proc, n);
return 0;
}
OUTPUT:
19
AIM: WRITE A C PROGRAM TO STIMULATE RR(ROUND
ROBIN) ALGORITHM AND CALCULATE TURN AROUND
AND WAITING TIME
CODE:
#include <stdio.h>
struct Process {
int id;
int burstTime;
int remainingTime;
int waitingTime;
int turnaroundTime;
};
20
printf("\nProcess ID\tBurst Time\tWaiting Time\tTurnaround Time\n");
for (int i = 0; i < n; i++) {
totalWaitingTime += proc[i].waitingTime;
totalTurnaroundTime += proc[i].turnaroundTime;
printf("%d\t\t%d\t\t%d\t\t%d\n",
proc[i].id, proc[i].burstTime,
proc[i].waitingTime, proc[i].turnaroundTime);
}
int main() {
int n, timeQuantum;
findWaitingTime(proc, n, timeQuantum);
findAvgTime(proc, n);
return 0;
}
OUTPUT:
21
AIM: WRITE A C PROGRAM TO IMPLEMENT PRIORITY
SCHEDULING AND TEST IT WITH DIFFERENT SETS OF
PRIORITIES
CODE:
#include <stdio.h>
struct Process {
int id;
int burstTime;
int waitingTime;
int turnaroundTime;
int priority;
};
float totalWaitingTime = 0;
float totalTurnaroundTime = 0;
22
totalWaitingTime += proc[i].waitingTime;
totalTurnaroundTime += proc[i].turnaroundTime;
printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\n",
proc[i].id, proc[i].burstTime, proc[i].priority,
proc[i].waitingTime, proc[i].turnaroundTime);
}
int main() {
int n;
findAvgTime(proc, n);
return 0;
}
OUTPUT:
23
EXPERIMENT 4
Interprocess Communication (IPC)
1)Write a program using pipes for IPC between parent and child
processes.
CODE:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
int pipefd[2];
pid_t pid;
char write_msg[] = "Hello from parent!";
char read_msg[100];
// Create a pipe
pipe(pipefd);
pid = fork();
if (pid < 0) {
perror("fork failed");
return 1;
}
if (pid == 0) {
// Child process - read from pipe
close(pipefd[1]); // Close the write end
read(pipefd[0], read_msg, sizeof(read_msg));
printf("Child received: %s\n", read_msg);
close(pipefd[0]);
} else {
// Parent process - write to pipe
close(pipefd[0]); // Close the read end
write(pipefd[1], write_msg, strlen(write_msg) + 1);
close(pipefd[1]);
}
return 0;
}
24
2. Shared Memory for Communication Between Multiple
Processes
CODE:
#include <stdio.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <string.h>
int main() {
int shm_id;
char *shm_ptr;
char write_msg[] = "Shared memory communication!";
return 0;
}
25
3) Message Queues for Data Exchange Between
Processes
CODE:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct message {
long msg_type;
char msg_text[100];
};
int main() {
key_t key = ftok("progfile", 65);
int msgid;
struct message msg;
// Send a message
msg.msg_type = 1;
strcpy(msg.msg_text, "Message Queue Communication!");
msgsnd(msgid, &msg, sizeof(msg), 0);
printf("Message Sent: %s\n", msg.msg_text);
// Receive a message
msgrcv(msgid, &msg, sizeof(msg), 1, 0);
printf("Message Received: %s\n", msg.msg_text);
CODE:
#include <stdio.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
sem_t *sem;
int main() {
// Create a semaphore
sem = sem_open("/sem_example", O_CREAT, 0644, 1);
if (sem == SEM_FAILED) {
perror("sem_open failed");
return 1;
}
// Critical section
printf("Process in critical section\n");
return 0;
}
27
EXPERIMENT 5
Thread Creation and Synchronization
Multithreading allows multiple threads (smaller units of a process)
to execute independently but share the same resources.
Multithreading can lead to performance improvements, but it also
introduces challenges such as race conditions. In this experiment,
we will use POSIX threads (pthreads) in C to create threads,
synchronize them using mutexes or semaphores, and resolve
issues like race conditions.
CODE:
#include <stdio.h>
#include <pthread.h>
int main() {
pthread_t threads[5];
int rc;
long t;
// Create 5 threads
for (t = 0; t < 5; t++) {
rc = pthread_create(&threads[t], NULL, print_message, (void*) t);
if (rc) {
printf("Error creating thread %ld\n", t);
return 1;
}
}
// Join threads to ensure they complete before the main thread ends
for (t = 0; t < 5; t++) {
pthread_join(threads[t], NULL);
28
}
return 0;
}
CODE:
#include <stdio.h>
#include <pthread.h>
int main() {
pthread_t threads[5];
int rc;
long t;
29
// Join threads to ensure they complete before the main thread ends
for (t = 0; t < 5; t++) {
pthread_join(threads[t], NULL);
}
CODE:
#include <stdio.h>
#include <pthread.h>
int counter = 0;
int main() {
pthread_t threads[5];
int rc;
// Create 5 threads
for (int t = 0; t < 5; t++) {
rc = pthread_create(&threads[t], NULL, increment_counter, NULL);
if (rc) {
printf("Error creating thread\n");
return 1;
}
}
// Join threads to ensure they complete before the main thread ends
for (int t = 0; t < 5; t++) {
pthread_join(threads[t], NULL);
}
30
printf("Counter value: %d\n", counter); // This might not be the expected value due to
race condition
return 0;
}
CODE:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int count = 0;
pthread_mutex_t mutex;
pthread_cond_t not_full;
pthread_cond_t not_empty;
31
pthread_cond_wait(¬_full, &mutex);
}
buffer[count++] = rand() % 100; // Produce a random number
printf("Produced: %d, Buffer size: %d\n", buffer[count - 1], count);
pthread_cond_signal(¬_empty); // Signal the consumer
pthread_mutex_unlock(&mutex);
sleep(1); // Simulate some work
}
return NULL;
}
int main() {
pthread_t producer_thread, consumer_thread;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(¬_full, NULL);
pthread_cond_init(¬_empty, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(¬_full);
pthread_cond_destroy(¬_empty);
return 0;
}
32
EXPERIMENT 6
Deadlock Detection and Prevention
CODE:
#include <stdio.h>
while (1) {
int progress_made = 0;
for (int i = 0; i < P; i++) {
if (!finish[i]) {
int can_allocate = 1;
for (int j = 0; j < R; j++) {
if (need[i][j] > work[j]) {
can_allocate = 0;
break;
}
}
if (can_allocate) {
for (int j = 0; j < R; j++) {
work[j] += allocation[i][j];
}
finish[i] = 1;
progress_made = 1;
}
}
}
if (!progress_made) {
break;
}
}
int main() {
int processes[] = {0, 1, 2, 3, 4}; // Process IDs
int available[] = {3, 3, 2}; // Available resources
int allocation[P][R] = {
{0, 1, 0},
{2, 0, 0},
{3, 0, 3},
{2, 1, 1},
{0, 0, 2}
};
int max[P][R] = {
{7, 5, 3},
{3, 2, 2},
{9, 0, 2},
{2, 2, 2},
{4, 3, 3}
};
return 0;
}
The Banker's Algorithm ensures that the system will never enter an
unsafe state by evaluating resource allocation requests and verifying if
they will lead to a deadlock. The algorithm avoids deadlock by ensuring
the system is always in a safe state.
#include <stdio.h>
int allocation[P][R] = {{0, 1, 0}, {2, 0, 0}, {3, 0, 3}, {2, 1, 1}, {0, 0, 2}};
int request[P][R] = {{1, 0, 2}, {1, 0, 0}, {0, 1, 1}, {1, 1, 0}, {0, 0, 1}};
int available[R] = {3, 3, 2};
int safe_state() {
int finish[P] = {0}; // To track processes that have finished
int work[R];
for (int i = 0; i < R; i++) {
work[i] = available[i];
}
while (1) {
int progress = 0;
for (int i = 0; i < P; i++) {
if (!finish[i]) {
int can_allocate = 1;
for (int j = 0; j < R; j++) {
if (request[i][j] > work[j]) {
can_allocate = 0;
break;
}
}
if (can_allocate) {
for (int j = 0; j < R; j++) {
work[j] += allocation[i][j];
}
finish[i] = 1;
progress = 1;
}
}
}
if (!progress) {
break;
}
}
int main() {
if (safe_state()) {
printf("The system is in a safe state.\n");
} else {
printf("Deadlock detected.\n");
}
return 0;
36
}
Here, both processes are waiting for the other to release a resource,
leading to a deadlock.
Resolution:
EXPERIMENT 7
Memory Management Techniques
Paging:
CODE:
#include <stdio.h>
37
// Function to simulate paging
void simulate_paging(int pages[], int num_pages, int frames[], int num_frames) {
int page_faults = 0;
int main() {
int pages[] = {0, 1, 2, 3, 0, 1, 2, 4, 5, 6}; // Reference string of pages
int num_pages = sizeof(pages) / sizeof(pages[0]);
int frames[FRAME_SIZE]; // Frame array to hold pages in memory
return 0;
}
38
Segmentation:
CODE:
#include <stdio.h>
#define MAX_SEGMENTS 5
int main() {
int segments[] = {10, -1, 20, 30, -1}; // Example segment table (use -1 for
unallocated)
39
int num_segments = sizeof(segments) / sizeof(segments[0]);
simulate_segmentation(segments, num_segments);
return 0;
}
FIFO (First-In-First-Out):
FIFO replaces the page that has been in memory the longest.
FIFO Algorithm in C:
CODE:
#include <stdio.h>
#define FRAME_SIZE 4
int main() {
int pages[] = {0, 1, 2, 3, 0, 1, 2, 4, 5, 6};
int num_pages = sizeof(pages) / sizeof(pages[0]);
int frames[FRAME_SIZE] = {-1, -1, -1, -1};
return 0;
}
LRU replaces the page that has not been used for the longest period.
CODE:
#include <stdio.h>
41
#define FRAME_SIZE 4
frames[min_index] = page;
page_faults++;
}
int main() {
int pages[] = {0, 1, 2, 3, 0, 1, 2, 4, 5, 6};
int num_pages = sizeof(pages) / sizeof(pages[0]);
int frames[FRAME_SIZE] = {-1, -1, -1, -1};
42
return 0;
}
CODE:
#include <stdio.h>
int main() {
int blocks[BLOCKS] = {10, 20, 30, 40, 50}; // Memory blocks
int processes[PROCESSES] = {5, 10, 15}; // Process sizes
43
return 0;
}
EXPERIMENT 8
File System Implementation
44
1)Write a program to simulate the creation, deletion,
and manipulation of files in a
directory.
we need to implement basic file system operations like creating, deleting,
and manipulating files within a directory. This would involve:
Create File: Add a new file to the directory, storing its name, size,
and allocation information.
Delete File: Remove a file from the directory and free up the
allocated space.
Manipulate File: Perform file operations such as renaming,
reading, or writing (this can be simulated using file metadata).
CODE:
#include <stdio.h>
#include <string.h>
#define MAX_FILES 10
#define MAX_NAME_LENGTH 50
// Initialize directory
void initDirectory(struct Directory *dir) {
dir->fileCount = 0;
}
// Create a file
void createFile(struct Directory *dir, char *name, int size) {
if (dir->fileCount < MAX_FILES) {
strcpy(dir->files[dir->fileCount].name, name);
dir->files[dir->fileCount].size = size;
dir->files[dir->fileCount].location = dir->fileCount; // Location =
index in directory
dir->fileCount++;
printf("File '%s' created.\n", name);
45
} else {
printf("Directory full. Cannot create more files.\n");
}
}
// Delete a file
void deleteFile(struct Directory *dir, char *name) {
for (int i = 0; i < dir->fileCount; i++) {
if (strcmp(dir->files[i].name, name) == 0) {
for (int j = i; j < dir->fileCount - 1; j++) {
dir->files[j] = dir->files[j + 1];
}
dir->fileCount--;
printf("File '%s' deleted.\n", name);
return;
}
}
printf("File '%s' not found.\n", name);
}
int main() {
struct Directory dir;
initDirectory(&dir);
deleteFile(&dir, "file1.txt");
listFiles(&dir);
return 0;
}
46
2) Implement file allocation methods (Contiguous,
Linked, Indexed).
File allocation methods
Contagious
CODE:
#include <stdio.h>
#include <string.h>
#define MAX_DISK_SIZE 10
struct File {
char name[50];
int size;
int location;
};
struct ContiguousAllocation {
int disk[MAX_DISK_SIZE];
};
int main() {
int location[MAX_DISK_SIZE]; // Array to store the linked block locations
};
struct LinkedAllocation {
int disk[MAX_DISK_SIZE]; // 0: free, 1: occupied
};
allocateLinked(&alloc, &file);
return 0;
}
struct ContiguousAllocation alloc = {0};
struct File file = {"file1.txt", 3, -1};
return 0;
}
Linked
CODE:
#include <stdio.h>
#include <string.h>
#define MAX_DISK_SIZE 10
struct File {
char name[50];
int size;
49
Indexed
CODE:
#include <stdio.h>
#include <string.h>
#define MAX_DISK_SIZE 10
struct File {
char name[50];
int size;
int location[MAX_DISK_SIZE]; // Store block locations directly in an
array
};
struct IndexedAllocation {
int disk[MAX_DISK_SIZE];
int index[MAX_DISK_SIZE]; // Index block for file
};
50
}
printf("\n");
return;
}
}
printf("Not enough space for indexed allocation.\n");
}
int main() {
struct IndexedAllocation alloc = {0};
struct File file = {"file1.txt", 3, {-1}}; // Initialize file location to -1
allocateIndexed(&alloc, &file);
return 0;
}
CODE:
#include <stdio.h>
#include <stdlib.h>
int main() {
int requests[] = {15, 34, 8, 12, 21};
51
int n = sizeof(requests) / sizeof(requests[0]);
int initial_position = 10;
fcfs(requests, n, initial_position);
return 0;
}
SSTF
CODE:
#include <stdio.h>
#include <stdlib.h>
int main() {
int requests[] = {15, 34, 8, 12, 21};
52
int n = sizeof(requests) / sizeof(requests[0]);
int initial_position = 10;
sstf(requests, n, initial_position);
return 0;
}
4. SCAN
CODE:
#include <stdio.h>
#include <stdlib.h>
int main() {
int requests[] = {15, 34, 8, 12, 21};
int n = sizeof(requests) / sizeof(requests[0]);
int initial_position = 10;
int disk_size = 50;
return 0;
}
54
5. CSCAN
CODE:
#include <stdio.h>
#include <stdlib.h>
55
// Process the requests
for (int i = 0; i < right_count; i++) {
seek_count += abs(current_position - right[i]);
current_position = right[i];
}
seek_count += abs(current_position - (disk_size - 1));
current_position = disk_size - 1;
for (int i = 0; i < left_count; i++) {
seek_count += abs(current_position - left[i]);
current_position = left[i];
}
int main() {
int requests[] = {15, 34, 8, 12, 21};
int n = sizeof(requests) / sizeof(requests[0]);
int initial_position = 10;
int disk_size = 50;
return 0;
}
56
EXPERIMENT 9
Virtual Memory Management
1. Simulate Virtual Memory using Paging
In this simulation, the virtual memory is divided into fixed-size pages, and
the physical memory is divided into fixed-size frames. The program
manages page allocation and simulates the process of accessing virtual
memory.
CODE;
#include <stdio.h>
#include <stdlib.h>
if (!replaced) {
// Replace the first frame if no empty frame
for (int j = 0; j < FRAME_SIZE - 1; j++) {
frames[j] = frames[j + 1];
}
frames[FRAME_SIZE - 1] = page;
}
}
int main() {
int reference_string[] = {0, 1, 2, 3, 0, 4, 2, 1, 3, 0, 4};
int n = sizeof(reference_string) / sizeof(reference_string[0]);
simulate_virtual_memory(reference_string, n);
return 0;
}
58
2. Demand Paging Concept
CODE:
#include <stdio.h>
#define NUM_PAGES 4
#define FRAME_SIZE 4
if (!found) {
page_faults++;
// Load page into an empty frame or replace the least recently
used
int replaced = 0;
for (int j = 0; j < FRAME_SIZE; j++) {
if (frames[j] == -1) {
frames[j] = page;
replaced = 1;
break;
}
}
if (!replaced) {
// Replace the first frame
for (int j = 0; j < FRAME_SIZE - 1; j++) {
frames[j] = frames[j + 1];
}
frames[FRAME_SIZE - 1] = page;
}
}
int main() {
int reference_string[] = {0, 1, 2, 3, 0, 4, 2, 1, 3, 0, 4};
int n = sizeof(reference_string) / sizeof(reference_string[0]);
demand_paging(reference_string, n);
return 0;
}
60
3. Simulate Page Replacement Policies (FIFO, LRU)
CODE:
#include <stdio.h>
#define FRAME_SIZE 4
int page_faults = 0;
61
for (int i = 0; i < n; i++) {
int found = 0;
if (frames[j] == page) {
found = 1;
break;
if (!found) {
page_faults++;
frames[rear] = page;
rear++;
} else {
frames[front] = page;
printf("Frames: ");
printf("\n");
int main() {
fifo_page_replacement(reference_string, n);
return 0;
CODE:
63
#include <stdio.h>
#define FRAME_SIZE 4
int page_faults = 0;
int found = 0;
if (frames[j] == page) {
found = 1;
least_recently_used = j;
break;
if (!found) {
page_faults++;
if (frames[j] == -1) {
lru_index = j;
64
break;
if (lru_index == -1) {
lru_index = least_recently_used;
frames[lru_index] = page;
printf("Frames: ");
printf("\n");
int main() {
lru_page_replacement(reference_string, n);
return 0;
65
4.Implement a program to track page faults during
process execution.
CODE:
#include <stdio.h>
int page_faults = 0;
66
for (int i = 0; i < n; i++) {
int found = 0;
// Check if the page is already in one of the frames (no page fault)
if (frames[j] == page) {
found = 1;
break;
if (!found) {
page_faults++;
int replaced = 0;
if (frames[j] == -1) {
frames[j] = page;
replaced = 1;
break;
if (!replaced) {
frames[FRAME_SIZE - 1] = page;
printf("\n");
int main() {
fifo_page_faults(reference_string, n);
return 0;
OUTPUT:
68
EXPERIMENT 10
Disk Scheduling Algorithms
FCFS is the simplest disk scheduling algorithm where the disk accesses
requests in the order they arrive, without any reordering. It is non-
preemptive and doesn't optimize for disk seek time.
CODE:
#include <stdio.h>
int main() {
int requests[] = {98, 183, 41, 122, 14, 124, 65, 67}; // Disk I/O requests
int num_requests = sizeof(requests) / sizeof(requests[0]);
int start = 53; // Initial position of the disk arm
return 0;
}
SSTF selects the request that is closest to the current disk head position.
It minimizes the seek time for each request but can lead to starvation if
some requests are far from the current position.
CODE:
#include <stdio.h>
#include <stdlib.h>
int main() {
int requests[] = {98, 183, 41, 122, 14, 124, 65, 67}; // Disk I/O requests
int num_requests = sizeof(requests) / sizeof(requests[0]);
int start = 53; // Initial position of the disk arm
return 0;
}
71
3. SCAN Disk Scheduling
CODE:
#include <stdio.h>
#include <stdlib.h>
// Reverse direction
printf("Reverse direction...\n");
for (int i = num_requests - 1; i >= 0; i--) {
if (requests[i] < start) {
int seek_time = abs(requests[i] - current_position);
total_seek_time += seek_time;
current_position = requests[i];
printf("Move to: %d, Seek Time: %d\n", current_position, seek_time);
}
}
int main() {
int requests[] = {98, 183, 41, 122, 14, 124, 65, 67}; // Disk I/O requests
int num_requests = sizeof(requests) / sizeof(requests[0]);
int start = 53; // Initial position of the disk arm
72
int disk_size = 200; // Maximum size of the disk
return 0;
}
CODE:
#include <stdio.h>
#include <stdlib.h>
int main() {
int requests[] = {98, 183, 41, 122, 14, 124, 65, 67}; // Disk I/O requests
int num_requests = sizeof(requests) / sizeof(requests[0]);
int start = 53; // Initial position of the disk arm
int disk_size = 200; // Maximum size of the disk
return 0;
}
74
S
75