/* David A. Hess CS382 Dining Philosophers */ #include #include #include #include #include #include extern int errno; #define SEMPERM 0600 #define LIMIT 300 int Prnt[2]; unsigned char prntcmd[1]; char *lisp_cmd[5][7]; 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, j, k; key_t semkey = 0x200; int phil0id,phil1id,phil2id,phil3id,phil4id,retval; int semvalue = 1; if(pipe(Prnt) < 0) perror("pipe Prnt fail"); lisp_cmd[0][0] = "philosopher_1_has_left_fork"; lisp_cmd[0][1] = "philosopher_1_has_right_fork"; lisp_cmd[0][2] = "philosopher_1_put_down_left_fork"; lisp_cmd[0][3] = "philosopher_1_put_down_right_fork"; lisp_cmd[0][4] = "philosopher_1_in_seat"; lisp_cmd[0][5] = "philosopher_1_is_eating"; lisp_cmd[0][6] = "philosopher_1_is_thinking"; lisp_cmd[1][0] = "philosopher_2_has_left_fork"; lisp_cmd[1][1] = "philosopher_2_has_right_fork"; lisp_cmd[1][2] = "philosopher_2_put_down_left_fork"; lisp_cmd[1][3] = "philosopher_2_put_down_right_fork"; lisp_cmd[1][4] = "philosopher_2_in_seat"; lisp_cmd[1][5] = "philosopher_2_is_eating"; lisp_cmd[1][6] = "philosopher_2_is_thinking"; lisp_cmd[2][0] = "philosopher_3_has_left_fork"; lisp_cmd[2][1] = "philosopher_3_has_right_fork"; lisp_cmd[2][2] = "philosopher_3_put_down_left_fork"; lisp_cmd[2][3] = "philosopher_3_put_down_right_fork"; lisp_cmd[2][4] = "philosopher_3_in_seat"; lisp_cmd[2][5] = "philosopher_3_is_eating"; lisp_cmd[2][6] = "philosopher_3_is_thinking"; lisp_cmd[3][0] = "philosopher_4_has_left_fork"; lisp_cmd[3][1] = "philosopher_4_has_right_fork"; lisp_cmd[3][2] = "philosopher_4_put_down_left_fork"; lisp_cmd[3][3] = "philosopher_4_put_down_right_fork"; lisp_cmd[3][4] = "philosopher_4_in_seat"; lisp_cmd[3][5] = "philosopher_4_is_eating"; lisp_cmd[3][6] = "philosopher_4_is_thinking"; lisp_cmd[4][0] = "philosopher_5_has_left_fork"; lisp_cmd[4][1] = "philosopher_5_has_right_fork"; lisp_cmd[4][2] = "philosopher_5_put_down_left_fork"; lisp_cmd[4][3] = "philosopher_5_put_down_right_fork"; lisp_cmd[4][4] = "philosopher_5_in_seat"; lisp_cmd[4][5] = "philosopher_5_is_eating"; lisp_cmd[4][6] = "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); } semkey += 0x010; } semvalue = 4; if((room = initsem(semkey,&semvalue)) < 0) { printf("Error initializing room semaphore\n"); exit(1); } 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]); printf("(opal:reconnect-garnet)"); printf("(load \"/work/users/cs382/d.cl\")"); for(i = 0; i < LIMIT; i++) { read(Prnt[0],prntcmd,1); j = *prntcmd >> 4; k = *prntcmd & 0x0f; printf("%s\n",lisp_cmd[j][k]); } kill(phil0id,SIGKILL); kill(phil1id,SIGKILL); kill(phil2id,SIGKILL); kill(phil3id,SIGKILL); kill(phil4id,SIGKILL); 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,k,retval; int *semvalue; unsigned char phil_pkup_lt[1],phil_pkup_rt[1],phil_ptdn_lt[1],phil_ptdn_rt[1]; unsigned char phil_sit[1],phil_eat[1],phil_think[1]; k = i << 4; *phil_pkup_lt = k | 0; *phil_pkup_rt = k | 1; *phil_ptdn_lt = k | 2; *phil_ptdn_rt = k | 3; *phil_sit = k | 4; *phil_eat = k | 5; *phil_think = k | 6; write(Prnt[1],phil_think,1); sleep(1); while(1) { p(room); write(Prnt[1],phil_sit,1); p(frk[i]); write(Prnt[1],phil_pkup_lt,1); p(frk[(i+1)%5]); write(Prnt[1],phil_pkup_rt,1); write(Prnt[1],phil_eat,1); sleep(2); write(Prnt[1],phil_ptdn_rt,1); v(frk[(i+1)%5]); write(Prnt[1],phil_ptdn_lt,1); v(frk[i]); write(Prnt[1],phil_think,1); v(room); sleep(1); } exit(0); }