/* * dinphil - The Dining Philosophers Problem * * By: Theo Van Dinter - 96/10/07 * * * This program was written to test a few different methods of solving the * dining philosopher's problem. Due to various work related problems * (ie: I have too much work to do ...), I have made no attempts to * complete the additional work for this project. This will become * obvious as you go through the code. (Notice that the variable 'type' * can only be true or false (hier or lr respectfully). Most things are * based upon this. It's a kluge, and had I had more time, it would be * implemented in a much nicer fashion, but as I've come to say: It * works. * * BTW: I added in a SPONCOM (Spontaneous Combustion) State for the * philosophers... It's only used if there's a problem getting or * putting down a chopstick (ie: semaphore error). Basically, the * philosopher goes 'poof', and takes any chopsticks they're holding * with them... * * BTW2: The code worked earlier, but I found out that the way I was handling * the pickup/number status codes was wrong. I figured that the status would * be the number if the phil. was trying to pickup his first stick, and then * it would be 'P' after the first was picked up and before the second one. * I then found out that the status should be a number whenever the philosopher * is trying to pickup a chopstick, and only 'P' for the brief 1/10th second * pause in between getting the sticks. This set of code now properly prints * that out. * * BTW3: Per Prof. Wills word, I am passing in this assignment late. * * BTW4: Due to the above bit, the deadlock detection broke (since it was only * looking for the "PICKUP" state. It works now. * */ #include #include #include #include #define MAXPHIL 5 #define EAT 'E' #define THINK 'T' #define PICKUP 'P' #define RELEASE 'R' #define SPONCOM 'S' #define FREE -1 #define SOLVPROB sleep(1) #define CHOWDOWN sleep(1) char *rgPhil, *rgStick; int *Sticks[MAXPHIL]; int cntPhil, philpids[MAXPHIL], type; int CreateProcess(void (*pFunc)(),int dvalue); int InitStuff(void); int CleanupStuff(void); int lchop(int); int rchop(int); void Philosopher(int); int GetResource(int); int ReleaseResource(int); extern int shmcreate(int); void main(int argc, char *argv[]) { struct timeval curtime; struct timezone tzone; char statusdisp[3][3]={" ","->","<-"}; int loop, loo, deadchk; if (argc!=3) /* Not correct! */ { printf("\nNot enough/too many parameters!\n\nUsage: %s [# of Phils] [Swapping Way]\n\n",argv[0]); printf("[# of Phils] Range between 2 and %d Philosophers.\n",MAXPHIL); printf("[Swapping Way] How to deal with the chopsticks... 'lr' for left-right,\n"); printf(" and 'hier' for hierarchical are the only ones supported.\n"); printf("\n"); exit(1); } cntPhil=atoi(argv[1]); if (cntPhil>MAXPHIL || cntPhil<2) { printf("\n# of Philosophers is invalid! Valid is 2-%d!\n",MAXPHIL); exit(1); } if (!strcasecmp(argv[2],"lr")) /* lr */ type=0; else if (!strcasecmp(argv[2],"hier")) /* hier */ type=1; else /* blah ... */ { printf("\nYou entered an unsupported mode. Sorry.\n"); exit(1); } /* Set the timezone structure for the gettimeofday() call below ... */ tzone.tz_minuteswest=300; tzone.tz_dsttime=DST_USA; if (InitStuff()==-1) /* Error! */ { printf("Error with InitStuff()!\n"); exit(1); } for (loop=0;loop<10*cntPhil;loop++) { gettimeofday(&curtime,&tzone); /* I assume no errors... grrr... */ printf("%9lu.%-6lu ",curtime.tv_sec,curtime.tv_usec); deadchk=0; for (loo=0;loo='0'&&rgPhil[loo]<='4') { if (!type&&rgPhil[loo]==rchop(loo)+'0') /* lr */ deadchk++; else if (type) /* hier */ if ((rgPhil[loo]==rchop(loo)+'0'&&rchop(loo)>lchop(loo))|| (rgPhil[loo]==lchop(loo)+'0'&&lchop(loo)>rchop(loo))) deadchk++; } /* These printing functions aren't the 'nicest' in existance, but they work... */ if (rgPhil[loo]==EAT) printf("%s%c%s",statusdisp[1],rgPhil[loo],statusdisp[2]); else if (rgPhil[loo]==THINK) printf("%s%c%s",statusdisp[0],rgPhil[loo],statusdisp[0]); else if (rgPhil[loo]==SPONCOM) printf("%s%c%s",statusdisp[0],rgPhil[loo],statusdisp[0]); else if (!type) /* lr */ { if (rgPhil[loo]==PICKUP) printf("%s%c%s",statusdisp[1],rgPhil[loo],statusdisp[0]); else if (rgPhil[loo]>='0' && rgPhil[loo]<='4') { if (rgPhil[loo]==lchop(loo)) printf("%s%c%s",statusdisp[2],rgPhil[loo],statusdisp[0]); else printf("%s%c%s",statusdisp[1],rgPhil[loo],statusdisp[1]); } else if (rgPhil[loo]==RELEASE) printf("%s%c%s",statusdisp[0],rgPhil[loo],statusdisp[2]); } else if (type) /* hier */ { if (rgPhil[loo]==PICKUP) printf("%s%c%s",lchop(loo)='0') { if (lchop(loo)rchop(loo) && rchop(loo)==rgPhil[loo]) printf("%s%c%s",statusdisp[0],rgPhil[loo],statusdisp[1]); else if (lchop(loo)>rchop(loo)) /* left one */ printf("%s%c%s",statusdisp[2],rgPhil[loo],statusdisp[2]); } else if (rgPhil[loo]==RELEASE) printf("%s%c%s",lchop(loo)=cntPhil) /* Deadlock! */ { printf("\nDeadlock!\n"); break; } sleepms(500); /* Pause 1/2 second. */ } if (CleanupStuff()==-1) /* Cleanup Philosophers/Shared Memory/etc... */ { printf("Error with CleanupStuff()!\n"); exit(1); } exit(0); /* Exit, error status 0 - Everything OK! */ } /* * CreateProcess - 96/09/09 * * CreateProcess will now take two parameters, and pass the second to the * forked child. - Originally written for OS-1 Project #2. * */ int CreateProcess(void (*pFunc)(),int dvalue) { int pid; if ((pid = fork()) == 0) /* We're the child */ { (*pFunc)(dvalue); /* Call function with value */ exit(0); /* If function doesn't quit, we'll die implicitly */ } return(pid); /* Return fork() value to the parent (-1 for error, PID otherwise) */ } int InitStuff() { int loop; rgPhil = (char *)shmcreate(cntPhil); rgStick= (char *)shmcreate(cntPhil); if (rgPhil==(char *)-1 || rgStick==(char *)-1) /* Error! */ return(-1); for(loop=0;loop