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,38 +41,53 @@ 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
		Add a link
		
	
		Reference in a new issue