Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
10 views

OS Assignment

Uploaded by

Mithun
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

OS Assignment

Uploaded by

Mithun
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

Q 1. Installation of Linux operating system.

i. Partitioning drives
ii. Configuring boot loader (GRUB/LILO)
iii. Network configuration
iv. Setting time zones
v. Creating password and user accounts
vi. Shutting downSol
i. Partitioning drives: During installation, choose automatic or manual
partitioning to organize storage space. Allocate space for root (/), swap, and
optionally /home partitions.

ii. Configuring boot loader (GRUB/LILO): Install GRUB (Grand Unified Boot
Loader) or LILO (Linux Loader) to the Master Boot Record (MBR) or the EFI
System Partition (ESP) to manage the boot process. Choose the appropriate
options based on your system configuration.

iii. Network configuration: Set up network connectivity by configuring network


interfaces, either via DHCP (Dynamic Host Configuration Protocol) for automatic
IP assignment or manually entering IP addresses, subnet masks, gateways, and
DNS servers.

iv. Setting time zones: Select the appropriate time zone during installation or
configure it afterward using system utilities like timedatectl or editing the
/etc/timezone file.

v. Creating password and user accounts: Create a root password and at least one
user account with appropriate privileges. Use the adduser or useradd command
to create users, and passwd to set passwords.

vi. Shutting down: After completing the installation and configuration, shut down
the system using the shutdown command with appropriate options (-h for halt, -r
for reboot) or through the graphical user interface.
Q 2. Study of Unix/Linux general purpose utility command list obtained
from(man, who, cat, cd, cp, ps, ls, mv, rm, mkdir, rmdir, echo, more,
date, time,kill, history, chmod, chown, finger, pwd, cal, logout,
shutdown) commands.
The Unix/Linux general-purpose utility commands are essential for various tasks:
1. man: Access manual pages for commands and programs.
2. who: Display information about users currently logged in.
3. cat: Concatenate and display files.
4. cd: Change directory.
5. cp: Copy files and directories.
6. ps: Display information about active processes.
7. ls: List directory contents.
8. mv: Move or rename files and directories.
9. rm: Remove files and directories.
10.mkdir: Create directories.
11.rmdir: Remove directories.
12.echo: Display text on the command line.
13.more: Display text files one screen at a time.
14.date: Display or set the system date and time.
15.time: Measure the time it takes to execute a command.
16.kill: Terminate processes by ID or name.
17.history: Display command history.
18.chmod: Change file permissions.
19.chown: Change file ownership.
20.finger: Display information about users.
21.pwd: Print the current working directory.
22.cal: Display a calendar.
23.logout: Log out of the current session.
24.shutdown: Shut down or reboot the system.

Q 3. Study of vi editor.
The vi editor is a versatile text editor commonly used in Unix and Linux operating
systems. It operates in two primary modes: command mode for executing
commands and insert mode for typing text. Users can navigate, edit, search, and
manipulate text efficiently using vi's extensive command set. It's favored for its
speed, powerful features, and availability across various Unix-based systems,
making it a valuable tool for programmers, system administrators, and users
working with text files.

Q 4. Study of Bash shell, Bourne shell and C shell in Unix/Linux


operating system.
Bash shell:

 Bash (Bourne Again Shell) is the default shell for most Unix/Linux
systems.
 It's an enhanced version of the original Bourne shell (sh).
 Bash supports features like command history, tab completion, and job
control.
 It's highly customizable and widely used due to its compatibility with
Bourne shell scripts.

Bourne shell:
 The original Unix shell, developed by Stephen Bourne in the 1970s.
 It's a simple and lightweight shell, lacking some advanced features found
in modern shells like Bash.
 Bourne shell scripts are still used, especially for portability across different
Unix systems.
 Its syntax and features are more limited compared to newer shells like
Bash.

C shell:

 The C shell (csh) is another Unix shell, inspired by the C programming


language syntax.
 It offers interactive features like command history and aliases, resembling
C language constructs.
 C shell scripts have a different syntax and structure compared to Bourne
shell scripts.
 While less common than Bash, C shell is still used in some Unix
environments, particularly among long-time Unix users who prefer its
interactive features.
Q 5. Study of Unix/Linux file system (tree structure).
The Unix/Linux file system follows a hierarchical tree structure:
 Root Directory (/): The top-level directory in the file system hierarchy,
denoted by a forward slash (/). All other directories and files are contained
within it.
 Subdirectories: Directories within the root directory, forming branches of
the tree structure. Examples include /bin, /etc, /home, and /usr.
 Files: Located within directories, files contain data or programs. They can
be text files, executables, configuration files, or special files like device
files.
 Directories: Folders used to organize files and subdirectories. They can
contain both files and other directories.
 Path: The path to a file or directory describes its location within the file
system tree. It starts from the root directory, with each directory separated
by a forward slash. For example, /usr/bin/bash represents the bash
executable located in the /bin directory within the /usr directory.
 Permissions: Each file and directory has associated permissions
governing who can read, write, or execute them. Permissions are set for
the owner, group, and others.
 Symbolic Links: Symbolic links are special files that point to other files
or directories. They provide a way to reference files and directories across
the file system.
 Mount Points: Mount points are directories used to access filesystems
located on different devices or partitions. They serve as entry points for
mounting external storage devices or network shares into the file system
tree.

Q 6. Study of .bashrc, /etc/bashrc and Environment variables.

1. .bashrc:
 User-specific Bash configuration file located in the user's home
directory (~/).
 Executes each time a new interactive Bash shell is opened for that
user.
 Used to customize the shell environment by defining aliases, setting
environment variables, and running other initialization commands
specific to the user's preferences.
2. /etc/bashrc:
 System-wide Bash configuration file located in the /etc directory.
 Applies settings globally to all users who use the Bash shell on the
system.
 Used by system administrators to set default configurations and
environment variables for all users.
3. Environment Variables:
 Dynamic named values affecting the behavior of processes in a
Unix/Linux system.
 Key-value pairs defining variables like PATH, HOME, USER, and
LANG.
 Can be set, accessed, and modified within shell scripts and by using
the 'export' command.
 Define aspects of the user's shell environment, including system
behavior, default paths, and user preferences.

Q 7. To write a C-program to implement following CPU scheduling


algorithms
i. First come first sever algorithm
ii. Shortest job first algorithm
iii. Shortest remaining time first algorithm
iv. Priority scheduling algorithm
v. Round robin algorithm

#include <stdio.h>
struct Process {
int pid; // Process ID
int arrival_time; // Arrival time of the process
int burst_time; // Burst time (execution time) of the process
};
void fcfs(struct Process processes[], int n) {
int waiting_time = 0;
float average_waiting_time;
printf("Process\t Arrival Time\t Burst Time\t Waiting Time\n");
for (int i = 0; i < n; i++) {
printf("%d\t\t %d\t\t %d\t\t %d\n", processes[i].pid, processes[i].arrival_time,
processes[i].burst_time, waiting_time);
waiting_time += processes[i].burst_time;
}
average_waiting_time = (float)waiting_time / n;
printf("\nAverage Waiting Time: %.2f\n", average_waiting_time);
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
struct Process processes[n];
for (int i = 0; i < n; i++) {
printf("Enter arrival time and burst time for process %d: ", i + 1);
scanf("%d %d", &processes[i].arrival_time, &processes[i].burst_time);
processes[i].pid = i + 1;
}
fcfs(processes, n);
return 0;
}

ii. Shortest job first algorithm


#include <stdio.h>
struct Process {
int pid; // Process ID
int arrival_time; // Arrival time of the process
int burst_time; // Burst time (execution time) of the process
int waiting_time; // Waiting time of the process
};
void swap(struct Process *a, struct Process *b) {
struct Process temp = *a;
*a = *b;
*b = temp;
}
void sort_by_burst_time(struct Process processes[], int n) {
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) {
swap(&processes[j], &processes[j + 1]);
}
}
}
}
void sjf(struct Process processes[], int n) {
int total_waiting_time = 0;
float average_waiting_time;
// Sort processes by burst time
sort_by_burst_time(processes, n);
printf("Process\t Arrival Time\t Burst Time\t Waiting Time\n");
int current_time = 0;
for (int i = 0; i < n; i++) {
printf("%d\t\t %d\t\t %d\t\t %d\n", processes[i].pid, processes[i].arrival_time,
processes[i].burst_time, current_time);
processes[i].waiting_time = current_time;
current_time += processes[i].burst_time;
total_waiting_time += processes[i].waiting_time;
}
average_waiting_time = (float)total_waiting_time / n;
printf("\nAverage Waiting Time: %.2f\n", average_waiting_time);
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
struct Process processes[n];
for (int i = 0; i < n; i++) {
printf("Enter arrival time and burst time for process %d: ", i + 1);
scanf("%d %d", &processes[i].arrival_time, &processes[i].burst_time);
processes[i].pid = i + 1;
}
sjf(processes, n);
return 0;
}

iii. Shortest remaining time first algorithm


#include <stdio.h>
#include <stdbool.h>
struct Process {
int pid; // Process ID
int arrival_time; // Arrival time of the process
int burst_time; // Burst time (execution time) of the process
int remaining_time; // Remaining burst time of the process
int completion_time; // Completion time of the process
bool completed; // Flag to track if the process has completed
};
int find_shortest_remaining_time(struct Process processes[], int n, int current_time) {
int shortest_index = -1;
int shortest_time = 99999; // Initialize with a large value
for (int i = 0; i < n; i++) {
if (!processes[i].completed && processes[i].arrival_time <= current_time &&
processes[i].remaining_time < shortest_time) {
shortest_index = i;
shortest_time = processes[i].remaining_time;
}
}
return shortest_index;
}
void srtf(struct Process processes[], int n) {
int total_waiting_time = 0;
float average_waiting_time;
int current_time = 0;
printf("Process\t Arrival Time\t Burst Time\t Completion Time\t Waiting Time\n");
while (true) {
int shortest_index = find_shortest_remaining_time(processes, n, current_time);
if (shortest_index == -1) {
break; // No process remaining to execute
}
struct Process *current_process = &processes[shortest_index]
printf("%d\t\t %d\t\t %d\t\t ", current_process->pid, current_process-
>arrival_time, current_process->burst_time)
if (current_process->remaining_time == current_process->burst_time) {
current_process->completion_time = current_time + 1; // First time executing
}
current_process->remaining_time--;
current_time++;
if (current_process->remaining_time == 0) {
current_process->completed = true;
current_process->waiting_time = current_process->completion_time -
current_process->arrival_time - current_process->burst_time;
total_waiting_time += current_process->waiting_time;
printf("%d\t\t\t %d\n", current_process->completion_time, current_process-
>waiting_time);
}
}
average_waiting_time = (float)total_waiting_time / n;
printf("\nAverage Waiting Time: %.2f\n", average_waiting_time);
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
struct Process processes[n];
for (int i = 0; i < n; i++) {
printf("Enter arrival time and burst time for process %d: ", i + 1);
scanf("%d %d", &processes[i].arrival_time, &processes[i].burst_time);
processes[i].pid = i + 1;
processes[i].remaining_time = processes[i].burst_time;
processes[i].completed = false;
}
srtf(processes, n);
return 0;
}

iv. Priority scheduling algorithm


#include <stdio.h>
struct Process {
int pid; // Process ID
int burst_time; // Burst time (execution time) of the process
int priority; // Priority of the process
};
void priority_scheduling(struct Process processes[], int n) {
int total_waiting_time = 0;
float average_waiting_time;
int completion_time[n];
int waiting_time[n];
// Initialize waiting time and completion time arrays
for (int i = 0; i < n; i++) {
waiting_time[i] = 0;
completion_time[i] = 0;
}
// Sort processes based on priority
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;
}
}
}
// Calculate waiting time and completion time for each process
for (int i = 0; i < n; i++) {
if (i == 0) {
completion_time[i] = processes[i].burst_time;
} else {
completion_time[i] = completion_time[i - 1] + processes[i].burst_time;
}
waiting_time[i] = completion_time[i] - processes[i].burst_time;
total_waiting_time += waiting_time[i];
}
// Display process details and waiting time
printf("Process\t Burst Time\t Priority\t Waiting Time\n");
for (int i = 0; i < n; i++) {
printf("%d\t\t %d\t\t %d\t\t %d\n", processes[i].pid, processes[i].burst_time,
processes[i].priority, waiting_time[i]);
}
// Calculate and display average waiting time
average_waiting_time = (float)total_waiting_time / n;
printf("\nAverage Waiting Time: %.2f\n", average_waiting_time);
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
struct Process processes[n];
// Input process details
for (int i = 0; i < n; i++) {
printf("Enter burst time and priority for process %d: ", i + 1);
scanf("%d %d", &processes[i].burst_time, &processes[i].priority);
processes[i].pid = i + 1;
}
// Perform priority scheduling
priority_scheduling(processes, n);
return 0;
}

v. Round robin algorithm.


#include <stdio.h>
#define MAX_PROCESSES 10
#define TIME_QUANTUM 2
struct Process {
int pid; // Process ID
int burst_time; // Burst time (execution time) of the process
int remaining_time; // Remaining burst time of the process
};
void round_robin(struct Process processes[], int n) {
int total_waiting_time = 0;
float average_waiting_time;
int completion_time[MAX_PROCESSES];
int waiting_time[MAX_PROCESSES];
int current_time = 0;
// Initialize waiting time and completion time arrays
for (int i = 0; i < n; i++) {
waiting_time[i] = 0;
completion_time[i] = 0;
}
// Execute processes in round-robin fashion
while (1) {
int done = 1; // Flag to check if all processes are completed
for (int i = 0; i < n; i++) {
if (processes[i].remaining_time > 0) {
done = 0; // Set the flag to 0 if there are remaining processes
if (processes[i].remaining_time > TIME_QUANTUM) {
current_time += TIME_QUANTUM;
processes[i].remaining_time -= TIME_QUANTUM;
} else {
current_time += processes[i].remaining_time;
completion_time[i] = current_time;
processes[i].remaining_time = 0;
}
}
}
if (done == 1) {
break; // Exit the loop if all processes are completed
}
}
// Calculate waiting time for each process
for (int i = 0; i < n; i++) {
waiting_time[i] = completion_time[i] - processes[i].burst_time;
total_waiting_time += waiting_time[i];
}
// Display process details and waiting time
printf("Process\t Burst Time\t Waiting Time\n");
for (int i = 0; i < n; i++) {
printf("%d\t\t %d\t\t %d\n", processes[i].pid, processes[i].burst_time, waiting_time[i]);
}
// Calculate and display average waiting time
average_waiting_time = (float)total_waiting_time / n;
printf("\nAverage Waiting Time: %.2f\n", average_waiting_time);
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
if (n > MAX_PROCESSES) {
printf("Maximum number of processes exceeded.\n");
return 1;
}
struct Process processes[MAX_PROCESSES];
// Input process details
for (int i = 0; i < n; i++) {
printf("Enter burst time for process %d: ", i + 1);
scanf("%d", &processes[i].burst_time);
processes[i].pid = i + 1;
processes[i].remaining_time = processes[i].burst_time;
}
// Perform round robin scheduling
round_robin(processes, n);
return 0;
}

Q 8. To write a C-program to implement the producer – consumer problem


using semaphores.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 5
#define NUM_ITEMS 10

int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;

sem_t mutex, full, empty;


void *producer(void *arg) {
for (int i = 0; i < NUM_ITEMS; i++) {
sem_wait(&empty);
sem_wait(&mutex);
buffer[in] = i;
printf("Produced item %d\n", buffer[in]);
in = (in + 1) % BUFFER_SIZE;
sem_post(&mutex);
sem_post(&full);
}
pthread_exit(NULL);
}
void *consumer(void *arg) {
for (int i = 0; i < NUM_ITEMS; i++) {
sem_wait(&full);
sem_wait(&mutex);
int item = buffer[out];
printf("Consumed item %d\n", item);
out = (out + 1) % BUFFER_SIZE;
sem_post(&mutex);
sem_post(&empty);
}
pthread_exit(NULL);
}
int main() {
pthread_t producer_thread, consumer_thread;
sem_init(&mutex, 0, 1);
sem_init(&full, 0, 0);
sem_init(&empty, 0, BUFFER_SIZE);

pthread_create(&producer_thread, NULL, producer, NULL);


pthread_create(&consumer_thread, NULL, consumer, NULL);
pthread_join(producer_thread, NULL);
pthread_join(consumer_thread, NULL);

sem_destroy(&mutex);
sem_destroy(&full);
sem_destroy(&empty);

return 0;
}

Q 9. To write a c program to implement IPC using shared memory.


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#define SHM_SIZE 1024 // Size of shared memory segment
int main() {
int shmid;
key_t key;
char *shm_ptr;
char *message = "Hello, shared memory!";

// Generate a unique key for the shared memory segment


key = ftok("shared_memory_key", 65);
if (key == -1) {
perror("ftok");
exit(1);
}
// Create a shared memory segment
shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666);
if (shmid == -1) {
perror("shmget");
exit(1);
}
// Attach the shared memory segment to the process's address space
shm_ptr = shmat(shmid, NULL, 0);
if (shm_ptr == (char *) -1) {
perror("shmat");
exit(1);
}
// Write data to the shared memory
strcpy(shm_ptr, message);
printf("Data written to shared memory: %s\n", shm_ptr);

// Detach the shared memory segment


if (shmdt(shm_ptr) == -1) {
perror("shmdt");
exit(1);
}
return 0;
}

Q 10. To write a C program to implement banker’s algorithm for deadlock


avoidance.
#include <stdio.h>
#include <stdbool.h>
#define MAX_PROCESSES 10
#define MAX_RESOURCES 10
int available[MAX_RESOURCES];
int maximum[MAX_PROCESSES][MAX_RESOURCES];
int allocation[MAX_PROCESSES][MAX_RESOURCES];
int need[MAX_PROCESSES][MAX_RESOURCES];
bool finished[MAX_PROCESSES];

int num_processes, num_resources;

// Function to initialize the banker's algorithm


void initialize() {
for (int i = 0; i < num_resources; i++) {
int sum = 0;
for (int j = 0; j < num_processes; j++) {
sum += allocation[j][i];
}
available[i] -= sum;
}
for (int i = 0; i < num_processes; i++) {
for (int j = 0; j < num_resources; j++) {
need[i][j] = maximum[i][j] - allocation[i][j];
}
}
}
// Function to check if a process can be allocated resources
bool canAllocate(int process) {
for (int i = 0; i < num_resources; i++) {
if (need[process][i] > available[i]) {
return false;
}
}
return true;
}
// Function to perform resource allocation
bool requestResources(int process, int request[]) {
for (int i = 0; i < num_resources; i++) {
if (request[i] > need[process][i]) {
printf("Request exceeds maximum need.\n");
return false;
}
if (request[i] > available[i]) {
printf("Not enough resources available.\n");
return false;
}
}

// Try to allocate the resources


for (int i = 0; i < num_resources; i++) {
available[i] -= request[i];
allocation[process][i] += request[i];
need[process][i] -= request[i];
}

// Check if the system is in a safe state


bool safe = false;
if (canAllocate(process)) {
safe = true;
finished[process] = true;
printf("Resources allocated successfully.\n");
} else {
printf("Resources cannot be allocated safely. Rolling back...\n");
// Roll back the resource allocation
for (int i = 0; i < num_resources; i++) {
available[i] += request[i];
allocation[process][i] -= request[i];
need[process][i] += request[i];
}
}
return safe;
}

int main() {
// Input number of processes and resources
printf("Enter number of processes: ");
scanf("%d", &num_processes);
printf("Enter number of resources: ");
scanf("%d", &num_resources);

// Input available resources


printf("Enter available resources: ");
for (int i = 0; i < num_resources; i++) {
scanf("%d", &available[i]);
}
// Input maximum resources needed for each process
printf("Enter maximum resources for each process:\n");
for (int i = 0; i < num_processes; i++) {
printf("Process %d: ", i + 1);
for (int j = 0; j < num_resources; j++) {
scanf("%d", &maximum[i][j]);
}
finished[i] = false;
}
// Input allocated resources for each process
printf("Enter allocated resources for each process:\n");
for (int i = 0; i < num_processes; i++) {
printf("Process %d: ", i + 1);
for (int j = 0; j < num_resources; j++) {
scanf("%d", &allocation[i][j]);
}
}
initialize();
// Input request for resources
int process;
printf("Enter process requesting resources: ");
scanf("%d", &process);
printf("Enter resource request: ");
int request[MAX_RESOURCES];
for (int i = 0; i < num_resources; i++) {
scanf("%d", &request[i]);
}
// Process the request
requestResources(process - 1, request);
return 0;
}
Q 11. To write a c program to implement Threading and Synchronization
Applications.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 5
pthread_mutex_t mutex;
int shared_variable = 0;

void *thread_function(void *arg) {


int thread_id = *((int *)arg);
pthread_mutex_lock(&mutex); // Lock the critical section
printf("Thread %d: shared_variable before increment = %d\n", thread_id,
shared_variable);
shared_variable++; // Increment the shared variable
printf("Thread %d: shared_variable after increment = %d\n", thread_id,
shared_variable);
pthread_mutex_unlock(&mutex); // Unlock the critical section

pthread_exit(NULL);
}
int main() {
pthread_t threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
pthread_mutex_init(&mutex, NULL); // Initialize the mutex lock
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i;
pthread_create(&threads[i], NULL, thread_function, &thread_ids[i]); // Create threads
}
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL); // Wait for threads to finish
}
pthread_mutex_destroy(&mutex); // Destroy the mutex lock

return 0;
}
Q 12.To write a C program for implementation memory allocation
methods for fixed partition using first fit.

#include <stdio.h>
#define MAX_PARTITIONS 10

// Structure to represent a partition


struct Partition {
int id; // Partition ID
int size; // Size of the partition
int process_id; // ID of the process allocated to the partition (-1 if empty)
};
// Array to store the partitions
struct Partition partitions[MAX_PARTITIONS];
// Function to initialize partitions
void initializePartitions() {
for (int i = 0; i < MAX_PARTITIONS; i++) {
partitions[i].id = i + 1;
partitions[i].size = 0;
partitions[i].process_id = -1; // -1 indicates the partition is empty
}
}
// Function to display the status of partitions
void displayPartitions() {
printf("Partition\tSize\tProcess ID\n");
for (int i = 0; i < MAX_PARTITIONS; i++) {
printf("%d\t\t%d\t\t%d\n", partitions[i].id, partitions[i].size, partitions[i].process_id);
}
}
// Function to allocate memory using First Fit
void firstFit(int process_id, int size) {
int i;
for (i = 0; i < MAX_PARTITIONS; i++) {
if (partitions[i].size >= size && partitions[i].process_id == -1) {
partitions[i].process_id = process_id;
printf("Process %d allocated to Partition %d\n", process_id, partitions[i].id);
break;
}
}
if (i == MAX_PARTITIONS) {
printf("No suitable partition found for Process %d\n", process_id);
}
}
int main() {
int num_processes, process_id, process_size;
// Initialize partitions
initializePartitions();
// Input number of processes
printf("Enter number of processes: ");
scanf("%d", &num_processes);

// Input process details and allocate memory using First Fit


for (int i = 0; i < num_processes; i++) {
printf("Enter Process ID and Size: ");
scanf("%d %d", &process_id, &process_size);
firstFit(process_id, process_size);
}
// Display partition status after allocation
printf("\nPartition Status after Allocation:\n");
displayPartitions();
return 0;
}

Q 13. Implementation of the following Page Replacement Algorithms


i. FIFO
ii. LRU
iii. LFU

i. FIFO
#include <stdio.h>
#include <stdbool.h>
#define NUM_FRAMES 3
#define NUM_PAGES 10

int frames[NUM_FRAMES];
int pages[NUM_PAGES];
int page_faults = 0;
// Function to initialize frames
void initializeFrames() {
for (int i = 0; i < NUM_FRAMES; i++) {
frames[i] = -1; // -1 indicates an empty frame
}
}
// Function to check if a page is present in frames
bool isPagePresent(int page) {
for (int i = 0; i < NUM_FRAMES; i++) {
if (frames[i] == page) {
return true;
}
}
return false;
}
// Function to display frames
void displayFrames() {
printf("Frames: ");
for (int i = 0; i < NUM_FRAMES; i++) {
if (frames[i] == -1) {
printf("- ");
} else {
printf("%d ", frames[i]);
}
}
printf("\n");
}
// Function to implement FIFO page replacement algorithm
void fifo() {
int frame_index = 0; // Index to keep track of the oldest frame

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


int page = pages[i];
if (!isPagePresent(page)) {
frames[frame_index] = page; // Replace the oldest frame with the new page
frame_index = (frame_index + 1) % NUM_FRAMES; // Update the index for the next
oldest frame
page_faults++; // Increment page fault count
}
displayFrames(); // Display frames after each page access
}
}
int main() {
// Initialize frames
initializeFrames();
// Input page sequence
printf("Enter the page sequence (length %d): ", NUM_PAGES);
for (int i = 0; i < NUM_PAGES; i++) {
scanf("%d", &pages[i]);
}
// Perform FIFO page replacement
fifo();
// Display total page faults
printf("Total Page Faults: %d\n", page_faults);
return 0;
}

ii. LRU

#include <stdio.h>
#include <stdbool.h>
#define NUM_FRAMES 3
#define NUM_PAGES 10

int frames[NUM_FRAMES];
int pages[NUM_PAGES];
int page_faults = 0;
// Function to initialize frames
void initializeFrames() {
for (int i = 0; i < NUM_FRAMES; i++) {
frames[i] = -1; // -1 indicates an empty frame
}
}
// Function to check if a page is present in frames
bool isPagePresent(int page) {
for (int i = 0; i < NUM_FRAMES; i++) {
if (frames[i] == page) {
return true;
}
}
return false;
}
// Function to display frames
void displayFrames() {
printf("Frames: ");
for (int i = 0; i < NUM_FRAMES; i++) {
if (frames[i] == -1) {
printf("- ");
} else {
printf("%d ", frames[i]);
}
}
printf("\n");
}
// Function to implement LRU page replacement algorithm
void lru() {
int counter[NUM_FRAMES] = {0}; // Counter to keep track of page usage
for (int i = 0; i < NUM_PAGES; i++) {
int page = pages[i];
if (!isPagePresent(page)) {
// Find the frame with the lowest usage counter (least recently used)
int min_counter = counter[0];
int min_index = 0;
for (int j = 1; j < NUM_FRAMES; j++) {
if (counter[j] < min_counter) {
min_counter = counter[j];
min_index = j;
}
}
frames[min_index] = page; // Replace the least recently used frame with the new page
page_faults++; // Increment page fault count
}
// Update the usage counter for the accessed page
for (int j = 0; j < NUM_FRAMES; j++) {
if (frames[j] != -1 && frames[j] != page) {
counter[j]++;
} else if (frames[j] == page) {
counter[j] = 0; // Reset counter for the accessed page
}
}
displayFrames(); // Display frames after each page access
}
}
int main() {
// Initialize frames
initializeFrames();

// Input page sequence


printf("Enter the page sequence (length %d): ", NUM_PAGES);
for (int i = 0; i < NUM_PAGES; i++) {
scanf("%d", &pages[i]);
}
// Perform LRU page replacement
lru();
// Display total page faults
printf("Total Page Faults: %d\n", page_faults);
return 0;
}

iii. LFU
#include <stdio.h>
#include <stdbool.h>
#define NUM_FRAMES 3
#define NUM_PAGES 10

int frames[NUM_FRAMES];
int pages[NUM_PAGES];
int page_faults = 0;
// Structure to represent a page entry in frames
struct PageEntry {
int page;
int frequency;
};
// Function to initialize frames
void initializeFrames() {
for (int i = 0; i < NUM_FRAMES; i++) {
frames[i] = -1; // -1 indicates an empty frame
}
}
// Function to check if a page is present in frames
bool isPagePresent(int page) {
for (int i = 0; i < NUM_FRAMES; i++) {
if (frames[i] == page) {
return true;
}
}
return false;
}
// Function to display frames
void displayFrames() {
printf("Frames: ");
for (int i = 0; i < NUM_FRAMES; i++) {
if (frames[i] == -1) {
printf("- ");
} else {
printf("%d ", frames[i]);
}
}
printf("\n");
}
// Function to implement LFU page replacement algorithm
void lfu() {
struct PageEntry page_entries[NUM_FRAMES];
for (int i = 0; i < NUM_FRAMES; i++) {
page_entries[i].page = -1;
page_entries[i].frequency = 0;
}
for (int i = 0; i < NUM_PAGES; i++) {
int page = pages[i];
if (!isPagePresent(page)) {
// Find the page with the least frequency in frames
int min_frequency = page_entries[0].frequency;
int min_index = 0;
for (int j = 1; j < NUM_FRAMES; j++) {
if (page_entries[j].frequency < min_frequency) {
min_frequency = page_entries[j].frequency;
min_index = j;
}
}
frames[min_index] = page; // Replace the page with least frequency with the new
page
page_entries[min_index].page = page;
page_entries[min_index].frequency = 1;
page_faults++; // Increment page fault count
} else {
// Increment the frequency of the accessed page
for (int j = 0; j < NUM_FRAMES; j++) {
if (frames[j] == page) {
page_entries[j].frequency++;
break;
}
}
}
displayFrames(); // Display frames after each page access
}
}
int main() {
// Initialize frames
initializeFrames();

// Input page sequence


printf("Enter the page sequence (length %d): ", NUM_PAGES);
for (int i = 0; i < NUM_PAGES; i++) {
scanf("%d", &pages[i]);
}
// Perform LFU page replacement
lfu();
// Display total page faults
printf("Total Page Faults: %d\n", page_faults);
return 0;
}

Q 14. Implementation of the following File Allocation Strategies


i. Sequential
ii. Indexed
iii. Linked

i. Sequential
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_BLOCKS 100
#define MAX_FILENAME_LENGTH 20

struct File {
char filename[MAX_FILENAME_LENGTH];
int start_block;
int num_blocks;
};
int disk[MAX_BLOCKS]; // Array to represent disk blocks
struct File files[MAX_BLOCKS]; // Array to store file information
int num_files = 0; // Number of files stored on disk
// Function to initialize disk
void initializeDisk() {
for (int i = 0; i < MAX_BLOCKS; i++) {
disk[i] = -1; // -1 indicates an empty block
}
}
// Function to display disk
void displayDisk() {
printf("Disk Status:\n");
for (int i = 0; i < MAX_BLOCKS; i++) {
printf("%3d ", i);
}
printf("\n");
for (int i = 0; i < MAX_BLOCKS; i++) {
printf("%3d ", disk[i]);
}
printf("\n");
}
// Function to check if a block is free
bool isBlockFree(int block) {
return disk[block] == -1;
}
// Function to allocate blocks sequentially for a file
void allocateBlocksSequential(char *filename, int num_blocks) {
int start_block = -1;
for (int i = 0; i < MAX_BLOCKS; i++) {
if (isBlockFree(i)) {
if (start_block == -1) {
start_block = i;
}
num_blocks--;
disk[i] = num_files; // Assign the file ID to the block
if (num_blocks == 0) {
break;
}
} else {
start_block = -1; // Reset start block if the sequence is broken
}
}
if (start_block != -1) {
// Store file information
strcpy(files[num_files].filename, filename);
files[num_files].start_block = start_block;
files[num_files].num_blocks = num_blocks + 1;
num_files++;
printf("File %s allocated at blocks %d-%d\n", filename, start_block, start_block +
files[num_files - 1].num_blocks - 1);
} else {
printf("Error: Insufficient free blocks for file allocation\n");
}
}
int main() {
initializeDisk();
// Example: Allocate files
allocateBlocksSequential("file1", 3);
allocateBlocksSequential("file2", 4);
allocateBlocksSequential("file3", 2);
// Display disk status
displayDisk();
return 0;
}

ii. Indexed
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_BLOCKS 100
#define MAX_FILENAME_LENGTH 20
#define MAX_INDEX_BLOCKS 10

struct IndexBlock {
int file_id;
int blocks[MAX_INDEX_BLOCKS];
int num_blocks;
};
struct File {
char filename[MAX_FILENAME_LENGTH];
int index_block;
int size;
};
int disk[MAX_BLOCKS]; // Array to represent disk blocks
struct File files[MAX_BLOCKS]; // Array to store file information
struct IndexBlock index_blocks[MAX_BLOCKS]; // Array to store index block information
int num_files = 0; // Number of files stored on disk
int num_index_blocks = 0; // Number of index blocks used
// Function to initialize disk
void initializeDisk() {
for (int i = 0; i < MAX_BLOCKS; i++) {
disk[i] = -1; // -1 indicates an empty block
}
}
// Function to display disk
void displayDisk() {
printf("Disk Status:\n");
for (int i = 0; i < MAX_BLOCKS; i++) {
printf("%3d ", i);
}
printf("\n");
for (int i = 0; i < MAX_BLOCKS; i++) {
printf("%3d ", disk[i]);
}
printf("\n");
}
// Function to check if a block is free
bool isBlockFree(int block) {
return disk[block] == -1;
}
// Function to allocate an index block for a file
int allocateIndexBlock(int file_id) {
int index_block = -1;
for (int i = 0; i < MAX_BLOCKS; i++) {
if (isBlockFree(i)) {
index_block = i;
disk[i] = file_id; // Assign the file ID to the block
num_index_blocks++;
break;
}
}
if (index_block != -1) {
printf("Index block allocated for file %d at block %d\n", file_id, index_block);
} else {
printf("Error: Insufficient free blocks for index block allocation\n");
}
return index_block;
}
// Function to allocate blocks for a file using an index block
void allocateBlocksIndexed(int file_id, int size) {
int index_block = allocateIndexBlock(file_id);
if (index_block != -1) {
int num_blocks = (size + MAX_INDEX_BLOCKS - 1) / MAX_INDEX_BLOCKS; // Calculate
number of index blocks needed
index_blocks[index_block].file_id = file_id;
index_blocks[index_block].num_blocks = num_blocks;
for (int i = 0; i < num_blocks; i++) {
for (int j = 0; j < MAX_INDEX_BLOCKS; j++) {
int block = i * MAX_INDEX_BLOCKS + j;
if (block < size) {
// Allocate data blocks for the file
for (int k = 0; k < MAX_BLOCKS; k++) {
if (isBlockFree(k)) {
index_blocks[index_block].blocks[j] = k;
disk[k] = file_id; // Assign the file ID to the block
size--;
break;
}
}
} else {
index_blocks[index_block].blocks[j] = -1; // -1 indicates end of file
}
}
}
files[num_files].index_block = index_block;
files[num_files].size = size;
printf("File %d allocated using indexed allocation\n", file_id);
num_files++;
}
}
int main() {
initializeDisk();
// Example: Allocate files
allocateBlocksIndexed(0, 7);
allocateBlocksIndexed(1, 11);
allocateBlocksIndexed(2, 5);
// Display disk status
displayDisk();
return 0;
}

iii. Linked
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#define MAX_BLOCKS 100


#define MAX_FILENAME_LENGTH 20
struct File {
char filename[MAX_FILENAME_LENGTH];
int start_block;
int size;
};

struct Block {
int data;
struct Block *next;
};

int disk[MAX_BLOCKS]; // Array to represent disk blocks


struct File files[MAX_BLOCKS]; // Array to store file information
struct Block *free_blocks = NULL; // Linked list to store free blocks
int num_files = 0; // Number of files stored on disk

// Function to initialize disk


void initializeDisk() {
for (int i = 0; i < MAX_BLOCKS; i++) {
disk[i] = -1; // -1 indicates an empty block
}
}

// Function to display disk


void displayDisk() {
printf("Disk Status:\n");
for (int i = 0; i < MAX_BLOCKS; i++) {
printf("%3d ", i);
}
printf("\n");
for (int i = 0; i < MAX_BLOCKS; i++) {
printf("%3d ", disk[i]);
}
printf("\n");
}

// Function to check if a block is free


bool isBlockFree(int block) {
return disk[block] == -1;
}

// Function to add a free block to the linked list


void addFreeBlock(int block) {
struct Block *new_block = (struct Block *)malloc(sizeof(struct Block));
if (new_block == NULL) {
printf("Error: Memory allocation failed\n");
exit(1);
}
new_block->data = block;
new_block->next = free_blocks;
free_blocks = new_block;
}

// Function to allocate blocks for a file using linked allocation


void allocateBlocksLinked(char *filename, int size) {
int start_block = -1;
int num_blocks_allocated = 0;
struct Block *prev_block = NULL;

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


if (isBlockFree(i)) {
// Allocate a block for the file
disk[i] = num_files; // Assign the file ID to the block
addFreeBlock(i);
num_blocks_allocated++;
if (start_block == -1) {
start_block = i;
}
if (num_blocks_allocated == size) {
break;
}
if (prev_block != NULL) {
prev_block->next = (struct Block *)malloc(sizeof(struct Block));
if (prev_block->next == NULL) {
printf("Error: Memory allocation failed\n");
exit(1);
}
prev_block = prev_block->next;
} else {
prev_block = (struct Block *)malloc(sizeof(struct Block));
if (prev_block == NULL) {
printf("Error: Memory allocation failed\n");
exit(1);
}
files[num_files].start_block = start_block;
files[num_files].size = size;
prev_block = prev_block;
}
prev_block->data = i;
prev_block->next = NULL;
}
}

if (start_block != -1) {
// Store file information
strcpy(files[num_files].filename, filename);
num_files++;
printf("File %s allocated using linked allocation\n", filename);
} else {
printf("Error: Insufficient free blocks for file allocation\n");
}
}

int main() {
initializeDisk();

// Example: Allocate files


allocateBlocksLinked("file1", 3);
allocateBlocksLinked("file2", 4);
allocateBlocksLinked("file3", 2);

// Display disk status


displayDisk();

return 0;
}

You might also like