Compare commits

..

1 commit

Author SHA1 Message Date
644926a361 feat: add SMTP server and mail sender scripts
Implement an SMTP server using aiosmtpd and a mail sender script. The 
server handles incoming messages and prints their content, while the 
mail sender constructs and sends an email message. These changes 
enable local email testing for the CNP assignment, improving 
development efficiency.
2025-03-24 03:41:40 +05:30
22 changed files with 52 additions and 2043 deletions

Binary file not shown.

View file

@ -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;
}

Binary file not shown.

View file

@ -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
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

View file

@ -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
}

Binary file not shown.

View file

@ -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;
}

Binary file not shown.

View file

@ -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
```
*/

Binary file not shown.

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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!"

View file

@ -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;
}