home *** CD-ROM | disk | FTP | other *** search
- /*
- * 5 dining philosophers: a sample rtx demo for gcc
- * simulation of the classic dining philosophers problem.
- *
- * ++jrb
- * bang: {any internet host}!dsrgsun.ces.CWRU.edu!bammi
- * domain: bammi@dsrgsun.ces.CWRU.edu
- * GEnie: J.Bammi
- * CIS: 71515,155
- */
- #include "grtxbind.h"
-
- #ifndef NULL
- #define NULL ((void *)0)
- #endif
-
- #define fflush(x) /* nothing */
- #define printf(x) Bconws(x)
- #define fprintf(s,x) Bconws(x)
- #define clear() printf("\033E")
- #define moveto(r,c) printf("\033Y"), Bconout(2,r+040),Bconout(2,c+040)
- #define Rand() (Random() >> 8)
- void Bconws();
-
- typedef struct {
- char *name; /* process name */
- char *pid; /* pid of process */
- short event; /* event (ready) condition */
- int me; /* my index */
- int left; /* index of phil to left */
- int right; /* index of phil to right */
- int col; /* column for printing */
- long message[4]; /* message buffer */
- short eventbuf; /* event buffer */
- } PHIL;
-
- /* 5 philosophers on a round table */
- PHIL phils[] = {
- {"phil-0", (char *)NULL, 0x001, 0, 4, 1, 0, 0L, 0L, 0L, 0L, 0 },
- {"phil-1", (char *)NULL, 0x002, 1, 0, 2, 16, 0L, 0L, 0L, 0L, 0 },
- {"phil-2", (char *)NULL, 0x004, 2, 1, 3, 32, 0L, 0L, 0L, 0L, 0 },
- {"phil-3", (char *)NULL, 0x008, 3, 2, 4, 48, 0L, 0L, 0L, 0L, 0 },
- {"phil-4", (char *)NULL, 0x010, 4, 3, 0, 64, 0L, 0L, 0L, 0L, 0 }
- };
-
- /* forks: number of forks available to philosopher i
- * note: mutex access at all times (ie only one process may read/write
- * any element of forks at one time, implemented via semaphore).
- * usage:
- * at any time forks[i] can only be 0, 1, or 2
- * when a philosopher [i] wants to eat, forks[i] must be 2,
- * if it is
- * decrement forks to the right and left by one and start eating
- * otherwise
- * wait for event phil[i].event (ready condition for phil i) to occur.
- *
- * when a philosopher is done eating,
- * increments forks to left and right
- * if forks[left] == 2 cause event phil[left].event
- * if forks[right] == 2 cause event phil[right].event
- */
- int forks [] = { 2, 2, 2, 2, 2 };
-
- /* fork semaphore (queue) */
- char *forkSemaphore;
-
- /* P/V on fork semaphore */
- #define Pfork(q) q_req (forkSemaphore, q, 0, 0L)
- #define Vfork(q) q_send(forkSemaphore, q)
-
- /* screen semaphore, for exclusive access to write to screen */
- char *screenSemaphore;
-
- /* P/V on screen semaphore */
- #define Pscreen(q) q_req (screenSemaphore, q, 0, 0L)
- #define Vscreen(q) q_send(screenSemaphore, q)
-
-
- /*
- * pickup
- * pickup both forks or wait until both avail
- */
- void pickup(phil)
- PHIL *phil; /* philosopher requesting forks */
- {
- Pfork(phil->message); /* mutually exclusive access to forks */
- if(forks[phil->me] != 2)
- {
- Vfork(phil->message); /* release */
- phil->eventbuf = phil->event;
- e_wait(&phil->eventbuf, 0, 0L); /* wait for ready condition */
- Pfork(phil->message);
- }
- /* get the two forks */
- forks[phil->left]--;
- forks[phil->right]--;
- Vfork(phil->message);
- }
-
- /*
- * putdown
- * done eating, put down forks,and signal any ready conditions
- */
- void putdown(phil)
- PHIL *phil;
- {
-
- Pfork(phil->message);
-
- /* drop forks and signal any events */
- if(++forks[phil->left] == 2)
- e_signal(phils[phil->left].pid, phils[phil->left].event);
- if(++forks[phil->right] == 2)
- e_signal(phils[phil->right].pid, phils[phil->right].event);
-
- Vfork(phil->message);
- }
-
- /*
- * philosopher process
- */
- void philosopher(phil)
- PHIL *phil;
- {
-
- Pscreen(phil->message);
- moveto(3, phil->col);
- printf(phil->name); fflush(stdout);
- Vscreen(phil->message);
-
- while(1)
- {
- Pscreen(phil->message);
- moveto(4, phil->col); printf(" Hungry "); fflush(stdout);
- Vscreen(phil->message);
- pickup(phil);
- /* eat */
- Pscreen(phil->message);
- moveto(4, phil->col); printf(" Eating "); fflush(stdout);
- Vscreen(phil->message);
- p_pause( (long)(((Rand() & 15) + 1) * 1000L) );
- putdown(phil);
- Pscreen(phil->message);
- moveto(4, phil->col); printf(" Thinking "); fflush(stdout);
- Vscreen(phil->message);
- p_pause( (long)(((Rand() & 15) + 1) * 1000L) );
- }
- /*NOTREACHED*/
- }
-
- /*
- * kill all live philosophers
- * free fork semaphore queue
- */
- void killall()
- {
- int i;
- for(i = 0; i < 5; i++)
- {
- if(phils[i].pid != NULL)
- {
- p_delete(phils[i].pid);
- moveto(4, phils[i].col);
- printf(" KILLED! "); fflush(stdout);
- }
- }
- q_delete(forkSemaphore);
- q_delete(screenSemaphore);
- }
-
- /*
- * print a int (short range only)
- */
- void printi(val)
- register int val;
- {
- register int j;
- register int div_idx;
- register int first;
- static int divisors[] = { 10000, 1000, 100, 10, 1 };
-
- /* Special Cases */
- if (val == 0)
- {
- Bconout(2, '0');
- return;
- }
- else if (val == -32768)
- {
- Bconws("-32768");
- return;
- }
-
- /* Get digit for each power of 10 and print them, skip leading 0's */
- first = div_idx = 0;
-
- if (val < 0)
- {
- Bconout(2, '-');
- val = -val;
- }
- while( div_idx < 5 )
- {
- if(((j = val / divisors[div_idx]) != 0) || first != 0)
- {
- Bconout(2, j + '0');
- first = 1;
- }
- val %= divisors[div_idx++];
- }
-
- }
-
- /*
- * the top level process, called after rtx initialization
- */
- void Top()
- {
- int i;
- long message[4];
- PHIL *stk;
-
- /* create semaphores */
- forkSemaphore = q_create("FORKSEM", 0);
- screenSemaphore = q_create("SCRSEM", 0);
-
- /* lower my prio (phils will be given higher prio) */
- p_priority((char *)NULL, -5);
- /* create the philosophers */
- for(i = 0; i < 5; i++)
- {
- stk = &phils[i];
- phils[i].pid = p_create(phils[i].name, p_priority((char *)NULL, 0)+1,
- p_slice((char *)NULL, 0), philosopher,
- (short)(sizeof(PHIL *)), &stk, 512L);
- if(phils[i].pid == (char *)NULL)
- {
- fprintf(stderr,"P_create failed\r\n");
- killall();
- return;
- }
-
- }
- moveto(10, 33); printf("Hit q to quit"); fflush(stdout);
- /* start it all up */
- Vscreen(message);
- Vfork(message);
-
- while((Crawio(0x00ff) & 0x07f) != 'q')
- {
- /* report process status */
- for(i = 0; i < 5; i++)
- {
- PROCESS_STATE status;
-
- p_info(phils[i].pid, &status);
- Pscreen(message);
- moveto(7, phils[i].col);
- if(status.EWAIT)
- printf(" event wait ");
- else if(status.QWAIT)
- printf(" queue wait ");
- else if(status.PAUSED)
- printf(" Paused ");
- else if(status.RUNNING)
- printf(" Running ");
- else if(status.READY)
- printf(" Ready ");
- else
- printf(" Unknown ");
- printi(forks[i]);
- fflush(stdout);
- Vscreen(message);
-
- p_pause(500L);
- }
- }
- killall();
- }
-
- void Bconws(str)
- char *str;
- {
- auto char *s = str;
-
- while(*s)
- Bconout(2, *s++);
- }
-
- extern BASEPAGE *_base;
-
- int main()
- {
- CONFIG config;
- char *RootPid;
-
- config.basepage = _base;
- config.max_proc = 32;
- config.max_msgs = 64;
- config.max_queues = 64;
- config.create_call = NULL;
- config.delete_call = NULL;
- config.switch_call = NULL;
-
- if((RootPid = rtx_install(&config)) == (char *)NULL)
- {
- fprintf(stderr, "microRtx could not be installed\r\n");
- exit(1);
- }
- clear();
-
- Top();
- rtx_remove();
- }
-