0% found this document useful (0 votes)
7 views

OS_Lab_program_manual

The document is an Operating System Lab Manual for BCS303, covering various labs including process system calls in C, CPU scheduling algorithms, producer-consumer problem using semaphores, interprocess communication using named pipes, and the Banker's Algorithm for deadlock avoidance. Each lab includes objectives, code overviews, and sample code demonstrating the concepts. The manual is intended for students to understand and implement key operating system principles through practical coding exercises.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

OS_Lab_program_manual

The document is an Operating System Lab Manual for BCS303, covering various labs including process system calls in C, CPU scheduling algorithms, producer-consumer problem using semaphores, interprocess communication using named pipes, and the Banker's Algorithm for deadlock avoidance. Each lab includes objectives, code overviews, and sample code demonstrating the concepts. The manual is intended for students to understand and implement key operating system principles through practical coding exercises.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

OPERATING SYSTEM LAB MANUAL BCS303

Lab 1 Process System Calls in C


Objective:
 To understand and implement Process system calls in C, including fork(), exec(), wait(), creating and
terminating processes.
Code Overview:
The provided C program demonstrates the creation of a child process using fork(), executing a command in the child
process using execl(), and waiting for the child process to complete using wait(). It also showcases the handling of
the child process termination status.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main() {
pid_t pid;
int status;
printf("Starting main program...\n");
// Fork a child process
pid = fork();
if (pid < 0) {
fprintf(stderr, "Fork failed\n");
return 1;
} else if (pid == 0) {
// Child process
printf("Child process executing...\n");
// Executing a command using execl
execl("/bin/ls", "ls", "-l", NULL);
// This line will only be reached if execl fails
perror("execl");
exit(EXIT_FAILURE);
} else {
// Parent process
printf("Parent process waiting for child...\n");
// Wait for the child process to finish
wait(&status);
if (WIFEXITED(status)) {
printf("Child process terminated with status: %d\n", WEXITSTATUS(status));
} else {
printf("Child process terminated abnormally\n");
}
printf("Parent process exiting...\n");
}
return 0;
}

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303

LAB 2 CPU Scheduling Algorithms Simulation in C


Objective
The objective of this lab is to understand and implement various CPU scheduling algorithms including FCFS (First
Come First Serve), SJF (Shortest Job First), Round Robin, and Priority Scheduling in C programming language.
Overview
In this lab, we'll create a C program that simulates four different CPU scheduling algorithms. The program will
calculate and display the turnaround time and waiting time for a set of predefined processes using these algorithms.
#include<stdio.h>
// Structure to represent a process
struct Process {
int pid; // Process ID
int burst_time; // Burst time
int arrival_time; // Arrival time
int priority; // Priority
};
// Function to calculate FCFS (First Come First Serve) scheduling
void FCFS(struct Process processes[], int n) {
int waiting_time = 0, turnaround_time = 0;
printf("\nFCFS Scheduling:\n");
printf("Process\t Waiting Time\t Turnaround Time\n");
for (int i = 0; i < n; i++) {
turnaround_time += processes[i].burst_time;
printf("%d\t %d\t\t %d\n", processes[i].pid, waiting_time, turnaround_time);
waiting_time += processes[i].burst_time;
}
printf("Average Waiting Time: %.2f\n", (float)waiting_time / n);
printf("Average Turnaround Time: %.2f\n", (float)turnaround_time / n);
}
// Function to calculate SJF (Shortest Job First) scheduling
void SJF(struct Process processes[], int n) {
// Sort processes based on burst time (shortest burst time first)
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (processes[j].burst_time > processes[j + 1].burst_time) {
struct Process temp = processes[j];
processes[j] = processes[j + 1];
processes[j + 1] = temp;
}
}
}
int waiting_time = 0, turnaround_time = processes[0].burst_time;
printf("\nSJF Scheduling:\n");
printf("Process\t Waiting Time\t Turnaround Time\n");
printf("%d\t %d\t\t %d\n", processes[0].pid, waiting_time, turnaround_time);
for (int i = 1; i < n; i++) {
waiting_time += processes[i - 1].burst_time;
turnaround_time += processes[i].burst_time;
printf("%d\t %d\t\t %d\n", processes[i].pid, waiting_time, turnaround_time);

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303
}
printf("Average Waiting Time: %.2f\n", (float)waiting_time / n);
printf("Average Turnaround Time: %.2f\n", (float)turnaround_time / n);
}
// Function to calculate Round Robin scheduling
void RoundRobin(struct Process processes[], int n, int quantum) {
int remaining_burst_time[n];
int total_waiting_time = 0, total_turnaround_time = 0;
// Initialize remaining burst times
for (int i = 0; i < n; i++)
remaining_burst_time[i] = processes[i].burst_time;
int time = 0;
printf("\nRound Robin Scheduling (Quantum = %d):\n", quantum);
printf("Process\t Waiting Time\t Turnaround Time\n");
while (1) {
int done = 1;
for (int i = 0; i < n; i++) {
if (remaining_burst_time[i] > 0) {
done = 0;
if (remaining_burst_time[i] > quantum) {
time += quantum;
remaining_burst_time[i] -= quantum;
} else {
time += remaining_burst_time[i];
total_turnaround_time += time - processes[i].arrival_time;
total_waiting_time += time - processes[i].arrival_time - processes[i].burst_time;
remaining_burst_time[i] = 0;
printf("%d\t %d\t\t %d\n", processes[i].pid, time - processes[i].arrival_time - processes[i].burst_time,
time - processes[i].arrival_time);
}
}
}
if (done == 1)
break;
}
printf("Average Waiting Time: %.2f\n", (float)total_waiting_time / n);
printf("Average Turnaround Time: %.2f\n", (float)total_turnaround_time / n);
}
// Function to calculate Priority scheduling
void Priority(struct Process processes[], int n) {
// Sort processes based on priority (higher priority first)
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (processes[j].priority > processes[j + 1].priority) {
struct Process temp = processes[j];
processes[j] = processes[j + 1];
processes[j + 1] = temp;
}
}
}
int waiting_time = 0, turnaround_time = processes[0].burst_time;
Prof. S.N SGBIT, Belagavi
OPERATING SYSTEM LAB MANUAL BCS303
printf("\nPriority Scheduling:\n");
printf("Process\t Waiting Time\t Turnaround Time\n");
printf("%d\t %d\t\t %d\n", processes[0].pid, waiting_time, turnaround_time);
for (int i = 1; i < n; i++) {
waiting_time += processes[i - 1].burst_time;
turnaround_time += processes[i].burst_time;
printf("%d\t %d\t\t %d\n", processes[i].pid, waiting_time, turnaround_time);
}
printf("Average Waiting Time: %.2f\n", (float)waiting_time / n);
printf("Average Turnaround Time: %.2f\n", (float)turnaround_time / n);
}
int main() {
int n = 4; // Number of processes
int quantum = 2; // Quantum for Round Robin
struct Process processes[n];
// Initialize processes (PID, Burst Time, Arrival Time, Priority)
processes[0] = (struct Process){1, 6, 1, 3};
processes[1] = (struct Process){2, 8, 1, 1};
processes[2] = (struct Process){3, 7, 2, 4};
processes[3] = (struct Process){4, 3, 3, 2};
FCFS(processes, n);
SJF(processes, n);
RoundRobin(processes, n, quantum);
Priority(processes, n);
return 0;
}

OUTPUT

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303
Lab 3 Develop a C program to simulate producer-consumer problem using semaphores
Objective: The objective is to implement a solution for the producer-consumer problem using semaphores in C
programming language. This problem involves synchronizing the actions of multiple producer and consumer threads
that share a fixed-size buffer, ensuring that producers don't produce when the buffer is full and consumers don't
consume when it's empty. Semaphores are employed to manage the access to the shared buffer, maintaining proper
synchronization and avoiding race conditions.

Overview:
1. Initialization: Initialize the necessary variables including the buffer, semaphores (empty and full), and mutex.

2. Producer Function: Create a function for the producer thread that generates items and attempts to add
them to the shared buffer. Ensure synchronization by using semaphores and mutex to manage access to the
buffer.

3. Consumer Function: Develop a function for the consumer thread that retrieves items from the buffer.
Employ semaphores and mutex to control access to the shared buffer and prevent consumption when the
buffer is empty.

4. Main Function: In the main() function, create threads for both the producer and consumer. Manage thread
creation, execution, and termination using pthread_create() and pthread_join().

5. Cleanup: Properly destroy and release the resources such as semaphores and mutex used in the solution to
avoid memory leaks.

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 5
int buffer[BUFFER_SIZE];
int count = 0;
int in = 0;
int out = 0;
sem_t empty;
sem_t full;
pthread_mutex_t mutex;
void *producer(void *arg) {
int item;
for (int i = 0; i < 10; ++i) {
item = i + 1; // Producing item
sem_wait(&empty);
pthread_mutex_lock(&mutex);
buffer[in] = item;
printf("Produced: %d\n", item);
in = (in + 1) % BUFFER_SIZE;
count++;
pthread_mutex_unlock(&mutex);
sem_post(&full);
}
pthread_exit(NULL);
}
void *consumer(void *arg) {
int item;
Prof. S.N SGBIT, Belagavi
OPERATING SYSTEM LAB MANUAL BCS303
for (int i = 0; i < 10; ++i) {
sem_wait(&full);
pthread_mutex_lock(&mutex);
item = buffer[out];
printf("Consumed: %d\n", item);
out = (out + 1) % BUFFER_SIZE;
count--;
pthread_mutex_unlock(&mutex);
sem_post(&empty);
} pthread_exit(NULL);
} int main() {
pthread_t producerThread, consumerThread;
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
pthread_mutex_init(&mutex, NULL);
pthread_create(&producerThread, NULL, producer, NULL);
pthread_create(&consumerThread, NULL, consumer, NULL);
pthread_join(producerThread, NULL);
pthread_join(consumerThread, NULL);
sem_destroy(&empty);
sem_destroy(&full);
pthread_mutex_destroy(&mutex);
return 0;
}

***********************************************************

OUTPUT
opera@opera-virtual-machine:~/Desktop$ gcc -o 1 1.c -pthreads
opera@opera-virtual-machine:~/Desktop$ ./1
Produced: 1
Produced: 2
Produced: 3
Produced: 4
Produced: 5
Consumed: 1
Consumed: 2
Consumed: 3
Consumed: 4
Consumed: 5
Produced: 6
Produced: 7
Produced: 8
Produced: 9
Produced: 10
Consumed: 6
Consumed: 7
Consumed: 8
Consumed: 9
Consumed: 10
opera@opera-virtual-machine:~/Desktop$

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303

Lab 4 Develop a C program which demonstrates interprocess communication between a


reader process and a writer process. Use mkfifo, open, read, write and close APIs in your
program.
Objective:
The objective is to demonstrate interprocess communication between a writer process and a reader process using
named pipes (FIFO) in a C program. The program should utilize mkfifo, open, read, write, and close APIs to establish
communication between these two processes through a shared named pipe.
Overview:
1. Writer Process (writerProcess()):
 Create a named pipe (FIFO) using mkfifo with a specified name (FIFO_NAME).
 Open the FIFO in write-only mode (O_WRONLY) using open.
 Write a message or data into the FIFO using write.
 Close the FIFO using close after writing the data.
2. Reader Process (readerProcess()):
 Open the same named pipe created by the writer in read-only mode (O_RDONLY) using open.
 Read data from the FIFO using read.
 Print the received data or message.
 Close the FIFO using close after reading the data.
3. Main Function (main()):
 Fork a child process using fork().
 In the parent process (writer), call the writerProcess() function to write data to the named pipe.
 In the child process (reader), call the readerProcess() function to read data from the named pipe.
 Ensure proper handling of errors such as failed forks, pipe creation, and data reading/writing failures.
4. Execution:
 Compile the C program using a C compiler (e.g., gcc).
 Run the compiled program, which will create two processes – a writer and a reader – that
communicate through the named pipe.
5. Cleanup:
 Ensure the named pipe is properly closed and unlinked after both processes finish communicating.
 Handle resource release to avoid memory leaks or unwanted resources.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>

#define FIFO_NAME "myfifo"

void writerProcess() {
int fd;
char *message = "Hello, reader!";

mkfifo(FIFO_NAME, 0666);
fd = open(FIFO_NAME, O_WRONLY);
write(fd, message, strlen(message) + 1);
close(fd);

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303

printf("Data sent to reader successfully!\n");


}

void readerProcess() {
int fd;
char readMessage[100];

fd = open(FIFO_NAME, O_RDONLY);
read(fd, readMessage, sizeof(readMessage));
printf("Received message: %s\n", readMessage);
close(fd);
}
int main() {
pid_t pid;
// Create a child process
pid = fork();
if (pid < 0) {
fprintf(stderr, "Fork failed!\n");
return 1;
} else if (pid > 0) {
// Parent process (Writer)
writerProcess();
} else {
// Child process (Reader)
readerProcess();
}
return 0;
}

*******************************************************************

OUTPUT
opera@opera-virtual-machine:~/Desktop$ gcc -o 1 1.c
opera@opera-virtual-machine:~/Desktop$ ./1
Data sent to reader successfully! Received message: Hello, reader!
opera@opera-virtual-machine:~/Desktop$

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303
Lab 5 Develop a C program to simulate Bankers Algorithm for DeadLock Avoidance.
Objective:
The objective of this program is to implement the Banker's Algorithm, a deadlock avoidance technique used in
operating systems, to ensure safe allocation of resources to processes and prevent deadlock situations.

Overview:
The program simulates the Banker's Algorithm for deadlock avoidance by taking input for the number of processes,
the number of resource types available, the maximum resources needed by each process, and the allocated
resources for each process.

1. Input Collection:

 Collects the number of processes and resources.

 Takes in available resources.

 Records allocated resources for each process.

2. Initialization:

 Initializes data structures for allocation, maximum, need, and finish arrays.

 Initializes the need array by calculating the remaining need (maximum - allocated) for each process.

 Initializes the finish array to track the finish status of each process.

3. Safety Checking (Banker's Algorithm):

 Checks if the system is in a safe state by employing the Banker's Algorithm.

 Simulates the resource allocation by checking if processes can execute safely without causing a
deadlock.

 Determines a safe sequence if one exists and displays it.

4. Output:

 Outputs whether the system is in a safe state or an unsafe state.

 If the system is in a safe state, displays the safe sequence of process execution to avoid deadlock.

#include <stdio.h>

#define MAX_PROCESSES 10
#define MAX_RESOURCES 10

int available[MAX_RESOURCES];
int allocation[MAX_PROCESSES][MAX_RESOURCES];
int need[MAX_PROCESSES][MAX_RESOURCES];
int finish[MAX_PROCESSES];

int num_processes, num_resources;

void input_data() {
printf("Enter number of processes and resources: ");
scanf("%d %d", &num_processes, &num_resources);

printf("Enter available resources: ");


Prof. S.N SGBIT, Belagavi
OPERATING SYSTEM LAB MANUAL BCS303
for (int i = 0; i < num_resources; ++i)
scanf("%d", &available[i]);

printf("Enter allocated resources for each process:\n");


for (int i = 0; i < num_processes; ++i) {
for (int j = 0; j < num_resources; ++j) {
scanf("%d", &allocation[i][j]);
need[i][j] = allocation[i][j]; // Initialize need array
}
finish[i] = 0; // Initialize finish array
}
}

int is_safe() {
int work[MAX_RESOURCES];
for (int i = 0; i < num_resources; ++i)
work[i] = available[i];

int safe_sequence[MAX_PROCESSES];
int count = 0;

while (count < num_processes) {


int found = 0;
for (int i = 0; i < num_processes; ++i) {
if (finish[i] == 0) {
int j;
for (j = 0; j < num_resources; ++j) {
if (need[i][j] > work[j])
break;
}
if (j == num_resources) {
for (int k = 0; k < num_resources; ++k)
work[k] += allocation[i][k];
safe_sequence[count++] = i;
finish[i] = 1;
found = 1;
}
}
}
if (found == 0) {
printf("System is in an unsafe state!\n");
return 0;
} }
printf("System is in a safe state.\nSafe sequence is: ");
for (int i = 0; i < num_processes - 1; ++i)
printf("P%d -> ", safe_sequence[i]);
printf("P%d\n", safe_sequence[num_processes - 1]);
return 1;
}
int main() {
input_data();
is_safe();
return 0;
}

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303

Lab 6 Develop a C program to simulate the following contiguous memory allocation


Techniques: a) Worst fit b) Best fit c) First fit.
Objective:
The objective of this program is to simulate three different contiguous memory allocation techniques—First Fit, Best
Fit, and Worst Fit—in a simple memory management system. The program aims to demonstrate how these allocation
strategies work by allocating memory blocks for processes of varying sizes.

Overview:
The C program simulates memory allocation using three different strategies:

1. First Fit: This strategy allocates the first available memory block that is large enough to accommodate the
process.

2. Best Fit: Here, the program allocates the smallest available block that is sufficient for the process, minimizing
wasted memory.

3. Worst Fit: This strategy allocates the largest available memory block, leaving behind the biggest free chunk.

The program utilizes an array of memory blocks represented by a structure containing information about each block's
size and allocation status. The allocateMemory() function iterates through these blocks based on the chosen strategy
('F' for First Fit, 'B' for Best Fit, and 'W' for Worst Fit) to find and allocate memory for a given process size.

#include <stdio.h>

#define MAX_MEMORY 1000 // Maximum memory size


#define NUM_BLOCKS 4 // Number of memory blocks

// Structure to represent each block of memory


struct MemoryBlock {
int size;
int allocated;
};

// Function to allocate memory using a specified strategy


void allocateMemory(struct MemoryBlock memory[], int processSize, char strategy) {
int idx = -1;
int fitSize = (strategy == 'B') ? MAX_MEMORY + 1 : -1;

for (int i = 0; i < NUM_BLOCKS; ++i) {


if (!memory[i].allocated && memory[i].size >= processSize) {
if ((strategy == 'F' && idx == -1) ||
(strategy == 'B' && memory[i].size < fitSize) ||
(strategy == 'W' && memory[i].size > fitSize)) {
idx = i;
fitSize = memory[i].size;
}
}
}

if (idx != -1) {
memory[idx].allocated = 1;
printf("Memory allocated for process of size %d using %c Fit at block %d\n", processSize, strategy, idx);
Prof. S.N SGBIT, Belagavi
OPERATING SYSTEM LAB MANUAL BCS303
} else {
printf("Insufficient memory for process of size %d using %c Fit\n", processSize, strategy);
}
}

int main() {
struct MemoryBlock memory[] = {{100, 0}, {500, 0}, {200, 0}, {300, 0}}; // Memory blocks

printf("Contiguous Memory Allocation Techniques:\n");

allocateMemory(memory, 350, 'F'); // First Fit for a process of size 350


allocateMemory(memory, 200, 'B'); // Best Fit for a process of size 200
allocateMemory(memory, 450, 'W'); // Worst Fit for a process of size 450

return 0;
}
OUTPUT

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303
Lab 7 Develop a C program to simulate page replacement algorithms: a) FIFO b) LRU
Objective:
The objective of this program is to simulate two fundamental page replacement algorithms - FIFO (First-In-First-Out)
and LRU (Least Recently Used) - used in operating systems for managing memory. The aim is to showcase how these
algorithms handle page faults and replace pages in a memory frame given a sequence of page references.

Overview:
The C program includes implementations for the FIFO and LRU page replacement algorithms using an array-based
memory representation. Key components of the program include:

1. PageFrame Structure: This structure represents each frame in memory and holds information about the page
number stored in the frame and, in the case of LRU, the time the page was last used.

2. initializeFrames(): A function to initialize the page frames with default values indicating an empty frame.

3. displayFrames(): A function to display the current state of the page frames at any point during the
simulation.

4. fifo(): Implements the FIFO page replacement algorithm, simulating how pages are replaced when a page
fault occurs. It tracks the order of page references and replaces the oldest page based on the FIFO principle.

5. lru(): Implements the LRU page replacement algorithm, using the concept of time used to replace the least
recently used page upon a page fault.

6. Main Function: Contains the reference string representing page references and creates arrays to hold frames
for both FIFO and LRU algorithms. It invokes the FIFO and LRU functions, displaying the page frame states
and the total number of page faults for each algorithm.

#include <stdio.h>
#include <stdbool.h>

#define MAX_FRAMES 3 // Maximum number of frames in memory

struct PageFrame {
int pageNumber;
int timeUsed;
};

void initializeFrames(struct PageFrame frames[], int numFrames) {


for (int i = 0; i < numFrames; ++i) {
frames[i].pageNumber = -1;
frames[i].timeUsed = 0;
}
}

void displayFrames(struct PageFrame frames[], int numFrames) {


printf("Current Page Frames: ");
for (int i = 0; i < numFrames; ++i)
printf("%d ", frames[i].pageNumber != -1 ? frames[i].pageNumber : -1);
printf("\n");
}

void fifo(struct PageFrame frames[], int pageReferences[], int numReferences) {


Prof. S.N SGBIT, Belagavi
OPERATING SYSTEM LAB MANUAL BCS303
initializeFrames(frames, MAX_FRAMES);
int frameIndex = 0, pageFaults = 0;

printf("\nFIFO Page Replacement:\n");

for (int i = 0; i < numReferences; ++i) {


int currentPage = pageReferences[i], j;
bool pageFound = false;

for (j = 0; j < MAX_FRAMES; ++j) {


if (frames[j].pageNumber == currentPage) {
pageFound = true;
break;
}
}

if (!pageFound) {
frames[frameIndex].pageNumber = currentPage;
frameIndex = (frameIndex + 1) % MAX_FRAMES;
pageFaults++;
displayFrames(frames, MAX_FRAMES);
}
}

printf("Total Page Faults: %d\n", pageFaults);


}

void lru(struct PageFrame frames[], int pageReferences[], int numReferences) {


initializeFrames(frames, MAX_FRAMES);
int pageFaults = 0;

printf("\nLRU Page Replacement:\n");

for (int i = 0; i < numReferences; ++i) {


int currentPage = pageReferences[i], j;
bool pageFound = false;

for (j = 0; j < MAX_FRAMES; ++j) {


if (frames[j].pageNumber == currentPage) {
frames[j].timeUsed = i;
pageFound = true;
break;
}
}

if (!pageFound) {
int leastUsedIdx = 0;
for (j = 1; j < MAX_FRAMES; ++j)
if (frames[j].timeUsed < frames[leastUsedIdx].timeUsed)
leastUsedIdx = j;

frames[leastUsedIdx].pageNumber = currentPage;
frames[leastUsedIdx].timeUsed = i;
pageFaults++;
displayFrames(frames, MAX_FRAMES);
Prof. S.N SGBIT, Belagavi
OPERATING SYSTEM LAB MANUAL BCS303
}
}

printf("Total Page Faults: %d\n", pageFaults);


}

int main() {
int pageReferences[] = {2, 3, 2, 1, 5, 2, 4, 5, 3, 2, 5};
int numReferences = sizeof(pageReferences) / sizeof(pageReferences[0]);

struct PageFrame fifoFrames[MAX_FRAMES], lruFrames[MAX_FRAMES];

fifo(fifoFrames, pageReferences, numReferences);


lru(lruFrames, pageReferences, numReferences);

return 0;
}

OUTPUT

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303

8. Simulate following File Organization Techniques a) Single level directory


Objective:
The objective of these C programs is to simulate file organization techniques, specifically focusing on:
1. Single Level Directory:
 Creating, deleting, and searching for files in a directory.
 Handling a directory structure where all files exist in a single level.
2. Two Level Directory:
 Creating, deleting, and searching for files in a hierarchical directory structure.
 Handling directories with multiple subdirectories, each containing its own set of files.
Overview:
Single Level Directory Program:
1. Initialization:
 Initializes a single-level directory structure with a fixed number of file slots.
2. File Creation:
 Implements a function to create a file in the directory.
 Checks for available slots and marks the file as occupied.
3. File Deletion:
 Implements a function to delete a file from the directory.
 Marks the corresponding slot as unoccupied.
4. File Search:
 Implements a function to search for a file in the directory.
 Indicates whether the file is present or not.
5. Main Function:
 Demonstrates the usage of the functions by creating, searching, and deleting files.
Two Level Directory Program:
1. Initialization:
 Initializes a two-level directory structure with a fixed number of directories and files per directory.
2. File Creation:
 Implements a function to create a file in a specific directory.
 Checks for available slots within the directory and marks the file as occupied.
3. File Deletion:
 Implements a function to delete a file from a specific directory.
 Marks the corresponding slot as unoccupied.
4. File Search:
 Implements a function to search for a file in a specific directory.
 Indicates whether the file is present or not.
5. Main Function:
 Demonstrates the usage of the functions by creating, searching, and deleting files within a two-level
directory structure.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_FILES 10
#define MAX_NAME_LENGTH 20
typedef struct {
char name[MAX_NAME_LENGTH];
int isOccupied;
} File;
File singleLevelDirectory[MAX_FILES];
void initializeSingleLevelDirectory() {

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303
for (int i = 0; i < MAX_FILES; i++) {
singleLevelDirectory[i].isOccupied = 0;
}}
void createFileSingleLevel(char fileName[]) {
for (int i = 0; i < MAX_FILES; i++) {
if (!singleLevelDirectory[i].isOccupied) {
strcpy(singleLevelDirectory[i].name, fileName);
singleLevelDirectory[i].isOccupied = 1;
printf("File '%s' created successfully.\n", fileName);
return;
}}
printf("Directory is full. Cannot create file '%s'.\n", fileName);
}
void deleteFileSingleLevel(char fileName[]) {
for (int i = 0; i < MAX_FILES; i++) {
if (singleLevelDirectory[i].isOccupied && strcmp(singleLevelDirectory[i].name, fileName) == 0) {
singleLevelDirectory[i].isOccupied = 0;
printf("File '%s' deleted successfully.\n", fileName);
return;
}}
printf("File '%s' not found.\n", fileName);
}
void searchFileSingleLevel(char fileName[]) {
for (int i = 0; i < MAX_FILES; i++) {
if (singleLevelDirectory[i].isOccupied && strcmp(singleLevelDirectory[i].name, fileName) == 0) {
printf("File '%s' found in the directory.\n", fileName);
return;
}}
printf("File '%s' not found.\n", fileName);
}
int main() {
initializeSingleLevelDirectory();
createFileSingleLevel("file1.txt");
createFileSingleLevel("file2.txt");
searchFileSingleLevel("file1.txt");
searchFileSingleLevel("file3.txt");
deleteFileSingleLevel("file2.txt");
deleteFileSingleLevel("file3.txt");
return 0;
}

OUTPUT

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303

8. Simulate following File Organization Techniques b) Two level directory


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_DIRECTORIES 5
#define MAX_FILES_PER_DIRECTORY 10
#define MAX_NAME_LENGTH 20

typedef struct {
char name[MAX_NAME_LENGTH];
int isOccupied;
} File;

typedef struct {
char name[MAX_NAME_LENGTH];
File files[MAX_FILES_PER_DIRECTORY];
} Directory;

Directory twoLevelDirectory[MAX_DIRECTORIES];

void initializeTwoLevelDirectory() {
for (int i = 0; i < MAX_DIRECTORIES; i++) {
twoLevelDirectory[i].name[0] = '\0';
for (int j = 0; j < MAX_FILES_PER_DIRECTORY; j++) {
twoLevelDirectory[i].files[j].isOccupied = 0;
}
}
}

void createFileTwoLevel(char fileName[], char directoryName[]) {


for (int i = 0; i < MAX_DIRECTORIES; i++) {
if (strcmp(twoLevelDirectory[i].name, directoryName) == 0) {
for (int j = 0; j < MAX_FILES_PER_DIRECTORY; j++) {
if (!twoLevelDirectory[i].files[j].isOccupied) {
strcpy(twoLevelDirectory[i].files[j].name, fileName);
twoLevelDirectory[i].files[j].isOccupied = 1;
printf("File '%s' created successfully in directory '%s'.\n", fileName, directoryName);
return;
}
}
printf("Directory '%s' is full. Cannot create file '%s'.\n", directoryName, fileName);
return;
}
}
printf("Directory '%s' not found. Cannot create file '%s'.\n", directoryName, fileName);
}

void deleteFileTwoLevel(char fileName[], char directoryName[]) {


for (int i = 0; i < MAX_DIRECTORIES; i++) {
if (strcmp(twoLevelDirectory[i].name, directoryName) == 0) {
for (int j = 0; j < MAX_FILES_PER_DIRECTORY; j++) {

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303
if (twoLevelDirectory[i].files[j].isOccupied && strcmp(twoLevelDirectory[i].files[j].name, fileName) == 0) {
twoLevelDirectory[i].files[j].isOccupied = 0;
printf("File '%s' deleted successfully from directory '%s'.\n", fileName, directoryName);
return;
}
}
printf("File '%s' not found in directory '%s'.\n", fileName, directoryName);
return;
}
}
printf("Directory '%s' not found. Cannot delete file '%s'.\n", directoryName, fileName);
}
void searchFileTwoLevel(char fileName[], char directoryName[]) {
for (int i = 0; i < MAX_DIRECTORIES; i++) {
if (strcmp(twoLevelDirectory[i].name, directoryName) == 0) {
for (int j = 0; j < MAX_FILES_PER_DIRECTORY; j++) {
if (twoLevelDirectory[i].files[j].isOccupied && strcmp(twoLevelDirectory[i].files[j].name, fileName) == 0) {
printf("File '%s' found in directory '%s'.\n", fileName, directoryName);
return;
}
}
printf("File '%s' not found in directory '%s'.\n", fileName, directoryName);
return;
}
}
printf("Directory '%s' not found. Cannot search for file '%s'.\n", directoryName, fileName);
}

int main() {
initializeTwoLevelDirectory();
strcpy(twoLevelDirectory[0].name, "dir1");
createFileTwoLevel("file1.txt", "dir1");
createFileTwoLevel("file2.txt", "dir1");
searchFileTwoLevel("file1.txt", "dir1");
searchFileTwoLevel("file3.txt", "dir1");
deleteFileTwoLevel("file2.txt", "dir1");
deleteFileTwoLevel("file3.txt", "dir1");
return 0;
}

OUTPUT

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303

9. Develop a C program to simulate the Linked file allocation strategies.


Objective:
The objective of this C program is to simulate the linked file allocation strategy on a disk. Linked file allocation
represents files as linked lists of blocks, where each block contains data and a pointer to the next block in the file. The
program aims to illustrate the allocation and deallocation of blocks for files on a simulated disk using this strategy.
Overview:
Initialization:
The program initializes a simulated disk with a specified number of blocks.
Each block on the disk is represented by a structure that contains data and a pointer to the next block.
Allocation:
The program includes a function (allocateBlock()) that allocates a block for a file.
It iterates through the disk's blocks, marks an available block as allocated, and returns the index of the allocated
block.
Deallocation:
The program includes a function (deallocateBlock()) that deallocates a previously allocated block.
It marks the specified block as deallocated and resets the next pointer.
Display Disk Status:
The program includes a function (displayDisk()) that displays the current status of the disk.
It shows the allocation status of each block and the linked structure of the files.
Main Function:
In the main() function, the program demonstrates the allocation and deallocation process for two example files.
It allocates blocks for the files, displays the disk status, deallocates some blocks, and displays the updated disk status.

#include <stdio.h>
#include <stdlib.h>

#define MAX_BLOCKS 50

typedef struct Block {


int data;
struct Block* next;
} Block;

Block disk[MAX_BLOCKS];

void initializeDisk() {
for (int i = 0; i < MAX_BLOCKS; i++) {
disk[i].data = 0;
disk[i].next = NULL;
}
}

int allocateBlock() {
for (int i = 0; i < MAX_BLOCKS; i++) {
if (disk[i].data == 0) {
disk[i].data = 1; // Mark the block as allocated
return i; // Return the index of the allocated block
}
}
return -1; // No available block
}

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303
void deallocateBlock(int blockIndex) {
if (blockIndex >= 0 && blockIndex < MAX_BLOCKS) {
disk[blockIndex].data = 0; // Mark the block as deallocated
disk[blockIndex].next = NULL; // Reset the next pointer
}}
void displayDisk() {
printf("Disk Status:\n");
for (int i = 0; i < MAX_BLOCKS; i++) {
printf("[%d]", disk[i].data);
if (disk[i].next != NULL) {
printf(" -> ");
} else {
printf("\n");
}
}
}
int main() {
initializeDisk();

// Allocate blocks for File 1


int block1 = allocateBlock();
int block2 = allocateBlock();
int block3 = allocateBlock();

// Allocate blocks for File 2


int block4 = allocateBlock();
int block5 = allocateBlock();

// Display disk status


displayDisk();

// Deallocate some blocks


deallocateBlock(block2);
deallocateBlock(block4);
// Display updated disk status
displayDisk();

return 0;
}
OUTPUT

Prof. S.N SGBIT, Belagavi


OPERATING SYSTEM LAB MANUAL BCS303
10. Develop a C program to simulate SCAN disk scheduling algorithm.
Objective:
The objective of this C program is to simulate the SCAN disk scheduling algorithm. The SCAN algorithm, also known
as the Elevator algorithm, is used to schedule requests for accessing data on a disk. It works by moving the disk arm
in one direction (towards higher track numbers or lower track numbers), servicing requests along the way. When it
reaches the end of the disk in that direction, it reverses its direction and continues servicing requests in the opposite
direction.
Overview:
1. User Input:
 The program prompts the user to input the number of disk requests, the actual disk requests, and
the initial position of the disk arm.
2. Sorting Requests:
 The program sorts the disk requests in ascending order. This is necessary for the SCAN algorithm to
service requests in a particular order.
3. Servicing Requests:
 The program simulates the SCAN disk scheduling algorithm by moving the disk arm towards higher
track numbers, servicing requests along the way.
 After reaching the highest track, it reverses direction and moves towards lower track numbers,
servicing requests in the opposite direction.
4. Head Movement Calculation:
 The program calculates the total head movement, which is the sum of the absolute differences
between the current track and the next serviced track.
5. Output:
 The program displays the order in which the requests are serviced and the total head movement.

#include <stdio.h>
#include <stdlib.h>

#define MAX_REQUESTS 100

void scanDisk(int requests[], int numRequests, int initialPosition) {


int totalMovement = 0;
int direction = 1; // 1 for moving towards higher track numbers, -1 for moving towards lower track numbers

printf("SCAN Disk Scheduling Algorithm:\n");

// Sort the requests in ascending order


for (int i = 0; i < numRequests - 1; i++) {
for (int j = 0; j < numRequests - i - 1; j++) {
if (requests[j] > requests[j + 1]) {
// Swap requests[j] and requests[j + 1]
int temp = requests[j];
requests[j] = requests[j + 1];
requests[j + 1] = temp;
}
}
}

// Find the index of initial position in the sorted requests


int initialIndex = 0;
while (initialIndex < numRequests && requests[initialIndex] < initialPosition) {
initialIndex++;
}
Prof. S.N SGBIT, Belagavi
OPERATING SYSTEM LAB MANUAL BCS303

// Move towards higher track numbers


for (int i = initialIndex; i < numRequests; i++) {
printf("Servicing request at track %d\n", requests[i]);
totalMovement += abs(requests[i] - initialPosition);
initialPosition = requests[i];
}
// Move towards lower track numbers
for (int i = initialIndex - 1; i >= 0; i--) {
printf("Servicing request at track %d\n", requests[i]);
totalMovement += abs(requests[i] - initialPosition);
initialPosition = requests[i];
}
printf("Total head movement: %d\n", totalMovement);
}

int main() {
int numRequests, initialPosition;

printf("Enter the number of disk requests: ");


scanf("%d", &numRequests);

if (numRequests <= 0 || numRequests > MAX_REQUESTS) {


printf("Invalid number of requests. Please enter a positive number up to %d.\n", MAX_REQUESTS);
return 1;
}
int requests[MAX_REQUESTS];
printf("Enter the disk requests (separated by spaces): ");
for (int i = 0; i < numRequests; i++) {
scanf("%d", &requests[i]);
}
printf("Enter the initial position of the disk arm: ");
scanf("%d", &initialPosition);

scanDisk(requests, numRequests, initialPosition);


return 0;
}
OUTPUT

Prof. S.N SGBIT, Belagavi

You might also like