1. Implement Banker’s algorithm.
Show the safe sequence and print the available vector at each
stage. There are 3 resources A, B, C – total instances of each resource are 10, 5, 7 respectively.
Allocation Max
ABCABC
P0 0 1 0 7 5 3
P1 2 0 0 3 2 2
P2 3 0 2 9 0 2
P3 2 1 1 2 2 2
P4 0 0 2 4 3 3
#include <stdio.h>
#include <stdbool.h>
#define PROCESSES 5
#define RESOURCES 3
void calculateNeed(int need[PROCESSES][RESOURCES], int max[PROCESSES][RESOURCES], int
allocation[PROCESSES][RESOURCES]) {
for (int i = 0; i < PROCESSES; i++) {
for (int j = 0; j < RESOURCES; j++) {
need[i][j] = max[i][j] - allocation[i][j];
}
}
}
bool isSafe(int processes[], int available[], int max[][RESOURCES], int allocation[][RESOURCES]) {
int need[PROCESSES][RESOURCES];
calculateNeed(need, max, allocation);
bool finish[PROCESSES] = {0};
int safeSeq[PROCESSES];
int work[RESOURCES];
for (int i = 0; i < RESOURCES; i++) {
work[i] = available[i];
}
int count = 0;
while (count < PROCESSES) {
bool found = false;
for (int p = 0; p < PROCESSES; p++) {
if (!finish[p]) {
bool canAllocate = true;
for (int j = 0; j < RESOURCES; j++) {
if (need[p][j] > work[j]) {
canAllocate = false;
break;
}
}
if (canAllocate) {
for (int k = 0; k < RESOURCES; k++) {
work[k] += allocation[p][k];
}
safeSeq[count++] = p;
finish[p] = true;
found = true;
}
}
}
if (!found) {
printf("System is not in a safe state.\n");
return false;
}
}
printf("System is in a safe state.\nSafe sequence is: ");
for (int i = 0; i < PROCESSES; i++) {
printf("%d ", safeSeq[i]);
}
printf("\n");
return true;
}
int main() {
int processes[PROCESSES];
for (int i = 0; i < PROCESSES; i++) processes[i] = i;
int available[RESOURCES];
printf("Enter available instances of resources (A, B, C): ");
for (int i = 0; i < RESOURCES; i++) {
scanf("%d", &available[i]);
}
int max[PROCESSES][RESOURCES], allocation[PROCESSES][RESOURCES];
printf("Enter the Max matrix (for each process P0 to P4):\n");
for (int i = 0; i < PROCESSES; i++) {
printf("P%d: ", i);
for (int j = 0; j < RESOURCES; j++) {
scanf("%d", &max[i][j]);
}
}
printf("Enter the Allocation matrix (for each process P0 to P4):\n");
for (int i = 0; i < PROCESSES; i++) {
printf("P%d: ", i);
for (int j = 0; j < RESOURCES; j++) {
scanf("%d", &allocation[i][j]);
}
}
isSafe(processes, available, max, allocation);
return 0;
}
2. Ast 5 : Solve the Producers-Consumers problem
a. using threads and semaphores b. using threads and mutex
Thread and semaphore
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
// Shared buffer and its parameters
int *buffer;
int bufferSize, in = 0, out = 0;
sem_t emptySlots, fullSlots, mutex; // Semaphores for synchronization
// Producer function
void *producer(void *param) {
int itemsToProduce = *((int *)param);
for (int i = 0; i < itemsToProduce; i++) {
int item = rand() % 100; // Produce a random item
sem_wait(&emptySlots); // Wait if no empty slots
sem_wait(&mutex); // Lock the buffer
// Add item to the buffer
buffer[in] = item;
printf("Producer produced: %d\n", item);
in = (in + 1) % bufferSize;
sem_post(&mutex); // Unlock the buffer
sem_post(&fullSlots); // Signal that a slot is full
sleep(1); // Simulate production delay
pthread_exit(0);
// Consumer function
void *consumer(void *param) {
int id = *((int *)param);
while (1) {
sem_wait(&fullSlots); // Wait if no full slots
sem_wait(&mutex); // Lock the buffer
// Consume item from the buffer
int item = buffer[out];
printf("Consumer %d consumed: %d\n", id, item);
out = (out + 1) % bufferSize;
sem_post(&mutex); // Unlock the buffer
sem_post(&emptySlots); // Signal that a slot is empty
sleep(1); // Simulate consumption delay
pthread_exit(0);
int main() {
int itemsToProduce;
// User input for buffer size and number of items
printf("Enter the size of the buffer: ");
scanf("%d", &bufferSize);
printf("Enter the number of items to produce: ");
scanf("%d", &itemsToProduce);
buffer = (int *)malloc(bufferSize * sizeof(int)); // Allocate memory for the buffer
// Initialize semaphores
sem_init(&emptySlots, 0, bufferSize); // Initially all slots are empty
sem_init(&fullSlots, 0, 0); // No slots are full initially
sem_init(&mutex, 0, 1); // Mutex starts unlocked
// Create threads for producer and consumers
pthread_t producerThread, consumerThread1, consumerThread2;
pthread_create(&producerThread, NULL, producer, &itemsToProduce);
int consumer1ID = 1, consumer2ID = 2;
pthread_create(&consumerThread1, NULL, consumer, &consumer1ID);
pthread_create(&consumerThread2, NULL, consumer, &consumer2ID);
// Wait for the producer to finish
pthread_join(producerThread, NULL);
// Cancel consumers (simulate stopping them after production is complete)
pthread_cancel(consumerThread1);
pthread_cancel(consumerThread2);
// Clean up
sem_destroy(&emptySlots);
sem_destroy(&fullSlots);
sem_destroy(&mutex);
free(buffer);
printf("Production and consumption completed.\n");
return 0;
MUTEX_THREAD
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
// Shared buffer and its parameters
int *buffer;
int bufferSize, in = 0, out = 0, count = 0; // Buffer and count
pthread_mutex_t mutex; // Mutex for synchronization
pthread_cond_t notEmpty, notFull; // Condition variables
// Producer function
void *producer(void *param) {
int itemsToProduce = *((int *)param);
for (int i = 0; i < itemsToProduce; i++) {
int item = rand() % 100; // Produce a random item
pthread_mutex_lock(&mutex); // Lock the buffer
// Wait if buffer is full
while (count == bufferSize)
pthread_cond_wait(¬Full, &mutex);
// Add item to the buffer
buffer[in] = item;
printf("Producer produced: %d\n", item);
in = (in + 1) % bufferSize;
count++;
pthread_cond_signal(¬Empty); // Signal that a slot is filled
pthread_mutex_unlock(&mutex); // Unlock the buffer
sleep(1); // Simulate production delay
pthread_exit(0);
// Consumer function
void *consumer(void *param) {
int id = *((int *)param);
while (1) {
pthread_mutex_lock(&mutex); // Lock the buffer
// Wait if buffer is empty
while (count == 0)
pthread_cond_wait(¬Empty, &mutex);
// Consume item from the buffer
int item = buffer[out];
printf("Consumer %d consumed: %d\n", id, item);
out = (out + 1) % bufferSize;
count--;
pthread_cond_signal(¬Full); // Signal that a slot is empty
pthread_mutex_unlock(&mutex); // Unlock the buffer
sleep(1); // Simulate consumption delay
pthread_exit(0);
int main() {
int itemsToProduce;
// User input for buffer size and number of items
printf("Enter the size of the buffer: ");
scanf("%d", &bufferSize);
printf("Enter the number of items to produce: ");
scanf("%d", &itemsToProduce);
buffer = (int *)malloc(bufferSize * sizeof(int)); // Allocate memory for the buffer
// Initialize mutex and condition variables
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(¬Empty, NULL);
pthread_cond_init(¬Full, NULL);
// Create threads for producer and consumers
pthread_t producerThread, consumerThread1, consumerThread2;
pthread_create(&producerThread, NULL, producer, &itemsToProduce);
int consumer1ID = 1, consumer2ID = 2;
pthread_create(&consumerThread1, NULL, consumer, &consumer1ID);
pthread_create(&consumerThread2, NULL, consumer, &consumer2ID);
// Wait for the producer to finish
pthread_join(producerThread, NULL);
// Cancel consumers (simulate stopping them after production is complete)
pthread_cancel(consumerThread1);
pthread_cancel(consumerThread2);
// Clean up
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(¬Empty);
pthread_cond_destroy(¬Full);
free(buffer);
printf("Production and consumption completed.\n");
return 0;
3. Simulate the following CPU scheduling algorithms:
a. First come First serve b. Shortest Job First (Non-preemptive) c. Shortest Job First (Preemptive) d.
Round Robin e. Priority (Non-preemptive) f. Priority (Non-preemptive)
(Draw the Gantt charts and display the finish time, turnaround time, waiting time for each
process)
A.FCFS
#include <stdio.h>
struct Process {
int pid, arrivalTime, burstTime, finishTime, waitingTime, turnaroundTime;
};
void findTimes(struct Process proc[], int n) {
proc[0].finishTime = proc[0].arrivalTime + proc[0].burstTime;
proc[0].turnaroundTime = proc[0].finishTime - proc[0].arrivalTime;
proc[0].waitingTime = proc[0].turnaroundTime - proc[0].burstTime;
for (int i = 1; i < n; i++) {
proc[i].finishTime = (proc[i].arrivalTime > proc[i - 1].finishTime)
? proc[i].arrivalTime + proc[i].burstTime
: proc[i - 1].finishTime + proc[i].burstTime;
proc[i].turnaroundTime = proc[i].finishTime - proc[i].arrivalTime;
proc[i].waitingTime = proc[i].turnaroundTime - proc[i].burstTime;
}
void drawGanttChart(struct Process proc[], int n) {
printf("\nGantt Chart:\n");
for (int i = 0; i < n; i++) {
printf(" | P%d ", proc[i].pid);
printf("|\n");
// Print time indicators
int currentTime = proc[0].arrivalTime;
printf("%d", currentTime);
for (int i = 0; i < n; i++) {
currentTime = proc[i].finishTime;
printf(" %d", currentTime);
printf("\n");
void FCFS(struct Process proc[], int n) {
findTimes(proc, n);
printf("\nPID\tArrival\tBurst\tFinish\tTurnaround\tWaiting\n");
for (int i = 0; i < n; i++) {
printf("%d\t%d\t%d\t%d\t%d\t\t%d\n", proc[i].pid, proc[i].arrivalTime,
proc[i].burstTime, proc[i].finishTime, proc[i].turnaroundTime, proc[i].waitingTime);
drawGanttChart(proc, n);
int main() {
int n;
printf("Enter number of processes: ");
scanf("%d", &n);
struct Process proc[n];
for (int i = 0; i < n; i++) {
proc[i].pid = i + 1;
printf("Enter Arrival Time and Burst Time for Process %d: ", i + 1);
scanf("%d %d", &proc[i].arrivalTime, &proc[i].burstTime);
FCFS(proc, n);
return 0;
B. Shortest Job First (Non-preemptive)
#include <stdio.h>
struct Process {
int pid, arrivalTime, burstTime, finishTime, waitingTime, turnaroundTime;
};
void sortProcesses(struct Process proc[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (proc[j].burstTime > proc[j + 1].burstTime) {
struct Process temp = proc[j];
proc[j] = proc[j + 1];
proc[j + 1] = temp;
}
void findTimes(struct Process proc[], int n) {
proc[0].finishTime = proc[0].arrivalTime + proc[0].burstTime;
proc[0].turnaroundTime = proc[0].finishTime - proc[0].arrivalTime;
proc[0].waitingTime = proc[0].turnaroundTime - proc[0].burstTime;
for (int i = 1; i < n; i++) {
proc[i].finishTime = proc[i - 1].finishTime + proc[i].burstTime;
proc[i].turnaroundTime = proc[i].finishTime - proc[i].arrivalTime;
proc[i].waitingTime = proc[i].turnaroundTime - proc[i].burstTime;
void displayGanttChart(struct Process proc[], int n) {
printf("\nGantt Chart:\n");
// Print process boxes
for (int i = 0; i < n; i++) {
printf(" | P%d ", proc[i].pid);
printf("|\n");
// Print timeline
int currentTime = proc[0].arrivalTime;
for (int i = 0; i < n; i++) {
if (i == 0) {
printf("%d ", currentTime);
currentTime = proc[i].finishTime;
printf("%d ", currentTime);
printf("\n");
void nonPreemptiveSJF(struct Process proc[], int n) {
sortProcesses(proc, n);
findTimes(proc, n);
// Display process details
printf("\nPID\tArrival\tBurst\tFinish\tTurnaround\tWaiting\n");
for (int i = 0; i < n; i++) {
printf("%d\t%d\t%d\t%d\t%d\t\t%d\n", proc[i].pid, proc[i].arrivalTime,
proc[i].burstTime, proc[i].finishTime, proc[i].turnaroundTime, proc[i].waitingTime);
// Display Gantt chart
displayGanttChart(proc, n);
int main() {
int n;
printf("Enter number of processes: ");
scanf("%d", &n);
struct Process proc[n];
for (int i = 0; i < n; i++) {
proc[i].pid = i + 1;
printf("Enter Arrival Time and Burst Time for Process %d: ", i + 1);
scanf("%d %d", &proc[i].arrivalTime, &proc[i].burstTime);
nonPreemptiveSJF(proc, n);
return 0;
C. Shortest Job First (Preemptive)
#include <stdio.h>
#include <limits.h>
struct Process {
int pid, arrivalTime, burstTime, remainingTime, finishTime, waitingTime, turnaroundTime;
};
struct GanttChart {
int pid, startTime, endTime;
};
void preemptiveSJF(struct Process proc[], int n) {
int totalTime = 0, completed = 0, shortest, finishTime, minTime = INT_MAX;
int totalBurstTime = 0;
int isShortest = 0;
for (int i = 0; i < n; i++) {
proc[i].remainingTime = proc[i].burstTime;
totalBurstTime += proc[i].burstTime;
struct GanttChart gantt[100];
int ganttIndex = 0;
while (completed != n) {
shortest = -1;
minTime = INT_MAX;
for (int i = 0; i < n; i++) {
if (proc[i].arrivalTime <= totalTime && proc[i].remainingTime > 0 &&
proc[i].remainingTime < minTime) {
minTime = proc[i].remainingTime;
shortest = i;
isShortest = 1;
if (!isShortest) {
totalTime++;
continue;
gantt[ganttIndex].pid = proc[shortest].pid;
gantt[ganttIndex].startTime = totalTime;
proc[shortest].remainingTime--;
if (proc[shortest].remainingTime == 0) {
completed++;
isShortest = 0;
finishTime = totalTime + 1;
proc[shortest].finishTime = finishTime;
proc[shortest].waitingTime = proc[shortest].finishTime - proc[shortest].burstTime -
proc[shortest].arrivalTime;
proc[shortest].turnaroundTime = proc[shortest].finishTime - proc[shortest].arrivalTime;
gantt[ganttIndex].endTime = ++totalTime;
ganttIndex++;
// Print process details
printf("\nPID\tArrival\tBurst\tFinish\tTurnaround\tWaiting\n");
for (int i = 0; i < n; i++) {
printf("%d\t%d\t%d\t%d\t%d\t\t%d\n", proc[i].pid, proc[i].arrivalTime,
proc[i].burstTime, proc[i].finishTime, proc[i].turnaroundTime, proc[i].waitingTime);
// Display text-based Gantt chart
printf("\nGantt Chart:\n");
// Print process boxes
for (int i = 0; i < ganttIndex; i++) {
printf("| P%d ", gantt[i].pid);
printf("|\n");
// Print timeline
for (int i = 0; i < ganttIndex; i++) {
printf("%d ", gantt[i].startTime);
}
printf("%d\n", gantt[ganttIndex - 1].endTime);
int main() {
int n;
printf("Enter number of processes: ");
scanf("%d", &n);
struct Process proc[n];
for (int i = 0; i < n; i++) {
proc[i].pid = i + 1;
printf("Enter Arrival Time and Burst Time for Process %d: ", i + 1);
scanf("%d %d", &proc[i].arrivalTime, &proc[i].burstTime);
preemptiveSJF(proc, n);
return 0;
D. Round Robin
#include <stdio.h>
struct Process {
int pid, arrivalTime, burstTime, remainingTime, finishTime, waitingTime, turnaroundTime;
};
void roundRobin(struct Process proc[], int n, int timeQuantum) {
int time = 0, completed = 0;
int tq = timeQuantum;
int totalBurstTime = 0;
int isCompleted[n];
for (int i = 0; i < n; i++) {
proc[i].remainingTime = proc[i].burstTime;
isCompleted[i] = 0;
totalBurstTime += proc[i].burstTime;
struct GanttChart {
int pid, startTime, endTime;
} gantt[100];
int ganttIndex = 0;
while (completed != n) {
int executed = 0;
for (int i = 0; i < n; i++) {
if (proc[i].arrivalTime <= time && proc[i].remainingTime > 0) {
executed = 1;
gantt[ganttIndex].pid = proc[i].pid;
gantt[ganttIndex].startTime = time;
if (proc[i].remainingTime <= tq) {
time += proc[i].remainingTime;
proc[i].remainingTime = 0;
proc[i].finishTime = time;
proc[i].turnaroundTime = proc[i].finishTime - proc[i].arrivalTime;
proc[i].waitingTime = proc[i].turnaroundTime - proc[i].burstTime;
completed++;
} else {
time += tq;
proc[i].remainingTime -= tq;
gantt[ganttIndex].endTime = time;
ganttIndex++;
if (!executed) {
time++;
// Display the process table
printf("\nPID\tArrival\tBurst\tFinish\tTurnaround\tWaiting\n");
for (int i = 0; i < n; i++) {
printf("%d\t%d\t%d\t%d\t%d\t\t%d\n", proc[i].pid, proc[i].arrivalTime,
proc[i].burstTime, proc[i].finishTime, proc[i].turnaroundTime, proc[i].waitingTime);
// Display the Gantt chart
printf("\nGantt Chart:\n");
for (int i = 0; i < ganttIndex; i++) {
printf(" | P%d ", gantt[i].pid);
printf("|\n");
int currentTime = 0;
for (int i = 0; i < ganttIndex; i++) {
if (gantt[i].startTime != currentTime) {
printf("%d ", gantt[i].startTime);
currentTime = gantt[i].endTime;
printf("%d ", gantt[i].endTime);
printf("\n");
int main() {
int n, timeQuantum;
printf("Enter number of processes: ");
scanf("%d", &n);
struct Process proc[n];
for (int i = 0; i < n; i++) {
proc[i].pid = i + 1;
printf("Enter Arrival Time and Burst Time for Process %d: ", i + 1);
scanf("%d %d", &proc[i].arrivalTime, &proc[i].burstTime);
printf("Enter Time Quantum: ");
scanf("%d", &timeQuantum);
roundRobin(proc, n, timeQuantum);
return 0;
}
E. Priority (preemptive)
#include <stdio.h>
#include <limits.h>
struct Process {
int pid, arrivalTime, burstTime, remainingTime, finishTime, waitingTime, turnaroundTime,
priority;
};
struct GanttChart {
int pid, startTime, endTime;
};
void preemptivePriority(struct Process proc[], int n) {
int totalTime = 0, completed = 0, highestPriority, minPriority = INT_MAX;
int totalBurstTime = 0, isHighest = 0;
for (int i = 0; i < n; i++) {
proc[i].remainingTime = proc[i].burstTime;
totalBurstTime += proc[i].burstTime;
struct GanttChart gantt[100];
int ganttIndex = 0;
while (completed != n) {
highestPriority = -1;
minPriority = INT_MAX;
for (int i = 0; i < n; i++) {
if (proc[i].arrivalTime <= totalTime && proc[i].remainingTime > 0 && proc[i].priority <
minPriority) {
minPriority = proc[i].priority;
highestPriority = i;
isHighest = 1;
if (!isHighest) {
totalTime++;
continue;
gantt[ganttIndex].pid = proc[highestPriority].pid;
gantt[ganttIndex].startTime = totalTime;
proc[highestPriority].remainingTime--;
if (proc[highestPriority].remainingTime == 0) {
completed++;
isHighest = 0;
proc[highestPriority].finishTime = totalTime + 1;
proc[highestPriority].waitingTime = proc[highestPriority].finishTime -
proc[highestPriority].burstTime - proc[highestPriority].arrivalTime;
proc[highestPriority].turnaroundTime = proc[highestPriority].finishTime -
proc[highestPriority].arrivalTime;
gantt[ganttIndex].endTime = ++totalTime;
ganttIndex++;
}
// Print process details
printf("\nPID\tArrival\tBurst\tPriority\tFinish\tTurnaround\tWaiting\n");
for (int i = 0; i < n; i++) {
printf("%d\t%d\t%d\t%d\t\t%d\t%d\t\t%d\n", proc[i].pid, proc[i].arrivalTime,
proc[i].burstTime, proc[i].priority, proc[i].finishTime, proc[i].turnaroundTime,
proc[i].waitingTime);
// Display text-based Gantt chart
printf("\nGantt Chart:\n");
// Print process boxes
for (int i = 0; i < ganttIndex; i++) {
printf("| P%d ", gantt[i].pid);
printf("|\n");
// Print timeline
for (int i = 0; i < ganttIndex; i++) {
printf("%d ", gantt[i].startTime);
printf("%d\n", gantt[ganttIndex - 1].endTime);
int main() {
int n;
printf("Enter number of processes: ");
scanf("%d", &n);
struct Process proc[n];
for (int i = 0; i < n; i++) {
proc[i].pid = i + 1;
printf("Enter Arrival Time, Burst Time, and Priority for Process %d: ", i + 1);
scanf("%d %d %d", &proc[i].arrivalTime, &proc[i].burstTime, &proc[i].priority);
preemptivePriority(proc, n);
return 0;
F. Priority (Non-preemptive)
#include <stdio.h>
#include <limits.h>
struct Process {
int pid, arrivalTime, burstTime, finishTime, waitingTime, turnaroundTime, priority;
};
void sortProcessesByPriority(struct Process proc[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (proc[j].priority > proc[j + 1].priority) {
struct Process temp = proc[j];
proc[j] = proc[j + 1];
proc[j + 1] = temp;
}
}
void findTimes(struct Process proc[], int n) {
proc[0].finishTime = proc[0].arrivalTime + proc[0].burstTime;
proc[0].turnaroundTime = proc[0].finishTime - proc[0].arrivalTime;
proc[0].waitingTime = proc[0].turnaroundTime - proc[0].burstTime;
for (int i = 1; i < n; i++) {
proc[i].finishTime = proc[i - 1].finishTime + proc[i].burstTime;
proc[i].turnaroundTime = proc[i].finishTime - proc[i].arrivalTime;
proc[i].waitingTime = proc[i].turnaroundTime - proc[i].burstTime;
void printGanttChart(struct Process proc[], int n) {
int totalTime = 0;
for (int i = 0; i < n; i++) {
totalTime += proc[i].burstTime;
printf("\nGantt Chart:\n");
// Print process execution bars
for (int i = 0; i < n; i++) {
printf("| P%d ", proc[i].pid);
printf("|\n");
// Print time markers
for (int i = 0; i < n; i++) {
printf("%d ", proc[i].arrivalTime);
printf("%d\n", totalTime);
void nonPreemptivePriority(struct Process proc[], int n) {
sortProcessesByPriority(proc, n);
findTimes(proc, n);
printf("\nPID\tArrival\tBurst\tPriority\tFinish\tTurnaround\tWaiting\n");
for (int i = 0; i < n; i++) {
printf("%d\t%d\t%d\t%d\t\t%d\t%d\t\t%d\n", proc[i].pid, proc[i].arrivalTime,
proc[i].burstTime, proc[i].priority, proc[i].finishTime, proc[i].turnaroundTime,
proc[i].waitingTime);
printGanttChart(proc, n);
int main() {
int n;
printf("Enter number of processes: ");
scanf("%d", &n);
struct Process proc[n];
for (int i = 0; i < n; i++) {
proc[i].pid = i + 1;
printf("Enter Arrival Time, Burst Time, and Priority for Process %d: ", i + 1);
scanf("%d %d %d", &proc[i].arrivalTime, &proc[i].burstTime, &proc[i].priority);
nonPreemptivePriority(proc, n);
return 0;
4. Simulate the following page replacement algorithms
a. FIFO b. LRU c. OPT
A. FIFO
#include <stdio.h>
#include <stdbool.h>
void fifo(int pages[], int n, int capacity) {
int frame[capacity], faults = 0, index = 0;
bool inFrame[100] = {false};
for (int i = 0; i < capacity; i++) frame[i] = -1;
for (int i = 0; i < n; i++) {
if (!inFrame[pages[i]]) {
frame[index] = pages[i];
index = (index + 1) % capacity;
faults++;
inFrame[pages[i]] = true;
printf("Frame: ");
for (int j = 0; j < capacity; j++) {
if (frame[j] != -1)
printf("%d ", frame[j]);
else
printf("- ");
printf("\n");
printf("FIFO Page Faults: %d\n", faults);
int main() {
int n, capacity;
printf("Enter the number of pages in the reference string: ");
scanf("%d", &n);
int referenceString[n];
printf("Enter the reference string:\n");
for (int i = 0; i < n; i++) {
scanf("%d", &referenceString[i]);
printf("Enter the number of page frames: ");
scanf("%d", &capacity);
printf("\nFIFO Algorithm:\n");
fifo(referenceString, n, capacity);
return 0;
}
B. OPT
#include <stdio.h>
#include <stdbool.h>
void optimal(int pages[], int n, int capacity) {
int frame[capacity], faults = 0;
for (int i = 0; i < capacity; i++) frame[i] = -1;
for (int i = 0; i < n; i++) {
bool inFrame = false;
for (int j = 0; j < capacity; j++) {
if (frame[j] == pages[i]) {
inFrame = true;
break;
if (!inFrame) {
if (i < capacity) {
frame[i] = pages[i];
} else {
int farthest = -1, replaceIndex = -1;
for (int j = 0; j < capacity; j++) {
int nextUse = n;
for (int k = i + 1; k < n; k++) {
if (frame[j] == pages[k]) {
nextUse = k;
break;
}
if (nextUse > farthest) {
farthest = nextUse;
replaceIndex = j;
frame[replaceIndex] = pages[i];
faults++;
printf("Frame: ");
for (int j = 0; j < capacity; j++) {
if (frame[j] != -1)
printf("%d ", frame[j]);
else
printf("- ");
printf("\n");
printf("OPT Page Faults: %d\n", faults);
int main() {
int n, capacity;
printf("Enter the number of pages in the reference string: ");
scanf("%d", &n);
int referenceString[n];
printf("Enter the reference string:\n");
for (int i = 0; i < n; i++) {
scanf("%d", &referenceString[i]);
printf("Enter the number of page frames: ");
scanf("%d", &capacity);
printf("\nOPT Algorithm:\n");
optimal(referenceString, n, capacity);
return 0;
C. LRU
#include <stdio.h>
#include <stdbool.h>
void lru(int pages[], int n, int capacity) {
int frame[capacity], faults = 0;
int lastUsed[capacity]; // To store the last used time of each frame
for (int i = 0; i < capacity; i++) {
frame[i] = -1;
lastUsed[i] = -1; // Initialize last used time for all frames
for (int i = 0; i < n; i++) {
bool inFrame = false;
int leastRecentlyUsed = -1, replaceIndex = -1;
// Check if the page is already in a frame
for (int j = 0; j < capacity; j++) {
if (frame[j] == pages[i]) {
inFrame = true;
lastUsed[j] = i; // Update the last used time
break;
// If the page is not in any frame, we need to replace a page
if (!inFrame) {
// If there is still space in the frames, place the page
if (i < capacity) {
frame[i] = pages[i];
lastUsed[i] = i;
} else {
// Find the least recently used page
for (int j = 0; j < capacity; j++) {
if (lastUsed[j] < leastRecentlyUsed || leastRecentlyUsed == -1) {
leastRecentlyUsed = lastUsed[j];
replaceIndex = j;
// Replace the least recently used page
frame[replaceIndex] = pages[i];
lastUsed[replaceIndex] = i;
faults++;
}
// Display current frame state
printf("Frame: ");
for (int j = 0; j < capacity; j++) {
if (frame[j] != -1)
printf("%d ", frame[j]);
else
printf("- ");
printf("\n");
printf("LRU Page Faults: %d\n", faults);
int main() {
int n, capacity;
printf("Enter the number of pages in the reference string: ");
scanf("%d", &n);
int referenceString[n];
printf("Enter the reference string:\n");
for (int i = 0; i < n; i++) {
scanf("%d", &referenceString[i]);
printf("Enter the number of page frames: ");
scanf("%d", &capacity);
printf("\nLRU Algorithm:\n");
lru(referenceString, n, capacity);
return 0;
Implement Reader Writer Prblem using
a. using threads and semaphores b. using threads and mutex
MUTEX_THREAD
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_mutex_t rw_mutex = PTHREAD_MUTEX_INITIALIZER; // Mutex for resource access
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // Mutex for reader count
int reader_count = 0; // Number of active readers
int shared_resource = 0; // Shared resource
void* reader(void* arg) {
int reader_id = ((int)arg);
pthread_mutex_lock(&mutex);
reader_count++;
if (reader_count == 1) {
pthread_mutex_lock(&rw_mutex); // First reader locks resource
pthread_mutex_unlock(&mutex);
// Reading the shared resource
printf("Reader %d is reading the shared resource: %d\n", reader_id, shared_resource);
pthread_mutex_lock(&mutex);
reader_count--;
if (reader_count == 0) {
pthread_mutex_unlock(&rw_mutex); // Last reader unlocks resource
pthread_mutex_unlock(&mutex);
return NULL;
void* writer(void* arg) {
int writer_id = ((int)arg);
pthread_mutex_lock(&rw_mutex); // Only one writer allowed
// Writing to the shared resource
shared_resource++;
printf("Writer %d updated the shared resource to: %d\n", writer_id, shared_resource);
pthread_mutex_unlock(&rw_mutex);
return NULL;
int main() {
int readers, writers;
printf("Enter the number of readers: ");
scanf("%d", &readers);
printf("Enter the number of writers: ");
scanf("%d", &writers);
pthread_t r_threads[readers], w_threads[writers];
int ids[readers + writers];
for (int i = 0; i < readers; i++) {
ids[i] = i + 1;
pthread_create(&r_threads[i], NULL, reader, &ids[i]);
for (int i = 0; i < writers; i++) {
ids[readers + i] = i + 1;
pthread_create(&w_threads[i], NULL, writer, &ids[readers + i]);
for (int i = 0; i < readers; i++) {
pthread_join(r_threads[i], NULL);
for (int i = 0; i < writers; i++) {
pthread_join(w_threads[i], NULL);
pthread_mutex_destroy(&rw_mutex);
pthread_mutex_destroy(&mutex);
return 0;
THREAD_SEMAPHOR
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
sem_t rw_mutex; // Semaphore for resource access
sem_t mutex; // Semaphore for reader count update
int reader_count = 0; // Number of active readers
int shared_resource = 0; // Shared resource
void* reader(void* arg) {
int reader_id = ((int)arg);
sem_wait(&mutex);
reader_count++;
if (reader_count == 1) {
sem_wait(&rw_mutex); // First reader locks resource
sem_post(&mutex);
// Reading the shared resource
printf("Reader %d is reading the shared resource: %d\n", reader_id, shared_resource);
sem_wait(&mutex);
reader_count--;
if (reader_count == 0) {
sem_post(&rw_mutex); // Last reader unlocks resource
sem_post(&mutex);
return NULL;
}
void* writer(void* arg) {
int writer_id = ((int)arg);
sem_wait(&rw_mutex); // Only one writer allowed
// Writing to the shared resource
shared_resource++;
printf("Writer %d updated the shared resource to: %d\n", writer_id, shared_resource);
sem_post(&rw_mutex);
return NULL;
int main() {
int readers, writers;
printf("Enter the number of readers: ");
scanf("%d", &readers);
printf("Enter the number of writers: ");
scanf("%d", &writers);
pthread_t r_threads[readers], w_threads[writers];
int ids[readers + writers];
sem_init(&rw_mutex, 0, 1);
sem_init(&mutex, 0, 1);
for (int i = 0; i < readers; i++) {
ids[i] = i + 1;
pthread_create(&r_threads[i], NULL, reader, &ids[i]);
}
for (int i = 0; i < writers; i++) {
ids[readers + i] = i + 1;
pthread_create(&w_threads[i], NULL, writer, &ids[readers + i]);
for (int i = 0; i < readers; i++) {
pthread_join(r_threads[i], NULL);
for (int i = 0; i < writers; i++) {
pthread_join(w_threads[i], NULL);
sem_destroy(&rw_mutex);
sem_destroy(&mutex);
return 0;