Compare commits

..

No commits in common. "s-branch-3" and "main" have entirely different histories.

2 changed files with 26 additions and 194 deletions
OS/C
Week8
theory/RTOS

View file

@ -1,11 +1,10 @@
{{REWRITTEN_CODE}}
#include <stdio.h>
// C program for Banker's Algorithm (Safety & Resource Request Loop)
// C program for Banker's Algorithm (Safety & Resource Request)
// Optimized for minimal code size (e.g., for writing on paper)
int main() {
int p, r, i, j, k, pid, req_pid = -1; // req_pid: -1=initial/between reqs, >=0 processing req
int p, r, i, j, k, pid, req_pid = -1; // p=procs, r=res; req_pid: -1=initial, >=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
@ -41,53 +40,38 @@ S:; // Safety Check Algorithm Label
// --- End Safety Check ---
// --- Post-Safety Check Decision Logic ---
if (req_pid != -1) { // Phase 3: Result of a specific request check
if (safe) { // Request granted
// 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
printf("Req OK. Seq:"); for(i=0; i<p; i++) printf(" P%d", seq[i]); puts("");
// State remains modified (available, alloc, need updated)
} else { // Request denied
} else { // Request denied if new state is unsafe
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]; }
}
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;
}
// No further action needed after handling the single request
}
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,152 +0,0 @@
#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;
}