operating system lab file 2024-25
operating system lab file 2024-25
i. Process management ,
ii. File management,
iii. Input/output System calls
iv. Solution:
i. Process management
ii. File management
iii. Input/output system calls
int main() {
printf("===== UNIX System Call Demonstration =====\n");
// i. PROCESS MANAGEMENT
printf("\n--- Process Management ---\n");
pid_t pid = fork(); // create a child process
if (pid < 0) {
perror("Fork failed");
exit(1);
} else if (pid == 0) {
printf("Child Process: PID = %d\n", getpid());
printf("Child says: Hello from child process!\n");
exit(0); // child exits
} else {
wait(NULL); // parent waits for child to finish
printf("Parent Process: PID = %d\n", getpid());
printf("Parent says: Child process finished.\n");
}
// ii. FILE MANAGEMENT
printf("\n--- File Management ---\n");
int fd = open("demo.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd < 0) {
perror("File open error");
exit(1);
}
const char *text = "This is a demo file written using system calls.\n";
write(fd, text, strlen(text));
close(fd);
return 0;
}
i. SJF ,
ii. Priority
iii. FCFS,
iv. Multi-level Queue.
#define MAX 10
typedef struct {
int pid;
int bt; // Burst Time
int at; // Arrival Time
int pri; // Priority
int queue; // Queue number (for multilevel)
} Process;
printf("PID\tBT\tWT\tTAT\n");
for (int i = 0; i < n; i++)
printf("%d\t%d\t%d\t%d\n", p[i].pid, p[i].bt, wt[i], tat[i]);
}
wt[0] = 0;
for (int i = 1; i < n; i++)
wt[i] = wt[i-1] + p[i-1].bt;
printf("PID\tBT\tWT\tTAT\n");
for (int i = 0; i < n; i++)
printf("%d\t%d\t%d\t%d\n", p[i].pid, p[i].bt, wt[i], tat[i]);
}
wt[0] = 0;
for (int i = 1; i < n; i++)
wt[i] = wt[i-1] + p[i-1].bt;
printf("PID\tBT\tPriority\tWT\tTAT\n");
for (int i = 0; i < n; i++)
printf("%d\t%d\t%d\t\t%d\t%d\n", p[i].pid, p[i].bt, p[i].pri, wt[i],
tat[i]);
}
// Function for Multilevel Queue Scheduling
void MultilevelQueue(Process p[], int n) {
printf("\n--- Multilevel Queue Scheduling ---\n");
Process queue1[MAX], queue2[MAX];
int n1 = 0, n2 = 0;
// Main Function
int main() {
Process p[MAX];
int n;
FCFS(p, n);
SJF(p, n);
Priority(p, n);
MultilevelQueue(p, n);
return 0;
}
🧪 Sample Input
Enter number of processes: 3
Process 1 - BT: 5
Process 1 - Priority: 2
Process 1 - Queue: 0
Process 2 - BT: 3
Process 2 - Priority: 1
Process 2 - Queue: 1
Process 3 - BT: 8
Process 3 - Priority: 3
Process 3 - Queue: 1
Program 4
i. Contiguous(using array)
ii. Linked �list(using linked-list)
iii. Indirect allocation (indexing)
Solution:
Here's a complete C program implementing file storage allocation techniques:
// ---------------------------
// Contiguous Allocation
// ---------------------------
void contiguousAllocation() {
int start, length, flag = 0;
printf("\n[Contiguous Allocation]\n");
printf("Enter starting block and length of file: ");
scanf("%d %d", &start, &length);
if (flag) {
printf("Contiguous blocks not available.\n");
} else {
for (int i = start; i < start + length; i++)
disk[i] = 1;
printf("File allocated at blocks: ");
for (int i = start; i < start + length; i++)
printf("%d ", i);
printf("\n");
}
}
// ---------------------------
// Linked List Allocation
// ---------------------------
typedef struct Node {
int block;
struct Node* next;
} Node;
void linkedListAllocation() {
int n, block;
Node* head = NULL, *temp = NULL, *newNode;
disk[block] = 1;
newNode = (Node*)malloc(sizeof(Node));
newNode->block = block;
newNode->next = NULL;
if (head == NULL)
head = newNode;
else
temp->next = newNode;
temp = newNode;
}
// ---------------------------
// Indexed Allocation
// ---------------------------
void indexedAllocation() {
int indexBlock, n, block;
printf("\n[Indexed Allocation]\n");
printf("Enter index block: ");
scanf("%d", &indexBlock);
if (disk[indexBlock] == 1) {
printf("Index block already allocated.\n");
return;
}
int blocks[n];
for (int i = 0; i < n; i++) {
printf("Enter block number %d: ", i + 1);
scanf("%d", &blocks[i]);
disk[indexBlock] = 1;
for (int i = 0; i < n; i++)
disk[blocks[i]] = 1;
// ---------------------------
// Main Function
// ---------------------------
int main() {
int choice;
while (1) {
printf("\n--- File Storage Allocation Menu ---\n");
printf("1. Contiguous Allocation\n");
printf("2. Linked List Allocation\n");
printf("3. Indexed Allocation\n");
printf("4. Exit\n");
printf("Choose method: ");
scanf("%d", &choice);
switch (choice) {
case 1: contiguousAllocation(); break;
case 2: linkedListAllocation(); break;
case 3: indexedAllocation(); break;
case 4: exit(0);
default: printf("Invalid choice!\n");
}
}
return 0;
}
This simulation uses a 1D array to represent the disk (disk[100]). Each method allocates space
differently:
Solution:
Here is a C program that implements Contiguous Memory Allocation Techniques:
i. Worst-Fit
ii. Best-Fit
iii. First-Fit
These algorithms are applied to allocate memory blocks to incoming processes based on
different strategies.
#define MAX 20
if (bestIdx != -1) {
allocation[i] = bestIdx;
blockSize[bestIdx] -= processSize[i];
}
}
if (worstIdx != -1) {
allocation[i] = worstIdx;
blockSize[worstIdx] -= processSize[i];
}
}
int main() {
int blockSize[MAX], processSize[MAX];
int m, n;
return 0;
}
🧪 Sample Input
Enter number of memory blocks: 5
Block 1: 100
Block 2: 500
Block 3: 200
Block 4: 300
Block 5: 600
Program 6
Solution:
Here's a simple C program that simulates the calculation of Internal and External
Fragmentation, based on:
Internal Fragmentation occurs when a process is allocated a block larger than required
— the leftover is internal.
External Fragmentation occurs when total free memory is enough, but not in
contiguous blocks large enough to fulfill a request.
#define MAX 50
int main() {
int blockCount, processCount;
int blocks[MAX], processes[MAX], allocation[MAX];
int i, j;
// First-Fit Allocation
for (i = 0; i < processCount; i++) {
allocation[i] = -1;
for (j = 0; j < blockCount; j++) {
if (blocks[j] >= processes[i]) {
allocation[i] = j;
blocks[j] -= processes[i]; // reduce available block
break;
}
}
}
// Calculate fragmentation
int internalFragmentation = 0;
for (i = 0; i < processCount; i++) {
if (allocation[i] != -1)
internalFragmentation += blocks[allocation[i]];
}
int externalFragmentation = 0;
int unallocated = 0;
for (i = 0; i < processCount; i++) {
if (allocation[i] == -1) {
unallocated++;
}
}
if (unallocated > 0) {
for (i = 0; i < blockCount; i++)
externalFragmentation += blocks[i];
}
return 0;
}
🧪 Sample Input:
Enter number of memory blocks: 4
Block 1: 100
Block 2: 500
Block 3: 200
Block 4: 300
This program uses First-Fit strategy and shows how much memory is:
Program 7
✅ Features:
#define MAX 20
typedef struct {
int pid; // Process ID
int start; // Start address
int size; // Memory size
} Process;
int main() {
int n, memorySize, totalMoved = 0;
Process processes[MAX];
// Input processes
for (int i = 0; i < n; i++) {
printf("Enter Process ID, Start Address, and Size (in KB) for Process
%d: ", i + 1);
scanf("%d%d%d", &processes[i].pid, &processes[i].start,
&processes[i].size);
}
printf("\nBefore Compaction:\n");
for (int i = 0; i < n; i++) {
printf("Process %d: Start = %d, Size = %d\n", processes[i].pid,
processes[i].start, processes[i].size);
}
// Perform Compaction
int currentStart = 0;
for (int i = 0; i < n; i++) {
if (processes[i].start != currentStart) {
totalMoved += processes[i].size;
processes[i].start = currentStart;
}
currentStart += processes[i].size;
}
printf("\nAfter Compaction:\n");
for (int i = 0; i < n; i++) {
printf("Process %d: New Start = %d, Size = %d\n", processes[i].pid,
processes[i].start, processes[i].size);
}
return 0;
}
🧪 Sample Input:
Enter total memory size: 1000
Enter number of processes: 3
Process 1: 1 100 200
Process 2: 2 400 150
Process 3: 3 700 100
🧾 Output:
Before Compaction:
Process 1: Start = 100, Size = 200
Process 2: Start = 400, Size = 150
Process 3: Start = 700, Size = 100
After Compaction:
Process 1: New Start = 0, Size = 200
Process 2: New Start = 200, Size = 150
Process 3: New Start = 350, Size = 100
Total Data Moved During Compaction = 300 KB
Free memory starts at address = 450 and size = 550 KB
Program 8
#define MAX 20
int main() {
int p, r; // number of processes and resources
int rag[MAX][MAX] = {0}; // adjacency matrix
char nodeName[MAX][10]; // node names
int total = p + r;
// Naming nodes
for (int i = 0; i < p; i++)
sprintf(nodeName[i], "P%d", i + 1);
for (int i = 0; i < r; i++)
sprintf(nodeName[p + i], "R%d", i + 1);
// Display RAG
printf("\nResource Allocation Graph (Adjacency Matrix):\n ");
for (int i = 0; i < total; i++)
printf("%4s", nodeName[i]);
printf("\n");
return 0;
}
🧪 Sample Input:
Enter number of processes: 2
Enter number of resources: 2
Enter number of edges: 4
Edge 1: 0 2 // P1 requests R1
Edge 2: 2 1 // R1 assigned to P2
Edge 3: 1 3 // P2 requests R2
Edge 4: 3 0 // R2 assigned to P1
🧾 Sample Output:
Resource Allocation Graph (Adjacency Matrix):
P1 P2 R1 R2
P1 0 0 1 0
P2 0 0 0 1
R1 0 1 0 0
R2 1 0 0 0
Program 9
Here's a C program to implement the Banker's Algorithm, which is used in operating systems
to avoid deadlock by checking for a safe sequence of process execution.
✅ Features:
#define MAX 10
int main() {
int n, m; // n = number of processes, m = number of resources
int alloc[MAX][MAX], max[MAX][MAX], need[MAX][MAX];
int avail[MAX];
bool finish[MAX] = {false};
int safeSeq[MAX], count = 0;
if (j == m) {
// This process can be completed
for (int k = 0; k < m; k++)
avail[k] += alloc[i][k];
safeSeq[count++] = i;
finish[i] = true;
found = true;
}
}
}
if (!found) {
printf("\nSystem is NOT in a safe state (Deadlock possible)\n");
return 1;
}
}
return 0;
}
🧪 Sample Input:
Processes: 5
Resources: 3
Allocation Matrix:
P0: 0 1 0
P1: 2 0 0
P2: 3 0 2
P3: 2 1 1
P4: 0 0 2
Maximum Matrix:
P0: 7 5 3
P1: 3 2 2
P2: 9 0 2
P3: 2 2 2
P4: 4 3 3
Available Resources: 3 3 2
✅ Output:
System is in a SAFE state.
Safe sequence is: P1 -> P3 -> P4 -> P0 -> P2
Let me know if you’d like this with resource request simulation, GUI visualization, or
C++/Python version.