diff --git a/CNP/Wireshark/SMTP/mail-sender.py b/CNP/Wireshark/SMTP/mail-sender.py deleted file mode 100644 index 186f05e..0000000 --- a/CNP/Wireshark/SMTP/mail-sender.py +++ /dev/null @@ -1,14 +0,0 @@ -import smtplib -from email.message import EmailMessage - -# the email message -msg = EmailMessage() -msg['Subject'] = 'CNP Assignment Email' -msg['From'] = 'aadit@example.com' -msg['To'] = 'shreyas@example.com' # used example.com just to not have a DNS error. -msg.set_content('Hello World. This is a message that is to be captured for the CNP FISAC II.') - -#SMTP server running on localhost on port 25 -with smtplib.SMTP('127.0.0.1', 25) as server: - server.set_debuglevel(1) # debug output to see the SMTP conversation (for dev log) - server.send_message(msg) diff --git a/CNP/Wireshark/SMTP/smtp-server.py b/CNP/Wireshark/SMTP/smtp-server.py deleted file mode 100644 index 1868743..0000000 --- a/CNP/Wireshark/SMTP/smtp-server.py +++ /dev/null @@ -1,33 +0,0 @@ -import asyncio -import uvloop -from aiosmtpd.controller import Controller - -# handler that just prints the message content -class PrintHandler: - async def handle_DATA(self, server, session, envelope): - print("Message from:", envelope.mail_from) - print("Recipients:", envelope.rcpt_tos) - print("Message data:") - print(envelope.content.decode('utf8', errors='replace')) - print("End of message") - # Respond with a success code - return '250 Message accepted for delivery' - -# uvloop for better performance -asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) - -def run_server(): - # SMTP server controller, binding to localhost on port 25 - controller = Controller(PrintHandler(), hostname='127.0.0.1', port=25) - controller.start() - print("SMTP server running on port 25. Press Ctrl+C to stop.") - try: - # Run forever - asyncio.get_event_loop().run_forever() - except KeyboardInterrupt: - pass - finally: - controller.stop() - -if __name__ == '__main__': - run_server() diff --git a/OS/C/Week10/aq1 b/OS/C/Week10/aq1 deleted file mode 100755 index 299cf23..0000000 Binary files a/OS/C/Week10/aq1 and /dev/null differ diff --git a/OS/C/Week10/aq1.c b/OS/C/Week10/aq1.c deleted file mode 100644 index 21da790..0000000 --- a/OS/C/Week10/aq1.c +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include - -// 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; imax_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; -} diff --git a/OS/C/Week10/aq2 b/OS/C/Week10/aq2 deleted file mode 100755 index e47ee89..0000000 Binary files a/OS/C/Week10/aq2 and /dev/null differ diff --git a/OS/C/Week10/aq2.c b/OS/C/Week10/aq2.c deleted file mode 100644 index a5dadf7..0000000 --- a/OS/C/Week10/aq2.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include // 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 -#include -#include // 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; -} diff --git a/OS/C/Week10/q2.c b/OS/C/Week10/q2.c deleted file mode 100644 index e69de29..0000000 diff --git a/OS/C/Week7/q2 b/OS/C/Week7/q2 deleted file mode 100755 index 7d6f5c4..0000000 Binary files a/OS/C/Week7/q2 and /dev/null differ diff --git a/OS/C/Week7/q2.c b/OS/C/Week7/q2.c index 92d64e0..1d68558 100644 --- a/OS/C/Week7/q2.c +++ b/OS/C/Week7/q2.c @@ -6,100 +6,106 @@ #include #include -#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; } diff --git a/OS/C/Week8/aq1 b/OS/C/Week8/aq1 deleted file mode 100755 index 901915e..0000000 Binary files a/OS/C/Week8/aq1 and /dev/null differ diff --git a/OS/C/Week8/aq1.c b/OS/C/Week8/aq1.c index 8b4318b..e69de29 100644 --- a/OS/C/Week8/aq1.c +++ b/OS/C/Week8/aq1.c @@ -1,95 +0,0 @@ -#include - -// 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 w[j]) { possible = 0; break; } - if(possible) { // If need <= work - for(k=0; k nd[pid][j]) { puts("Err:Req>Need"); goto end; } - // Check 2: Request <= Available - for(j=0; j av[j]) { puts("Wait:Req>Avail"); goto end; } - - // Tentatively allocate resources - for(j=0; j -#include - -// 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= 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; -} diff --git a/OS/C/Week9/q1.c b/OS/C/Week9/q1.c deleted file mode 100644 index cb48a66..0000000 --- a/OS/C/Week9/q1.c +++ /dev/null @@ -1,272 +0,0 @@ -#include -#include -#include // 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; -}