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 <semaphore.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define NR 3 // NUM_READERS
|
#define NUM_READERS 3
|
||||||
#define NW 2 // NUM_WRITERS
|
#define NUM_WRITERS 2
|
||||||
|
|
||||||
// shared data structure - simple integer
|
// shared data structure - simple integer
|
||||||
int sd = 0; // shared_data
|
int shared_data = 0;
|
||||||
|
|
||||||
// sync variables
|
// sync variables
|
||||||
pthread_mutex_t m; // mutex for rc protection
|
pthread_mutex_t mutex; // mutex for read_count protection
|
||||||
sem_t w; // semaphore for writer access control
|
sem_t wrt; // semaphore for writer access control
|
||||||
int rc = 0; // read_count: tracks active readers
|
int read_count = 0; // tracks active readers
|
||||||
|
|
||||||
void* r(void* arg) { // reader
|
void* reader(void* arg) {
|
||||||
int id = *((int*)arg);
|
int id = *((int*)arg);
|
||||||
while (1) {
|
while (1) {
|
||||||
// read delay sim
|
// read delay sim
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
// critical section entry
|
// critical section entry
|
||||||
pthread_mutex_lock(&m);
|
pthread_mutex_lock(&mutex);
|
||||||
rc++;
|
read_count++;
|
||||||
if (rc == 1) {
|
if (read_count == 1) {
|
||||||
// first reader blocks writers
|
// first reader blocks writers
|
||||||
sem_wait(&w);
|
sem_wait(&wrt);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&m);
|
pthread_mutex_unlock(&mutex);
|
||||||
|
|
||||||
// critical section
|
// 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
|
sleep(2); // read time sim
|
||||||
|
|
||||||
// critical section exit
|
// critical section exit
|
||||||
pthread_mutex_lock(&m);
|
pthread_mutex_lock(&mutex);
|
||||||
rc--;
|
read_count--;
|
||||||
if (rc == 0) {
|
if (read_count == 0) {
|
||||||
// last reader unblocks writers
|
// last reader unblocks writers
|
||||||
sem_post(&w);
|
sem_post(&wrt);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&m);
|
pthread_mutex_unlock(&mutex);
|
||||||
}
|
}
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* w_func(void* arg) { // writer
|
void* writer(void* arg) {
|
||||||
int id = *((int*)arg);
|
int id = *((int*)arg);
|
||||||
while (1) {
|
while (1) {
|
||||||
// write delay sim
|
// write delay sim
|
||||||
sleep(3);
|
sleep(3);
|
||||||
|
|
||||||
// critical section entry
|
// critical section entry
|
||||||
sem_wait(&w); // exclusive access control
|
sem_wait(&wrt); // exclusive access control
|
||||||
|
|
||||||
// critical section
|
// critical section
|
||||||
sd++; // shared_data modification
|
shared_data += 1;
|
||||||
printf("Writer %d is writing: sd becomes %d\n", id, sd);
|
printf("Writer %d is writing: shared_data becomes %d\n", id, shared_data);
|
||||||
sleep(2); // write time sim
|
sleep(2); // write time sim
|
||||||
|
|
||||||
// critical section exit
|
// critical section exit
|
||||||
sem_post(&w);
|
sem_post(&wrt);
|
||||||
}
|
}
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
pthread_t rts[NR], wts[NW]; // reader/writer threads
|
pthread_t readers[NUM_READERS], writers[NUM_WRITERS];
|
||||||
int rids[NR], wids[NW]; // reader/writer ids
|
int reader_ids[NUM_READERS], writer_ids[NUM_WRITERS];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// sync init
|
// sync init
|
||||||
pthread_mutex_init(&m, NULL);
|
pthread_mutex_init(&mutex, NULL);
|
||||||
sem_init(&w, 0, 1); // binary semaphore init
|
sem_init(&wrt, 0, 1); // binary semaphore init
|
||||||
|
|
||||||
// reader thread creation
|
// reader thread creation
|
||||||
for (i = 0; i < NR; i++) {
|
for (i = 0; i < NUM_READERS; i++) {
|
||||||
rids[i] = i + 1;
|
reader_ids[i] = i + 1;
|
||||||
pthread_create(&rts[i], NULL, r, &rids[i]);
|
if (pthread_create(&readers[i], NULL, reader, &reader_ids[i]) != 0) {
|
||||||
|
perror("Failed to create reader thread");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// writer thread creation
|
// writer thread creation
|
||||||
for (i = 0; i < NW; i++) {
|
for (i = 0; i < NUM_WRITERS; i++) {
|
||||||
wids[i] = i + 1;
|
writer_ids[i] = i + 1;
|
||||||
pthread_create(&wts[i], NULL, w_func, &wids[i]);
|
if (pthread_create(&writers[i], NULL, writer, &writer_ids[i]) != 0) {
|
||||||
|
perror("Failed to create writer thread");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// thread joining
|
// thread joining
|
||||||
for (i = 0; i < NR; i++) {
|
for (i = 0; i < NUM_READERS; i++) {
|
||||||
pthread_join(rts[i], NULL);
|
pthread_join(readers[i], NULL);
|
||||||
}
|
}
|
||||||
for (i = 0; i < NW; i++) {
|
for (i = 0; i < NUM_WRITERS; i++) {
|
||||||
pthread_join(wts[i], NULL);
|
pthread_join(writers[i], NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
pthread_mutex_destroy(&m);
|
pthread_mutex_destroy(&mutex);
|
||||||
sem_destroy(&w);
|
sem_destroy(&wrt);
|
||||||
|
|
||||||
return 0;
|
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
|
read -p "Enter a number: " num
|
||||||
echo "Usage: $0 <filename1> <filename2>"
|
if [[ $num -gt 10 ]]; then
|
||||||
exit 1
|
echo "Number is greater than 10"
|
||||||
|
elif [[ $num -eq 10 ]]; then
|
||||||
|
echo "Number is exactly 10"
|
||||||
|
else
|
||||||
|
echo "Number is less than 10"
|
||||||
fi
|
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