Compare commits
1 commit
main
...
s-branch-1
Author | SHA1 | Date | |
---|---|---|---|
644926a361 |
22 changed files with 52 additions and 2043 deletions
BIN
OS/C/Week10/aq1
BIN
OS/C/Week10/aq1
Binary file not shown.
|
@ -1,50 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Page Replacement: FIFO & Optimal (Minimal Code for Paper)
|
||||
int main() {
|
||||
int nf, np, i, j, k, pf, hit, idx, max_f, vic; // nf=frames, np=pages, pf=faults, idx=fifo_idx, max_f=max_future, vic=victim
|
||||
int *rs, *f; // rs=ref_string, f=frames
|
||||
|
||||
printf("F N:"); scanf("%d%d", &nf, &np); // Frames, NumPages
|
||||
rs = malloc(np * sizeof(int));
|
||||
f = malloc(nf * sizeof(int));
|
||||
if(!rs || !f) return 1; // Basic alloc check
|
||||
printf("RS:"); for(i=0; i<np; i++) scanf("%d", &rs[i]); // Ref String
|
||||
|
||||
// FIFO
|
||||
puts("FIFO"); pf=0; idx=0;
|
||||
for(k=0; k<nf; k++) f[k]=-1; // Init frames
|
||||
for(i=0; i<np; i++){ // Iterate ref string
|
||||
hit=0; for(k=0; k<nf; k++) if(f[k]==rs[i]) {hit=1; break;} // Check hit
|
||||
if(!hit){ // Page Fault
|
||||
pf++; f[idx]=rs[i]; idx=(idx+1)%nf; // Replace using FIFO index
|
||||
}
|
||||
}
|
||||
printf("F:%d\n", pf); // Print Faults
|
||||
|
||||
// Optimal
|
||||
puts("OPT"); pf=0;
|
||||
for(k=0; k<nf; k++) f[k]=-1; // Re-init frames
|
||||
for(i=0; i<np; i++){ // Iterate ref string
|
||||
hit=0; for(k=0; k<nf; k++) if(f[k]==rs[i]) {hit=1; break;} // Check hit
|
||||
if(!hit){ // Page Fault
|
||||
pf++; int empty=-1; for(k=0; k<nf; k++) if(f[k]==-1) {empty=k; break;} // Find empty frame
|
||||
if(empty!=-1) f[empty]=rs[i]; // Use empty frame if available
|
||||
else { // No empty frames, find victim
|
||||
vic=0; max_f=-1; // Victim index, max future distance
|
||||
for(k=0; k<nf; k++){ // Check each current frame 'f[k]'
|
||||
int fut=-1; // Index of next use for f[k]
|
||||
for(j=i+1; j<np; j++) if(f[k]==rs[j]) {fut=j; break;} // Look ahead
|
||||
if(fut==-1) {vic=k; break;} // f[k] not used again? Best victim. Stop search.
|
||||
if(fut>max_f) {max_f=fut; vic=k;} // f[k] used later than current max? Update victim.
|
||||
}
|
||||
f[vic]=rs[i]; // Replace victim frame
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("F:%d\n", pf); // Print Faults
|
||||
|
||||
free(rs); free(f); // Free memory
|
||||
return 0;
|
||||
}
|
BIN
OS/C/Week10/aq2
BIN
OS/C/Week10/aq2
Binary file not shown.
|
@ -1,78 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h> // For malloc, free
|
||||
|
||||
// C program for LRU Page Replacement Simulation
|
||||
// Optimized for minimal code size (e.g., for writing on paper)
|
||||
|
||||
int main() {
|
||||
int nf, np, i, j, pg, idx, lru, pf = 0, time = 0, min_t;
|
||||
// nf=num frames, np=num pages, pf=page faults, time=logical clock
|
||||
// idx=found index, lru=least recently used index, pg=current page
|
||||
|
||||
// Input frame count (nf) and page reference string length (np)
|
||||
printf("Frames Pages:"); scanf("%d%d", &nf, &np);
|
||||
|
||||
// Dynamic Allocation
|
||||
int *f = malloc(nf * sizeof(int)); // f: frames array
|
||||
int *c = malloc(nf * sizeof(int)); // c: counter/lru time array
|
||||
int *p = malloc(np * sizeof(int)); // p: page reference string array
|
||||
|
||||
// Input page reference string
|
||||
printf("Pages:");
|
||||
for(i=0; i<np; ) scanf("%d", p+i++); // Read pages into p
|
||||
|
||||
// Initialize frames to -1 (empty)
|
||||
for(i=0; i<nf; i++) f[i]=-1; // Can also use for(i=nf;i--;)f[i]=-1;
|
||||
|
||||
// --- LRU Algorithm ---
|
||||
for(i=0; i<np; i++) { // Iterate through page reference string
|
||||
pg = p[i]; // Current page
|
||||
idx = -1; // Reset found index
|
||||
|
||||
// 1. Search if page 'pg' is already in frames 'f'
|
||||
for(j=0; j<nf; j++) {
|
||||
if(f[j] == pg) {
|
||||
idx = j; // Page found at index j
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(idx != -1) { // 2a. Page Hit
|
||||
c[idx] = ++time; // Update last used time for the hit page
|
||||
} else { // 2b. Page Fault
|
||||
pf++; // Increment page fault counter
|
||||
lru = 0; // Index to replace (default to 0)
|
||||
min_t = 0x7FFFFFFF; // Initialize minimum time to max int
|
||||
|
||||
// 3. Find replacement slot: first empty (-1) or LRU
|
||||
for(j=0; j<nf; j++) {
|
||||
if(f[j] == -1) { // Found an empty frame
|
||||
lru = j;
|
||||
break; // Use the first empty frame
|
||||
}
|
||||
if(c[j] < min_t) { // Track frame with the smallest time (LRU)
|
||||
min_t = c[j];
|
||||
lru = j;
|
||||
}
|
||||
}
|
||||
// 'lru' now holds index of empty slot or the least recently used page
|
||||
|
||||
// 4. Replace frame and update its time
|
||||
f[lru] = pg;
|
||||
c[lru] = ++time;
|
||||
}
|
||||
// Optional: print frame state after each step (for debugging)
|
||||
// printf(" (%d):",pg); for(j=0; j<nf; j++)printf(" %d", f[j]==-1?-1:f[j]); puts("");
|
||||
}
|
||||
// --- End Algorithm ---
|
||||
|
||||
// Output total page faults
|
||||
printf("Faults: %d\n", pf);
|
||||
|
||||
// Free dynamically allocated memory
|
||||
free(f);
|
||||
free(c);
|
||||
free(p);
|
||||
|
||||
return 0; // End of program
|
||||
}
|
198
OS/C/Week10/q1.c
198
OS/C/Week10/q1.c
|
@ -1,198 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h> // For INT_MAX in optimal
|
||||
|
||||
// Function to check if a page is present in frames
|
||||
int isPresent(int page, int *frames, int num_frames) {
|
||||
for (int i = 0; i < num_frames; i++) {
|
||||
if (frames[i] == page) {
|
||||
return 1; // Present
|
||||
}
|
||||
}
|
||||
return 0; // Not present
|
||||
}
|
||||
|
||||
// Function to print the current state of frames (for debugging/visualization)
|
||||
void printFrames(int *frames, int num_frames) {
|
||||
printf("Frames: ");
|
||||
for (int i = 0; i < num_frames; i++) {
|
||||
if (frames[i] == -1) {
|
||||
printf("[ ] ");
|
||||
} else {
|
||||
printf("[%d] ", frames[i]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// FIFO Page Replacement Simulation
|
||||
int simulateFIFO(int *ref_string, int num_refs, int num_frames) {
|
||||
int *frames = (int *)malloc(num_frames * sizeof(int));
|
||||
if (frames == NULL) {
|
||||
perror("Failed to allocate memory for frames");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (int i = 0; i < num_frames; i++) {
|
||||
frames[i] = -1; // Initialize frames as empty (-1 indicates empty)
|
||||
}
|
||||
|
||||
int page_faults = 0;
|
||||
int frame_index = 0; // Points to the next frame to be replaced (FIFO queue head)
|
||||
|
||||
printf("\n--- FIFO Simulation ---\n");
|
||||
for (int i = 0; i < num_refs; i++) {
|
||||
int current_page = ref_string[i];
|
||||
printf("Ref: %d -> ", current_page);
|
||||
|
||||
if (!isPresent(current_page, frames, num_frames)) {
|
||||
page_faults++;
|
||||
frames[frame_index] = current_page;
|
||||
frame_index = (frame_index + 1) % num_frames; // Move to next frame in circular fashion
|
||||
printf("Fault! ");
|
||||
printFrames(frames, num_frames);
|
||||
} else {
|
||||
printf("Hit. ");
|
||||
printFrames(frames, num_frames);
|
||||
}
|
||||
}
|
||||
|
||||
free(frames);
|
||||
return page_faults;
|
||||
}
|
||||
|
||||
// Function to find the optimal page to replace
|
||||
int findOptimalVictim(int *frames, int num_frames, int *ref_string, int num_refs, int current_index) {
|
||||
int victim_frame = -1;
|
||||
int farthest_use = -1; // Index of the farthest future use
|
||||
|
||||
for (int i = 0; i < num_frames; i++) {
|
||||
int page_in_frame = frames[i];
|
||||
int next_use = INT_MAX; // Assume page is never used again initially
|
||||
|
||||
// Look for the next occurrence of this page in the reference string
|
||||
for (int j = current_index + 1; j < num_refs; j++) {
|
||||
if (ref_string[j] == page_in_frame) {
|
||||
next_use = j;
|
||||
break; // Found the *next* use
|
||||
}
|
||||
}
|
||||
|
||||
// If this page is never used again, it's the best victim
|
||||
if (next_use == INT_MAX) {
|
||||
return i; // Return the index of the frame holding this page
|
||||
}
|
||||
|
||||
// Otherwise, track the page whose next use is farthest away
|
||||
if (next_use > farthest_use) {
|
||||
farthest_use = next_use;
|
||||
victim_frame = i; // This frame holds the current best candidate for victim
|
||||
}
|
||||
}
|
||||
// Should always find a victim if frames are full, defaults to first if logic error/all used soon
|
||||
return (victim_frame == -1) ? 0 : victim_frame;
|
||||
}
|
||||
|
||||
|
||||
// Optimal Page Replacement Simulation
|
||||
int simulateOptimal(int *ref_string, int num_refs, int num_frames) {
|
||||
int *frames = (int *)malloc(num_frames * sizeof(int));
|
||||
if (frames == NULL) {
|
||||
perror("Failed to allocate memory for frames");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (int i = 0; i < num_frames; i++) {
|
||||
frames[i] = -1; // Initialize frames as empty
|
||||
}
|
||||
|
||||
int page_faults = 0;
|
||||
int current_frame_count = 0;
|
||||
|
||||
printf("\n--- Optimal Simulation ---\n");
|
||||
for (int i = 0; i < num_refs; i++) {
|
||||
int current_page = ref_string[i];
|
||||
printf("Ref: %d -> ", current_page);
|
||||
|
||||
if (!isPresent(current_page, frames, num_frames)) {
|
||||
page_faults++;
|
||||
printf("Fault! ");
|
||||
|
||||
// Check if there are empty frames first
|
||||
if (current_frame_count < num_frames) {
|
||||
frames[current_frame_count] = current_page;
|
||||
current_frame_count++;
|
||||
} else {
|
||||
// Frames are full, need to find the optimal victim
|
||||
int victim_index = findOptimalVictim(frames, num_frames, ref_string, num_refs, i);
|
||||
frames[victim_index] = current_page; // Replace victim
|
||||
}
|
||||
printFrames(frames, num_frames);
|
||||
} else {
|
||||
printf("Hit. ");
|
||||
printFrames(frames, num_frames);
|
||||
}
|
||||
}
|
||||
|
||||
free(frames);
|
||||
return page_faults;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
int num_frames;
|
||||
int num_refs;
|
||||
int *ref_string;
|
||||
|
||||
// Get number of frames
|
||||
printf("Enter the number of page frames: ");
|
||||
scanf("%d", &num_frames);
|
||||
if (num_frames <= 0) {
|
||||
printf("Number of frames must be positive.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get number of page references
|
||||
printf("Enter the number of page references in the sequence: ");
|
||||
scanf("%d", &num_refs);
|
||||
if (num_refs <= 0) {
|
||||
printf("Number of references must be positive.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Allocate memory for reference string
|
||||
ref_string = (int *)malloc(num_refs * sizeof(int));
|
||||
if (ref_string == NULL) {
|
||||
perror("Failed to allocate memory for reference string");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the reference string
|
||||
printf("Enter the page reference sequence (e.g., 7 0 1 2 0 ...):\n");
|
||||
for (int i = 0; i < num_refs; i++) {
|
||||
if (scanf("%d", &ref_string[i]) != 1) {
|
||||
printf("Invalid input for reference sequence.\n");
|
||||
free(ref_string);
|
||||
return 1;
|
||||
}
|
||||
if (ref_string[i] < 0) {
|
||||
printf("Page numbers cannot be negative.\n");
|
||||
free(ref_string);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Run Simulations ---
|
||||
int fifo_faults = simulateFIFO(ref_string, num_refs, num_frames);
|
||||
int optimal_faults = simulateOptimal(ref_string, num_refs, num_frames);
|
||||
|
||||
// --- Print Results ---
|
||||
printf("\n--- Results ---\n");
|
||||
printf("Reference String Length: %d\n", num_refs);
|
||||
printf("Number of Frames: %d\n", num_frames);
|
||||
printf("FIFO Page Faults: %d\n", fifo_faults);
|
||||
printf("Optimal Page Faults: %d\n", optimal_faults);
|
||||
|
||||
// --- Cleanup ---
|
||||
free(ref_string);
|
||||
|
||||
return 0;
|
||||
}
|
169
OS/C/Week10/q2.c
169
OS/C/Week10/q2.c
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
201
OS/C/Week11/q1.c
201
OS/C/Week11/q1.c
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
BIN
OS/C/Week7/q2
BIN
OS/C/Week7/q2
Binary file not shown.
|
@ -6,100 +6,106 @@
|
|||
#include <semaphore.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define NR 3 // NUM_READERS
|
||||
#define NW 2 // NUM_WRITERS
|
||||
#define NUM_READERS 3
|
||||
#define NUM_WRITERS 2
|
||||
|
||||
// shared data structure - simple integer
|
||||
int sd = 0; // shared_data
|
||||
int shared_data = 0;
|
||||
|
||||
// sync variables
|
||||
pthread_mutex_t m; // mutex for rc protection
|
||||
sem_t w; // semaphore for writer access control
|
||||
int rc = 0; // read_count: tracks active readers
|
||||
pthread_mutex_t mutex; // mutex for read_count protection
|
||||
sem_t wrt; // semaphore for writer access control
|
||||
int read_count = 0; // tracks active readers
|
||||
|
||||
void* r(void* arg) { // reader
|
||||
void* reader(void* arg) {
|
||||
int id = *((int*)arg);
|
||||
while (1) {
|
||||
// read delay sim
|
||||
sleep(1);
|
||||
|
||||
// critical section entry
|
||||
pthread_mutex_lock(&m);
|
||||
rc++;
|
||||
if (rc == 1) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
read_count++;
|
||||
if (read_count == 1) {
|
||||
// first reader blocks writers
|
||||
sem_wait(&w);
|
||||
sem_wait(&wrt);
|
||||
}
|
||||
pthread_mutex_unlock(&m);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
// critical section
|
||||
printf("Reader %d is reading sd = %d\n", id, sd);
|
||||
printf("Reader %d is reading shared_data = %d\n", id, shared_data);
|
||||
sleep(2); // read time sim
|
||||
|
||||
// critical section exit
|
||||
pthread_mutex_lock(&m);
|
||||
rc--;
|
||||
if (rc == 0) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
read_count--;
|
||||
if (read_count == 0) {
|
||||
// last reader unblocks writers
|
||||
sem_post(&w);
|
||||
sem_post(&wrt);
|
||||
}
|
||||
pthread_mutex_unlock(&m);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void* w_func(void* arg) { // writer
|
||||
void* writer(void* arg) {
|
||||
int id = *((int*)arg);
|
||||
while (1) {
|
||||
// write delay sim
|
||||
sleep(3);
|
||||
|
||||
// critical section entry
|
||||
sem_wait(&w); // exclusive access control
|
||||
sem_wait(&wrt); // exclusive access control
|
||||
|
||||
// critical section
|
||||
sd++; // shared_data modification
|
||||
printf("Writer %d is writing: sd becomes %d\n", id, sd);
|
||||
shared_data += 1;
|
||||
printf("Writer %d is writing: shared_data becomes %d\n", id, shared_data);
|
||||
sleep(2); // write time sim
|
||||
|
||||
// critical section exit
|
||||
sem_post(&w);
|
||||
sem_post(&wrt);
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
pthread_t rts[NR], wts[NW]; // reader/writer threads
|
||||
int rids[NR], wids[NW]; // reader/writer ids
|
||||
pthread_t readers[NUM_READERS], writers[NUM_WRITERS];
|
||||
int reader_ids[NUM_READERS], writer_ids[NUM_WRITERS];
|
||||
int i;
|
||||
|
||||
// sync init
|
||||
pthread_mutex_init(&m, NULL);
|
||||
sem_init(&w, 0, 1); // binary semaphore init
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
sem_init(&wrt, 0, 1); // binary semaphore init
|
||||
|
||||
// reader thread creation
|
||||
for (i = 0; i < NR; i++) {
|
||||
rids[i] = i + 1;
|
||||
pthread_create(&rts[i], NULL, r, &rids[i]);
|
||||
for (i = 0; i < NUM_READERS; i++) {
|
||||
reader_ids[i] = i + 1;
|
||||
if (pthread_create(&readers[i], NULL, reader, &reader_ids[i]) != 0) {
|
||||
perror("Failed to create reader thread");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
// writer thread creation
|
||||
for (i = 0; i < NW; i++) {
|
||||
wids[i] = i + 1;
|
||||
pthread_create(&wts[i], NULL, w_func, &wids[i]);
|
||||
for (i = 0; i < NUM_WRITERS; i++) {
|
||||
writer_ids[i] = i + 1;
|
||||
if (pthread_create(&writers[i], NULL, writer, &writer_ids[i]) != 0) {
|
||||
perror("Failed to create writer thread");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
// thread joining
|
||||
for (i = 0; i < NR; i++) {
|
||||
pthread_join(rts[i], NULL);
|
||||
for (i = 0; i < NUM_READERS; i++) {
|
||||
pthread_join(readers[i], NULL);
|
||||
}
|
||||
for (i = 0; i < NW; i++) {
|
||||
pthread_join(wts[i], NULL);
|
||||
for (i = 0; i < NUM_WRITERS; i++) {
|
||||
pthread_join(writers[i], NULL);
|
||||
}
|
||||
|
||||
// cleanup
|
||||
pthread_mutex_destroy(&m);
|
||||
sem_destroy(&w);
|
||||
pthread_mutex_destroy(&mutex);
|
||||
sem_destroy(&wrt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
BIN
OS/C/Week8/aq1
BIN
OS/C/Week8/aq1
Binary file not shown.
|
@ -1,95 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
// 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; // 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
|
||||
|
||||
// Input available, max, allocation matrices
|
||||
printf("Av:"); for(j=0; j<r; j++) scanf("%d", &av[j]);
|
||||
printf("Max:\n"); for(i=0; i<p; i++) for(j=0; j<r; j++) scanf("%d", &max[i][j]);
|
||||
printf("Alloc:\n"); for(i=0; i<p; i++) for(j=0; j<r; j++) scanf("%d", &al[i][j]);
|
||||
|
||||
// Calculate need matrix: need = max - alloc
|
||||
for(i=0; i<p; i++) for(j=0; j<r; j++) nd[i][j] = max[i][j] - al[i][j];
|
||||
|
||||
S:; // Safety Check Algorithm Label
|
||||
int s_idx = 0, c = 0, safe = 0; // s_idx=seq index, c=count finished, safe=flag
|
||||
for(j=0; j<r; j++) w[j] = av[j]; // work = avail
|
||||
for(i=0; i<p; i++) fin[i] = 0; // finish[p] = {false}
|
||||
// Find sequence using safety algorithm logic
|
||||
while(c < p) { // Loop until all processes are finished or deadlock
|
||||
int found = 0; // Flag to check if a process was found in this pass
|
||||
for(i=0; i<p; i++) { // Iterate through processes
|
||||
if(!fin[i]) { // If process i not finished
|
||||
int possible = 1; // Check if need <= work
|
||||
for(j=0; j<r; j++) if(nd[i][j] > w[j]) { possible = 0; break; }
|
||||
if(possible) { // If need <= work
|
||||
for(k=0; k<r; k++) w[k] += al[i][k]; // work = work + alloc
|
||||
fin[i] = 1; seq[s_idx++] = i; c++; found = 1; // Mark finished, add to seq
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!found) break; // If no process found in a full pass, break (unsafe state)
|
||||
}
|
||||
if(c == p) safe = 1; // If all processes finished, state is safe
|
||||
|
||||
// --- 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
|
||||
printf("Req OK. Seq:"); for(i=0; i<p; i++) printf(" P%d", seq[i]); puts("");
|
||||
} 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]; }
|
||||
}
|
||||
// No further action needed after handling the single request
|
||||
}
|
||||
|
||||
end: return 0; // End of program
|
||||
}
|
||||
|
||||
/*
|
||||
```
|
||||
P R: 5 3
|
||||
Av: 3 3 2
|
||||
Max:
|
||||
7 5 3
|
||||
3 2 2
|
||||
9 0 2
|
||||
2 2 2
|
||||
4 3 3
|
||||
Alloc:
|
||||
0 1 0
|
||||
2 0 0
|
||||
3 0 2
|
||||
2 1 1
|
||||
0 0 2
|
||||
```
|
||||
*/
|
BIN
OS/C/Week9/aq1
BIN
OS/C/Week9/aq1
Binary file not shown.
125
OS/C/Week9/aq1.c
125
OS/C/Week9/aq1.c
|
@ -1,125 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Dynamic Storage Allocation: First Fit & Best Fit
|
||||
// Optimized for minimal code size (e.g., for writing on paper)
|
||||
|
||||
// Block structure: s=start, z=size, p=process_id (0 if free)
|
||||
struct B {int s, z, p;} *b;
|
||||
int nb = 0, cap = 4, mem_sz; // num_blocks, capacity, total_memory_size
|
||||
|
||||
// insb: insert block at index idx, maintain order by start address 's'
|
||||
void insb(int idx, int s, int z, int p) {
|
||||
if (nb >= cap) {
|
||||
cap *= 2;
|
||||
b = realloc(b, cap * sizeof(struct B));
|
||||
// Note: Real-world code checks realloc failure. Skipped for brevity.
|
||||
}
|
||||
for (int k = nb; k > idx; k--) b[k] = b[k-1]; // Shift right
|
||||
b[idx] = (struct B){s, z, p};
|
||||
nb++;
|
||||
}
|
||||
|
||||
// rmb: remove block at index idx
|
||||
void rmb(int idx) {
|
||||
for (int k = idx; k < nb - 1; k++) b[k] = b[k+1]; // Shift left
|
||||
nb--;
|
||||
}
|
||||
|
||||
// pb: print current blocks state
|
||||
void pb() {
|
||||
printf("Mem:[");
|
||||
// Print each block: start:size! (allocated) or start:size (free)
|
||||
for(int i=0; i<nb; i++) printf(" %d:%d%s", b[i].s, b[i].z, b[i].p ? "!" : "");
|
||||
printf(" ]\n");
|
||||
}
|
||||
|
||||
// ff: First Fit allocation
|
||||
void ff(int pid, int sz) {
|
||||
int f = -1; // found index
|
||||
for (int i = 0; i < nb; i++) { // Find first free block large enough
|
||||
if (!b[i].p && b[i].z >= sz) { f = i; break; }
|
||||
}
|
||||
if (f != -1) { // Block found
|
||||
if (b[f].z > sz) { // Need to split block
|
||||
// Insert new free block for the remainder after the allocated part
|
||||
insb(f + 1, b[f].s + sz, b[f].z - sz, 0);
|
||||
b[f].z = sz; // Adjust size of the now-allocated block
|
||||
}
|
||||
b[f].p = pid; // Mark block as allocated to pid
|
||||
printf("FF OK P%d->%d@%d\n", pid, sz, b[f].s);
|
||||
} else printf("FF Fail P%d(%d)\n", pid, sz); // Allocation failed
|
||||
pb(); // Show memory state
|
||||
}
|
||||
|
||||
// bf: Best Fit allocation
|
||||
void bf(int pid, int sz) {
|
||||
int bi = -1, min_z = mem_sz + 1; // best_index, min_suitable_size
|
||||
for (int i = 0; i < nb; i++) { // Find smallest free block large enough
|
||||
if (!b[i].p && b[i].z >= sz && b[i].z < min_z) {
|
||||
min_z = b[i].z; // Update best size found
|
||||
bi = i; // Update best index found
|
||||
}
|
||||
}
|
||||
if (bi != -1) { // Best fit block found
|
||||
if (b[bi].z > sz) { // Need to split block
|
||||
// Insert new free block for the remainder
|
||||
insb(bi + 1, b[bi].s + sz, b[bi].z - sz, 0);
|
||||
b[bi].z = sz; // Adjust size of the allocated block
|
||||
}
|
||||
b[bi].p = pid; // Mark block allocated
|
||||
printf("BF OK P%d->%d@%d\n", pid, sz, b[bi].s);
|
||||
} else printf("BF Fail P%d(%d)\n", pid, sz); // Allocation failed
|
||||
pb(); // Show memory state
|
||||
}
|
||||
|
||||
// de: Deallocate block associated with pid
|
||||
void de(int pid) {
|
||||
int f = -1; // found index
|
||||
for (int i = 0; i < nb; i++) if (b[i].p == pid) { f = i; break; } // Find block by pid
|
||||
|
||||
if (f != -1) { // Block found
|
||||
printf("De OK P%d@%d(%d)\n", pid, b[f].s, b[f].z);
|
||||
b[f].p = 0; // Mark block as free
|
||||
|
||||
// Try merging with the *next* block if it exists and is free
|
||||
if (f + 1 < nb && !b[f+1].p) {
|
||||
b[f].z += b[f+1].z; // Absorb next block's size
|
||||
rmb(f + 1); // Remove the next block entry
|
||||
}
|
||||
// Try merging with the *previous* block if it exists and is free
|
||||
if (f > 0 && !b[f-1].p) {
|
||||
b[f-1].z += b[f].z; // Add current block's size to previous
|
||||
rmb(f); // Remove the current block entry (now merged)
|
||||
// f = f-1; // If index 'f' were needed after merge, adjust it
|
||||
}
|
||||
pb(); // Show memory state
|
||||
} else printf("De Fail P%d\n", pid); // Deallocation failed (pid not found)
|
||||
}
|
||||
|
||||
// Main driver loop
|
||||
int main() {
|
||||
printf("MemSz:"); scanf("%d", &mem_sz); // Get total memory size
|
||||
b = malloc(cap * sizeof(struct B)); // Allocate initial block array
|
||||
if (!b) return 1; // Handle malloc failure
|
||||
b[0] = (struct B){0, mem_sz, 0}; // Create the first block (all memory, free)
|
||||
nb = 1;
|
||||
pb(); // Show initial state
|
||||
|
||||
int choice, pid, sz;
|
||||
printf("1:FF 2:BF 3:Dealloc 0:Exit\n");
|
||||
// Loop until user enters 0
|
||||
while(scanf("%d", &choice) == 1 && choice) {
|
||||
if (choice == 1 || choice == 2) { // Allocate request
|
||||
printf("PID Sz:"); scanf("%d%d", &pid, &sz);
|
||||
if (choice == 1) ff(pid, sz); else bf(pid, sz);
|
||||
} else if (choice == 3) { // Deallocate request
|
||||
printf("PID:"); scanf("%d", &pid);
|
||||
de(pid);
|
||||
} else printf("?\n"); // Invalid choice
|
||||
printf("1:FF 2:BF 3:Dealloc 0:Exit\n"); // Prompt again
|
||||
}
|
||||
|
||||
free(b); // Free the block array memory
|
||||
return 0;
|
||||
}
|
|
@ -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;
|
||||
}
|
272
OS/C/Week9/q1.c
272
OS/C/Week9/q1.c
|
@ -1,272 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h> // For INT_MAX
|
||||
|
||||
// Structure for a memory block
|
||||
typedef struct Block {
|
||||
int id; // Block ID (optional, can use address for uniqueness)
|
||||
int size; // Size of the block
|
||||
int allocated; // 0 if free, 1 if allocated
|
||||
int process_id; // ID of process allocated to this block (-1 if free)
|
||||
struct Block *next; // Pointer to the next block in the list
|
||||
struct Block *prev; // Pointer to the previous block in the list (for potential merging)
|
||||
} Block;
|
||||
|
||||
// Global head of the memory block linked list
|
||||
Block *memory_head = NULL;
|
||||
|
||||
// Function to create a new block node
|
||||
Block* create_block(int id, int size, int allocated, int process_id) {
|
||||
Block *new_block = (Block*)malloc(sizeof(Block));
|
||||
if (!new_block) {
|
||||
perror("Failed to allocate memory for block");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
new_block->id = id;
|
||||
new_block->size = size;
|
||||
new_block->allocated = allocated;
|
||||
new_block->process_id = process_id;
|
||||
new_block->next = NULL;
|
||||
new_block->prev = NULL;
|
||||
return new_block;
|
||||
}
|
||||
|
||||
// Function to initialize the memory list with one large free block
|
||||
void initialize_memory(int total_size) {
|
||||
if (memory_head != NULL) {
|
||||
// Simple cleanup for re-initialization (more robust needed for general use)
|
||||
Block *current = memory_head;
|
||||
Block *next_node;
|
||||
while(current != NULL) {
|
||||
next_node = current->next;
|
||||
free(current);
|
||||
current = next_node;
|
||||
}
|
||||
memory_head = NULL; // Reset head
|
||||
}
|
||||
memory_head = create_block(0, total_size, 0, -1); // ID 0, size, free, no process
|
||||
}
|
||||
|
||||
// Function to display the current state of memory blocks
|
||||
void display_memory() {
|
||||
Block *current = memory_head;
|
||||
printf("Memory Blocks:\n");
|
||||
printf("----------------------------------------------------\n");
|
||||
printf("| ID | Size | Status | Process ID |\n");
|
||||
printf("----------------------------------------------------\n");
|
||||
while (current != NULL) {
|
||||
printf("| %-2d | %-9d | %-9s | %-10d |\n",
|
||||
current->id,
|
||||
current->size,
|
||||
current->allocated ? "Allocated" : "Free",
|
||||
current->allocated ? current->process_id : -1);
|
||||
current = current->next;
|
||||
}
|
||||
printf("----------------------------------------------------\n\n");
|
||||
}
|
||||
|
||||
// Function to allocate memory using First Fit strategy
|
||||
int allocate_first_fit(int process_id, int required_size) {
|
||||
Block *current = memory_head;
|
||||
Block *best_block = NULL;
|
||||
|
||||
// Find the first free block that is large enough
|
||||
while (current != NULL) {
|
||||
if (!current->allocated && current->size >= required_size) {
|
||||
best_block = current;
|
||||
break; // First fit found
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
// If a suitable block is found
|
||||
if (best_block != NULL) {
|
||||
// Check if splitting is necessary (and worthwhile, e.g., remaining > 0)
|
||||
if (best_block->size > required_size) {
|
||||
// Create a new block for the remaining free space
|
||||
int remaining_size = best_block->size - required_size;
|
||||
// For simplicity, assigning next available ID - needs better management in real system
|
||||
int new_block_id = best_block->id + 1; // simplistic ID assignment
|
||||
Block *new_free_block = create_block(new_block_id, remaining_size, 0, -1);
|
||||
|
||||
// Update the allocated block
|
||||
best_block->size = required_size;
|
||||
best_block->allocated = 1;
|
||||
best_block->process_id = process_id;
|
||||
|
||||
// Insert the new free block into the list
|
||||
new_free_block->next = best_block->next;
|
||||
new_free_block->prev = best_block;
|
||||
if (best_block->next != NULL) {
|
||||
best_block->next->prev = new_free_block;
|
||||
}
|
||||
best_block->next = new_free_block;
|
||||
|
||||
// Renumber subsequent block IDs (basic approach)
|
||||
Block* temp = new_free_block->next;
|
||||
int current_id = new_block_id + 1;
|
||||
while (temp != NULL) {
|
||||
temp->id = current_id++;
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
} else { // Exact fit or minimal leftover space (allocate the whole block)
|
||||
best_block->allocated = 1;
|
||||
best_block->process_id = process_id;
|
||||
}
|
||||
printf("Process %d allocated %d units using First Fit in Block %d.\n", process_id, required_size, best_block->id);
|
||||
return 1; // Allocation successful
|
||||
} else {
|
||||
printf("Process %d (size %d) could not be allocated using First Fit.\n", process_id, required_size);
|
||||
return 0; // Allocation failed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Function to allocate memory using Best Fit strategy
|
||||
int allocate_best_fit(int process_id, int required_size) {
|
||||
Block *current = memory_head;
|
||||
Block *best_block = NULL;
|
||||
int min_waste = INT_MAX;
|
||||
|
||||
// Find the smallest free block that is large enough
|
||||
while (current != NULL) {
|
||||
if (!current->allocated && current->size >= required_size) {
|
||||
int waste = current->size - required_size;
|
||||
if (waste < min_waste) {
|
||||
min_waste = waste;
|
||||
best_block = current;
|
||||
}
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
// If a suitable block is found
|
||||
if (best_block != NULL) {
|
||||
// Check if splitting is necessary (and worthwhile, e.g., remaining > 0)
|
||||
if (best_block->size > required_size) {
|
||||
// Create a new block for the remaining free space
|
||||
int remaining_size = best_block->size - required_size;
|
||||
int new_block_id = best_block->id + 1; // simplistic ID assignment
|
||||
Block *new_free_block = create_block(new_block_id, remaining_size, 0, -1);
|
||||
|
||||
// Update the allocated block
|
||||
best_block->size = required_size;
|
||||
best_block->allocated = 1;
|
||||
best_block->process_id = process_id;
|
||||
|
||||
// Insert the new free block into the list
|
||||
new_free_block->next = best_block->next;
|
||||
new_free_block->prev = best_block;
|
||||
if (best_block->next != NULL) {
|
||||
best_block->next->prev = new_free_block;
|
||||
}
|
||||
best_block->next = new_free_block;
|
||||
|
||||
// Renumber subsequent block IDs (basic approach)
|
||||
Block* temp = new_free_block->next;
|
||||
int current_id = new_block_id + 1;
|
||||
while (temp != NULL) {
|
||||
temp->id = current_id++;
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
} else { // Exact fit (allocate the whole block)
|
||||
best_block->allocated = 1;
|
||||
best_block->process_id = process_id;
|
||||
}
|
||||
printf("Process %d allocated %d units using Best Fit in Block %d.\n", process_id, required_size, best_block->id);
|
||||
return 1; // Allocation successful
|
||||
} else {
|
||||
printf("Process %d (size %d) could not be allocated using Best Fit.\n", process_id, required_size);
|
||||
return 0; // Allocation failed
|
||||
}
|
||||
}
|
||||
|
||||
// Function to free all allocated memory for the linked list
|
||||
void cleanup_memory() {
|
||||
Block *current = memory_head;
|
||||
Block *next_node;
|
||||
while (current != NULL) {
|
||||
next_node = current->next;
|
||||
free(current);
|
||||
current = next_node;
|
||||
}
|
||||
memory_head = NULL;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
int total_memory;
|
||||
int num_processes;
|
||||
int *process_sizes = NULL; // Dynamically allocated array for process sizes
|
||||
int i;
|
||||
|
||||
// --- Input ---
|
||||
printf("Enter the total size of memory: ");
|
||||
scanf("%d", &total_memory);
|
||||
if (total_memory <= 0) {
|
||||
printf("Invalid memory size.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Enter the number of processes: ");
|
||||
scanf("%d", &num_processes);
|
||||
if (num_processes <= 0) {
|
||||
printf("Invalid number of processes.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Dynamically allocate array for process sizes
|
||||
process_sizes = (int*)malloc(num_processes * sizeof(int));
|
||||
if (!process_sizes) {
|
||||
perror("Failed to allocate memory for process sizes");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Enter the size required for each process:\n");
|
||||
for (i = 0; i < num_processes; i++) {
|
||||
printf("Process %d size: ", i + 1);
|
||||
scanf("%d", &process_sizes[i]);
|
||||
if (process_sizes[i] <= 0) {
|
||||
printf("Invalid process size. Please enter a positive value.\n");
|
||||
free(process_sizes);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
||||
// --- First Fit Simulation ---
|
||||
printf("--- First Fit Allocation ---\n");
|
||||
initialize_memory(total_memory);
|
||||
printf("Initial Memory State:\n");
|
||||
display_memory();
|
||||
|
||||
for (i = 0; i < num_processes; i++) {
|
||||
allocate_first_fit(i + 1, process_sizes[i]); // Process IDs starting from 1
|
||||
display_memory(); // Show state after each allocation attempt
|
||||
}
|
||||
printf("Final Memory State after First Fit:\n");
|
||||
display_memory();
|
||||
|
||||
|
||||
// --- Best Fit Simulation ---
|
||||
printf("\n--- Best Fit Allocation ---\n");
|
||||
initialize_memory(total_memory); // Re-initialize memory for a fresh start
|
||||
printf("Initial Memory State:\n");
|
||||
display_memory();
|
||||
|
||||
for (i = 0; i < num_processes; i++) {
|
||||
allocate_best_fit(i + 1, process_sizes[i]); // Process IDs starting from 1
|
||||
display_memory(); // Show state after each allocation attempt
|
||||
}
|
||||
printf("Final Memory State after Best Fit:\n");
|
||||
display_memory();
|
||||
|
||||
// --- Cleanup ---
|
||||
free(process_sizes); // Free the dynamically allocated process sizes array
|
||||
cleanup_memory(); // Free the memory blocks linked list
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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!"
|
121
OS/endsem/cq.c
121
OS/endsem/cq.c
|
@ -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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue