Compare commits
1 commit
main
...
s-branch-3
Author | SHA1 | Date | |
---|---|---|---|
6699115e40 |
2 changed files with 194 additions and 26 deletions
|
@ -1,10 +1,11 @@
|
||||||
|
{{REWRITTEN_CODE}}
|
||||||
#include <stdio.h>
|
#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)
|
// Optimized for minimal code size (e.g., for writing on paper)
|
||||||
|
|
||||||
int main() {
|
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
|
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 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
|
int w[r], fin[p], seq[p]; // w=work, fin=finish, seq=safe sequence
|
||||||
|
@ -40,37 +41,52 @@ S:; // Safety Check Algorithm Label
|
||||||
|
|
||||||
// --- End Safety Check ---
|
// --- End Safety Check ---
|
||||||
|
|
||||||
// Handle result based on phase (initial check or request check)
|
// --- Post-Safety Check Decision Logic ---
|
||||||
if(req_pid == -1) { // Phase 1: Initial State Check
|
if (req_pid != -1) { // Phase 3: Result of a specific request check
|
||||||
if(safe) {
|
if (safe) { // Request granted
|
||||||
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
|
|
||||||
printf("Req OK. Seq:"); for(i=0; i<p; i++) printf(" P%d", seq[i]); puts("");
|
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)");
|
puts("Req DENIED (unsafe)");
|
||||||
// Rollback state to before tentative allocation
|
// Rollback state to before tentative allocation
|
||||||
pid = req_pid; // Restore pid for rollback
|
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]; }
|
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
|
end: return 0; // End of program
|
||||||
}
|
}
|
||||||
|
|
152
OS/C/theory/RTOS/edf-rms.c
Normal file
152
OS/C/theory/RTOS/edf-rms.c
Normal 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;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue