0% found this document useful (0 votes)
41 views40 pages

OS Lab Manual Data Science

The document is a practical file for the Operating System course (CD405) at Baderia Global Institute of Engineering and Management, detailing the vision, mission, educational objectives, outcomes, and specific outcomes of the program. It includes laboratory regulations, a list of experiments, and sample codes for CPU scheduling algorithms such as FCFS, SJF, and Priority scheduling. The document aims to provide a comprehensive overview of the course structure and expectations for students in the Data Science branch.

Uploaded by

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

OS Lab Manual Data Science

The document is a practical file for the Operating System course (CD405) at Baderia Global Institute of Engineering and Management, detailing the vision, mission, educational objectives, outcomes, and specific outcomes of the program. It includes laboratory regulations, a list of experiments, and sample codes for CPU scheduling algorithms such as FCFS, SJF, and Priority scheduling. The document aims to provide a comprehensive overview of the course structure and expectations for students in the Data Science branch.

Uploaded by

abhisheksingh.cs
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 40

A Practical File

of
Operating System
(CD405)

Department of Computer Science and Engineering - Data Science

Submitted by

Name:
Enrollment No:
Semester: IV
Branch: Data Science
Session: Jan Jun 2025

Department of Computer Science and Engineering

Baderia Global Institute of Engineering and Management, Jabalpur (M.P.)


Global Square, Patan Bypass, Raigwan, Jabalpur, M.P., 482002
Operating System Lab Manual (CD 405)

Contents

● Vision and Mission of the Institute

● Vision and Mission of the Department

● Program Educational Objective

● Program Outcomes

● Program Specific Outcomes

● Course Outcomes

● Laboratory Regulations and Safety Rules

● List of Experiments

Operating System (CD 405)


Vision and Mission of the Institute

Vision

Transforming life by providing professional education with excellence.

Mission

1. Quality Education: Providing Education with quality and shaping up Technocrats and
building managers with a focus on adapting to changing technologies.
2. Focused Research & Innovation: Focusing on Research and Development and fostering
Innovation among the academic community of the Institution.
3. People Focused: Accountable and committed to institutional operations for effective
functioning by Faculty members, Staff and Students.
4. Holistic Learning: Focus on conceptual learning with practical experience and experimental
learning with strong Industrial connections and collaborations.
5. Service to Society: Providing Technical and Managerial services to society for betterment of
their quality of life with best of the skills, compassion and empathy.

Operating System (CD 405)


Vision and Mission of the Department

Vision and Mission of the Department

Vision

Cultivating leaders in Data Science who drive innovation and informed decision-making through the
power of data analytics and scientific discovery.

Mission
The program strives to:

1. Foster a student-centric learning environment that equips graduates with cutting-edge knowledge and
skills in data science, analytics, and related technologies.
2. Develop professionals who can apply data-driven approaches to solve complex problems across
diverse industries, with a commitment to ethical standards and societal well-being.
3. Continuously enhance faculty expertise through ongoing training, ensuring the delivery of high-
quality education and mentorship.
4. Promote collaboration between academia and industry through research and consultancy projects,
providing students with practical experiences and opportunities for conceptual learning.

Operating System (CD 405)


Program Education Objectives

1. To impart in depth concepts of the subject in terms of both theoretical and practical aspects to
achieve excellent University Outputs.
2. To produce technically sound engineering graduates who would fulfill the latest requirements of
computer science and IT industry at modest cost with the calibre of solving intricacies of deeper
programming concepts.
3. To inculcate the lessons of communication skills, teamwork spirit and professional attitude to the
budding engineering graduates.
4. In order to get versatile growth of the students, participation of students in extracurricular
activities is also made compulsory; and also to develop ethical attitudes in the graduates so that
they can also become good citizens of the nation.
5. To develop leadership and entrepreneurship qualities in budding graduates so that they will
cherish and nourish the society and the nation with modern trends of digitization and blossom it
with their unparalleled technical expertise.

Operating System (CD 405)


Program Outcomes

1. Engineering knowledge: Apply the knowledge of mathematics, science, engineering


fundamentals, and an engineering specialization for the solution of complex engineering problems.
2. Problem analysis: Identify, formulate, research literature, and analyze complex engineering
problems reaching substantiated conclusions using first principles of mathematics, natural sciences,
and engineering sciences.
3. Design/development of solutions: Design solutions for complex engineering problems and
design system components or processes that meet the specified needs with appropriate
consideration for public health and safety, and cultural, societal, and environmental considerations.
4. Conduct investigations of complex problems: Use research based knowledge and research
methods including design of experiments, analysis and interpretation of data, and synthesis of
information to provide valid conclusions.
5. Modern tool usage: Create, select, and apply appropriate techniques, resources, and modern
engineering and IT tools, including prediction and modeling to complex engineering activities, with
an understanding of the limitations.
6. The engineer and society: Apply reasoning informed by the contextual knowledge to assess
societal, health, safety, legal and cultural issues and the consequent responsibilities relevant to the
professional engineering practice.
7. Environment and sustainability: Understand the impact of the professional engineering
solutions in societal and environmental contexts, and demonstrate the knowledge of, and need for
sustainable development.
8. Ethics: Apply ethical principles and commit to professional ethics and responsibilities and
norms of the engineering practice.
9. Individual and team work: Function effectively as an individual, and as a member or leader in
diverse teams, and in multidisciplinary settings.
10. Communication: Communicate effectively on complex engineering activities with the
engineering community and with the society at large, such as, being able to comprehend and write
effective reports and design documentation, make effective presentations, and give and receive
clear instructions.
11. Project management and finance: Demonstrate knowledge and understanding of the
engineering and management principles and apply these to one’s own work, as a member and
leader in a team, to manage projects and in multidisciplinary environments.
12. Life-long learning: Recognize the need for, and have the preparation and ability to engage in
independent and life-long learning in the broadest context of technological change.
Operating System (CD 405)
Program Specific Outcomes

Graduates will be able to-

PSO 1: Proficiency in Computer Systems: Capability to understand, analyze and develop computer
programs in the areas related algorithms, system software, multimedia, web design, cloud computing
and networking enable designing of computer systems that are efficient and support the degree of
complexity.

PSO 2: Proficiency in Software Development: Ability to understand the structure and methodologies of
software systems with keen knowledge about software design process and practical expertise in the
programming languages and the open system platform.

PSO 3: Proficiency in Mathematics and science concepts: Capable of applying mathematics and science
concepts to solve computation tasks and model real world problems using suitable algorithms and data
structures.

PSO 4: Successful career as a Computer Science Engineer: Ability to employ themselves as computer
professionals, to be an entrepreneur having innovative ideas and sound knowledge in various domains
leads to enthusiasm in higher studies and research.

Operating System (CD 405)


Course Outcomes

After Completing the course student should be able to:

CO1: Define the fundamental concepts of operating systems, including their functions, types, and
characteristics.

CO2: Apply file system concepts, disk organization, and directory structures. Evaluate and choose disk
allocation methods, and analyze disk scheduling algorithms

CO3: Implement CPU scheduling algorithms and comprehend memory management techniques,
including partitioning, swapping, segmentation, and paging. Apply the concept of virtual memory
through demand paging.

CO4: Design and construct solutions utilizing semaphores to manage concurrent processes effectively,
mitigating deadlock concerns.

CO5: Analyze case studies of Unix/Linux, Windows, and other network, distributed, and multiprocessor
operating systems to understand their architecture and functionalities.

Operating System (CD 405)


Laboratory Regulations and Safety Rules

The following Regulations and Safety Rules must be observed in all concerned laboratory locations.

1. It is the duty of all concerned parties who use any electrical laboratory to take all reasonable
steps to safeguard the HEALTH and SAFETY of themselves and all other users and visitors.
2. Make sure that all equipment is properly working before using it for laboratory exercises. Any
defective equipment must be reported immediately to the Lab. Instructors or Lab. Technical Staff.
3. Students are allowed to use only the equipment provided in the experiment manual or equipment
used for senior project laboratory.
4. Power supply terminals connected to any circuit are only energized with the presence of the
Instructor or Lab. Staff.
5. Students should keep a safe distance from the circuit breakers, electric circuits or any moving
parts during the experiment.
6. Avoid any part of your body to be connected to the energized circuit and ground.
7. Switch off the equipment and disconnect the power supplies from the circuit before leaving the
laboratory.
8. Observe cleanliness and proper laboratory housekeeping of the equipment and other related
accessories.
9. Wear proper clothes and safety gloves or goggles required in working areas that involve
fabrications of printed circuit boards, chemicals process control system, antenna communication
equipment and laser facility laboratories.
10. Double check your circuit connections specifically in handling electrical power machines, AC
motors and generators before switching “ON” the power supply.
11. Make sure that the last connection to be made in your circuit is the power supply and the first
thing to be disconnected is also the power supply.
12. Equipment should not be removed, transferred to any location without permission from the
laboratory staff.
13. Software installation in any computer laboratory is not allowed without the permission from the
Laboratory Staff.
14. Computer games are strictly prohibited in the computer laboratory.
15. Students are not allowed to use any equipment without proper orientation and actual hands on
equipment operation.

Operating System (CD 405)


INDEX

S.No. Name of the Program Date Signature

Implement the FCFS CPU scheduling algorithm


1 and demonstrate its process allocation.

Develop and demonstrate the SJF CPU scheduling


algorithm, highlighting its impact on process
2
completion time.

Construct and analyze the Priority CPU Scheduling


algorithm, showcasing how different priorities affect
3
scheduling.

Implement the Round Robin CPU scheduling


algorithm, and evaluate its effect on process
4
fairness and turnaround time.

Compare and evaluate various CPU scheduling


algorithms, emphasizing differences in turnaround
5
time and waiting time.

Design a solution for the Reader-Writers problem,


applying synchronization techniques to prevent data
6
inconsistency.

Develop a solution to the Dining Philosophers


7 problem, applying deadlock avoidance strategies
and analyzing outcomes.

Implement and compare various page replacement


8 algorithms, analyzing their impact on memory
management performance.

Develop and evaluate different Disk and Drum


9 scheduling algorithms, examining their efficiency in
disk utilization.

Operating System (CD 405)


Apply the Banker’s algorithm for deadlock
10 avoidance, evaluating its effectiveness in resource
allocation.

Operating System (CD 405)


Experiment 1: Implement the FCFS CPU scheduling algorithm and demonstrate its process allocation.

Program:

#include <stdio.h>

// Structure to represent a process


struct Process {
int id;
int arrival_time;
int burst_time;
int waiting_time;
int turnaround_time;
};

void fcfs_scheduling(struct Process processes[], int n) {


int current_time = 0;
int total_wait_time = 0;
int total_turnaround_time = 0;

printf("Process | Arrival Time | Burst Time | Waiting Time | Turnaround Time\n");

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


// Calculate waiting time
if (current_time < processes[i].arrival_time) {
current_time = processes[i].arrival_time;
}

processes[i].waiting_time = current_time - processes[i].arrival_time;


processes[i].turnaround_time = processes[i].waiting_time + processes[i].burst_time;

// Update total times


total_wait_time += processes[i].waiting_time;
total_turnaround_time += processes[i].turnaround_time;

// Update current time


current_time += processes[i].burst_time;

printf(" %d | %d | %d | %d | %d\n",
processes[i].id, processes[i].arrival_time, processes[i].burst_time,
processes[i].waiting_time, processes[i].turnaround_time);
}

// Calculate and display average times


double avg_wait_time = (double) total_wait_time / n;
double avg_turnaround_time = (double) total_turnaround_time / n;

printf("\nAverage Waiting Time: %.2f\n", avg_wait_time);


printf("Average Turnaround Time: %.2f\n", avg_turnaround_time);
}
Operating System (CD 405)
int main() {
// Input: List of processes with their IDs, arrival times, and burst times
struct Process processes[] = {
{1, 0, 5},
{2, 1, 3},
{3, 2, 8},
{4, 3, 6}
};

int n = sizeof(processes) / sizeof(processes[0]);

// Call the function to demonstrate FCFS scheduling


fcfs_scheduling(processes, n);

return 0;
}

Sample Output:
Process | Arrival Time | Burst Time | Waiting Time | Turnaround Time
1 | 0 | 5 | 0 | 5
2 | 1 | 3 | 4 | 7
3 | 2 | 8 | 7 | 15
4 | 3 | 6 | 13 | 19

Average Waiting Time: 6.00


Average Turnaround Time: 11.50

Operating System (CD 405)


Experiment 2: Develop and demonstrate the SJF CPU scheduling algorithm, highlighting its impact on
process completion time.

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

// Structure to represent a process


struct Process {
int id;
int arrival_time;
int burst_time;
int waiting_time;
int turnaround_time;
bool completed;
};

void sjf_scheduling(struct Process processes[], int n) {


int completed = 0, current_time = 0;
int total_wait_time = 0, total_turnaround_time = 0;

printf("Process | Arrival Time | Burst Time | Waiting Time | Turnaround Time\n");

while (completed < n) {


int shortest = -1;
int min_burst = 1e9;

// Find the process with the shortest burst time that has arrived
for (int i = 0; i < n; i++) {
if (!processes[i].completed && processes[i].arrival_time <= current_time && processes[i].burst_time <
min_burst) {
min_burst = processes[i].burst_time;
shortest = i;
}
}

if (shortest == -1) {
// No process is ready to execute, increment time
current_time++;
continue;
}

// Process the selected process


processes[shortest].waiting_time = current_time - processes[shortest].arrival_time;
processes[shortest].turnaround_time = processes[shortest].waiting_time + processes[shortest].burst_time;

// Update total times


total_wait_time += processes[shortest].waiting_time;
total_turnaround_time += processes[shortest].turnaround_time;

// Update current time and mark process as completed


Operating System (CD 405)
current_time += processes[shortest].burst_time;
processes[shortest].completed = true;
completed++;

printf(" %d | %d | %d | %d | %d\n",
processes[shortest].id, processes[shortest].arrival_time, processes[shortest].burst_time,
processes[shortest].waiting_time, processes[shortest].turnaround_time);
}
// Calculate and display average times
double avg_wait_time = (double) total_wait_time / n;
double avg_turnaround_time = (double) total_turnaround_time / n;

printf("\nAverage Waiting Time: %.2f\n", avg_wait_time);


printf("Average Turnaround Time: %.2f\n", avg_turnaround_time);
}

int main() {
// Input: List of processes with their IDs, arrival times, and burst times
struct Process processes[] = {
{1, 0, 6, 0, 0, false},
{2, 1, 8, 0, 0, false},
{3, 2, 7, 0, 0, false},
{4, 3, 3, 0, 0, false}
};
int n = sizeof(processes) / sizeof(processes[0]);
// Call the function to demonstrate SJF scheduling
sjf_scheduling(processes, n);

return 0;
}

Sample Output:
Process | Arrival Time | Burst Time | Waiting Time | Turnaround Time
1 | 0 | 6 | 0 | 6
4 | 3 | 3 | 3 | 6
3 | 2 | 7 | 7 | 14
2 | 1 | 8 | 13 | 21

Average Waiting Time: 5.25


Average Turnaround Time: 11.75

Operating System (CD 405)


Experiment 3: Construct and analyze the Priority CPU Scheduling algorithm, showcasing how different
priorities affect scheduling.

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

// Structure to represent a process


struct Process {
int id;
int arrival_time;
int burst_time;
int priority;
int waiting_time;
int turnaround_time;
bool completed;
};

void priority_scheduling(struct Process processes[], int n) {


int completed = 0, current_time = 0;
int total_wait_time = 0, total_turnaround_time = 0;

printf("Process | Arrival Time | Burst Time | Priority | Waiting Time | Turnaround Time\n");

while (completed < n) {


int highest_priority = -1;
int max_priority = -1;

// Find the process with the highest priority that has arrived
for (int i = 0; i < n; i++) {
if (!processes[i].completed && processes[i].arrival_time <= current_time && processes[i].priority >
max_priority) {
max_priority = processes[i].priority;
highest_priority = i;
}
}

if (highest_priority == -1) {
// No process is ready to execute, increment time
current_time++;
continue;
}

// Process the selected process


processes[highest_priority].waiting_time = current_time - processes[highest_priority].arrival_time;
processes[highest_priority].turnaround_time = processes[highest_priority].waiting_time +
processes[highest_priority].burst_time;

// Update total times


total_wait_time += processes[highest_priority].waiting_time;
Operating System (CD 405)
total_turnaround_time += processes[highest_priority].turnaround_time;

// Update current time and mark process as completed


current_time += processes[highest_priority].burst_time;
processes[highest_priority].completed = true;
completed++;

printf(" %d | %d | %d | %d | %d | %d\n",
processes[highest_priority].id, processes[highest_priority].arrival_time,
processes[highest_priority].burst_time,
processes[highest_priority].priority, processes[highest_priority].waiting_time,
processes[highest_priority].turnaround_time);
}

// Calculate and display average times


double avg_wait_time = (double) total_wait_time / n;
double avg_turnaround_time = (double) total_turnaround_time / n;

printf("\nAverage Waiting Time: %.2f\n", avg_wait_time);


printf("Average Turnaround Time: %.2f\n", avg_turnaround_time);
}

int main() {
// Input: List of processes with their IDs, arrival times, burst times, and priorities
struct Process processes[] = {
{1, 0, 6, 2, 0, 0, false},
{2, 1, 8, 1, 0, 0, false},
{3, 2, 7, 3, 0, 0, false},
{4, 3, 3, 4, 0, 0, false}
};

int n = sizeof(processes) / sizeof(processes[0]);

// Call the function to demonstrate Priority scheduling


priority_scheduling(processes, n);

return 0;
}

Operating System (CD 405)


Sample Output:

Process | Arrival Time | Burst Time | Priority | Waiting Time | Turnaround Time
3 | 2 | 7 | 3 | 5 | 12
4 | 3 | 3 | 4 | 2 | 5
1 | 0 | 6 | 2 | 0 | 6
2 | 1 | 8 | 1 | 7 | 15

Average Waiting Time: 3.50


Average Turnaround Time: 9.50

Operating System (CD 405)


Experiment 4: Implement the Round Robin CPU scheduling algorithm, and evaluate its effect on process
fairness and turnaround time

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

// Structure to represent a process


struct Process {
int id;
int arrival_time;
int burst_time;
int remaining_time;
int waiting_time;
int turnaround_time;
};

void round_robin_scheduling(struct Process processes[], int n, int quantum) {


int current_time = 0, completed = 0;
int total_wait_time = 0, total_turnaround_time = 0;

printf("Process | Arrival Time | Burst Time | Waiting Time | Turnaround Time\n");

while (completed < n) {


bool progress = false;

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


if (processes[i].remaining_time > 0 && processes[i].arrival_time <= current_time) {
progress = true;
if (processes[i].remaining_time > quantum) {
current_time += quantum;
processes[i].remaining_time -= quantum;
} else {
current_time += processes[i].remaining_time;
processes[i].waiting_time = current_time - processes[i].arrival_time - processes[i].burst_time;
processes[i].turnaround_time = processes[i].waiting_time + processes[i].burst_time;
total_wait_time += processes[i].waiting_time;
total_turnaround_time += processes[i].turnaround_time;
processes[i].remaining_time = 0;
completed++;

printf(" %d | %d | %d | %d | %d\n",
processes[i].id, processes[i].arrival_time, processes[i].burst_time,
processes[i].waiting_time, processes[i].turnaround_time);
}
}
}

if (!progress) {
current_time++;
}
Operating System (CD 405)
}

// Calculate and display average times


double avg_wait_time = (double) total_wait_time / n;
double avg_turnaround_time = (double) total_turnaround_time / n;

printf("\nAverage Waiting Time: %.2f\n", avg_wait_time);


printf("Average Turnaround Time: %.2f\n", avg_turnaround_time);
}

int main() {
// Input: List of processes with their IDs, arrival times, and burst times
struct Process processes[] = {
{1, 0, 6, 6, 0, 0},
{2, 1, 8, 8, 0, 0},
{3, 2, 7, 7, 0, 0},
{4, 3, 3, 3, 0, 0}
};

int n = sizeof(processes) / sizeof(processes[0]);


int quantum = 4; // Time quantum

// Call the function to demonstrate Round Robin scheduling


round_robin_scheduling(processes, n, quantum);

return 0;
}

Sample Output:

Process | Arrival Time | Burst Time | Waiting Time | Turnaround Time


1 | 0 | 6 | 4 | 10
4 | 3 | 3 | 0 | 3
3 | 2 | 7 | 4 | 11
2 | 1 | 8 | 7 | 15

Average Waiting Time: 3.75


Average Turnaround Time: 9.75

Operating System (CD 405)


Experiment 5: Compare and evaluate various CPU scheduling algorithms, emphasizing differences in
turnaround time and waiting time.

Program:

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

// Structure to represent a process


struct Process {
int id, arrival_time, burst_time, waiting_time, turnaround_time, remaining_time;
};

// Function to calculate averages and display results


void display_results(struct Process processes[], int n, int total_wait_time, int total_turnaround_time) {
printf("Process | Waiting Time | Turnaround Time\n");
for (int i = 0; i < n; i++) {
printf(" %d | %d | %d\n",
processes[i].id, processes[i].waiting_time, processes[i].turnaround_time);
}
printf("\nAverage Waiting Time: %.2f\n", (double)total_wait_time / n);
printf("Average Turnaround Time: %.2f\n", (double)total_turnaround_time / n);
}

// Function for FCFS scheduling


void fcfs_scheduling(struct Process processes[], int n) {
int current_time = 0, total_wait_time = 0, total_turnaround_time = 0;

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


if (current_time < processes[i].arrival_time) current_time = processes[i].arrival_time;
processes[i].waiting_time = current_time - processes[i].arrival_time;
processes[i].turnaround_time = processes[i].waiting_time + processes[i].burst_time;
current_time += processes[i].burst_time;
total_wait_time += processes[i].waiting_time;
total_turnaround_time += processes[i].turnaround_time;
}

printf("\nFCFS Scheduling:\n");
display_results(processes, n, total_wait_time, total_turnaround_time);
}

// Function for Round Robin scheduling


void round_robin_scheduling(struct Process processes[], int n, int quantum) {
int current_time = 0, completed = 0, total_wait_time = 0, total_turnaround_time = 0;

while (completed < n) {


for (int i = 0; i < n; i++) {
if (processes[i].remaining_time > 0) {
if (processes[i].remaining_time > quantum) {
current_time += quantum;
processes[i].remaining_time -= quantum;
Operating System (CD 405)
} else {
current_time += processes[i].remaining_time;
processes[i].waiting_time = current_time - processes[i].arrival_time - processes[i].burst_time;
processes[i].turnaround_time = processes[i].waiting_time + processes[i].burst_time;
total_wait_time += processes[i].waiting_time;
total_turnaround_time += processes[i].turnaround_time;
processes[i].remaining_time = 0;
completed++;
}
}
}
}

printf("\nRound Robin Scheduling:\n");


display_results(processes, n, total_wait_time, total_turnaround_time);
}

int main() {
struct Process processes[] = {{1, 0, 6, 0, 0, 6}, {2, 1, 8, 0, 0, 8}, {3, 2, 7, 0, 0, 7}, {4, 3, 3, 0, 0, 3}};
int n = sizeof(processes) / sizeof(processes[0]);
int quantum = 4;

fcfs_scheduling(processes, n);

// Reset remaining times for Round Robin Scheduling


for (int i = 0; i < n; i++) {
processes[i].remaining_time = processes[i].burst_time;
}

round_robin_scheduling(processes, n, quantum);

return 0;
}

Operating System (CD 405)


Sample Output:

Process 1: Arrival Time = 0, Burst Time = 6


Process 2: Arrival Time = 1, Burst Time = 8
Process 3: Arrival Time = 2, Burst Time = 7
Process 4: Arrival Time = 3, Burst Time = 3

FCFS Scheduling:
Process | Waiting Time | Turnaround Time
1 | 0 | 6
2 | 5 | 13
3 | 10 | 17
4 | 12 | 15

Average Waiting Time: 6.75


Average Turnaround Time: 12.75

Round Robin Scheduling:


Process | Waiting Time | Turnaround Time
1 | 4 | 10
2 | 6 | 14
3 | 8 | 15
4 | 3 | 6

Average Waiting Time: 5.25


Average Turnaround Time: 11.25

Operating System (CD 405)


Experiment 6: Design a solution for the Reader-Writers problem, applying synchronization techniques to
prevent data inconsistency.

Program:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

// Shared data and synchronization primitives


int shared_data = 0; // The shared data being accessed
int reader_count = 0; // Number of active readers
pthread_mutex_t mutex; // Mutex for reader_count synchronization
pthread_mutex_t write_lock; // Lock to ensure writers exclusive access

// Reader function
void* reader(void* arg) {
int id = *(int*)arg;
free(arg);

pthread_mutex_lock(&mutex);
reader_count++;
if (reader_count == 1) {
pthread_mutex_lock(&write_lock); // First reader locks the writers
}
pthread_mutex_unlock(&mutex);

// Reading shared data


printf("Reader %d: Read shared data = %d\n", id, shared_data);
sleep(1); // Simulate read delay

pthread_mutex_lock(&mutex);
reader_count--;
if (reader_count == 0) {
pthread_mutex_unlock(&write_lock); // Last reader unlocks the writers
}
pthread_mutex_unlock(&mutex);

return NULL;
}

// Writer function
void* writer(void* arg) {
int id = *(int*)arg;
free(arg);

pthread_mutex_lock(&write_lock); // Writer gets exclusive access

// Writing to shared data


shared_data++;
printf("Writer %d: Updated shared data to %d\n", id, shared_data);
Operating System (CD 405)
sleep(2); // Simulate write delay

pthread_mutex_unlock(&write_lock);

return NULL;
}

int main() {
pthread_t readers[5], writers[2];

// Initialize mutexes
pthread_mutex_init(&mutex, NULL);
pthread_mutex_init(&write_lock, NULL);

// Create reader and writer threads


for (int i = 0; i < 5; i++) {
int* id = malloc(sizeof(int));
*id = i + 1;
pthread_create(&readers[i], NULL, reader, id);
}

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


int* id = malloc(sizeof(int));
*id = i + 1;
pthread_create(&writers[i], NULL, writer, id);
}

// Wait for all threads to finish


for (int i = 0; i < 5; i++) {
pthread_join(readers[i], NULL);
}
for (int i = 0; i < 2; i++) {
pthread_join(writers[i], NULL);
}

// Destroy mutexes
pthread_mutex_destroy(&mutex);
pthread_mutex_destroy(&write_lock);

printf("Reader-Writer simulation completed.\n");


return 0;
}

Sample Output:
Reader 1: Read shared data = 0
Reader 2: Read shared data = 0
Reader 3: Read shared data = 0
Writer 1: Updated shared data to 1
Reader 4: Read shared data = 1
Reader 5: Read shared data = 1
Writer 2: Updated shared data to 2
Operating System (CD 405)
Experiment 7: Develop a solution to the Dining Philosophers problem, applying deadlock avoidance strategies
and analyzing outcomes.

Program:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#define NUM_PHILOSOPHERS 5

// Mutex array for forks


pthread_mutex_t forks[NUM_PHILOSOPHERS];

// Philosopher function
void* philosopher(void* arg) {
int id = *(int*)arg;
free(arg);

int left_fork = id; // Left fork index


int right_fork = (id + 1) % NUM_PHILOSOPHERS; // Right fork index

while (1) {
// Thinking
printf("Philosopher %d is thinking.\n", id);
sleep(1);

// Deadlock avoidance: Pick forks in a specific order


if (id % 2 == 0) {
// Even-numbered philosophers pick the left fork first
pthread_mutex_lock(&forks[left_fork]);
printf("Philosopher %d picked up left fork %d.\n", id, left_fork);

pthread_mutex_lock(&forks[right_fork]);
printf("Philosopher %d picked up right fork %d.\n", id, right_fork);
} else {
// Odd-numbered philosophers pick the right fork first
pthread_mutex_lock(&forks[right_fork]);
printf("Philosopher %d picked up right fork %d.\n", id, right_fork);

pthread_mutex_lock(&forks[left_fork]);
printf("Philosopher %d picked up left fork %d.\n", id, left_fork);
}

// Eating
printf("Philosopher %d is eating.\n", id);
sleep(2);

// Put down forks


pthread_mutex_unlock(&forks[left_fork]);
printf("Philosopher %d put down left fork %d.\n", id, left_fork);
Operating System (CD 405)
pthread_mutex_unlock(&forks[right_fork]);
printf("Philosopher %d put down right fork %d.\n", id, right_fork);
}

return NULL;
}

int main() {
pthread_t philosophers[NUM_PHILOSOPHERS];

// Initialize mutexes
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_mutex_init(&forks[i], NULL);
}

// Create philosopher threads


for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
int* id = malloc(sizeof(int));
*id = i;
pthread_create(&philosophers[i], NULL, philosopher, id);
}

// Wait for threads to finish (this won't happen in this simulation)


for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_join(philosophers[i], NULL);
}

// Destroy mutexes
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_mutex_destroy(&forks[i]);
}

return 0;
}

Operating System (CD 405)


Sample Output:
Philosopher 0 is thinking.
Philosopher 1 is thinking.
Philosopher 2 is thinking.
Philosopher 3 is thinking.
Philosopher 4 is thinking.
Philosopher 0 picked up left fork 0.
Philosopher 0 picked up right fork 1.
Philosopher 0 is eating.
Philosopher 1 picked up right fork 1.
Philosopher 1 picked up left fork 2.
Philosopher 1 is eating.
...
Philosopher 4 is thinking.
Philosopher 4 picked up right fork 4.
Philosopher 4 picked up left fork 0.
Philosopher 4 is eating.

Operating System (CD 405)


Experiment 8: Implement and compare various page replacement algorithms, analyzing their impact on
memory management performance

Program:

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

#define PAGE_COUNT 10

// FIFO Page Replacement


int fifo_page_replacement(int pages[], int page_count, int frame_count) {
int frames[frame_count];
for (int i = 0; i < frame_count; i++) {
frames[i] = -1;
}

int page_faults = 0, index = 0;

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


int page = pages[i];
int page_found = 0;

// Check if the page is already in the frames


for (int j = 0; j < frame_count; j++) {
if (frames[j] == page) {
page_found = 1;
break;
}
}

// If the page is not found, we have a page fault


if (!page_found) {
frames[index] = page;
index = (index + 1) % frame_count;
page_faults++;
}
}

return page_faults;
}

// Optimal Page Replacement


int optimal_page_replacement(int pages[], int page_count, int frame_count) {
int frames[frame_count];
for (int i = 0; i < frame_count; i++) {
frames[i] = -1;
}

int page_faults = 0;
Operating System (CD 405)
for (int i = 0; i < page_count; i++) {
int page = pages[i];
int page_found = 0;

// Check if the page is already in the frames


for (int j = 0; j < frame_count; j++) {
if (frames[j] == page) {
page_found = 1;
break;
}
}

// If page is not found, replace a page


if (!page_found) {
if (i < frame_count) {
frames[i] = page;
} else {
int farthest = -1;
int replace_index = -1;

// Find the page that will not be used for the longest time
for (int j = 0; j < frame_count; j++) {
int found = 0;
for (int k = i + 1; k < page_count; k++) {
if (frames[j] == pages[k]) {
found = 1;
break;
}
}

if (!found) {
replace_index = j;
break;
}

if (farthest < 0) {
farthest = i;
replace_index = j;
}
}

frames[replace_index] = page;
}
page_faults++;
}
}

return page_faults;
}

Operating System (CD 405)


// LRU Page Replacement
int lru_page_replacement(int pages[], int page_count, int frame_count) {
int frames[frame_count];
int last_used[frame_count];
for (int i = 0; i < frame_count; i++) {
frames[i] = -1;
last_used[i] = -1;
}

int page_faults = 0;

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


int page = pages[i];
int page_found = 0;

// Check if the page is in the frames


for (int j = 0; j < frame_count; j++) {
if (frames[j] == page) {
page_found = 1;
last_used[j] = i;
break;
}
}

if (!page_found) {
int lru_index = -1;
int oldest = i;
for (int j = 0; j < frame_count; j++) {
if (frames[j] == -1) {
lru_index = j;
break;
} else if (last_used[j] < oldest) {
oldest = last_used[j];
lru_index = j;
}
}
frames[lru_index] = page;
last_used[lru_index] = i;
page_faults++;
}
}

return page_faults;
}

// LFU Page Replacement


int lfu_page_replacement(int pages[], int page_count, int frame_count) {
int frames[frame_count];
int frequency[frame_count];
for (int i = 0; i < frame_count; i++) {
frames[i] = -1;
Operating System (CD 405)
frequency[i] = 0;
}

int page_faults = 0;

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


int page = pages[i];
int page_found = 0;

// Check if the page is in the frames


for (int j = 0; j < frame_count; j++) {
if (frames[j] == page) {
page_found = 1;
frequency[j]++;
break;
}
}

if (!page_found) {
int lfu_index = -1;
int min_freq = INT_MAX;

// Find the least frequently used page


for (int j = 0; j < frame_count; j++) {
if (frames[j] == -1) {
lfu_index = j;
break;
} else if (frequency[j] < min_freq) {
min_freq = frequency[j];
lfu_index = j;
}
}
frames[lfu_index] = page;
frequency[lfu_index] = 1;
page_faults++;
}
}

return page_faults;
}

// Main function to compare all algorithms


int main() {
// Sample page reference string
int pages[] = {7, 0, 1, 2, 0, 3, 0, 4, 2, 3};
int page_count = sizeof(pages) / sizeof(pages[0]);
int frame_count = 3;

// Call and compare each page replacement algorithm


int fifo_faults = fifo_page_replacement(pages, page_count, frame_count);
int optimal_faults = optimal_page_replacement(pages, page_count, frame_count);
Operating System (CD 405)
int lru_faults = lru_page_replacement(pages, page_count, frame_count);
int lfu_faults = lfu_page_replacement(pages, page_count, frame_count);

// Display results
printf("Page Reference String: ");
for (int i = 0; i < page_count; i++) {
printf("%d ", pages[i]);
}
printf("\n");

printf("FIFO Page Faults: %d\n", fifo_faults);

Sample Output:

Page Reference String: 7 0 1 2 0 3 0 4 2 3


FIFO Page Faults: 7
Optimal Page Faults: 6
LRU Page Faults: 7
LFU Page Faults: 6

Operating System (CD 405)


Experiment 9: Develop and evaluate different Disk and Drum scheduling algorithms, examining their
efficiency in disk utilization.

Program:

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

#define MAX_REQUESTS 100

// FCFS Disk Scheduling Algorithm


int fcfs(int requests[], int n, int start) {
int total_seek_time = 0;
int current_position = start;
for (int i = 0; i < n; i++) {
total_seek_time += abs(current_position - requests[i]);
current_position = requests[i];
}
return total_seek_time;
}

// SSTF Disk Scheduling Algorithm


int sstf(int requests[], int n, int start) {
int total_seek_time = 0;
int current_position = start;
int visited[MAX_REQUESTS] = {0};
int count = 0;

while (count < n) {


int min_distance = INT_MAX;
int next_request = -1;

// Find the nearest request


for (int i = 0; i < n; i++) {
if (!visited[i]) {
int distance = abs(requests[i] - current_position);
if (distance < min_distance) {
min_distance = distance;
next_request = i;
}
}
}

visited[next_request] = 1;
total_seek_time += min_distance;
current_position = requests[next_request];
count++;
}

return total_seek_time;
Operating System (CD 405)
}

// SCAN Disk Scheduling Algorithm


int scan(int requests[], int n, int start, int max_track) {
int total_seek_time = 0;
int current_position = start;

// Sort the requests


int sorted_requests[MAX_REQUESTS];
for (int i = 0; i < n; i++) {
sorted_requests[i] = requests[i];
}
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
if (sorted_requests[j] > sorted_requests[j+1]) {
int temp = sorted_requests[j];
sorted_requests[j] = sorted_requests[j+1];
sorted_requests[j+1] = temp;
}
}
}

// Find position of current head


int i = 0;
while (i < n && sorted_requests[i] < current_position) {
i++;
}

// Move towards 0
for (int j = i-1; j >= 0; j--) {
total_seek_time += abs(current_position - sorted_requests[j]);
current_position = sorted_requests[j];
}

// Move towards max track


for (int j = i; j < n; j++) {
total_seek_time += abs(current_position - sorted_requests[j]);
current_position = sorted_requests[j];
}

return total_seek_time;
}

// C-SCAN Disk Scheduling Algorithm


int cscan(int requests[], int n, int start, int max_track) {
int total_seek_time = 0;
int current_position = start;

// Sort the requests


int sorted_requests[MAX_REQUESTS];
for (int i = 0; i < n; i++) {
Operating System (CD 405)
sorted_requests[i] = requests[i];
}
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
if (sorted_requests[j] > sorted_requests[j+1]) {
int temp = sorted_requests[j];
sorted_requests[j] = sorted_requests[j+1];
sorted_requests[j+1] = temp;
}
}
}

// Move towards max track


int i = 0;
while (i < n && sorted_requests[i] < current_position) {
i++;
}

for (int j = i; j < n; j++) {


total_seek_time += abs(current_position - sorted_requests[j]);
current_position = sorted_requests[j];
}

total_seek_time += (max_track - current_position); // jump to the other end of the disk

current_position = 0;

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


total_seek_time += abs(current_position - sorted_requests[j]);
current_position = sorted_requests[j];
}

return total_seek_time;
}

// Main function to evaluate algorithms


int main() {
int requests[] = {98, 183, 41, 122, 14, 124, 65, 67};
int n = sizeof(requests) / sizeof(requests[0]);
int start = 53; // Starting position of the disk head
int max_track = 200; // Maximum number of tracks

printf("Disk Requests: ");


for (int i = 0; i < n; i++) {
printf("%d ", requests[i]);
}
printf("\n");

// FCFS Evaluation
int fcfs_seek_time = fcfs(requests, n, start);
printf("FCFS Seek Time: %d\n", fcfs_seek_time);
Operating System (CD 405)
// SSTF Evaluation
int sstf_seek_time = sstf(requests, n, start);
printf("SSTF Seek Time: %d\n", sstf_seek_time);

// SCAN Evaluation
int scan_seek_time = scan(requests, n, start, max_track);
printf("SCAN Seek Time: %d\n", scan_seek_time);

// C-SCAN Evaluation
int cscan_seek_time = cscan(requests, n, start, max_track);
printf("C-SCAN Seek Time: %d\n", cscan_seek_time);

return 0;
}

Sample Output:

Disk Requests: 98 183 41 122 14 124 65 67


FCFS Seek Time: 640
SSTF Seek Time: 236
SCAN Seek Time: 391
C-SCAN Seek Time: 436

Operating System (CD 405)


Experiment 10: Apply the Banker’s algorithm for deadlock avoidance, evaluating its effectiveness in resource
allocation.

Program:

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

#define P 5 // Number of processes


#define R 3 // Number of resources

// Function to calculate Need matrix


void calculateNeed(int need[][R], int max[][R], int allocation[][R]) {
for (int i = 0; i < P; i++) {
for (int j = 0; j < R; j++) {
need[i][j] = max[i][j] - allocation[i][j];
}
}
}

// Function to check if the system is in a safe state


bool isSafe(int available[], int allocation[][R], int need[][R]) {
int work[R];
bool finish[P] = {false};

// Initialize work to Available


for (int i = 0; i < R; i++) {
work[i] = available[i];
}

int count = 0;
while (count < P) {
bool found = false;

// Find a process whose needs can be satisfied with the available resources
for (int p = 0; p < P; p++) {
if (!finish[p]) {
bool canFinish = true;
for (int i = 0; i < R; i++) {
if (need[p][i] > work[i]) {
canFinish = false;
break;
}
}

if (canFinish) {
// If the process can finish, simulate the release of resources
for (int i = 0; i < R; i++) {
work[i] += allocation[p][i];
}
finish[p] = true;
Operating System (CD 405)
count++;
found = true;
}
}
}

if (!found) {
return false; // If no process can proceed, the system is not in a safe state
}
}

return true; // All processes can finish, the system is in a safe state
}

// Function to request resources from a process


bool requestResources(int available[], int allocation[][R], int need[][R], int process, int request[]) {
// Check if request is valid
for (int i = 0; i < R; i++) {
if (request[i] > need[process][i]) {
printf("Error: Process has exceeded maximum claim.\n");
return false;
}
if (request[i] > available[i]) {
printf("Resources not available, process must wait.\n");
return false;
}
}

// Pretend to allocate the resources


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

// Check if the system is still in a safe state


if (isSafe(available, allocation, need)) {
return true; // Safe state, request granted
} else {
// Rollback the changes as the state is unsafe
for (int i = 0; i < R; i++) {
available[i] += request[i];
allocation[process][i] -= request[i];
need[process][i] += request[i];
}
printf("Request denied, unsafe state.\n");
return false; // Unsafe state, request denied
}
}

int main() {
Operating System (CD 405)
int available[] = {3, 3, 2}; // Available resources
int max[][R] = {{7, 5, 3},
{3, 2, 2},
{9, 0, 2},
{2, 2, 2},
{4, 3, 3}}; // Maximum resource demand

int allocation[][R] = {{0, 1, 0},


{2, 1, 1},
{3, 2, 2},
{2, 1, 1},
{0, 0, 2}}; // Currently allocated resources

int need[P][R]; // Need matrix


calculateNeed(need, max, allocation);

printf("System is in a safe state: %s\n", isSafe(available, allocation, need) ? "Yes" : "No");

// Example request
int request[] = {1, 0, 2}; // Request by process 1 for resources
int process = 1;

printf("\nRequesting resources for Process %d: ", process);


if (requestResources(available, allocation, need, process, request)) {
printf("Request granted.\n");
} else {
printf("Request denied.\n");
}

return 0;
}

Sample Output:

System is in a safe state: Yes

Requesting resources for Process 1: Resources not available, process must wait.
Request denied.

Operating System (CD 405)

You might also like