os lab pdf

23
REPORT ON OPERATING SYSTEM LAB Presented by Rohit Kanaujiya Course: M.Tech. (CSDP) Roll no: 13MA60R01 Department of Mathematics Indian Institute of Technology Kharagpur 2014

Transcript of os lab pdf

Page 1: os lab pdf

REPORT

ON

OPERATING SYSTEM LAB

Presented by

Rohit Kanaujiya

Course: M.Tech. (CSDP)

Roll no: 13MA60R01

Department of Mathematics

Indian Institute of Technology

Kharagpur

2014

Page 2: os lab pdf

Abstract

In this report I had given an overview of parallel computing, available within a short time

frame. The information about each topic is kept as compact as possible. Moreover, I went brief

explanation about Amdahl’s, in addition to Flynn’s taxonomy. In this few hardware concepts

processor architecture and memory organization are conceal but used further.

An Attempt is made to list all machines. The machines are described according to their macro

architectural class. Shared and distributed-memory SIMD an MIMD machines are discerned.

In order to go further, algorithm concepts dependencies, race conditions, mutual exclusion,

synchronization, parallel slowdown are also discussed briefly. Continuation to this parallel

programming models are also included, in addition to recent science and technology applications.

Some conclusions are also defined.

Page 3: os lab pdf

List of Problems

Abstract

1. Introduction

1. Error handler program

1.1. Statement and algorithm

1.2. Program implementation

2. Terminal Handler program

2.1. Statement and algorithm

2.2. Program implementation

3. Banker’s algorithm

3.1. Statement and algorithm

3.2. Program implementation

4. Sleeping barber program

4.1. Statement and algorithm

4.2. Program implementation

5. Dining Philosophers problem

5.1. Statement and algorithm

5.2. Program implementation

Page 4: os lab pdf

4

1. Error Handler Problem

1.1 Statement and algorithm

Five silent philosophers sit at a table around a bowl of food. A fork is placed between each pair

of adjacent philosophers. Each philosopher must alternately think and eat. However, a

philosopher can only eat food when he has both left and right forks. Each fork can be held by

only one philosopher and so a philosopher can use the fork only if it's not being used by another

philosopher. After he finishes eating, he needs to put down both forks so they become available

to others. A philosopher can grab the fork on his right or the one on his left as they become

available, but can't start eating before getting both of them.

Eating is not limited by the amount of food left: assume an infinite supply.

The problem is how to design a discipline of behavior such that each philosopher won't

starve; i.e., can forever continue to alternate between eating and thinking assuming that any

philosopher cannot know when others may want to eat or think.

1.2. Program implementation

#include"types.h"

#include "defs.h"

#include"param.h"

#include"memlayout.h"

#include"mmu.h"

#include"proc.h"

#include"x86.h"

#include"traps.h"

#include"spinlock.h"

void idtinit(void);

extern uint ticks;

void tvinit(void);

extern struct spinlock tickslock;

// Interrupt descriptor table (shared by all CPUs).

struct gatedesc idt[256];

Page 5: os lab pdf

5

extern uint vectors[]; // in vectors.S: array of 256 entry pointers

struct spinlock tickslock;

uint ticks;

void tvinit(void)

{

int i;

for(i = 0; i < 256; i++)

SETGATE(idt[i], 0, SEG_KCODE<<3, vectors[i], 0);

SETGATE(idt[T_SYSCALL], 1, SEG_KCODE<<3, vectors[T_SYSCALL],

DPL_USER);

initlock(&tickslock, "time");

}

void idtinit(void)

{

lidt(idt, sizeof(idt));

}

void trap(struct trapframe *tf)

{

if(tf−>trapno == T_SYSCALL){

if(proc−>killed)

exit();

proc−>tf = tf;

syscall();

if(proc−>killed)

exit();

return; }

switch(tf−>trapno){

case T_IRQ0 + IRQ_TIMER:

if(cpu−>id == 0){

acquire(&tickslock);

Page 6: os lab pdf

6

ticks++;

wakeup(&ticks);

release(&tickslock);

}

lapiceoi();

break;

case T_IRQ0 + IRQ_IDE:

ideintr();

lapiceoi();

break;

case T_IRQ0 + IRQ_IDE+1:

// Bochs generates spurious IDE1 interrupts.

break;

case T_IRQ0 + IRQ_KBD:

kbdintr();

lapiceoi();

break;

case T_IRQ0 + IRQ_COM1:

uartintr();

lapiceoi();

break;

case T_IRQ0 + 7:

case T_IRQ0 + IRQ_SPURIOUS:

cprintf("cpu%d: spurious interrupt at %x:%x\n",

cpu−>id, tf−>cs, tf−>eip);

lapiceoi();

break;

default:

if(proc == 0 || (tf−>cs&3) == 0){

// In kernel, it must be our mistake.

cprintf("unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n",

tf−>trapno, cpu−>id, tf−>eip, rcr2());

panic("trap");

}

// In user space, assume process misbehaved.

Page 7: os lab pdf

7

cprintf("pid %d %s: trap %d err %d on cpu %d "

"eip 0x%x addr 0x%x−−kill proc\n",

proc−>pid, proc−>name, tf−>trapno, tf−>err, cpu−>id, tf−>eip,

rcr2());

proc−>killed = 1;

}

// Force process exit if it has been killed and is in user space.

// (If it is still executing in the kernel, let it keep running

// until it gets to the regular system call return.)

if(proc && proc−>killed && (tf−>cs&3) == DPL_USER)

exit();

// Force process to give up CPU on clock tick.

// If interrupts were on while locks held, would need to check nlock.

if(proc && proc−>state == RUNNING && tf−>trapno == T_IRQ0+IRQ_TIMER)

yield();

// Check if the process has been killed since we yielded

if(proc && proc−>killed && (tf−>cs&3) == DPL_USER)

exit();

}

Page 8: os lab pdf

8

2. Terminal Handler

Terminals support the standard system I/O operations, as well as a collection of terminal-

specific operations to control input-character editing and output delays. At the lowest level

are the terminal device drivers that control the hardware terminal ports. Terminal input is

handled according to the underlying communication characteristics, such as baud rate, and

according to a set of software-controllable parameters, such as parity checking.

Layered above the terminal device drivers are line disciplines that provide various degrees of

character processing.

The default line discipline is selected when a port is being used for an interactive login. The

line discipline is run in canonical mode; input is processed to provide standard line-oriented

editing functions, and input is presented to a process on a line-by-line basis.

Screen editors and programs that communicate with other computers generally run in non-

canonical mode (also commonly referred to as raw mode or character-at-a-time mode). In

this mode, input is passed through to the reading process immediately and without interpreta-

tion. All special-character input processing is disabled, no erase or other line editing pro-

cessing is done, and all characters are passed to the program that is reading from the terminal.

It is possible to configure the terminal in thousands of combinations between these two ex-

tremes. For example, a screen editor that wanted to receive user interrupts asynchronously

might enable the special characters that generate signals and enable output flow control, but

otherwise run in non-canonical mode; all other characters would be passed through to the

process uninterrupted.

On output, the terminal handler provides simple formatting services, including

• Converting the line-feed character to the two-character carriage-return-line-feed

sequence

• Inserting delays after certain standard control characters

• Expanding tabs

• Displaying echoed nongraphic ASCII characters as a two-character sequence of the

form “^C” (i.e., the ASCII caret character followed by the ASCII character that is the

character’s value offset from the ASCII “@” character).

Each of these formatting services can be disabled individually by a process through

control requests.

Page 9: os lab pdf

9

#include<stdio.h>

void save_context_switch();

void cpu(int v[]);

void pic();

void k_i_h();

int charout=0;

char key;

main()

{ char a;

int n=1,i;

printf("process going on\n");

while(n!=5)

{

if(n!=4)

sleep(1);

else

scanf("%c",&a);

key=a;

charout++;

n++;

}

printf("key is pressed\n");

sleep(1);

sleep(1);

printf("signal is passed to IRQ1\n");

for(i=0;i<2;i++)

sleep(1);

printf("INTERRUPT SENT TO PIC\n\n ");

pic();

}

void pic()

{ char a;

int v[2];

sleep(1);

printf("status of E-FLAG register before receiving the interrupt\n\n");

printf("31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5

4 3 2 1 0 \n");

printf("-----------------------------------------------------------------------------------------------

-\n");

printf(" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 vm rf 0 nt io of if df tf sf zf 0 af 0 pf

1 cf\n");

printf(" pl\n ");

printf(" ----------------------------------------------------------------------------------------------

--\n");

//scanf("%c",&a);

sleep(1);

printf("bit 9 of E-FLAG register is set 1\n\n");

printf("after receiving the interrupt\n\n");

printf("31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5

4 3 2 1 0 \n");

Page 10: os lab pdf

10

printf("-----------------------------------------------------------------------------------------------

-\n");

printf(" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 vm rf 0 nt io of 1 df tf sf zf 0 af 0 pf 1

cf\n");

printf(" pl\n ");

printf(" ----------------------------------------------------------------------------------------------

--\n");

sleep(1);

//scanf("%c",&a);

printf("\nPIC traslateS interrupt into the interrupt vector v\n\n");

sleep(1);

printf("\n Interrupt flag masked\n");

sleep(1);

sleep(1);

printf("31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5

4 3 2 1 0 \n");

printf("-----------------------------------------------------------------------------------------------

-\n");

printf(" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 vm rf 0 nt io of 0 df tf sf zf 0 af 0 pf 1

cf\n");

printf(" pl\n ");

printf(" ----------------------------------------------------------------------------------------------

--\n");

v[0]=1;

v[1]=54;

sleep(1);

printf("\nPIC sends the interrupt vector to the CPU\n\n ");

cpu(v);

}

void cpu(int v[])

{ printf("CPU accepts the interrupt vector\n");

int a[8][2]={{50,0},{51,1},{52,2},{53,3},{54,4},{55,5},{56,6},{57,7}};

int i,c;

for(i=0;i<8;i++)

if(v[1]==a[i][0])

c=a[i][1];

switch(c)

{

case 0:

break;

case 1:

break;

case 2:

break;

case 3:

break;

case 4: printf("keyboard interrupt handler selected\n");

sleep(1);

save_context_switch();

k_i_h();

Page 11: os lab pdf

11

printf("restore context\n");

sleep(1);

printf("CPU sends an aknowledgment\n");

break;

case 5:

break;

case 6:

break;

case 7:

printf("");

}

}

void save_context_switch()

{

sleep(1);

printf("\nUser mode to kernal mode:\n");

sleep(1);

printf("Switch to kernel stacks\n\n");

sleep(1);

printf("Save E-FLAGES \n");

sleep(1);

printf("\nproceess state\n");

sleep(1);

printf("program counter\n");

sleep(1);

printf("\nStack Pointer\n");

sleep(1);

printf("\nmemory allocation in PCB\n");

}

void k_i_h()

{

char x;

sleep(1);

printf("\nBuffer Variable incremented\n\n");

sleep(1);

fflush(stdout);

scanf("%c",&x);

scanf("%c",&x);

printf("\n Interrupt masked\n\n");

if(charout>0)

{

printf("display process called\n\n");

sleep(1);

printf("%c\n\n",key);

charout--;

printf("\n buffer variable decremented\n");

}

sleep(1);

printf("\nkeyboard interrupt handler sends end of interrupt to cpu\n\n");

}

Page 12: os lab pdf

12

3. Banker’s algorithm

Originally, The Banker’s algorithm is a resource allocation and deadlock avoidance

algorithm developed by Edsger Dijkstra that tests for safety by simulating the allocation of pre-

determined maximum possible amounts of all resources, and then makes a ”safe-state” check

to test for possible deadlock conditions for all other pending activities, before deciding whether

allocation should be allowed to continue. The Banker’s algorithm is run by the operating

system whenever a process requests resources. The algorithm prevents deadlock by denying or

postponing the request if it determines that accepting the request could put the system in an

unsafe state (one where deadlock could occur).

3.1 Statement and algorithm

Sources

For the Banker’s algorithm to work, it needs to know three things:

1. How much of each resource each process could possibly request

2. How much of each resource each process is currently holding

3. How much of each resource the system has available

Safe and Unsafe States

A state is considered safe if it is possible for all processes to finish executing (terminate).

Since the system cannot know when a process will terminate, or how many resources it will

have requested by then, the system assumes that all processes will eventually attempt to

acquire their stated maximum resources and terminate soon afterward. This is a reasonable

assumption in most cases since the system is not particularly concerned with how long each

process runs (at least not from a deadlock avoidance perspective). Also, if a process

terminates without acquiring its maximum resources, it only makes it easier on the system.

Given that assumption, the algorithm determines if a state is safe by trying to find a

hypothetical set of requests by the processes that would allow each to acquire (one-by-one)

its maximum resources and then terminate (returning its resources to the system). Any state

where no such set exists is an unsafe state. In a safe state, at least one process should be able

to acquire its maximum possible set of resources, and proceed to termination.

The simplified algorithm when the system receives a request for resources, it runs the

Banker’s algorithm to determine if it is safe to grant the request. The algorithm is fairly

straight forward once the distinction between safe and unsafe states is understood.

Page 13: os lab pdf

13

1. Can the request be granted?

• If not, the request is impossible and must either be denied or put on a waiting list

2. Assume that the request is granted

3. Is the new state safe?

• If so grant the request

• If not, either deny the request or put it on a waiting list Whether the system denies or

postpones an impossible or unsafe request is a decision specific to the operating system.

3.2 Program implementation

#include<iostream>

#include<conio.h>

#define MAX 20

using std::cin;

using std::cout;

using std::endl;

class bankers

{ private:

int al[MAX][MAX],m[MAX][MAX],n[MAX][MAX],avail[MAX];

int nop,nor,k,result[MAX],pnum,work[MAX],finish[MAX];

public:

bankers();

void input();

void method();

int search(int);

void display();

};

bankers::bankers()

{ k=0;

Page 14: os lab pdf

14

for(int i=0;i<MAX;i++)

{

for(int j=0;j<MAX;j++)

{

al[i][j]=0; m[i][j]=0; n[i][j]=0;

}

avail[i]=0;

result[i]=0;

finish[i]=0;

}

}

void bankers::input()

{ int i,j;

cout<<"Enter the number of processes:";

cin>>nop;

cout<<"Enter the number of resources:";

cin>>nor;

cout<<"Enter the allocated resources for each process: "<<endl;

for(i=0;i<nop;i++)

{ cout<<"\nProcess "<<i;

for(j=0;j<nor;j++)

{ cout<<"\nResource "<<j<<":";

cin>>al[i][j];

}

}

cout<<"Enter the maximum resources that are needed for each process: "<<endl;

for(i=0;i<nop;i++)

{ cout<<"\nProcess"<<i;

for(j=0;j<nor;j++)

{ cout<<"\nResouce"<<j<<":";

cin>>m[i][j];

n[i][j]=m[i][j]-al[i][j];

}

}

Page 15: os lab pdf

15

cout<<"Enter the currently available resources in the system: ";

for(j=0;j<nor;j++)

{ cout<<"Resource "<<j<<":";

cin>>avail[j];

work[j]=-1;

}

for(i=0;i<nop;i++)

finish[i]=0;

}

void bankers::method()

{ int i=0,j,flag;

while(1)

{ if(finish[i]==0)

{ pnum =search(i);

if(pnum!=-1)

{ result[k++]=i;

finish[i]=1;

for(j=0;j<nor;j++)

{ avail[j]=avail[j]+al[i][j];

}

}

}

i++;

if(i==nop)

{ flag=0;

for(j=0;j<nor;j++)

if(avail[j]!=work[j])

flag=1;

for(j=0;j<nor;j++)

work[j]=avail[j];

if(flag==0)

break;

else

i=0;

}

Page 16: os lab pdf

16

}

}

int bankers::search(int i)

{ int j;

for(j=0;j<nor;j++)

if(n[i][j]>avail[j])

return -1;

return 0;

}

void bankers::display()

{ int i,j;

cout<<endl<<"OUTPUT:";

cout<<endl<<"========\n";

cout<<endl<<"PROCESS\t ALLOTED\t MAXIMUM\t NEED";

for(i=0;i<nop;i++)

{ cout<<"\nP"<<i+1<<"\t ";

for(j=0;j<nor;j++)

{ cout<<al[i][j]<<" ";

}

cout<<"\t ";

for (j=0;j<nor;j++)

{ cout<<m[i][j]<<" ";

}

cout<<"\t ";

for(j=0;j<nor;j++ )

{ cout<<n[i][j]<<" ";

}

}

cout<<"\n\nThe sequence of the safe processes are: \n\n";

for(i=0;i<k;i++)

{ int temp = result[i]+1 ;

cout<<"P"<<temp<<" ";

}

cout<<"\n\nThe sequence of unsafe processes are: \n\n";

int flg=0;

Page 17: os lab pdf

17

for (i=0;i<nop;i++)

{ if(finish[i]==0)

{ flg=1;

}

cout<<"P"<<i<<" ";

}

cout<<endl<<"\n\nRESULT:";

cout<<endl<<"=======\n";

if(flg==1)

cout<<endl<<"The system is not in safe state and deadlock may occur!!";

else

cout<<endl<<"The system is in safe state and deadlock will not occur!!";

}

main()

{ cout<<"BANKER's ALGORITHM\n"<<endl;

bankers B;

B.input ( );

B.method ( );

B.display ( );

getch();

}

Page 18: os lab pdf

18

4. Sleeping Barber Problem

4.1 Statement and algorithm

The barber shop has one barber, one barber chair, and n chairs for waiting customers, if any, to

sit on. If there are no customers present, the barber sits down in the barber chair and falls asleep.

When a customer arrives, he has to wake up the sleeping barber. If additional customers arrive

while the barber is cutting a customer's hair, they either sit down (if there are empty chairs) or

leave the shop (if all chairs are full).

4.2. Program implementation

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#include <sys/shm.h>

#define CUSTOMERS 0

#define BARBERS 1

#define MUTEX 2

#define CHAIRS 5

void up(int sem_id,int sem_num,struct sembuf *semaphore) {

semaphore->sem_num=sem_num;

semaphore->sem_op=1;

semaphore->sem_flg=0;

semop(sem_id,semaphore,1);

}

void down(int sem_id,int sem_num,struct sembuf *semaphore) {

semaphore->sem_num=sem_num;

semaphore->sem_op=-1;

semaphore->sem_flg=0;

semop(sem_id,semaphore,1);

}

void initSem(int sem_id,int sem_num,int val) {

union semnum {

int val;

struct semid_ds *buf;

unsigned short *array;

}

argument;

argument.val=val;

semctl(sem_id,sem_num,SETVAL,argument);

}

int main() {

int sem_key=1111,shm_key=2222;

int sem_id,shm_id;

Page 19: os lab pdf

19

int *waiting;

struct sembuf semaphore;

int count=1;

shm_id=shmget(shm_key,sizeof(int),IPC_CREAT|0666);

sem_id=semget(sem_key,3,IPC_CREAT|0666);

waiting=shmat(shm_id,NULL,0);

*waiting=0;

initSem(sem_id,CUSTOMERS,0);

initSem(sem_id,BARBERS,0);

initSem(sem_id,MUTEX,1);

printf("There are %d chairs.\n",CHAIRS);

if(fork()) {

/* The barber part. */

while(1) {

down(sem_id,CUSTOMERS,&semaphore);

down(sem_id,MUTEX,&semaphore);

*waiting=*waiting-1;

up(sem_id,BARBERS,&semaphore);

up(sem_id,MUTEX,&semaphore);

printf("The barber is now cutting hair.\n");

sleep(6); /* Slowly cut the hair */

}

}

else {

/* The customer part. */

while(1) {

sleep(1); /* Customers come in fast */

down(sem_id,MUTEX,&semaphore);

if(*waiting < CHAIRS) {

printf("Customer %d is seated.\n",count++);

*waiting=*waiting+1;

up(sem_id,CUSTOMERS,&semaphore);

up(sem_id,MUTEX,&semaphore);

}

else

{

printf("Customer %d left the shop.\n",count++);

up(sem_id,MUTEX,&semaphore);

}

}

}

}

Page 20: os lab pdf

20

5. Dining Philospher Problem

5.1 Statement and algorithm

Five silent philosophers sit at a table around a bowl of food. A fork is placed between each pair

of adjacent philosophers. Each philosopher must alternately think and eat. However, a

philosopher can only eat food when he has both left and right forks. Each fork can be held by

only one philosopher and so a philosopher can use the fork only if it's not being used by another

philosopher. After he finishes eating, he needs to put down both forks so they become available

to others. A philosopher can grab the fork on his right or the one on his left as they become

available, but can't start eating before getting both of them.

Eating is not limited by the amount of food left: assume an infinite supply.

The problem is how to design a discipline of behavior such that each philosopher won't

starve; i.e., can forever continue to alternate between eating and thinking assuming that any

philosopher cannot know when others may want to eat or think.

5.2. Program implementation

#include<stdio.h>

#include<pthread.h>

#include<semaphore.h>

#define cls() printf("33[H33[J]]")

#define EATINGTIME 1

void * philosopher1();

void * philosopher2();

void * philosopher3();

void * philosopher4();

void * philosopher5();

int end=0;

int main()

{

char a[2];

pthread_t t1,t2,t3,t4,t5;

pthread_attr_t at1;

pthread_attr_init(&at1);

pthread_attr_setdetachstate(&at1,PTHREAD_CREATE_DETACHED);

sem_init(&sem15,0,1);

sem_init(&sem12,0,1);

sem_init(&sem23,0,1);

sem_init(&sem34,0,1);

sem_init(&sem45,0,1);

cls();

Page 21: os lab pdf

21

printf("\n\n\n\n\n\n");

printf("____________________________________________________________________________

_________");

printf("\n\n\n\t\t\tDINNING PHILOSOPHER PROBLEM.");

printf("\n\t\t\t____________________________");

printf("\n\n\t\tNO. OF PHILOSOPHERS :5");

printf("\n\n\t\tNO. OF FORKS(SPOONS):5\n");

printf("____________________________________________________________________________

_________");

printf("\n\n\n\t\tPRESS ENTER TO CONTINUE…………………");

fgets(a,2,stdin);

cls();

pthread_create(&t1,&at1,philosopher1,NULL);

pthread_create(&t2,&at1,philosopher2,NULL);

pthread_create(&t3,&at1,philosopher3,NULL);

pthread_create(&t4,&at1,philosopher4,NULL);

pthread_create(&t5,&at1,philosopher5,NULL);

while(end!=5)

{

}

}

void * philosopher1()

{

int i=0;

printf("\n\t\tPHILOSOPHER-1 THINKING.\n");

while(i<EATINGTIME)

{

sleep(1);

sem_wait(&sem15);

sem_wait(&sem12);

printf("\n\t\t\t* PHILOSOPHER-1 EATING.\n");

sleep(1);

sem_post(&sem15);

sem_post(&sem12);

printf("\n\t\tPHILOSOPHER-1 THINKING.\n");

i++;

}

end++;

}

void * philosopher2()

{

int i=0;

printf("\n\t\tPHILOSOPHER-2 THINKING.\n");

while(i<EATINGTIME)

{

sleep(1);

sem_wait(&sem12);

sem_wait(&sem23);

printf("\n\t\t\t* PHILOSOPHER-2 EATING.*\n");

sleep(1);

Page 22: os lab pdf

22

sem_post(&sem12);

sem_post(&sem23);

printf("\n\t\tPHILOSOPHER-2 THINKING.\n");

i++;

}

end++;

}

void * philosopher3()

{

int i=0;

printf("\n\t\tPHILOSOPHER-3 THINKING.\n");

while(i<EATINGTIME)

{

sleep(1);

sem_wait(&sem23);

sem_wait(&sem34);

printf("\n\t\t\t* PHILOSOPHER-3 EATING.*\n");

sleep(1);

sem_post(&sem23);

sem_post(&sem34);

printf("\n\t\tPHILOSOPHER-3 THINKING.\n");

i++;

}

end++;

}

void * philosopher4()

{

int i=0;

printf("\n\t\tPHILOSOPHER-4 THINKING.\n");

while(i<EATINGTIME)

{

sleep(1);

sem_wait(&sem34);

sem_wait(&sem45);

printf("\n\t\t\t* PHILOSOPHER-4 EATING.*\n");

sleep(1);

sem_post(&sem34);

sem_post(&sem45);

printf("\n\t\tPHILOSOPHER-4 THINKING.\n");

i++;

}

end++;

}

void * philosopher5()

{

int i=0;

printf("\n\t\tPHILOSOPHER-5 THINKING.\n");

while(i<EATINGTIME)

{

Page 23: os lab pdf

23

sleep(1);

sem_wait(&sem45);

sem_wait(&sem15);

printf("\n\t\t\t* PHILOSOPHER-5 EATING.*\n");

sleep(1);

sem_post(&sem45);

sem_post(&sem15);

printf("\n\t\tPHILOSOPHER-5 THINKING.\n");

i++;

}

end++;

}