CS644 Example User-level programs for Xinu, in $xuex

Build with “make U=mon-worker”, “make U=prodcons” with $xuex/Makefile

/* mon-worker.c: example app for Xinu with 2 processes */

/* special XINU stdio.h, based on Linux stdio.h, see $xuinc/stdio.h */

#include <stdio.h>

/* Linux string.h in /groups/ulab/gcc-cross/i386-linuxaout/include */

#include <string.h>

 

int workcount = 0;

#define BUFLEN 80

void work(int ncycles);

void docycle(int n);

 

void main(void)

{

  int nwork;

  char buf[BUFLEN];

 

  printf("Enter cycles of work for worker to do: ");

  fgets(buf,BUFLEN,CONSOLE);

  sscanf(buf,"%d",&nwork);

  printf("Type <CR> for progress report, control-space or ~r to abort\n");

  resume(create(work,1000,20,"worker",1,nwork));

  while (1)

    {

      getc(CONSOLE);            /* wait for <CR> from keyboard */

      printf("worker at # %d\n",workcount);  /* report on worker */

    }

}

/* worker top-level function: do ncycles of "work" */

void work(int ncycles)

{

  int i;

  printf("Worker starting\n");

  for (i=1;i<=ncycles;i++)

    {

      docycle(i);               /* do ith work cycle */

      workcount++;              /* count it where parent can see it */

    }

}

/* one "cycle" of worker work */

void docycle(int n)

{

  int i;

  char buf1[] = "abcdefghijklmnopqrstuvwxyz";

  char buf2[BUFLEN];

 

  for (i=0;i<n;i++)

      strcpy(buf2, buf1);       /* do a little work */

}

 

 

 

/* prodcons.c - main, prod2, cons2, with N spots in shared buffer  */

#include <stdio.h>

#define N 10

/* Note that this simple queue is meant to be used with semaphores--

 * on its own, it doesn't know if it's empty or full!  Both cases

 * have head == tail.  One semaphore is enough to keep track of this.

 * Two semaphores are needed for control of both producer and consumer.

 */

int a[N];  /* shared buffer */

int head, tail; /* for buffer used as queue */

void prod2(int consumed, int produced, int mutex);

void cons2(int consumed, int produced, int mutex);

 

/*--------------------------------------------------------------------------

 *    main --  producer and consumer process synchronized with semaphores

 *--------------------------------------------------------------------------

*/

void main(void)

{

  int produced, consumed, mutex;

 

  consumed = screate(N);        /* scount = number of empty spots in buffer */

  produced = screate(0);        /* scount = number of filled spots in buffer */

  mutex = screate(1);

  head = tail = 0;              /* initialize buffer as queue */

  resume( create(cons2, 1000, 20, "cons", 3, consumed, produced, mutex));

  resume( create(prod2, 1000, 20, "prod", 3, consumed, produced, mutex));

}

 

/*----------------------------------------------------------------------------

 *    prod2   --  increment n 200 times, waiting for space in buffer

 *----------------------------------------------------------------------------

 */

void prod2(int consumed, int produced, int mutex)

{

    int i, n = 0;

 

    for( i=1; i<=200; i++ )  {

        wait(consumed);

        n++;                    /* "produce" another number */

        wait(mutex);

        a[head++] = n;          /* enqueue(n) */

        if (head >= N)          /* ... */

            head = 0;           /* ... */

        signal(mutex);

        signal(produced);

    }

}

 

/*----------------------------------------------------------------------------

 *  cons2 -- print 200 times, waiting as needed for some numbers to be produced

 *----------------------------------------------------------------------------

 */

void cons2(int consumed, int produced, int mutex)

{

    int i, n;

 

    for( i=1;  i<=200; i++ )  {

        wait(produced);

        wait(mutex);

        n = a[tail++];          /* n = dequeue() */

        if (tail >= N)          /* ... */

            tail = 0;           /* ... */

        signal(mutex);

        printf("number consumed is %d \n",  n);

        signal(consumed);

    }

}