0% found this document useful (0 votes)
15 views37 pages

Lab Second OS

algorithms implementation in os

Uploaded by

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

Lab Second OS

algorithms implementation in os

Uploaded by

useranjalee
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

2) WAP in C to demonstrate the process creation and termination in Linux.

Theory: C program uses fork() to create a child process. exit() is called to terminate the child
process. wait() is used by the parent to wait for the child to finish, ensuring proper
synchronization. (getpid(), getppid()): These functions fetch the current process ID and the
parent process ID, which help visualize how the parent and child relate.
GCC (GNU Compiler Collection): Compiles .c file into an executable.
Linux Terminal: Runs commands like gcc, executes program, and displays output.
VS Code: Used for writing and editing C code.
Remote SSH Extension (VS Code): Lets you connect to Ubuntu VM and write code directly
into it.
Ubuntu VM (via VirtualBox or UTM): Linux environment for compiling and running the code.

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

int main()
{
pid_t pid;

// Create a child process


pid = fork();

if (pid < 0)
{
perror("Fork failed");
exit(1);
}
else if (pid == 0)
{
// Child process
printf("\n--- Child Process ---\n");
printf("Child PID: %d\n", getpid());
printf("Parent PID: %d\n", getppid());
printf("Child is terminating now.\n");
exit(0);
}
else
{
// Parent process
printf("\n--- Parent Process ---\n");
printf("Parent PID: %d\n", getpid());
printf("Created Child PID: %d\n", pid);
printf("Parent is waiting for child to terminate...\n");
wait(NULL); // Wait for child
printf("Child terminated. Parent ends.\n");
}
printf("\nLab No.: 2\nName: Anjali Rai\nRoll No./Section: 02/A\n");
return 0;
}

Output:

3) WAP in C to demonstrate the thread creation and termination in Linux.

Theory: C program uses pthread_create() to spawn a new thread that runs concurrently with
the main thread. pthread_exit() is used to terminate the thread gracefully. pthread_join()
ensures the main thread waits for the created thread to finish, achieving proper
synchronization. pthread_self() fetches the thread ID, helping to distinguish between threads.
GCC (GNU Compiler Collection): Compiles .c file into an executable using the -pthread flag
to enable POSIX threading support.
Linux Terminal: Runs compilation (gcc) and execution commands (./thread_demo), and
displays output for both main and thread execution.
VS Code: Used for writing and editing the C code.
Remote SSH Extension (VS Code): Allows you to connect to your Ubuntu virtual machine
and directly write/run code inside it from your host machine.
Ubuntu VM (via VirtualBox or UTM): Linux environment used to compile and run the multi-
threaded C program.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

// Function executed by the thread


void* thread_function(void* arg) {
printf("Thread: Hello from the thread! Thread ID: %lu\n", pthread_self());
sleep(1); // Simulate some work
printf("Thread: Thread is exiting.\n");
pthread_exit(NULL); // Terminate thread
}

int main() {
pthread_t thread;

printf("Main: Creating a thread...\n");

// Create a new thread


if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {
perror("Failed to create thread");
return 1;
}

printf("Main: Waiting for the thread to finish...\n");

// Wait for the thread to terminate


if (pthread_join(thread, NULL) != 0) {
perror("Failed to join thread");
return 2;
}

printf("Main: Thread has finished. Program ending.\n");


printf("\nLab No.: 3\nName: Anjali Rai\nRoll No./Section: 02/A\n");
return 0;
}

Output:

4.a) WAP to simulate the solution producer consumer problem using semaphore.

Theory: C program uses pthread_create() to create producer and consumer threads.


sem_wait() and sem_post() are used for synchronization through semaphores (empty and full)
to manage buffer slots. pthread_mutex_lock() and pthread_mutex_unlock() ensure that only
one thread accesses the shared buffer at a time, preventing race conditions. pthread_exit()
cleanly terminates threads, and pthread_join() ensures the main program waits for them to
complete. getcwd() is used to display the current working directory before execution.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

#define SIZE 5

int buffer[SIZE];
int in = 0, 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 = rand() % 100;
sem_wait(&empty);
pthread_mutex_lock(&mutex);

buffer[in] = item;
printf("Producer produced: %d at index %d\n", item, in);
in = (in + 1) % SIZE;

pthread_mutex_unlock(&mutex);
sem_post(&full);

sleep(1);
}
pthread_exit(NULL);
}

void *consumer(void *arg)


{
int item;
for (int i = 0; i < 10; i++)
{
sem_wait(&full);
pthread_mutex_lock(&mutex);

item = buffer[out];
printf("Consumer consumed: %d from index %d\n", item, out);
out = (out + 1) % SIZE;

pthread_mutex_unlock(&mutex);
sem_post(&empty);

sleep(1);
}
pthread_exit(NULL);
}

int main()
{
char path[PATH_MAX];
if (getcwd(path, sizeof(path)) != NULL) {
printf("Running from: %s\n\n", path);
} else {
perror("getcwd() error");
}
pthread_t prod, cons;

sem_init(&empty, 0, SIZE);
sem_init(&full, 0, 0);
pthread_mutex_init(&mutex, NULL);

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


pthread_create(&cons, NULL, consumer, NULL);

pthread_join(prod, NULL);
pthread_join(cons, NULL);

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

printf("\nLab No.: 4.a)\nName: Anjali Rai\nRoll No./Section: 02/A\n");


return 0;
}
Output:
4.b) WAP to simulate the solution of dining philosopher's problem using semaphore.

Theory: C program uses pthread_create() to create philosopher threads. Each thread


represents a philosopher who alternates between thinking and eating. sem_wait() and
sem_post() are used with fork semaphores and a room semaphore to control access and avoid
deadlock. The room semaphore ensures that only NUM - 1 philosophers attempt to pick up
forks simultaneously. pthread_mutex_lock() and pthread_mutex_unlock() are not used, as
semaphores handle all synchronization. malloc() dynamically allocates unique IDs for each
thread, and free() is called inside the thread to avoid memory leaks. pthread_exit() is used to
cleanly terminate threads, while pthread_join() ensures the main thread waits for all
philosophers to finish. getcwd() displays the current working directory before execution
begins.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <limits.h>
#include <semaphore.h>

#define NUM 5
#define ROUNDS 3

sem_t forks[NUM];
sem_t room;

void *philosopher(void *num)


{
int id = *(int *)num;
free(num);

for (int i = 0; i < ROUNDS; i++)


{
printf("Philosopher %d is thinking (round %d).\n", id, i + 1);
sleep(1);

sem_wait(&room);
sem_wait(&forks[id]);
sem_wait(&forks[(id + 1) % NUM]);

printf("Philosopher %d is eating (round %d).\n", id, i + 1);


sleep(2);

sem_post(&forks[(id + 1) % NUM]);
sem_post(&forks[id]);
sem_post(&room);
}

pthread_exit(NULL);
}

int main()
{
char path[PATH_MAX];
if (getcwd(path, sizeof(path)) != NULL)
{
printf("Running from: %s\n\n", path);
}
else
{
perror("getcwd() error");
}

pthread_t threads[NUM];

sem_init(&room, 0, NUM - 1);

for (int i = 0; i < NUM; i++)


sem_init(&forks[i], 0, 1);

for (int i = 0; i < NUM; i++)


{
int *id = malloc(sizeof(int));
*id = i;
pthread_create(&threads[i], NULL, philosopher, id);
}

for (int i = 0; i < NUM; i++)


pthread_join(threads[i], NULL);

for (int i = 0; i < NUM; i++)


sem_destroy(&forks[i]);

sem_destroy(&room);

printf("\nLab No.: 4.b)\nName: Anjali Rai\nRoll No./Section: 02/A\n");

return 0;
}

Output:
4.c) WAP to simulate the solution of producer consumer problem using message
passing technique.

Theory: C program uses pthread_create() to create producer and consumer threads.


pthread_cond_wait() and pthread_cond_signal() are used to simulate message passing
between threads via condition variables (not_full, not_empty) to synchronize access to the
shared buffer.
pthread_mutex_lock() and pthread_mutex_unlock() ensure that only one thread accesses the
buffer at a time, preventing race conditions.
pthread_exit() cleanly terminates the threads, while pthread_join() ensures the main program
waits for both producer and consumer threads to complete.
getcwd() is optionally used to display the current working directory before execution.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <pthread.h>
#include <unistd.h>

#define SIZE 5
#define ITEMS 10

int buffer[SIZE];
int in = 0, out = 0, count = 0;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;


pthread_cond_t not_full = PTHREAD_COND_INITIALIZER;
pthread_cond_t not_empty = PTHREAD_COND_INITIALIZER;

void* producer(void* arg) {


for (int i = 1; i <= ITEMS; i++) {
sleep(1);
pthread_mutex_lock(&lock);
while (count == SIZE)
pthread_cond_wait(&not_full, &lock);

buffer[in] = i;
printf("Producer: Produced item %d at buffer[%d]\n", i, in);
in = (in + 1) % SIZE;
count++;
pthread_cond_signal(&not_empty);
pthread_mutex_unlock(&lock);
}
pthread_exit(NULL);
}

void* consumer(void* arg) {


for (int i = 1; i <= ITEMS; i++) {
sleep(2);
pthread_mutex_lock(&lock);
while (count == 0)
pthread_cond_wait(&not_empty, &lock);

int item = buffer[out];


printf("Consumer: Consumed item %d from buffer[%d]\n", item, out);
out = (out + 1) % SIZE;
count--;
pthread_cond_signal(&not_full);
pthread_mutex_unlock(&lock);
}
pthread_exit(NULL);
}

int main() {
char path[PATH_MAX];
if (getcwd(path, sizeof(path)) != NULL) {
printf("Running from: %s\n\n", path);
} else {
perror("getcwd() error");
}
pthread_t prod, cons;
printf("Simulation of Producer-Consumer using Message Passing (Condition
Variables)\n\n");
pthread_create(&prod, NULL, producer, NULL);
pthread_create(&cons, NULL, consumer, NULL);
pthread_join(prod, NULL);
pthread_join(cons, NULL);
printf("\nExecution completed.\n");
printf("\nLab No.: 4.c)\nName: Anjali Rai\nRoll No./Section: 02/A\n");

return 0;
}

Output:

5.a) WAP to simulate FCFS CPU Scheduling Algorithm.

Theory: C program simulates First-Come-First-Served (FCFS) CPU scheduling using basic


C constructs like arrays, loops, and conditionals.
getcwd() from <unistd.h> and <limits.h> is used to display the current working directory at
the start of execution.
Process burst times and arrival times are input by the user and stored in arrays.
Processes are sorted by arrival time using a simple selection sort to ensure FCFS order.
The program then calculates each process’s completion time (CT), turnaround time (TAT),
and waiting time (WT) based on scheduling logic.
A Gantt chart is printed to visually show process execution order.
Finally, a summary table is printed, and average turnaround time and average waiting time
are computed to evaluate scheduling performance.
The program does not use multithreading or external libraries, making it a clean illustration
of non-preemptive scheduling using basic C.

Code:
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
int main()
{
char path[PATH_MAX];
if (getcwd(path, sizeof(path)) != NULL)
{
printf("Running from: %s\n\n", path);
}
else
{
perror("getcwd() error");
}
int n, i, j;
printf("Enter number of processes to schedule: ");
scanf("%d", &n);

int burst[n], arrival[n], index[n];


int completion[n], turnaround[n], waiting[n];

// Input burst times


printf("Enter burst times:\n");
for (i = 0; i < n; i++)
{
scanf("%d", &burst[i]);
index[i] = i + 1;
}

// Input arrival times


printf("Enter arrival times:\n");
for (i = 0; i < n; i++)
scanf("%d", &arrival[i]);

// Sort by arrival time (simple selection sort)


for (i = 0; i < n; i++)
{
int min = arrival[i], pos = i;
for (j = i + 1; j < n; j++)
{
if (arrival[j] < min)
{
min = arrival[j];
pos = j;
}
}

// Swap arrival
int tmp = arrival[i];
arrival[i] = arrival[pos];
arrival[pos] = tmp;

// Swap burst
tmp = burst[i];
burst[i] = burst[pos];
burst[pos] = tmp;

// Swap index
tmp = index[i];
index[i] = index[pos];
index[pos] = tmp;
}

// Compute CT, TAT, WT


int time = 0;
for (i = 0; i < n; i++)
{
if (time < arrival[i])
time = arrival[i];

time += burst[i];
completion[i] = time;
turnaround[i] = completion[i] - arrival[i];
waiting[i] = turnaround[i] - burst[i];
}

// Print Gantt Chart


printf("\nGantt Chart:\n|");
for (i = 0; i < n; i++)
printf(" P%d |", index[i]);
printf("\n0");

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


printf(" %d", completion[i]);
printf("\n");

// Print Table
printf("\nPID\tAT\tBT\tCT\tTAT\tWT\n");
double total_tat = 0, total_wt = 0;
for (i = 0; i < n; i++)
{
printf("P%d\t%d\t%d\t%d\t%d\t%d\n",
index[i], arrival[i], burst[i], completion[i], turnaround[i], waiting[i]);
total_tat += turnaround[i];
total_wt += waiting[i];
}

printf("\nAverage Turnaround Time: %.2lf", total_tat / n);


printf("\nAverage Waiting Time: %.2lf\n", total_wt / n);
printf("\nLab No.: 5.a)\nName: Anjali Rai\nRoll No./Section: 02/A\n");

return 0;
}

Output:
5.b) WAP to simulate SJF CPU Scheduling Algorithm

Theory: C program simulates Shortest Job First (SJF) Non-Preemptive CPU scheduling
using arrays and loops to manage process data.
getcwd() from <unistd.h> and <limits.h> is used to display the current working directory
before execution.
User inputs arrival time and burst time for each process, which are stored in arrays.
The program uses selection logic to choose the process with the shortest burst time among
those that have already arrived (at[i] <= time) and are not yet completed.

Code:
#include <stdio.h>
#include <unistd.h>
#include <limits.h>

int main() {
char path[PATH_MAX];
if (getcwd(path, sizeof(path)) != NULL)
{
printf("Running from: %s\n\n", path);
}
else
{
perror("getcwd() error");
}
int n, i, time = 0, smallest;
int at[10], bt[10], ct[10], tat[10], wt[10], index[10];
int original_bt[10];
float total_tat = 0, total_wt = 0;

printf("Enter the number of processes: ");


scanf("%d", &n);

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


printf("Enter arrival time for process P%d: ", i + 1);
scanf("%d", &at[i]);
printf("Enter burst time for process P%d: ", i + 1);
scanf("%d", &bt[i]);
original_bt[i] = bt[i]; // Store original burst time for final WT calculation
index[i] = i + 1;
}

int completed = 0;
printf("\nGantt Chart:\n|");
while (completed < n) {
smallest = -1;

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


if (at[i] <= time && bt[i] > 0) {
if (smallest == -1 || bt[i] < bt[smallest])
smallest = i;
}
}

if (smallest == -1) {
time++;
continue;
}

printf(" P%d |", smallest + 1);

time += bt[smallest];
ct[smallest] = time;
tat[smallest] = ct[smallest] - at[smallest];
wt[smallest] = tat[smallest] - original_bt[smallest];

total_tat += tat[smallest];
total_wt += wt[smallest];

bt[smallest] = 0; // mark as completed


completed++;
}

// Time line
printf("\n0");
time = 0;
completed = 0;
while (completed < n) {
smallest = -1;
for (i = 0; i < n; i++) {
if (at[i] <= time && original_bt[i] > 0) {
if (bt[i] == 0 && ct[i] > time)
smallest = i;
}
}

if (smallest != -1) {
time = ct[smallest];
printf(" %d", time);
completed++;
} else {
time++;
}
}

// Output table
printf("\n\nPID\tAT\tBT\tCT\tTAT\tWT\n");
for (i = 0; i < n; i++) {
printf("P%d\t%d\t%d\t%d\t%d\t%d\n", i + 1, at[i], original_bt[i], ct[i], tat[i], wt[i]);
}

printf("\nAverage Turnaround Time = %.2f\n", total_tat / n);


printf("Average Waiting Time = %.2f\n", total_wt / n);
printf("\nLab No.: 5.b)\nName: Anjali Rai\nRoll No./Section: 02/A\n");

return 0;
}

Output:
5.c) WAP to simulate SRTF CPU Scheduling Algorithm.

Theory: C program implements Shortest Job First (SJF) Preemptive scheduling (also called
Shortest Remaining Time First).
getcwd() from <unistd.h> and <limits.h> is used to display the current working directory
before execution starts.
User inputs arrival time and burst time for each process, stored in arrays.
The program simulates CPU scheduling time unit by time unit, selecting the process with the
shortest remaining burst time that has already arrived.
Process execution is tracked per time unit, decrementing the burst time of the chosen process.

Code:
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
int main() {
char path[PATH_MAX];
if (getcwd(path, sizeof(path)) != NULL) {
printf("Running from: %s\n\n", path);
} else {
perror("getcwd() error");
}
int a[10], b[10], x[10];
int waiting[10], turnaround[10], completion[10];
int i, smallest, count = 0, time = 0, n;
float avg = 0, tt = 0;

printf("\nEnter the number of processes: ");


scanf("%d", &n);

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


printf("Enter arrival time of process P%d: ", i + 1);
scanf("%d", &a[i]);
}

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


printf("Enter burst time of process P%d: ", i + 1);
scanf("%d", &b[i]);
x[i] = b[i]; // store original burst time
}

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


completion[i] = 0;
waiting[i] = 0;
turnaround[i] = 0;
}

int gantt_proc[100], gantt_time[100], gantt_len = 0;

int last_proc = -1;


while (count != n) {
smallest = -1;
for (i = 0; i < n; i++) {
if (a[i] <= time && b[i] > 0) {
if (smallest == -1 || b[i] < b[smallest])
smallest = i;
}
}

if (smallest == -1) {
time++;
continue;
}

b[smallest]--;
if (last_proc != smallest) {
gantt_proc[gantt_len] = smallest;
gantt_time[gantt_len] = time;
gantt_len++;
last_proc = smallest;
}

if (b[smallest] == 0) {
count++;
completion[smallest] = time + 1;
turnaround[smallest] = completion[smallest] - a[smallest];
waiting[smallest] = turnaround[smallest] - x[smallest];

avg += waiting[smallest];
tt += turnaround[smallest];
}
time++;
}

gantt_time[gantt_len] = time;

printf("\n\nGantt Chart:\n");
for (i = 0; i < gantt_len; i++) {
printf("| P%d ", gantt_proc[i] + 1);
}
printf("|\n");

for (i = 0; i <= gantt_len; i++) {


printf("%-6d", gantt_time[i]);
}
printf("\n");

printf("\nPID\tAT\tBT\tCT\tTAT\tWT\n");
for (i = 0; i < n; i++) {
printf("P%d\t%d\t%d\t%d\t%d\t%d\n", i + 1, a[i], x[i], completion[i], turnaround[i],
waiting[i]);
}

printf("\nAverage Waiting Time = %.2f", avg / n);


printf("\nAverage Turnaround Time = %.2f\n", tt / n);
printf("\nLab No.: 5.c)\nName: Anjali Rai\nRoll No./Section: 02/A\n");

return 0;
}

Output:

5.d) WAP to simulate Round Robin CPU Scheduling Algorithm

Theory: This C program simulates the Round Robin CPU scheduling algorithm, where each
process is assigned a fixed time quantum and executed in a circular order. It uses arrays to
store arrival time, burst time, and remaining time for up to 10 processes, and implements
logic to calculate turnaround time, waiting time, and generate a Gantt chart showing the
execution sequence. The program uses standard C libraries (stdio.h, unistd.h, limits.h) for
input/output and retrieving the current working directory. It calculates and displays average
waiting and turnaround times, and uses conditionals and loops to control the scheduling flow,
while ensuring synchronization of process arrival with CPU availability.

Code:
#include<stdio.h>
#include <unistd.h>
#include <limits.h>

int main() {
char path[PATH_MAX];
if (getcwd(path, sizeof(path)) != NULL) {
printf("Running from: %s\n\n", path);
} else {
perror("getcwd() error");
}
int cnt, j, n, t, remain, flag = 0, tq;
int wt = 0, tat = 0, at[10], bt[10], rt[10];
int gantt_process[100], gantt_start[100], gantt_end[100], gidx = 0;

printf("Enter Total Process:\t ");


scanf("%d", &n);
remain = n;

for (cnt = 0; cnt < n; cnt++) {


printf("Enter Arrival Time and Burst Time for Process Process Number %d :", cnt + 1);
scanf("%d", &at[cnt]);
scanf("%d", &bt[cnt]);
rt[cnt] = bt[cnt];
}

printf("Enter Time Quantum:\t");


scanf("%d", &tq);

printf("\n\nProcess\t|Turnaround Time|Waiting Time\n\n");

for (t = 0, cnt = 0; remain != 0;) {


if (rt[cnt] <= tq && rt[cnt] > 0) {
gantt_start[gidx] = t;
t += rt[cnt];
gantt_end[gidx] = t;
gantt_process[gidx] = cnt + 1;
gidx++;

rt[cnt] = 0;
flag = 1;
} else if (rt[cnt] > 0) {
gantt_start[gidx] = t;
rt[cnt] -= tq;
t += tq;
gantt_end[gidx] = t;
gantt_process[gidx] = cnt + 1;
gidx++;
}

if (rt[cnt] == 0 && flag == 1) {


remain--;
printf("P[%d]\t|\t%d\t|\t%d\n", cnt + 1, t - at[cnt], t - at[cnt] - bt[cnt]);
wt += t - at[cnt] - bt[cnt];
tat += t - at[cnt];
flag = 0;
}

if (cnt == n - 1)
cnt = 0;
else if (at[cnt + 1] <= t)
cnt++;
else
cnt = 0;
}

printf("\nAverage Waiting Time= %f\n", wt * 1.0 / n);


printf("Avg Turnaround Time = %f\n", tat * 1.0 / n);

printf("\nGantt Chart:\n");
for (int i = 0; i < gidx; i++) {
printf("| P%d ", gantt_process[i]);
}
printf("|\n");

printf("0");
for (int i = 0; i < gidx; i++) {
printf("%6d", gantt_end[i]);
}
printf("\n");
printf("\nLab No.: 5.d)\nName: Anjali Rai\nRoll No./Section: 02/A\n");

return 0;
}

Output:
5.e) WAP to simulate Non-Preemptive Priority Scheduling Algorithm

Theory: This C program implements the Non-Preemptive Priority Scheduling algorithm with
support for process arrival time, allowing the CPU to schedule the highest-priority process
that has already arrived. Each process is defined by its burst time, priority, and arrival time,
and the scheduler selects the process with the lowest priority number (i.e., higher actual
priority) from the set of available processes. The program calculates and prints each process’s
waiting time and turnaround time, as well as the average waiting and turnaround times. Core
programming concepts include arrays for managing multiple processes, looping and
conditional logic for selection and timing, and manual process selection using priority
comparison. It uses standard libraries like <stdio.h> for input/output, <unistd.h> and
<limits.h> to display the current working directory using getcwd(). The logic ensures that
once a process is executed, it is marked as completed by assigning it unreachable values. The
program outputs results in a tabular format and is suitable for understanding how non-
preemptive priority scheduling works with dynamic arrival of processes.

Code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <limits.h>

void main()
{
char path[PATH_MAX];
if (getcwd(path, sizeof(path)) != NULL) {
printf("Running from: %s\n\n", path);
} else {
perror("getcwd() error");
}
int pn = 0; //Processes Number
int CPU = 0; //CPU Current time
int allTime = 0; // Time neded to finish all processes
printf("Enter Processes Count: ");
scanf("%d",&pn);
int AT[pn];
int ATt[pn];
int NoP = pn;
int PT[pn]; //Processes Time
int PP[pn]; //Processes piriorty
int PPt[pn];
int waittingTime[pn];
int turnaroundTime[pn];
int i=0;
//Scanning Time and Piriorty
for(i=0 ;i<pn ;i++){
printf("\nBurst time for P%d: ",i+1);
scanf("%d",&PT[i]);
printf("Piriorty for P%d: ",i+1);
scanf("%d",&PP[i]);
PPt[i] = PP[i];
printf("Arrival Time for P%d: ",i+1);
scanf("%d",&AT[i]);
ATt[i] = AT[i];
}

int LAT = 0; //LastArrivalTime


for(i = 0; i < pn; i++)
if(AT[i] > LAT)
LAT = AT[i];

int MAX_P = 0; //Max Piriorty


for(i = 0; i < pn; i++)
if(PPt[i] > MAX_P)
MAX_P = PPt[i];

int ATi = 0; //Pointing to Arrival Time indix


int P1 = PPt[0]; //Pointing to 1st piriorty Value
int P2 = PPt[0]; //Pointing to 2nd piriorty Value

int j = -1;
while(NoP > 0 && CPU <= 1000){
for(i = 0; i < pn; i++){
if((ATt[i] <= CPU) && (ATt[i] != (LAT+10))){
if(PPt[i] != (MAX_P+1)){
P2 = PPt[i];
j= 1;

if(P2 < P1){


j= 1;
ATi = i;
P1 = PPt[i];
P2 = PPt[i];
}
}
}
}

if(j == -1){
CPU = CPU+1;
continue;
}else{

waittingTime[ATi] = CPU - ATt[ATi];


CPU = CPU + PT[ATi];
turnaroundTime[ATi] = CPU - ATt[ATi];
ATt[ATi] = LAT +10;
j = -1;
PPt[ATi] = MAX_P + 1;
ATi = 0; //Pointing to Arrival Time indix
P1 = MAX_P+1; //Pointing to 1st piriorty Value
P2 = MAX_P+1; //Pointing to 2nd piriorty Value
NoP = NoP - 1;

}
}

printf("\nPN\tPT\tPP\tAT\tWT\tTT\n\n");
for(i = 0; i < pn; i++){

printf("P%d\t%d\t%d\t%d\t%d\t%d\n",i+1,PT[i],PP[i],AT[i],waittingTime[i],turnaroundTim
e[i]);
}

int AvgWT = 0;
int AVGTaT = 0;
for(i = 0; i < pn; i++){
AvgWT = waittingTime[i] + AvgWT;
AVGTaT = turnaroundTime[i] + AVGTaT;
}

printf("AvgWaittingTime = %d\nAvgTurnaroundTime = %d\n",AvgWT/pn,AVGTaT/pn);


printf("\nLab No.: 5.e)\nName: Anjali Rai\nRoll No./Section: 02/A\n");
}

Output:
5. f) WAP to simulate Preemptive Priority Scheduling Algorithm

Theory: The program uses a min-heap (priority queue) implemented with arrays and heap
operations (insert, extractminimum, and order) to efficiently select the highest priority
process at each time unit. Processes are initially sorted by arrival time using qsort, and the
CPU time is simulated step-by-step, allowing preemption after each unit. The program
leverages standard C syntax, including structs, pointers, dynamic arrays, and formatted I/O,
and runs in a Unix-like environment using getcwd to display the current directory.

Code:
#include <stdio.h>
#include <unistd.h>
#include <limits.h>

struct Process {
int processID;
int burstTime;
int tempburstTime;
int arrivalTime;
int priority;
int completionTime;
int turnaroundTime;
int waitingTime;
int intime;
};

void swap(struct Process* a, struct Process* b) {


struct Process temp = *a;
*a = *b;
*b = temp;
}

void insert(struct Process Heap[], struct Process value, int* heapsize, int* currentTime) {
int start = *heapsize;
Heap[*heapsize] = value;
if (Heap[*heapsize].intime == -1)
Heap[*heapsize].intime = *currentTime;
++(*heapsize);
while (start != 0 && Heap[(start - 1) / 2].priority > Heap[start].priority) {
swap(&Heap[(start - 1) / 2], &Heap[start]);
start = (start - 1) / 2;
}
}

void order(struct Process Heap[], int* heapsize, int start) {


int smallest = start;
int left = 2 * start + 1;
int right = 2 * start + 2;
if (left < *heapsize && Heap[left].priority < Heap[smallest].priority)
smallest = left;
if (right < *heapsize && Heap[right].priority < Heap[smallest].priority)
smallest = right;
if (smallest != start) {
swap(&Heap[smallest], &Heap[start]);
order(Heap, heapsize, smallest);
}
}

struct Process extractminimum(struct Process Heap[], int* heapsize) {


struct Process min = Heap[0];
--(*heapsize);
if (*heapsize >= 1) {
Heap[0] = Heap[*heapsize];
order(Heap, heapsize, 0);
}
return min;
}

int compare(const void* a, const void* b) {


return ((struct Process*)a)->arrivalTime - ((struct Process*)b)->arrivalTime;
}

void scheduling(struct Process Heap[], struct Process array[], int n, int* heapsize, int*
currentTime, int ganttProcess[], int ganttStart[], int ganttEnd[], int* gidx) {
if (*heapsize == 0)
return;
struct Process min = extractminimum(Heap, heapsize);

ganttProcess[*gidx] = min.processID;
ganttStart[*gidx] = *currentTime;
--min.burstTime;
(*currentTime)++;
ganttEnd[*gidx] = *currentTime;
(*gidx)++;

if (min.burstTime > 0) {
insert(Heap, min, heapsize, currentTime);
} else {
for (int i = 0; i < n; i++) {
if (array[i].processID == min.processID) {
array[i].completionTime = *currentTime;
break;
}
}
}
}

void priority(struct Process array[], int n) {


qsort(array, n, sizeof(struct Process), compare);
int insertedprocess = 0, heapsize = 0;
int currentTime = array[0].arrivalTime;
struct Process Heap[4 * n];
int ganttProcess[1000], ganttStart[1000], ganttEnd[1000], gidx = 0;

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


array[i].tempburstTime = array[i].burstTime;
array[i].intime = -1;
}

do {
if (insertedprocess != n) {
for (int i = 0; i < n; i++) {
if (array[i].arrivalTime == currentTime) {
++insertedprocess;
insert(Heap, array[i], &heapsize, &currentTime);
}
}
}
scheduling(Heap, array, n, &heapsize, &currentTime, ganttProcess, ganttStart, ganttEnd,
&gidx);
if (heapsize == 0 && insertedprocess == n)
break;
} while (1);

float totalWaiting = 0, totalTurnaround = 0;

printf("\nProcess | Arrival | Burst | Completion | Turnaround | Waiting\n");


for (int i = 0; i < n; i++) {
array[i].turnaroundTime = array[i].completionTime - array[i].arrivalTime;
array[i].waitingTime = array[i].turnaroundTime - array[i].tempburstTime;
totalTurnaround += array[i].turnaroundTime;
totalWaiting += array[i].waitingTime;
printf("P%-7d %-8d %-6d %-11d %-11d %-7d\n",
array[i].processID,
array[i].arrivalTime,
array[i].tempburstTime,
array[i].completionTime,
array[i].turnaroundTime,
array[i].waitingTime);
}

printf("\nAverage Turnaround Time = %.2f\n", totalTurnaround / n);


printf("Average Waiting Time = %.2f\n", totalWaiting / n);

printf("\nGantt Chart:\n");

if (gidx > 0) {
int start = ganttStart[0];
int end = ganttEnd[0];
int pid = ganttProcess[0];

printf("|");
for (int i = 1; i < gidx; i++) {
if (ganttProcess[i] == pid && ganttStart[i] == end) {
end = ganttEnd[i];
} else {
printf(" P%d |", pid);
pid = ganttProcess[i];
start = ganttStart[i];
end = ganttEnd[i];
}
}
printf(" P%d |\n", pid);

start = ganttStart[0];
end = ganttEnd[0];
pid = ganttProcess[0];
printf("%d", start);
for (int i = 1; i < gidx; i++) {
if (ganttProcess[i] == pid && ganttStart[i] == end) {
end = ganttEnd[i];
} else {
printf("%6d", end);
pid = ganttProcess[i];
start = ganttStart[i];
end = ganttEnd[i];
}
}
printf("%6d\n", end);
}
}

int main() {
char path[PATH_MAX];
if (getcwd(path, sizeof(path)) != NULL) {
printf("Running from: %s\n\n", path);
} else {
perror("getcwd() error");
}

int n;
printf("Enter number of processes: ");
scanf("%d", &n);
struct Process a[n];

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


a[i].processID = i + 1;
printf("\nEnter arrival time for process %d: ", i + 1);
scanf("%d", &a[i].arrivalTime);
printf("Enter burst time for process %d: ", i + 1);
scanf("%d", &a[i].burstTime);
printf("Enter priority for process %d (lower is higher priority): ", i + 1);
scanf("%d", &a[i].priority);
}

priority(a, n);

printf("\nLab No.: 5.f)\nName: Anjali Rai\nRoll No./Section: 02/A\n");

return 0;
}

Output:

6. a) WAP to implement Bankers Algorithm for multiple type of resources to decide


safe/unsafe state.

Theory: It uses arrays and matrices to represent resource allocation (alloc), maximum
demand (max), and available resources (avail), and calculates the remaining needs with the
calculateNeed function. The core function isSafe simulates resource allocation by checking if
processes can complete safely in some order without causing deadlock, using loops and
boolean flags to track finished processes and resource availability (work). The program takes
user input for the number of processes and resources, allocation and max matrices, and
available resources, applying standard C control structures (for, if), arrays, and input/output
functions (scanf, printf) to interactively test system safety. It also uses getcwd to display the
current working directory before execution.

Code:
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <limits.h>
#define MAX_P 10
#define MAX_R 10

void calculateNeed(int need[MAX_P][MAX_R], int max[MAX_P][MAX_R], int


alloc[MAX_P][MAX_R], int n, int m) {
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
need[i][j] = max[i][j] - alloc[i][j];
}

bool isSafe(int processes[], int avail[], int max[][MAX_R], int alloc[][MAX_R], int n, int m)
{
int need[MAX_P][MAX_R];
calculateNeed(need, max, alloc, n, m);

bool finish[MAX_P] = {false};


int safeSeq[MAX_P];
int work[MAX_R];

for (int i = 0; i < m; i++)


work[i] = avail[i];

int count = 0;
while (count < n) {
bool found = false;
for (int p = 0; p < n; p++) {
if (!finish[p]) {
int j;
for (j = 0; j < m; j++) {
if (need[p][j] > work[j])
break;
}
if (j == m) {
for (int k = 0; k < m; k++)
work[k] += alloc[p][k];
safeSeq[count++] = p;
finish[p] = true;
found = true;
}
}
}
if (!found) {
printf("\nThe system is NOT in a safe state.\n");
return false;
}
}

printf("\nThe system is in a safe state.\nSafe sequence is: ");


for (int i = 0; i < n; i++)
printf("P[%d] ", safeSeq[i]);
printf("\n");
return true;
}

int main() {
char path[PATH_MAX];
if (getcwd(path, sizeof(path)) != NULL) {
printf("Running from: %s\n\n", path);
} else {
perror("getcwd() error");
}
int n, m;
int processes[MAX_P];
int max[MAX_P][MAX_R], alloc[MAX_P][MAX_R], avail[MAX_R];

printf("Enter number of processes: ");


scanf("%d", &n);

printf("Enter number of resources: ");


scanf("%d", &m);

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


processes[i] = i;

printf("\nEnter Allocation Matrix (%d x %d):\n", n, m);


for (int i = 0; i < n; i++) {
printf("P[%d]: ", i);
for (int j = 0; j < m; j++) {
scanf("%d", &alloc[i][j]);
}
}

printf("\nEnter Max Matrix (%d x %d):\n", n, m);


for (int i = 0; i < n; i++) {
printf("P[%d]: ", i);
for (int j = 0; j < m; j++) {
scanf("%d", &max[i][j]);
}
}

printf("\nEnter Available Resources (%d values):\n", m);


for (int i = 0; i < m; i++) {
scanf("%d", &avail[i]);
}

isSafe(processes, avail, max, alloc, n, m);


printf("\nLab No.: 6.a)\nName: Anjali Rai\nRoll No./Section: 02/A\n");

return 0; }
Output:

6. b) WAP for deadlock detection in the system having multiple type of resources. (The
program should list the deadlocked process in case of deadlock detection results
true)

Theory: This C program implements the Banker's algorithm for deadlock detection. It checks
if processes can safely acquire resources without causing a deadlock by comparing
their maximum need against available resources. The algorithm calculates a need matrix,
simulates resource allocation, and identifies deadlocked processes if any remain unfinished.
The program uses multi-dimensional arrays for resource tracking, loops for matrix
operations, and conditional checks to determine system safety. It also displays the current
directory using getcwd() and takes user input for resource allocation data. The output
confirms whether the system is in a safe state or has deadlocks.

Code:
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <limits.h>

#define MAX_P 10
#define MAX_R 10
void calculateNeed(int need[MAX_P][MAX_R], int max[MAX_P][MAX_R], int
alloc[MAX_P][MAX_R], int n, int m) {
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
need[i][j] = max[i][j] - alloc[i][j];
}

bool detectDeadlock(int processes[], int alloc[][MAX_R], int max[][MAX_R], int avail[], int
n, int m) {
int need[MAX_P][MAX_R];
calculateNeed(need, max, alloc, n, m);

bool finish[MAX_P] = {false};


int work[MAX_R];
for (int i = 0; i < m; i++)
work[i] = avail[i];

bool progress;
do {
progress = false;
for (int i = 0; i < n; i++) {
if (!finish[i]) {
int j;
for (j = 0; j < m; j++) {
if (need[i][j] > work[j])
break;
}
if (j == m) {
for (int k = 0; k < m; k++)
work[k] += alloc[i][k];
finish[i] = true;
progress = true;
}
}
}
} while (progress);

bool deadlock_found = false;


printf("\nDeadlocked processes: ");
for (int i = 0; i < n; i++) {
if (!finish[i]) {
printf("P[%d] ", processes[i]);
deadlock_found = true;
}
}

if (!deadlock_found) {
printf("None");
}
printf("\n");
return deadlock_found;
}

int main() {
char path[PATH_MAX];
if (getcwd(path, sizeof(path)) != NULL)
{
printf("Running from: %s\n\n", path);
}
else
{
perror("getcwd() error");
}
int n, m;
int processes[MAX_P];
int alloc[MAX_P][MAX_R], max[MAX_P][MAX_R], avail[MAX_R];

printf("Enter number of processes: ");


scanf("%d", &n);

printf("Enter number of resource types: ");


scanf("%d", &m);

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


processes[i] = i;

printf("\nEnter Allocation Matrix (%d x %d):\n", n, m);


for (int i = 0; i < n; i++) {
printf("P[%d]: ", i);
for (int j = 0; j < m; j++)
scanf("%d", &alloc[i][j]);
}

printf("\nEnter Max Matrix (%d x %d):\n", n, m);


for (int i = 0; i < n; i++) {
printf("P[%d]: ", i);
for (int j = 0; j < m; j++)
scanf("%d", &max[i][j]);
}

printf("\nEnter Available Resources (%d values):\n", m);


for (int i = 0; i < m; i++)
scanf("%d", &avail[i]);

if (detectDeadlock(processes, alloc, max, avail, n, m))


printf("Deadlock detected in the system.\n");
else
printf("No deadlock detected. System is safe.\n");
printf("\nLab No.: 6.b)\nName: Anjali Rai\nRoll No./Section: 02/A\n");
return 0;
}

Output:
Padmakanya Multiple Campus
Bagbazar, Kathmandu
(Tribhuvan University)

LAB REPORT ON

Operating System (CSC264)

SUBMITTED BY: SUBMITTED TO:


Name: Anjali Rai Bipin Timalsina
Roll no.: 02
Faculty/Semester: Fourth Semester
Section: ‘A’
Contents
Lab Title/Question Submission Date Remarks
No.
2 WAP in C to demonstrate the process 2082-04-12
creation and termination in Linux.
3 WAP in C to demonstrate the thread
creation and termination in Linux.
4(a) WAP to simulate the solution of
producer consumer problem using
semaphore.
4(b) WAP to simulate the solution of dining
philosopher's problem using semaphore.
4(c) WAP to simulate the solution of
producer consumer problem using
message passing technique.
5(a) WAP to simulate FCFS CPU Scheduling
Algorithm
5(b) WAP to simulate SJF CPU Scheduling
Algorithm
5(c) WAP to simulate SRTF CPU Scheduling
Algorithm
5(d) WAP to simulate Round Robin CPU
Scheduling Algorithm
5(e) WAP to simulate Non-Preemptive
Priority Scheduling Algorithm
5(f) WAP to simulate Preemptive Priority
Scheduling Algorithm
6(a) WAP to implement Bankers Algorithm
for multiple type of resources to decide
safe/unsafe state.
6(b) WAP for deadlock detection in the
system having multiple type of resources.
The program should list the deadlocked
process in case of deadlock detection
results

You might also like