Compare commits

..

1 commit

Author SHA1 Message Date
6699115e40 feat: implement EDF and RMS scheduling algorithms
Add a new RTOS scheduling implementation with EDF and RMS algorithms. 
Introduce a task structure and create task threads to simulate task 
execution. Optimize the Banker's Algorithm code comments for clarity. 
These changes enhance the understanding and functionality of the 
scheduling mechanisms in the system.
2025-04-04 16:10:41 +05:30
12 changed files with 201 additions and 1212 deletions

View file

@ -1,169 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <limits.h> // For INT_MAX
// Structure to represent a frame and its last used time
typedef struct {
int page_number;
int last_used_time;
} Frame;
// Function to find if a page exists in frames and return its index
// Also updates the last_used_time if found
int find_page(Frame frames[], int n_frames, int page, int current_time) {
for (int i = 0; i < n_frames; i++) {
if (frames[i].page_number == page) {
frames[i].last_used_time = current_time; // Update time on hit
return i; // Page found (Hit)
}
}
return -1; // Page not found (Fault)
}
// Function to find the index of the Least Recently Used (LRU) page
int find_lru_index(Frame frames[], int n_frames) {
int min_time = INT_MAX;
int lru_index = 0;
for (int i = 0; i < n_frames; i++) {
// Frame must contain a valid page (not -1)
if (frames[i].page_number != -1 && frames[i].last_used_time < min_time) {
min_time = frames[i].last_used_time;
lru_index = i;
}
}
return lru_index;
}
// Function to print the current state of frames
void print_frames(Frame frames[], int n_frames) {
printf("[");
for (int i = 0; i < n_frames; i++) {
if (frames[i].page_number == -1) {
printf(" - ");
} else {
printf(" %d ", frames[i].page_number);
}
}
printf("]\n");
}
int main() {
int n_frames, n_pages;
int *pages = NULL; // Reference string
Frame *frames = NULL; // Frames in memory
int page_faults = 0;
int page_hits = 0;
int current_time = 0; // Counter to track usage time
int frame_idx = 0; // Index for filling empty frames initially
// 1. Get Inputs
printf("Enter the number of frames: ");
if (scanf("%d", &n_frames) != 1 || n_frames <= 0) {
fprintf(stderr, "Error: Invalid number of frames.\n");
return 1;
}
printf("Enter the number of pages in the reference string: ");
if (scanf("%d", &n_pages) != 1 || n_pages <= 0) {
fprintf(stderr, "Error: Invalid number of pages.\n");
return 1;
}
// 2. Allocate Memory
pages = (int *)malloc(n_pages * sizeof(int));
if (pages == NULL) {
perror("Failed to allocate memory for pages");
return 1;
}
frames = (Frame *)malloc(n_frames * sizeof(Frame));
if (frames == NULL) {
perror("Failed to allocate memory for frames");
free(pages); // Clean up already allocated memory
return 1;
}
printf("Enter the page reference string (space-separated %d integers):\n", n_pages);
for (int i = 0; i < n_pages; i++) {
if (scanf("%d", &pages[i]) != 1) {
fprintf(stderr, "Error reading page reference string.\n");
free(pages);
free(frames);
return 1;
}
}
// 3. Initialize Frames
for (int i = 0; i < n_frames; i++) {
frames[i].page_number = -1; // -1 indicates empty frame
frames[i].last_used_time = -1; // Initialize time
}
printf("\n--- LRU Simulation Start ---\n");
printf("Frames: %d | Reference String Length: %d\n\n", n_frames, n_pages);
// 4. Process Page References
for (int i = 0; i < n_pages; i++) {
current_time++; // Increment time step for each reference
int current_page = pages[i];
printf("Ref: %d -> ", current_page);
int found_index = find_page(frames, n_frames, current_page, current_time);
if (found_index != -1) {
// Page Hit
page_hits++;
printf("Hit ");
} else {
// Page Fault
page_faults++;
printf("Fault ");
// Find a place for the new page
int replace_index = -1;
// Check for an empty frame first
for(int k=0; k < n_frames; k++){
if(frames[k].page_number == -1){
replace_index = k;
break;
}
}
if (replace_index != -1) {
// Use the empty frame
frames[replace_index].page_number = current_page;
frames[replace_index].last_used_time = current_time;
printf("(loaded into empty frame %d) ", replace_index);
} else {
// No empty frames, find LRU page to replace
replace_index = find_lru_index(frames, n_frames);
printf("(replaced P%d in frame %d) ", frames[replace_index].page_number, replace_index);
frames[replace_index].page_number = current_page;
frames[replace_index].last_used_time = current_time;
}
}
print_frames(frames, n_frames); // Show frame status after each step
}
// 5. Output Results
printf("\n--- LRU Simulation End ---\n");
printf("Total Page References: %d\n", n_pages);
printf("Total Page Hits: %d\n", page_hits);
printf("Total Page Faults: %d\n", page_faults);
if (n_pages > 0) {
printf("Hit Rate: %.2f%%\n", (double)page_hits / n_pages * 100.0);
printf("Fault Rate: %.2f%%\n", (double)page_faults / n_pages * 100.0);
} else {
printf("Hit Rate: N/A\n");
printf("Fault Rate: N/A\n");
}
// 6. Free Memory
free(pages);
free(frames);
return 0;
}

View file

@ -1,176 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// Function to check if a page exists in frames
bool isPagePresent(int* frames, int num_frames, int page) {
for (int i = 0; i < num_frames; i++) {
if (frames[i] == page) {
return true;
}
}
return false;
}
// FIFO Page Replacement Algorithm
void fifo(int* reference_string, int num_pages, int num_frames) {
int* frames = (int*)malloc(num_frames * sizeof(int));
int page_faults = 0;
int frame_index = 0;
// Initialize frames with -1 (indicating empty)
for (int i = 0; i < num_frames; i++) {
frames[i] = -1;
}
printf("\nFIFO Page Replacement Algorithm:\n");
printf("Reference String: ");
for (int i = 0; i < num_pages; i++) {
printf("%d ", reference_string[i]);
}
printf("\n\n");
for (int i = 0; i < num_pages; i++) {
printf("Page %d: ", reference_string[i]);
// Check if page already exists in frames
if (!isPagePresent(frames, num_frames, reference_string[i])) {
// Replace page at current frame_index
frames[frame_index] = reference_string[i];
frame_index = (frame_index + 1) % num_frames;
page_faults++;
printf("Page Fault! Frames: ");
} else {
printf("No Page Fault. Frames: ");
}
// Print current state of frames
for (int j = 0; j < num_frames; j++) {
if (frames[j] == -1) {
printf("[ ] ");
} else {
printf("[%d] ", frames[j]);
}
}
printf("\n");
}
printf("\nTotal Page Faults (FIFO): %d\n", page_faults);
free(frames);
}
// Function to find index of page that will be used farthest in future
int findOptimalPage(int* reference_string, int* frames, int num_frames, int num_pages, int current_position) {
int farthest = -1;
int index = -1;
for (int i = 0; i < num_frames; i++) {
int j;
for (j = current_position + 1; j < num_pages; j++) {
if (frames[i] == reference_string[j]) {
if (j > farthest) {
farthest = j;
index = i;
}
break;
}
}
// If page is never used in future
if (j == num_pages) {
return i;
}
}
// If all pages will be used in future, return the one used farthest
return (index == -1) ? 0 : index;
}
// Optimal Page Replacement Algorithm
void optimal(int* reference_string, int num_pages, int num_frames) {
int* frames = (int*)malloc(num_frames * sizeof(int));
int page_faults = 0;
// Initialize frames with -1 (indicating empty)
for (int i = 0; i < num_frames; i++) {
frames[i] = -1;
}
printf("\nOptimal Page Replacement Algorithm:\n");
printf("Reference String: ");
for (int i = 0; i < num_pages; i++) {
printf("%d ", reference_string[i]);
}
printf("\n\n");
for (int i = 0; i < num_pages; i++) {
printf("Page %d: ", reference_string[i]);
// Check if page already exists in frames
if (!isPagePresent(frames, num_frames, reference_string[i])) {
int free_frame = -1;
// Check if there's an empty frame
for (int j = 0; j < num_frames; j++) {
if (frames[j] == -1) {
free_frame = j;
break;
}
}
if (free_frame != -1) {
// If empty frame exists, use it
frames[free_frame] = reference_string[i];
} else {
// Find optimal page to replace
int replace_index = findOptimalPage(reference_string, frames, num_frames, num_pages, i);
frames[replace_index] = reference_string[i];
}
page_faults++;
printf("Page Fault! Frames: ");
} else {
printf("No Page Fault. Frames: ");
}
// Print current state of frames
for (int j = 0; j < num_frames; j++) {
if (frames[j] == -1) {
printf("[ ] ");
} else {
printf("[%d] ", frames[j]);
}
}
printf("\n");
}
printf("\nTotal Page Faults (Optimal): %d\n", page_faults);
free(frames);
}
int main() {
int num_pages, num_frames;
printf("Enter number of frames: ");
scanf("%d", &num_frames);
printf("Enter number of pages in reference string: ");
scanf("%d", &num_pages);
int* reference_string = (int*)malloc(num_pages * sizeof(int));
printf("Enter the reference string (page numbers):\n");
for (int i = 0; i < num_pages; i++) {
scanf("%d", &reference_string[i]);
}
// Run FIFO algorithm
fifo(reference_string, num_pages, num_frames);
// Run Optimal algorithm
optimal(reference_string, num_pages, num_frames);
free(reference_string);
return 0;
}

View file

@ -1,201 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 100
// Function for SSTF (Shortest Seek Time First)
void sstf(int arr[], int n, int head) {
int visited[MAX] = {0}, total_seek = 0, current = head;
printf("\nSSTF Sequence:\n%d ", current);
for (int count = 0; count < n; count++) {
int index = -1, minDist = 1e9;
for (int i = 0; i < n; i++) {
if (!visited[i]) {
int dist = abs(arr[i] - current);
if (dist < minDist) {
minDist = dist;
index = i;
}
}
}
visited[index] = 1;
total_seek += minDist;
current = arr[index];
printf("-> %d ", current);
}
printf("\nTotal Seek Time: %d\n", total_seek);
}
// Helper function: Bubble sort in ascending order
void sortAsc(int arr[], int n) {
for (int i = 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++)
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// Helper function: Bubble sort in descending order
void sortDesc(int arr[], int
for (int i = 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++)
if (arr[i] < arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// Function for SCAN (Elevator Algorithm)
// Assumes movement is towards the left first, then reverses.
void scan(int arr[], int n, int head, int disk_size) {
int left[MAX], right[MAX], l = 0, r = 0;
for (int i = 0; i < n; i++) {
if (arr[i] < head)
left[l++] = arr[i];
else
right[r++] = arr[i];
}
sortDesc(left, l);
sortAsc(right, r);
int total_seek = 0, current = head;
printf("\nSCAN Sequence:\n%d ", current);
// Service left side (moving toward 0)
for (int i = 0; i < l; i++) {
total_seek += abs(current - left[i]);
current = left[i];
printf("-> %d ", current);
}
// If not already at 0, move to 0
if (current != 0) {
total_seek += current;
current = 0;
printf("-> %d ", current);
}
// Then service right side (moving right)
for (int i = 0; i < r; i++) {
total_seek += abs(right[i] - current);
current = right[i];
printf("-> %d ", current);
}
printf("\nTotal Seek Time: %d\n", total_seek);
}
// Function for C-SCAN (Circular SCAN)
// Assumes movement to the right; after reaching the end, the head jumps to 0.
void cscan(int arr[], int n, int head, int disk_size) {
int left[MAX], right[MAX], l = 0, r = 0;
for (int i = 0; i < n; i++) {
if (arr[i] < head)
left[l++] = arr[i];
else
right[r++] = arr[i];
}
sortAsc(left, l);
sortAsc(right, r);
int total_seek = 0, current = head;
printf("\nC-SCAN Sequence:\n%d ", current);
// Service requests to the right
for (int i = 0; i < r; i++) {
total_seek += abs(right[i] - current);
current = right[i];
printf("-> %d ", current);
}
// Go to the end if not reached
if (current != disk_size - 1) {
total_seek += abs(disk_size - 1 - current);
current = disk_size - 1;
printf("-> %d ", current);
}
// Jump to beginning (simulate wrap-around)
total_seek += (disk_size - 1);
current = 0;
printf("-> %d ", current);
// Service the left side
for (int i = 0; i < l; i++) {
total_seek += abs(left[i] - current);
current = left[i];
printf("-> %d ", current);
}
printf("\nTotal Seek Time: %d\n", total_seek);
}
// Function for C-LOOK
// Assumes movement to the right; after the furthest request, it jumps to the smallest request.
void clook(int arr[], int n, int head) {
int left[MAX], right[MAX], l = 0, r = 0;
for (int i = 0; i < n; i++) {
if (arr[i] < head)
left[l++] = arr[i];
else
right[r++] = arr[i];
}
sortAsc(left, l);
sortAsc(right, r);
int total_seek = 0, current = head;
printf("\nC-LOOK Sequence:\n%d ", current);
// Service the right side
for (int i = 0; i < r; i++) {
total_seek += abs(right[i] - current);
current = right[i];
printf("-> %d ", current);
}
// Jump to the leftmost request if any exist on the left
if (l > 0) {
total_seek += abs(current - left[0]);
current = left[0];
printf("-> %d ", current);
for (int i = 1; i < l; i++) {
total_seek += abs(left[i] - current);
current = left[i];
printf("-> %d ", current);
}
}
printf("\nTotal Seek Time: %d\n", total_seek);
}
int main() {
int choice, n, head, disk_size;
int arr[MAX];
printf("Menu:\n");
printf("1. SSTF\n");
printf("2. SCAN\n");
printf("3. C-SCAN\n");
printf("4. C-LOOK\n");
printf("Enter your choice: ");
scanf("%d", &choice);
printf("Enter number of requests: ");
scanf("%d", &n);
printf("Enter the request queue (space separated): ");
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
printf("Enter initial head position: ");
scanf("%d", &head);
if (ce == 2 || choice == 3) { // SCAN and C-SCAN require the disk size
printf("Enter disk size: ");
scanf("%d", &disk_size);
}
switch (choice) {
case 1:
sstf(arr, n, head);
break;
case 2:
scan(arr, n, head, disk_size);
break;
case 3:
cscan(arr, n, head, disk_size);
break;
case 4:
clook(arr, n, head);
break;
default:
printf("Invalid choice!\n");
}
return 0;
}

View file

@ -1,234 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
void sstf(int requests[], int n, int head) {
int total_seek = 0;
int completed = 0;
int visited[100] = {0};
int current = head;
printf("\nSSTF Disk Scheduling\n");
printf("Seek Sequence: %d", head);
while (completed < n) {
int min_distance = INT_MAX;
int min_index = -1;
for (int i = 0; i < n; i++) {
if (!visited[i]) {
int distance = abs(requests[i] - current);
if (distance < min_distance) {
min_distance = distance;
min_index = i;
}
}
}
visited[min_index] = 1;
current = requests[min_index];
total_seek += min_distance;
completed++;
printf(" -> %d", current);
}
printf("\nTotal Seek Time: %d\n", total_seek);
}
void scan(int requests[], int n, int head, int disk_size) {
int total_seek = 0;
int direction = 1; // 1 for moving right, 0 for moving left
int current = head;
printf("\nSCAN Disk Scheduling\n");
printf("Seek Sequence: %d", head);
// Sort requests
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (requests[j] > requests[j + 1]) {
int temp = requests[j];
requests[j] = requests[j + 1];
requests[j + 1] = temp;
}
}
}
// Find position of head in sorted array
int index;
for (index = 0; index < n; index++) {
if (requests[index] >= head)
break;
}
// Move right
for (int i = index; i < n; i++) {
current = requests[i];
printf(" -> %d", current);
total_seek += abs(current - head);
head = current;
}
// Move to the end of disk
printf(" -> %d", disk_size - 1);
total_seek += abs(disk_size - 1 - head);
head = disk_size - 1;
// Move left
for (int i = index - 1; i >= 0; i--) {
current = requests[i];
printf(" -> %d", current);
total_seek += abs(current - head);
head = current;
}
printf("\nTotal Seek Time: %d\n", total_seek);
}
void cscan(int requests[], int n, int head, int disk_size) {
int total_seek = 0;
int current = head;
printf("\nC-SCAN Disk Scheduling\n");
printf("Seek Sequence: %d", head);
// Sort requests
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (requests[j] > requests[j + 1]) {
int temp = requests[j];
requests[j] = requests[j + 1];
requests[j + 1] = temp;
}
}
}
// Find position of head in sorted array
int index;
for (index = 0; index < n; index++) {
if (requests[index] >= head)
break;
}
// Move right
for (int i = index; i < n; i++) {
current = requests[i];
printf(" -> %d", current);
total_seek += abs(current - head);
head = current;
}
// Move to the end of disk
printf(" -> %d", disk_size - 1);
total_seek += abs(disk_size - 1 - head);
// Move to the beginning
printf(" -> 0");
total_seek += disk_size - 1;
head = 0;
// Move right again
for (int i = 0; i < index; i++) {
current = requests[i];
printf(" -> %d", current);
total_seek += abs(current - head);
head = current;
}
printf("\nTotal Seek Time: %d\n", total_seek);
}
void clook(int requests[], int n, int head) {
int total_seek = 0;
int current = head;
printf("\nC-LOOK Disk Scheduling\n");
printf("Seek Sequence: %d", head);
// Sort requests
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (requests[j] > requests[j + 1]) {
int temp = requests[j];
requests[j] = requests[j + 1];
requests[j + 1] = temp;
}
}
}
// Find position of head in sorted array
int index;
for (index = 0; index < n; index++) {
if (requests[index] >= head)
break;
}
// Move right
for (int i = index; i < n; i++) {
current = requests[i];
printf(" -> %d", current);
total_seek += abs(current - head);
head = current;
}
// Move to first request
for (int i = 0; i < index; i++) {
current = requests[i];
printf(" -> %d", current);
total_seek += abs(current - head);
head = current;
}
printf("\nTotal Seek Time: %d\n", total_seek);
}
int main() {
int requests[100], n, head, disk_size, choice;
printf("Enter the number of disk requests: ");
scanf("%d", &n);
printf("Enter the disk requests: ");
for (int i = 0; i < n; i++) {
scanf("%d", &requests[i]);
}
printf("Enter the initial head position: ");
scanf("%d", &head);
printf("Enter the disk size (0 to size-1): ");
scanf("%d", &disk_size);
do {
printf("\n\nDisk Scheduling Algorithms\n");
printf("1. SSTF (Shortest Seek Time First)\n");
printf("2. SCAN\n");
printf("3. C-SCAN\n");
printf("4. C-LOOK\n");
printf("5. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
sstf(requests, n, head);
break;
case 2:
scan(requests, n, head, disk_size);
break;
case 3:
cscan(requests, n, head, disk_size);
break;
case 4:
clook(requests, n, head);
break;
case 5:
printf("Exiting program...\n");
break;
default:
printf("Invalid choice!\n");
}
} while (choice != 5);
return 0;
}

View file

View file

@ -1,153 +0,0 @@
#include <stdio.h>
// Define Task structure (simplified for memorization)
typedef struct {
int id; // Task ID
int period; // Period (also deadline for simplicity)
int execution_time; // Worst-case execution time (WCET)
// --- Simulation State ---
int remaining_execution; // Remaining execution time for current instance
int absolute_deadline; // Absolute deadline for current instance
int time_to_arrival; // Time until the next instance arrives/is released
} Task;
// --- Global Variables ---
// Define the tasks for the simulation (Example Set)
// Format: {id, Period, ExecutionTime, 0, 0, 0} <-- Initial state values
Task tasks[] = {
{1, 5, 2, 0, 0, 0}, // Task 1: Period=5, Exec Time=2
{2, 8, 3, 0, 0, 0} // Task 2: Period=8, Exec Time=3
// Add more tasks here if needed
};
// Calculate number of tasks automatically
int num_tasks = sizeof(tasks) / sizeof(Task);
// Set simulation duration (e.g., Hyperperiod or a fixed time)
// LCM(5, 8) = 40
int simulation_time = 40;
// --- Rate Monotonic (RM) Simulation ---
void simulate_rm() {
printf("--- Rate Monotonic Scheduling ---\n");
// Reset task states for the simulation run
for (int i = 0; i < num_tasks; i++) {
tasks[i].remaining_execution = 0;
tasks[i].absolute_deadline = 0;
tasks[i].time_to_arrival = 0; // All tasks start at time 0
}
// Main simulation loop
for (int time = 0; time < simulation_time; time++) {
// 1. Check for task arrivals (release time)
for (int i = 0; i < num_tasks; i++) {
if (tasks[i].time_to_arrival == 0) {
// Check if the previous instance of this task missed its deadline
if (tasks[i].remaining_execution > 0) {
printf("!!! Time %d: Task %d MISSED DEADLINE !!!\n", time, tasks[i].id);
// Simple handling: Continue with the new instance, old one is lost
}
// Release new instance of the task
tasks[i].remaining_execution = tasks[i].execution_time;
tasks[i].absolute_deadline = time + tasks[i].period; // Deadline = Period
tasks[i].time_to_arrival = tasks[i].period; // Set timer for the *next* arrival
}
tasks[i].time_to_arrival--; // Decrement time until the next arrival for all tasks
}
// 2. Select highest priority task to run (RM: Shortest Period has highest priority)
int task_to_run = -1; // -1 indicates CPU Idle
int highest_priority = 10000; // Initialize with a low priority (large period)
for (int i = 0; i < num_tasks; i++) {
// Check if task is ready (has arrived and needs execution)
if (tasks[i].remaining_execution > 0) {
// RM priority check: Lower period value means higher priority
if (tasks[i].period < highest_priority) {
highest_priority = tasks[i].period;
task_to_run = i; // Select this task
}
}
}
// 3. Execute the selected task (or remain idle)
if (task_to_run != -1) {
// Task selected to run
printf("Time %d: Task %d running\n", time, tasks[task_to_run].id);
tasks[task_to_run].remaining_execution--; // Execute for one time unit
// Optional: Check if task just finished
// if (tasks[task_to_run].remaining_execution == 0) {
// printf("Time %d: Task %d finished\n", time + 1, tasks[task_to_run].id);
// }
} else {
// No task ready to run
printf("Time %d: CPU Idle\n", time);
}
}
printf("--- RM Simulation Complete ---\n");
}
// --- Earliest Deadline First (EDF) Simulation ---
void simulate_edf() {
printf("\n--- Earliest Deadline First Scheduling ---\n");
// Reset task states
for (int i = 0; i < num_tasks; i++) {
tasks[i].remaining_execution = 0;
tasks[i].absolute_deadline = 0;
tasks[i].time_to_arrival = 0;
}
// Main simulation loop
for (int time = 0; time < simulation_time; time++) {
// 1. Check for task arrivals (same as RM)
for (int i = 0; i < num_tasks; i++) {
if (tasks[i].time_to_arrival == 0) {
if (tasks[i].remaining_execution > 0) {
printf("!!! Time %d: Task %d MISSED DEADLINE !!!\n", time, tasks[i].id);
}
tasks[i].remaining_execution = tasks[i].execution_time;
tasks[i].absolute_deadline = time + tasks[i].period;
tasks[i].time_to_arrival = tasks[i].period;
}
tasks[i].time_to_arrival--;
}
// 2. Select highest priority task to run (EDF: Earliest Absolute Deadline has highest priority)
int task_to_run = -1;
int earliest_deadline = 10000; // Initialize with a late deadline
for (int i = 0; i < num_tasks; i++) {
// Check if task is ready
if (tasks[i].remaining_execution > 0) {
// EDF priority check: Lower deadline value means higher priority (earlier deadline)
if (tasks[i].absolute_deadline < earliest_deadline) {
earliest_deadline = tasks[i].absolute_deadline;
task_to_run = i; // Select this task
}
}
}
// 3. Execute the selected task (same as RM)
if (task_to_run != -1) {
printf("Time %d: Task %d running\n", time, tasks[task_to_run].id);
tasks[task_to_run].remaining_execution--;
// Optional: Check finish
// if (tasks[task_to_run].remaining_execution == 0) {
// printf("Time %d: Task %d finished\n", time + 1, tasks[task_to_run].id);
// }
} else {
printf("Time %d: CPU Idle\n", time);
}
}
printf("--- EDF Simulation Complete ---\n");
}
// --- Main Function ---
int main() {
// Run Rate Monotonic simulation
simulate_rm();
// Run Earliest Deadline First simulation
simulate_edf();
return 0; // Indicate successful execution
}

View file

@ -1,10 +1,11 @@
{{REWRITTEN_CODE}}
#include <stdio.h>
// C program for Banker's Algorithm (Safety & Resource Request)
// C program for Banker's Algorithm (Safety & Resource Request Loop)
// Optimized for minimal code size (e.g., for writing on paper)
int main() {
int p, r, i, j, k, pid, req_pid = -1; // p=procs, r=res; req_pid: -1=initial, >=0 processing req
int p, r, i, j, k, pid, req_pid = -1; // req_pid: -1=initial/between reqs, >=0 processing req
printf("P R:"); scanf("%d%d", &p, &r); // Input num processes and resources
int av[r], max[p][r], al[p][r], nd[p][r], req[r]; // av=avail, al=alloc, nd=need
int w[r], fin[p], seq[p]; // w=work, fin=finish, seq=safe sequence
@ -40,38 +41,53 @@ S:; // Safety Check Algorithm Label
// --- End Safety Check ---
// Handle result based on phase (initial check or request check)
if(req_pid == -1) { // Phase 1: Initial State Check
if(safe) {
printf("SAFE. Seq:"); for(i=0; i<p; i++) printf(" P%d", seq[i]); puts("");
} else { puts("UNSAFE"); goto end; } // If unsafe initially, exit
// Phase 2: Resource Request
printf("PID Req:"); scanf("%d", &pid); req_pid = pid; // Get requesting proc ID
printf("Req:"); for(j=0; j<r; j++) scanf("%d", &req[j]); // Get request vector
// Check 1: Request <= Need
for(j=0; j<r; j++) if(req[j] > nd[pid][j]) { puts("Err:Req>Need"); goto end; }
// Check 2: Request <= Available
for(j=0; j<r; j++) if(req[j] > av[j]) { puts("Wait:Req>Avail"); goto end; }
// Tentatively allocate resources
for(j=0; j<r; j++) { av[j]-=req[j]; al[pid][j]+=req[j]; nd[pid][j]-=req[j]; }
puts("Checking req safety...");
goto S; // Re-run safety check on the new state
} else { // Phase 3: Post-Request Safety Check Result
if(safe) { // Request is granted if new state is safe
// --- Post-Safety Check Decision Logic ---
if (req_pid != -1) { // Phase 3: Result of a specific request check
if (safe) { // Request granted
printf("Req OK. Seq:"); for(i=0; i<p; i++) printf(" P%d", seq[i]); puts("");
} else { // Request denied if new state is unsafe
// State remains modified (available, alloc, need updated)
} else { // Request denied
puts("Req DENIED (unsafe)");
// Rollback state to before tentative allocation
pid = req_pid; // Restore pid for rollback
for(j=0; j<r; j++) { av[j]+=req[j]; al[pid][j]-=req[j]; nd[pid][j]+=req[j]; }
}
// No further action needed after handling the single request
req_pid = -1; // Reset for next request cycle
goto R; // Go ask for the next request or exit
} else { // Phase 1: Result of the initial state check
if (safe) {
printf("SAFE. Seq:"); for(i=0; i<p; i++) printf(" P%d", seq[i]); puts("");
// Initial state is safe, proceed to handle requests
} else {
puts("UNSAFE"); // Initial state unsafe, cannot proceed
goto end;
}
}
R:; // Phase 2: Resource Request Loop Label
printf("PID Req (-1 to exit):"); scanf("%d", &pid);
if (pid < 0) goto end; // Exit condition
// Basic check if PID is valid, can add pid >= p check if needed
if (pid >= p) { puts("Invalid PID."); goto R;}
printf("Req:"); for(j=0; j<r; j++) scanf("%d", &req[j]); // Get request vector
// Check 1: Request <= Need
int check_fail = 0;
for(j=0; j<r; j++) if(req[j] > nd[pid][j]) { check_fail = 1; break; }
if (check_fail) { puts("Err:Req>Need"); goto R; } // Ask for next request
// Check 2: Request <= Available
check_fail = 0;
for(j=0; j<r; j++) if(req[j] > av[j]) { check_fail = 1; break; }
if (check_fail) { puts("Wait:Req>Avail"); goto R; } // Ask for next request
// Tentatively allocate resources
for(j=0; j<r; j++) { av[j]-=req[j]; al[pid][j]+=req[j]; nd[pid][j]-=req[j]; }
req_pid = pid; // Set flag indicating we are checking this specific request
puts("Checking req safety...");
goto S; // Re-run safety check on the new tentative state
end: return 0; // End of program
}

View file

@ -1,81 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#define BLOCKS 4
#define REQUESTS 5
// Memory configuration
int memory[BLOCKS] = {100, 50, 25, 10};
int allocated[BLOCKS] = {0, 0, 0, 0};
// Helper: Reset allocation state
void resetAllocation() {
for(int i = 0; i < BLOCKS; i++) {
allocated[i] = 0;
}
}
// Print memory status
void printMemory() {
printf("\nMemory Status:\n");
for(int i = 0; i < BLOCKS; i++) {
printf("[Size: %d, %s] -> ", memory[i],
allocated[i] ? "Allocated" : "Free");
}
printf("NULL\n\n");
}
// First Fit allocation
void firstFit(int size) {
for(int i = 0; i < BLOCKS; i++) {
if (!allocated[i] && memory[i] >= size) {
allocated[i] = 1;
printf("Allocated %d bytes using First Fit\n", size);
return;
}
}
printf("First Fit: No suitable block found for %d bytes\n", size);
}
// Best Fit allocation
void bestFit(int size) {
int best = -1;
int bestSize = 999999;
for(int i = 0; i < BLOCKS; i++) {
if(!allocated[i] && memory[i] >= size && memory[i] < bestSize) {
bestSize = memory[i];
best = i;
}
}
if(best != -1) {
allocated[best] = 1;
printf("Allocated %d bytes using Best Fit\n", size);
} else {
printf("Best Fit: No suitable block found for %d bytes\n", size);
}
}
// Main function: run allocation sequence
int main() {
int requests[REQUESTS] = {15, 35, 60, 10, 5};
printf("=== FIRST FIT ===\n");
printMemory();
for(int i = 0; i < REQUESTS; i++) {
firstFit(requests[i]);
printMemory();
}
resetAllocation();
printf("=== BEST FIT ===\n");
printMemory();
for(int i = 0; i < REQUESTS; i++) {
bestFit(requests[i]);
printMemory();
}
return 0;
}

View file

@ -1,6 +1,8 @@
if [[ $# -lt 3 ]]; then
echo "Usage: $0 <filename1> <filename2>"
exit 1
read -p "Enter a number: " num
if [[ $num -gt 10 ]]; then
echo "Number is greater than 10"
elif [[ $num -eq 10 ]]; then
echo "Number is exactly 10"
else
echo "Number is less than 10"
fi
if

152
OS/C/theory/RTOS/edf-rms.c Normal file
View file

@ -0,0 +1,152 @@
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
// Define task structure
typedef struct {
int id;
int period;
int deadline;
int execution_time;
void (*task_function)(void);
int remaining_time;
} task_t;
// Define global variables
task_t tasks[3]; // Example with 3 tasks
int num_tasks = 3;
pthread_t task_threads[3];
sem_t scheduler_sem;
int current_time = 0;
// Task functions (example)
void task1_function() {
printf("Task 1 executing at time %d\n", current_time);
usleep(tasks[0].execution_time * 1000); // Simulate execution time
}
void task2_function() {
printf("Task 2 executing at time %d\n", current_time);
usleep(tasks[1].execution_time * 1000); // Simulate execution time
}
void task3_function() {
printf("Task 3 executing at time %d\n", current_time);
usleep(tasks[2].execution_time * 1000); // Simulate execution time
}
// EDF Scheduler
int edf_scheduler() {
int earliest_deadline = 100000; // Initialize with a large value
int earliest_task_index = -1;
for (int i = 0; i < num_tasks; i++) {
if (tasks[i].remaining_time > 0 && tasks[i].deadline < earliest_deadline) {
earliest_deadline = tasks[i].deadline;
earliest_task_index = i;
}
}
return earliest_task_index;
}
// Rate Monotonic Scheduler (RMS) - Simplified for Demonstration
int rms_scheduler() {
int shortest_period = 100000; // Initialize with a large value
int shortest_period_task_index = -1;
for (int i = 0; i < num_tasks; i++) {
if (tasks[i].remaining_time > 0 && tasks[i].period < shortest_period) {
shortest_period = tasks[i].period;
shortest_period_task_index = i;
}
}
return shortest_period_task_index;
}
// Task thread function
void *task_thread(void *arg) {
task_t *task = (task_t *)arg;
while (1) {
sem_wait(&scheduler_sem); // Wait for scheduler to release
if (task->remaining_time > 0) {
task->task_function();
task->remaining_time -= task->execution_time;
if (task->remaining_time <= 0) {
printf("Task %d completed at time %d\n", task->id, current_time);
}
}
}
pthread_exit(NULL);
}
int main() {
// Initialize tasks (EDF Example)
tasks[0].id = 1;
tasks[0].period = 50;
tasks[0].deadline = 50;
tasks[0].execution_time = 10;
tasks[0].task_function = task1_function;
tasks[0].remaining_time = tasks[0].execution_time;
tasks[1].id = 2;
tasks[1].period = 100;
tasks[1].deadline = 100;
tasks[1].execution_time = 15;
tasks[1].task_function = task2_function;
tasks[1].remaining_time = tasks[1].execution_time;
tasks[2].id = 3;
tasks[2].period = 200;
tasks[2].deadline = 200;
tasks[2].execution_time = 20;
tasks[2].task_function = task3_function;
tasks[2].remaining_time = tasks[2].execution_time;
// Initialize semaphore
sem_init(&scheduler_sem, 0, 0);
// Create task threads
for (int i = 0; i < num_tasks; i++) {
pthread_create(&task_threads[i], NULL, task_thread, &tasks[i]);
}
// RTOS Scheduler Loop
for (current_time = 0; current_time < 500; current_time++) {
// Choose scheduling algorithm (EDF or RMS)
int next_task_index = edf_scheduler(); // Use EDF
//int next_task_index = rms_scheduler(); // Or Use RMS
if (next_task_index != -1) {
sem_post(&scheduler_sem); // Release the semaphore to the selected task
}
usleep(1000); // Simulate 1ms time slice
// Update deadlines for EDF scheduler
for (int i = 0; i < num_tasks; i++) {
if (current_time % tasks[i].period == 0) {
tasks[i].deadline = current_time + tasks[i].period;
tasks[i].remaining_time = tasks[i].execution_time;
printf("Task %d released at time %d, deadline = %d\n", tasks[i].id, current_time, tasks[i].deadline);
}
}
}
// Clean up
for (int i = 0; i < num_tasks; i++) {
pthread_cancel(task_threads[i]);
}
sem_destroy(&scheduler_sem);
return 0;
}

View file

@ -1,46 +0,0 @@
#!/bin/bash
# Ask for the directory
echo "Enter directory path:"
read dir
while true; do
echo ""
echo "Menu:"
echo "1. Convert .txt files to .py in $dir"
echo "2. List ownership properties (ls -l) of all files in $dir"
echo "3. Count .sh files and subdirectories in $dir"
echo "4. Exit"
echo -n "Choose an option: "
read option
case $option in
1)
for file in "$dir"/*.txt; do
if [ -f "$file" ]; then
new="${file%.txt}.py"
mv "$file" "$new"
echo "Renamed: $file -> $new"
fi
done
;;
2)
ls -l "$dir"
;;
3)
sh_count=$(ls -1 "$dir"/*.sh 2>/dev/null | wc -l)
dir_count=$(ls -d "$dir"/*/ 2>/dev/null | wc -w)
echo ".sh file count: $sh_count"
echo "Subdirectory count: $dir_count"
;;
4)
echo "Exiting..."
break
;;
*)
echo "Invalid option. Please try again."
;;
esac
done
echo "Bye!"

View file

@ -1,121 +0,0 @@
#include <stdio.h>
#include <pthread.h>
#include <limits.h>
#define MAX_PROC 10
#define MAX_REF 100
#define MAX_FRAMES 10
typedef struct {
int id; // Process ID
int frames; // Number of frames for this process
int n; // Number of page references
int ref[MAX_REF]; // Array of page references
int faults; // Page faults counter
} Process;
Process procs[MAX_PROC];
int proc_count = 0;
void *simulateOptimal(void *arg) {
Process *p = (Process *)arg;
int frameArr[MAX_FRAMES];
int i, j;
// Initialize frames as empty (-1)
for (i = 0; i < p->frames; i++) {
frameArr[i] = -1;
}
p->faults = 0;
// Process each page reference
for (i = 0; i < p->n; i++) {
int page = p->ref[i];
int found = 0;
// Check if page is already in a frame
for (j = 0; j < p->frames; j++) {
if (frameArr[j] == page) {
found = 1;
break;
}
}
if (found)
continue;
// Page fault occurs
p->faults++;
// Look for an empty frame (-1)
int empty = -1;
for (j = 0; j < p->frames; j++) {
if (frameArr[j] == -1) {
empty = j;
break;
}
}
if (empty != -1) {
frameArr[empty] = page;
continue;
}
// No empty frame; choose a victim using Optimal algorithm:
int replace = 0, farthest = -1;
for (j = 0; j < p->frames; j++) {
int k, nextUse = INT_MAX;
for (k = i + 1; k < p->n; k++) {
if (frameArr[j] == p->ref[k]) {
nextUse = k;
break;
}
}
if (nextUse > farthest) {
farthest = nextUse;
replace = j;
}
}
frameArr[replace] = page;
}
printf("Process %d: Faults = %d\n", p->id, p->faults);
return NULL;
}
int main() {
int i, j;
pthread_t threads[MAX_PROC];
// Input the number of processes
printf("Enter number of processes (max %d): ", MAX_PROC);
scanf("%d", &proc_count);
if (proc_count > MAX_PROC) proc_count = MAX_PROC;
// Input process details
for (i = 0; i < proc_count; i++) {
procs[i].id = i + 1;
printf("\nProcess %d:\n", procs[i].id);
printf("Enter number of frames (max %d): ", MAX_FRAMES);
scanf("%d", &procs[i].frames);
if (procs[i].frames > MAX_FRAMES) procs[i].frames = MAX_FRAMES;
printf("Enter number of page references (max %d): ", MAX_REF);
scanf("%d", &procs[i].n);
if (procs[i].n > MAX_REF) procs[i].n = MAX_REF;
printf("Enter %d page references (space separated): ", procs[i].n);
for (j = 0; j < procs[i].n; j++) {
scanf("%d", &procs[i].ref[j]);
}
}
// Create a thread for each process simulation
for (i = 0; i < proc_count; i++) {
pthread_create(&threads[i], NULL, simulateOptimal, &procs[i]);
}
int totalFaults = 0;
// Wait for all threads to complete
for (i = 0; i < proc_count; i++) {
pthread_join(threads[i], NULL);
totalFaults += procs[i].faults;
}
// Calculate and display average faults
printf("\nAverage Page Faults: %.2f\n", (float)totalFaults / proc_count);
return 0;
}