home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************/
- /* philosophers.c */
- /* demo of some of the features of odin.library 2.5 */
- /* Created 6-Jun-90 */
- /* Last modified 27-Aug-90 */
- /* Link with odinglue.o */
- /*****************************************************************/
-
- #include "exec/types.h"
- #include "exec/semaphores.h"
- #include "stdio.h"
- #include "odin.h"
-
- struct Library *OpenLibrary();
-
- #define PHILONUM 4 /* number of philosophers */
-
- struct OdinBase *OdinBase; /* the global baseptr */
-
- /* structure of allocation-envelope */
- struct Forks {
- Envelope e;
- BOOL inuse[PHILONUM];
- };
-
- /* argument for the philosopher processes */
- struct PEnv {
- Envelope e;
- int num;
- };
-
- struct Forks *the_forks;
- struct SignalSemaphore xx;
-
- /* protect C-functions that are not re-entrant */
- #define CR(s) ObtainSemaphore(&xx); { s } ReleaseSemaphore(&xx);
- #define USE(n) (copy_forks->inuse[n])?printf("%d ",n):printf(" ")
-
- char s[PHILONUM][20]; /* holds the names */
-
- /* make name with single-digit suffix */
- char *philoname(str,name,num)
- char *str,*name;
- int num;
- {
- register char *s2;
-
- s2 = str;
- while(*name) *s2++ = *name++;
- *s2++ = num + '0';
- *s2 = 0;
- return str;
- }
-
- /* the body of the new processes, must be re-entrant */
- struct PEnv *philosopher(env)
- struct PEnv *env;
- {
- int i,me;
- struct Forks *f;
- FILE *win;
-
- me = env->num;
-
- /* open monitorwindow */
- switch(me) {
- case 0: CR(win = fopen("CON:10/10/200/80/Philo0","w");)
- break;
- case 1: CR(win = fopen("CON:220/10/200/80/Philo1","w");)
- break;
- case 2: CR(win = fopen("CON:10/115/200/80/Philo2","w");)
- break;
- case 3: CR(win = fopen("CON:220/115/200/80/Philo3","w");)
- break;
- default:
- break;
- }
-
- /* let each philosopher eat 20 times */
- for(i = 0; i < 20; i++) {
- f = (struct Forks *)AwaitNamedEnvelope("Forkalloc");
- while (f->inuse[me] || f->inuse[(me+1) % PHILONUM]) {
- Out(f);
- f = (struct Forks *)AwaitNamedEnvelope("Forkalloc");
- }
-
- /* no one used the forks, now sit on them */
- f->inuse[me] = TRUE;
- f->inuse[(me+1) % PHILONUM] = TRUE;
-
- /* allow others to look at me eating */
- Out(f);
-
- /* eat */
- CR(fprintf(win,"philosopher #%d eating\n",me);)
-
- /* release the forks */
- f = (struct Forks *)AwaitNamedEnvelope("Forkalloc");
- f->inuse[me] = FALSE;
- f->inuse[(me+1) % PHILONUM] = FALSE;
- Out(f);
- }
- CR(fclose(win);)
- return(env);
- }
-
- main()
- {
- int i;
- struct PEnv *env;
- struct Forks *copy_forks;
-
- /* set up semaphore to protect C library routines that are */
- /* not re-entrant */
-
- InitSemaphore(&xx);
-
- /* open odin.library */
- OdinBase = (struct OdinBase *)OpenLibrary("RAM:odin.library",0L);
- if(OdinBase == NULL) {
- printf("Error: Couldn't open odin.library\n");
- exit(10);
- }
-
- /* now create a few philosopher-processes */
- for(i = 0; i < PHILONUM; i++) {
- env = (struct PEnv *)CreateEnvelope(
- philoname(&s[i][0],"phil#",i),
- (ULONG)sizeof(struct PEnv));
- env->e.e_proc = philosopher;
- env->num = i;
- (void)Eval(env,0L,8000L,EVAL_PROCESS);
- }
-
- /* init the allocation envelope */
- the_forks = (struct Forks *)CreateEnvelope("Forkalloc",
- (ULONG)sizeof(struct Forks));
-
- for(i = 0; i < PHILONUM; i++) the_forks->inuse[i] = FALSE;
-
- Out(the_forks);
-
- copy_forks = (struct Forks *)CreateEnvelope("Forkalloc",
- (ULONG)sizeof(struct Forks));
- while((env = (struct PEnv *)PollNamedEnvelope(&s[0][0])) == NULL) {
- Rd(copy_forks);
- CR( printf("Forks in use: ");
- USE(0);
- USE(1);
- USE(2);
- USE(3);
- printf("\n");
- )
- }
-
- DisposeEnvelope(copy_forks);
- DisposeEnvelope(env);
-
- /* now wait for other philosophers to die */
- for(i = 1; i < PHILONUM; i++) {
- DisposeEnvelope(AwaitNamedEnvelope(&s[i][0]));
- }
-
- /* get rid of allocation-envelope, wait at most 10 secs */
- DisposeEnvelope(AwaitTimed("Forkalloc",10L,0L));
- CloseLibrary(OdinBase);
- }
-