/* David A. Hess CS382 Dining Philosophers */ #include #include #include #include #include #include #include #include extern int errno; #define SEMPERM 0600 initsem(); p(); v(); int Prnt[2]; char prntcmd[34]; char *phil_pkup_lt[5],*phil_pkup_rt[5],*phil_ptdn_lt[5]; char *phil_ptdn_rt[5],*phil_sit[5],*phil_eat[5],*phil_think[5]; struct stat x; int initsem(semkey,semvalue) key_t semkey; int *semvalue; { int status = 0, semid; if((semid = semget(semkey,1,SEMPERM|IPC_CREAT|IPC_EXCL))==-1) { if(errno == EEXIST) semid = semget(semkey,1,0); }else status = semctl(semid,0,SETVAL,semvalue); if(semid == -1 || status == -1) { perror("initsem failed"); return(-1); }else return semid; } int p(semid) int semid; { struct sembuf p_buf; p_buf.sem_num = 0; p_buf.sem_op = -1; p_buf.sem_flg = SEM_UNDO; if(semop(semid, &p_buf, 1) == -1) { perror("p(semid) failed"); exit(1); }else return(0); } int v(semid) int semid; { struct sembuf v_buf; v_buf.sem_num = 0; v_buf.sem_op = 1; v_buf.sem_flg = SEM_UNDO; if(semop(semid, &v_buf, 1) == -1) { perror("v(semid) failed"); exit(1); }else return(0); } main() { int frk[5], room, i; key_t semkey = 0x200; int phil0id,phil1id,phil2id,phil3id,phil4id,retval; int semvalue = 1; if(pipe(Prnt) < 0) perror("pipe Cntl fail"); phil_pkup_lt[0] = "philosopher_1_has_left_fork "; phil_pkup_rt[0] = "philosopher_1_has_right_fork "; phil_ptdn_lt[0] = "philosopher_1_put_down_left_fork "; phil_ptdn_rt[0] = "philosopher_1_put_down_right_fork"; phil_sit[0] = "philosopher_1_in_seat "; phil_eat[0] = "philosopher_1_is_eating "; phil_think[0] = "philosopher_1_is_thinking "; phil_pkup_lt[1] = "philosopher_2_has_left_fork "; phil_pkup_rt[1] = "philosopher_2_has_right_fork "; phil_ptdn_lt[1] = "philosopher_2_put_down_left_fork "; phil_ptdn_rt[1] = "philosopher_2_put_down_right_fork"; phil_sit[1] = "philosopher_2_in_seat "; phil_eat[1] = "philosopher_2_is_eating "; phil_think[1] = "philosopher_2_is_thinking "; phil_pkup_lt[2] = "philosopher_3_has_left_fork "; phil_pkup_rt[2] = "philosopher_3_has_right_fork "; phil_ptdn_lt[2] = "philosopher_3_put_down_left_fork "; phil_ptdn_rt[2] = "philosopher_3_put_down_right_fork"; phil_sit[2] = "philosopher_3_in_seat "; phil_eat[2] = "philosopher_3_is_eating "; phil_think[2] = "philosopher_3_is_thinking "; phil_pkup_lt[3] = "philosopher_4_has_left_fork "; phil_pkup_rt[3] = "philosopher_4_has_right_fork "; phil_ptdn_lt[3] = "philosopher_4_put_down_left_fork "; phil_ptdn_rt[3] = "philosopher_4_put_down_right_fork"; phil_sit[3] = "philosopher_4_in_seat "; phil_eat[3] = "philosopher_4_is_eating "; phil_think[3] = "philosopher_4_is_thinking "; phil_pkup_lt[4] = "philosopher_5_has_left_fork "; phil_pkup_rt[4] = "philosopher_5_has_right_fork "; phil_ptdn_lt[4] = "philosopher_5_put_down_left_fork "; phil_ptdn_rt[4] = "philosopher_5_put_down_right_fork"; phil_sit[4] = "philosopher_5_in_seat "; phil_eat[4] = "philosopher_5_is_eating "; phil_think[4] = "philosopher_5_is_thinking "; for(i=0;i<5;i++) { if((frk[i] = initsem(semkey,&semvalue)) < 0) { printf("Error initializing frk[%d] semaphore\n",i); exit(1); } printf("frk[%d] initialized to semid %d\n",i,frk[i]); retval = semctl(frk[i],0,GETVAL,semvalue); printf("frk[%d] initialized to semvalue %d\n",i,retval); semkey += 0x010; } semvalue = 4; if((room = initsem(semkey,&semvalue)) < 0) { printf("Error initializing room semaphore\n"); exit(1); }else printf("room initialized to semid %d\n",room); retval = semctl(room,0,GETVAL,semvalue); printf("room initialized to semvalue %d\n",retval); if((phil0id = fork()) < 0) { perror("phil 0 failed\n"); exit(1); }else if(phil0id == 0) { close(Prnt[0]); philosopher(0,frk,room); }else if((phil1id = fork()) < 0) { perror("phil 1 failed\n"); exit(1); }else if(phil1id == 0) { close(Prnt[0]); philosopher(1,frk,room); }else if((phil2id = fork()) < 0) { perror("phil 2 failed\n"); exit(1); }else if(phil2id == 0) { close(Prnt[0]); philosopher(2,frk,room); }else if((phil3id = fork()) < 0) { perror("phil 3 failed\n"); exit(1); }else if(phil3id == 0) { close(Prnt[0]); philosopher(3,frk,room); }else if((phil4id = fork()) < 0) { perror("phil 4 failed\n"); exit(1); }else if(phil4id == 0) { close(Prnt[0]); philosopher(4,frk,room); }else { close(Prnt[1]); wait(0); printf("Now printing from pipe\n"); if(fstat(Prnt[0],&x) == -1) perror("fstat Prnt\n"); while(x.st_size > 0) { read(Prnt[0],prntcmd,33); for(i = 0; i < 33 && prntcmd[i] != ' '; i++); prntcmd[i] = '\0'; printf("%s\n",prntcmd); if(fstat(Prnt[0],&x) == -1) perror("fstat Prnt\n"); } printf("Time to stop. Now killing semaphores.\n"); retval = semctl(room,0,IPC_RMID,4); for(i=0;i<5;i++) retval = semctl(frk[i],0,IPC_RMID,1); } exit(0); } int philosopher(i,frk,room) int i, frk[], room; { int j,retval; int *semvalue; for(j=0;j<2;j++) { fprintf(stderr,"%s\n",phil_think[i]); write(Prnt[1],phil_think[i],33); sleep(1); p(room); fprintf(stderr,"%s\n",phil_sit[i]); write(Prnt[1],phil_sit[i],33); /* retval = semctl(room,0,GETVAL,semvalue); fprintf(stderr,"room semvalue %d\n",retval); sleep(1); */ p(frk[i]); fprintf(stderr,"%s\n",phil_pkup_lt[i]); write(Prnt[1],phil_pkup_lt[i],33); /* retval = semctl(frk[i],0,GETVAL,semvalue); fprintf(stderr,"frk[%d] semid %d semvalue %d\n",i,frk[i],retval); sleep(1); */ p(frk[(i+1)%5]); fprintf(stderr,"%s\n",phil_pkup_rt[i]); write(Prnt[1],phil_pkup_rt[i],33); /* retval = semctl(frk[(i+1)%5],0,GETVAL,semvalue); fprintf(stderr,"frk[%d] semid %d semvalue %d\n",((i+1)%5),frk[(i+1)%5],retval); */ fprintf(stderr,"%s\n",phil_eat[i]); write(Prnt[1],phil_eat[i],33); sleep(2); v(frk[(i+1)%5]); fprintf(stderr,"%s\n",phil_ptdn_rt[i]); write(Prnt[1],phil_ptdn_rt[i],33); /* retval = semctl(frk[(i+1)%5],0,GETVAL,semvalue); fprintf(stderr,"frk[%d] semid %d semvalue %d\n",((i+1)%5),frk[(i+1)%5],retval); sleep(1); */ v(frk[i]); fprintf(stderr,"%s\n",phil_ptdn_lt[i]); write(Prnt[1],phil_ptdn_lt[i],33); /* retval = semctl(frk[i],0,GETVAL,semvalue); fprintf(stderr,"frk[%d] semid %d semvalue %d\n",i,frk[i],retval); */ v(room); /* retval = semctl(room,0,GETVAL,semvalue); fprintf(stderr,"room semvalue %d\n",retval); sleep(1); */ } printf("phil %d is done\n",i); exit(0); }