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);
}
}