home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / lang / odinlib2_7.lzh / PHILOSOPHERS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-16  |  3.9 KB  |  168 lines

  1. /*****************************************************************/
  2. /* philosophers.c                                                */
  3. /* demo of some of the features of odin.library 2.5              */
  4. /* Created 6-Jun-90                                              */
  5. /* Last modified 27-Aug-90                                       */
  6. /* Link with odinglue.o                                          */
  7. /*****************************************************************/
  8.  
  9. #include    "exec/types.h"
  10. #include    "exec/semaphores.h"
  11. #include    "stdio.h"
  12. #include    "odin.h"
  13.  
  14. struct Library *OpenLibrary();
  15.  
  16. #define PHILONUM 4            /* number of philosophers */
  17.  
  18. struct OdinBase *OdinBase;        /* the global baseptr */
  19.  
  20. /* structure of allocation-envelope */
  21. struct Forks {
  22.     Envelope e;
  23.     BOOL inuse[PHILONUM];
  24. };
  25.  
  26. /* argument for the philosopher processes */
  27. struct PEnv {
  28.     Envelope e;
  29.     int    num;
  30. };
  31.  
  32. struct Forks *the_forks;
  33. struct SignalSemaphore xx;
  34.  
  35. /* protect C-functions that are not re-entrant */
  36. #define CR(s) ObtainSemaphore(&xx); { s } ReleaseSemaphore(&xx);
  37. #define USE(n) (copy_forks->inuse[n])?printf("%d ",n):printf("  ")
  38.  
  39. char s[PHILONUM][20];            /* holds the names */
  40.  
  41. /* make name with single-digit suffix */
  42. char *philoname(str,name,num)
  43. char *str,*name;
  44. int  num;
  45. {
  46.     register char *s2;
  47.  
  48.     s2 = str;
  49.     while(*name) *s2++ = *name++;
  50.     *s2++ = num  + '0';
  51.     *s2 = 0;
  52.     return str;
  53. }
  54.  
  55. /* the body of the new processes, must be re-entrant */
  56. struct PEnv *philosopher(env)
  57. struct PEnv *env;
  58. {
  59.     int i,me;
  60.     struct Forks *f;
  61.     FILE *win;
  62.  
  63.     me = env->num;
  64.  
  65.     /* open monitorwindow */
  66.     switch(me) {
  67.         case 0:    CR(win = fopen("CON:10/10/200/80/Philo0","w");)
  68.             break;
  69.         case 1: CR(win = fopen("CON:220/10/200/80/Philo1","w");)
  70.             break;
  71.         case 2: CR(win = fopen("CON:10/115/200/80/Philo2","w");)
  72.             break;
  73.         case 3: CR(win = fopen("CON:220/115/200/80/Philo3","w");)
  74.             break;
  75.         default:
  76.             break;
  77.     }
  78.  
  79.     /* let each philosopher eat 20 times */
  80.     for(i = 0; i < 20; i++) {
  81.         f = (struct Forks *)AwaitNamedEnvelope("Forkalloc");
  82.         while (f->inuse[me] || f->inuse[(me+1) % PHILONUM]) {
  83.             Out(f);
  84.             f = (struct Forks *)AwaitNamedEnvelope("Forkalloc");
  85.         }
  86.  
  87.         /* no one used the forks, now sit on them */
  88.         f->inuse[me] = TRUE;
  89.         f->inuse[(me+1) % PHILONUM] = TRUE;
  90.  
  91.         /* allow others to look at me eating */
  92.         Out(f);
  93.  
  94.         /* eat */
  95.         CR(fprintf(win,"philosopher #%d eating\n",me);)
  96.  
  97.         /* release the forks */
  98.         f = (struct Forks *)AwaitNamedEnvelope("Forkalloc");
  99.         f->inuse[me] = FALSE;
  100.         f->inuse[(me+1) % PHILONUM] = FALSE;
  101.         Out(f);
  102.     }
  103.     CR(fclose(win);)
  104.     return(env);
  105. }
  106.  
  107. main()
  108. {
  109.     int i;
  110.     struct PEnv *env;
  111.     struct Forks *copy_forks;
  112.  
  113.     /* set up semaphore to protect C library routines that are */
  114.     /* not re-entrant */
  115.  
  116.     InitSemaphore(&xx);
  117.  
  118.     /* open odin.library */
  119.     OdinBase = (struct OdinBase *)OpenLibrary("RAM:odin.library",0L);
  120.     if(OdinBase == NULL) {
  121.         printf("Error: Couldn't open odin.library\n");
  122.         exit(10);
  123.     }
  124.  
  125.     /* now create a few philosopher-processes */
  126.     for(i = 0; i < PHILONUM; i++) {
  127.         env = (struct PEnv *)CreateEnvelope(
  128.             philoname(&s[i][0],"phil#",i),
  129.             (ULONG)sizeof(struct PEnv));
  130.         env->e.e_proc = philosopher;
  131.         env->num = i;
  132.         (void)Eval(env,0L,8000L,EVAL_PROCESS);
  133.     }
  134.  
  135.     /* init the allocation envelope */
  136.     the_forks = (struct Forks *)CreateEnvelope("Forkalloc",
  137.                         (ULONG)sizeof(struct Forks));
  138.  
  139.     for(i = 0; i < PHILONUM; i++) the_forks->inuse[i] = FALSE;
  140.  
  141.     Out(the_forks);
  142.  
  143.     copy_forks = (struct Forks *)CreateEnvelope("Forkalloc",
  144.                         (ULONG)sizeof(struct Forks));
  145.     while((env = (struct PEnv *)PollNamedEnvelope(&s[0][0])) == NULL) {
  146.         Rd(copy_forks);
  147.         CR(    printf("Forks in use: ");
  148.             USE(0);
  149.             USE(1);
  150.             USE(2);
  151.             USE(3);
  152.             printf("\n");
  153.         )
  154.     }
  155.  
  156.     DisposeEnvelope(copy_forks);
  157.     DisposeEnvelope(env);
  158.  
  159.     /* now wait for other philosophers to die */
  160.     for(i = 1; i < PHILONUM; i++) {
  161.         DisposeEnvelope(AwaitNamedEnvelope(&s[i][0]));
  162.     }
  163.  
  164.     /* get rid of allocation-envelope, wait at most 10 secs */
  165.     DisposeEnvelope(AwaitTimed("Forkalloc",10L,0L));
  166.     CloseLibrary(OdinBase);
  167. }
  168.