OS LAB REPORT
KONCHADA CHAKREESH
(123AD0014)
Experiment: Practice Linux Commands
1. pwd: Present Working Directory
2. mkdir: Create a new directory
3. nl : Returns content of file with line number
4. du: Estimate file usage
5. df: Report file system disk space usage
6. sort: Sort lines of text files
7. wc: Print line, word, byte for a file
8. cat: Concatenate files and show content also
9. head: Outputs first part of files
10. tail: Outputs last part of files
Experiment: Grep Commands
Syntax of grep: grep [option] pattern [file]
1. -c: Count matching lines
2. -h: Prints matching lines from two files
3. -i: Case Insensitive matching
4. -l: List Matching filenames
5. -n: Shows line numbers
6. -v: Invert Matching
7. -e: Multiple patterns
8. -w: Match whole word
9. -o: Prints only matching parts
10. -A: Shows line after match
Experiment: Implement cp, ps Command in
XV6
1. Code in cp.c
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fcntl.h"
char buf[512];
int main(int argc, char *argv[])
{
int fd0, fd1, n;
if(argc != 3){
printf(2, "Usage: cp source destination\n");
exit();
}
if((fd0 = open(argv[1], O_RDONLY)) < 0){
printf(2, "cp: cannot open %s\n", argv[1]);
exit();
}
if((fd1 = open(argv[2], O_CREATE|O_WRONLY)) < 0){
printf(2, "cp: cannot create %s\n", argv[2]);
close(fd0);
exit();
}
while((n = read(fd0, buf, sizeof(buf))) > 0){
if(write(fd1, buf, n) != n){
printf(2, "cp: write error\n");
exit();
}
}
close(fd0);
close(fd1);
exit();
}
2. Add _cp\ to the UPROGS section in Makefile:
UPROGS=\
_cat\
_echo\
_grep\
_init\
_kill\ _ln\
_ls\
_mkdir\
_rm\
_sh\
_stressfs\
_usertests\
_wc\
_zombie\
_cp\
3. PS command implementation
#include "types.h" #include "stat.h" #include "user.h" int main() {
printf(1, "PID\tPPID\n"); // Header for process table
procdump(); // Calls the kernel function to display process information
exit(); }
Experiment: Non Preemptive Algorithms
1. FCFS
#include <stdio.h>
#include <stdlib.h>
typedef struct Process{
int pid;
int arrival_time;
int finish_time;
int burst_time;
int waiting_time;
int turnaround_time;
float ratio;
} Process;
void sortProcess(Process* procs, int n){
for(int i = 0; i < n; i++){
for(int j = 0; j < n - i - 1; j++){
if(procs[j].arrival_time > procs[j+1].arrival_time){
Process temp = procs[j];
procs[j] = procs[j+1];
procs[j+1] = temp;
}
}
}
}
void calculateTimes(Process* procs, int n){
for(int i = 0; i < n; i++){
procs[i].turnaround_time = procs[i].finish_time - procs[i].arrival_time;
procs[i].waiting_time = procs[i].turnaround_time - procs[i].burst_time;
}
}
void waitTime(Process* procs, int n){
float avg_wait_time = 0;
for(int i = 0; i < n; i++){
avg_wait_time += procs[i].waiting_time;
}
a v g _ w a i t _ t i m e = ( a v g _ w a i t _ t i m e / n ) ;
printf("%.2f ", avg_wait_time);
}
void FCFS(Process* procs, int n){
sortProcess(procs, n);
procs[0].finish_time = procs[0].arrival_time + procs[0].burst_time;
for(int i = 1; i < n; i++){
if(procs[i].arrival_time > procs[i-1].finish_time)
procs[i].finish_time = procs[i].arrival_time + procs[i].burst_time;
else
procs[i].finish_time = procs[i-1].finish_time + procs[i].burst_time;
}
2. SJF
void SJF(Process* procs, int n){
int currentTime = 0;
int completed = 0;
int complete[100] = {0};
while(completed != n){
int sjf_index = -1;
int min_burst = 10000;
for(int i = 0; i < n; i++){
if(procs[i].arrival_time <= currentTime && !complete[i]){
if(procs[i].burst_time < min_burst){
min_burst = procs[i].burst_time;
sjf_index = i;
}
}
if(procs[i].burst_time == min_burst){
if(procs[i].arrival_time < procs[sjf_index].arrival_time){
sjf_index = i;
}
}
}
if(sjf_index == -1){
currentTime++;
}
e l s e {
procs[sjf_index].finish_time = currentTime +
procs[sjf_index].burst_time;
currentTime = procs[sjf_index].finish_time;
completed++;
complete[sjf_index] = 1;
}
}
calculateTimes(procs, n);
}
3.LJF
void LJF(Process* procs, int n){
int currentTime = 0;
int completed = 0;
int complete[100] = {0};
while(completed != n){
int ljf_index = -1;
int max_burst = -10000;
for(int i = 0; i < n; i++){
if(procs[i].arrival_time <= currentTime && !complete[i]){
if(procs[i].burst_time > max_burst){
max_burst = procs[i].burst_time;
ljf_index = i;
}
}
if(procs[i].burst_time == max_burst){
if(procs[i].arrival_time < procs[ljf_index].arrival_time){
ljf_index = i;
}
}
}
if(ljf_index == -1){
currentTime++;
}
else{
procs[ljf_index].finish_time = currentTime +
procs[ljf_index].burst_time;
currentTime = procs[ljf_index].finish_time;
completed++;
complete[ljf_index] = 1;
}
}
c a l c u l a t e T i m e s ( p r o c s , n ) ;
}
float responseCal(struct Process proc, int currentTime){
int waiting_time = currentTime - proc.arrival_time;
return (float)( waiting_time + proc.burst_time) / proc.burst_time;
}
4.HRRN
void HRRN(Process* procs, int n){
int currentTime = 0;
int completed = 0;
int complete[100] = {0};
while(completed != n){
int hr_index = -1;
float max_ratio = -1;
for(int i = 0; i < n; i++){
if(procs[i].arrival_time <= currentTime && !complete[i]){
float response_ratio = responseCal(procs[i], currentTime);
if(response_ratio > max_ratio){
max_ratio = response_ratio;
hr_index = i;
}
}
}
if(hr_index == -1){
currentTime++;
}
e l s e {
procs[hr_index].finish_time = currentTime +
procs[hr_index].burst_time;
currentTime = procs[hr_index].finish_time;
completed++;
complete[hr_index] = 1;
}
}
calculateTimes(procs, n);
}
Experiment: Preemptive Algorithms
1. SRTF
include <stdio.h>
#include <limits.h>
#include <stdlib.h>
typedef struct Process{
int at; int
bt; int rbt;
int ft; int
wt; int tat;
int priority;
}Process;
int findMinRemainingTime(Process* p, int n, int current){
int min = INT_MAX;
int selected = -1;
for(int i = 0; i < n; i++){
if(p[i].at <= current && p[i].rbt < min && p[i].rbt > 0){
min = p[i].rbt;
selected = i;
}
}
return selected;
}
int findMaxRemainingTime(Process* p, int n, int current){
int max = INT_MIN;
int selected = -1;
for(int i = 0; i < n; i++){
if(p[i].at <= current && p[i].rbt > max && p[i].rbt > 0){
max = p[i].rbt;
selected = i;
}
}
return selected;
}
void SRTF(Process* p, int n){
int current = 0;
int completed = 0;
while(completed != n){
int selected = findMinRemainingTime(p, n, current);
if(selected == -1){
current++;
continue;
}
p[selected].rbt--;
current++;
if(p[selected].rbt == 0){
completed++; p[selected].ft = current;
p[selected].tat = p[selected].ft - p[selected].at;
p[selected].wt = p[selected].tat - p[selected].bt;
}
}
}
2. LRTF
void LRTF(Process* p, int n){
int current = 0;
int completed = 0;
while(completed != n){
int selected = findMaxRemainingTime(p, n, current);
if(selected == -1){
current++;
continue;
}
p[selected].rbt--;
current++;
if(p[selected].rbt == 0){
completed++; p[selected].ft = current;
p[selected].tat = p[selected].ft - p[selected].at;
p[selected].wt = p[selected].tat - p[selected].bt;
}
}
}
3.Highest Priority
void HighestPriority(Process* p, int n){
int current = 0;
int completed = 0;
while(completed != n){
int selected = -1;
int high = INT_MAX;
for(int i = 0; i < n; i++){
if(p[i].at <= current && p[i].rbt > 0 && p[i].priority < high){
high = p[i].priority;
selected = i;
}
}
if(selected == -1){
current++;
continue;
}
p [ s e l e c t e d ] . r b t - - ;
c u r r e n t + + ;
if(p[selected].rbt == 0){
completed++; p[selected].ft = current;
p[selected].tat = p[selected].ft - p[selected].at;
p[selected].wt = p[selected].tat - p[selected].bt;
}
}
}
4.Round Robin
void RoundRobin(Process* p, int n, int quantum){
int current = 0;
int completed = 0;
int* queue = (int*)malloc(n * sizeof(int));
int front = 0, rear = -1;
int in_queue[100] = {0};
while(completed != n){
for(int i = 0; i < n; i++){
if(p[i].at <= current && p[i].rbt > 0 && !in_queue[i]){
queue[++rear] = i;
in_queue[i] = 1;
}
}
if(front > rear){
current++;
front = 0;
rear = -1;
continue;
}
int selected = queue[front++];
in_queue[selected] = 0;
int ex_time = (p[selected].rbt < quantum) ? p[selected].rbt : quantum;
p[selected].rbt -= ex_time;
current += ex_time;
if(p[selected].rbt > 0){
for(int i = 0; i < n; i++){
if(p[i].at <= current && p[i].rbt > 0 && !in_queue[i] && i !=
selected){
queue[++rear] = i;
in_queue[i] = 1;
}
}
queue[++rear] = selected;
in_queue[selected] = 1;
}
e l s e {
completed++; p[selected].ft = current;
p[selected].tat = p[selected].ft - p[selected].at;
p[selected].wt = p[selected].tat - p[selected].bt;
}
}
free(queue);
}
void avgWait(Process* p, int n){
float avg_wait = 0;
for(int i = 0; i < n; i++){
avg_wait += p[i].wt;
}
avg_wait /= n;
printf("%.1f ", avg_wait);
}
Experiment: Producer Consumer Using
Shared Memory
Code
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
typedef struct {
int buffer[20]; int
in; int out;
int count;
int sum;
int totalProduced;
int totalConsumed;
pid_t consumerPids[2];
} sharedData;
void produceItem(sharedData* shared, int item){
shared->buffer[shared->in] = item;
shared->in = (shared->in + 1) % 20;
shared->count++;
shared->totalProduced++;
printf("Produced %d by producer\n", item);
} void producer(sharedData*
shared){
int item;
for (int item = 1; item <= 50; item++){
while(shared->count == 20){
usleep(1000);
}
produceItem(shared, item);
}
printf("All Items are produced\n");
}
int consumeItem(int consumerId, sharedData* shared){
int item;
item = shared->buffer[shared->out];
shared->out = (shared->out + 1) % 20;
shared->count--;
shared->totalConsumed++;
printf("Consumer %d consumed %d\n", consumerId, item);
return item;
}
void consumer(int id, sharedData* shared){
int item;
while(1){
if(shared->totalProduced == 50 && shared->totalConsumed == 50)
break;
if(shared->count == 0){
if(shared->totalConsumed == 50)
break;
usleep(100);
continue;
}
item = consumeItem(id, shared);
shared->sum += item;
usleep(2000);
}
p r i n t f ( " C o n s u m e r % d c o n s u m e d a l l t h e i t
}
int main(){
int shmid;
sharedData* shared;
pid_t pid;
int i, status;
shmid = shmget(IPC_PRIVATE, sizeof(sharedData), IPC_CREAT | 0666);
shared = (sharedData*) shmat(shmid, NULL, 0);
shared->in = 0; shared-
>out = 0; shared->count =
0; shared->sum = 0;
shared->totalProduced = 0;
shared->totalConsumed = 0;
pid = fork();
if(pid == 0){
producer(shared);
exit(0);
}
for(int i = 0; i < 2; i++){
pid = fork();
if(pid == 0){
consumer(i, shared);
exit(0);
} else
shared->consumerPids[i] = pid;
}
for(int i = 0; i < 3; i++){
wait(&status);
}
printf("Sum is: %d", shared->sum);
return 0;
}
Experiment: Implementation of
Semaphores
Producer Consumer
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define BUFFER_SIZE 20
#define MAX_ITEMS 50
int buffer[BUFFER_SIZE];
int in = 0; int out = 0;
int produced_count = 0;
int consumed_count = 0;
sem_t full;
sem_t empty;
pthread_mutex_t mutex;
void* producer(void* arg){
int item = 1;
while(produced_count < MAX_ITEMS){
sem_wait(&empty);
pthread_mutex_lock(&mutex);
buffer[in] = item;
printf("Produced: %d\n", item);
in = (in + 1) % BUFFER_SIZE;
item++;
produced_count++;
pthread_mutex_unlock(&mutex);
sem_post(&full);
}
pthread_exit(NULL);
}
void* consumer(void* arg){
usleep(100);
while(consumed_count < MAX_ITEMS){
sem_wait(&full);
pthread_mutex_lock(&mutex);
int item = buffer[out];
printf("Consumed: %d by Consumer %ld\n", item, (long)arg);
out = (out + 1) % BUFFER_SIZE;
consumed_count++;
pthread_mutex_unlock(&mutex);
sem_post(&empty);
}
pthread_exit(NULL);
} int
main(){
pthread_t producerThread, consumerThread1, consumerThread2;
sem_init(&full, 0, 1);
sem_init(&empty, 0, BUFFER_SIZE);
pthread_mutex_init(&mutex, NULL);
pthread_create(&producerThread, NULL, producer, NULL);
pthread_create(&consumerThread1, NULL, consumer, (void*)1);
pthread_create(&consumerThread2, NULL, consumer, (void*)2);
pthread_join(producerThread, NULL);
pthread_join(consumerThread1, NULL);
pthread_join(consumerThread2, NULL);
pthread_mutex_destroy(&mutex);
sem_destroy(&full);
sem_destroy(&empty);
return 0;
}
Reader-Writer's Problem
#include<semaphore.h> #include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
sem_t x,y;
pthread_t tid;
pthread_t writerthreads[100],readerthreads[100];
int readercount = 0;
void *reader(void* param)
{
sem_wait(&x);
readercount++;
if(readercount==1)
sem_wait(&y);
sem_post(&x);
printf("%d reader is inside\n",readercount);
usleep(3);
sem_wait(&x);
readercount--;
if(readercount==0)
{
sem_post(&y);
}
s e m _ p o s t ( & x ) ;
p r i n t f ( " % d R e a d e r i s l e a v i n g \ n " , r e a d e r c
r e t u r n N U L L ;
}
void *writer(void* param)
{
printf("Writer is trying to enter\n");
sem_wait(&y);
printf("Writer has entered\n");
sem_post(&y);
printf("Writer is leaving\n");
return NULL;
}
int main()
{
int n2,i; printf("Enter the number of
readers:");
scanf("%d",&n2);
printf("\n");
int n1[n2];
sem_init(&x,0,1);
sem_init(&y,0,1);
for(i=0;i<n2;i++)
{
pthread_create(&writerthreads[i],NULL,reader,NULL);
pthread_create(&readerthreads[i],NULL,writer,NULL);
}
for(i=0;i<n2;i++)
{
pthread_join(writerthreads[i],NULL);
pthread_join(readerthreads[i],NULL);
}
return 0;
}
Diner's Philosophers Problem
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
sem_t room;
sem_t chopstick[5];
void * philosopher(void *);
void eat(int);
int main()
{
int i,a[5];
pthread_t tid[5];
sem_init(&room,0,4);
for(i=0;i<5;i++)
sem_init(&chopstick[i],0,1);
for(i=0;i<5;i++){
a[i]=i;
pthread_create(&tid[i],NULL,philosopher,(void *)&a[i]);
}
for(i=0;i<5;i++)
pthread_join(tid[i],NULL);
return 0;
}
void * philosopher(void * num)
{
int phil=*(int *)num;
sem_wait(&room);
printf("\nPhilosopher %d has entered room",phil);
sem_wait(&chopstick[phil]);
sem_wait(&chopstick[(phil+1)%5]);
eat(phil);
sleep(2);
printf("\nPhilosopher %d has finished eating",phil);
sem_post(&chopstick[(phil+1)%5]);
sem_post(&chopstick[phil]);
sem_post(&room);
}
void eat(int phil)
{
printf("\nPhilosopher %d is eating",phil);
}
Experiment: Page Replacement
Algorithms
First In First Out
#include <stdio.h>
int search(int a1[], int c1, int target){
for(int i = 0; i <= c1; i++){
if(a1[i] == target) return 1;
}
return 0;
}
int main(){
int no_frames, no_page;
scanf("%d", &no_frames);
scanf("%d", &no_page);
int frame_array[no_frames];
int page_array[no_page];
int count = -1;
int top = 0;
int fault = 0;
for(int i = 0; i < no_page; i++){
scanf("%d", &page_array[i]);
}
for(int i = 0; i < no_page; i++){
if(search(frame_array, count, page_array[i]) == 0){
fault++;
count++;
top = (top + 1) % no_frames;
frame_array[top] = page_array[i];
}
}
printf("%d", fault);
}
Least Recently used Replacement
#include <stdio.h>
int search(int a1[], int count, int target) {
for (int i = 0; i < count; i++) {
if (a1[i] == target) return i;
}
r e t u r n - 1 ;
}
int findLRU(int time[], int count) {
int min = time[0], min_idx = 0;
for (int i = 1; i < count; i++) {
if (time[i] < min) {
min = time[i];
min_idx = i;
}
}
return min_idx;
}
int main() {
int nf, np;
scanf("%d %d", &nf, &np);
int fqueue[nf];
int time[nf];
int count = 0;
int parray[np];
int fault = 0;
int current_time = 0;
for (int i = 0; i < np; i++) {
scanf("%d", &parray[i]);
}
for (int i = 0; i < nf; i++) {
fqueue[i] = -1;
time[i] = 0;
}
for (int i = 0; i < np; i++) {
int page = parray[i];
int pos = search(fqueue, count, page);
if (pos == -1) {
fault++;
if (count < nf) {
fqueue[count] = page;
time[count] = current_time++;
count++;
} else {
int lru_idx = findLRU(time, nf);
fqueue[lru_idx] = page;
time[lru_idx] = current_time++;
}
} else {
time[pos] = current_time++;
}
}
printf("%d", fault);
return 0;
}