<?xml version='1.0' encoding='utf-8'?><!DOCTYPE nta PUBLIC '-//Uppaal Team//DTD Flat System 1.0//EN' 'http://www.docs.uu.se/docs/rtmv/uppaal/xml/flat-1_0.dtd'><nta><declaration>
//This model corresponds to the solution to the bounded-buffer
//Producer/Consumer Problem Using Semaphores discussed by Stallings
//in Figure 5.13 (Operating Systems, Fifth edition).
//Basically the same solution also is presented in Figure 2-12
//of Tanenbaum &amp; Woodhull (Operating Systems, Second edition)

//Model constructed by Frits Vaandrager on 15/3/06
//Ideas from Martijn Hendriks, Koen Vermeer, Justus Freijzer, and Bart Kerkhoff
//have been used in this model.

const int sizeofbuffer=1000;

const int M = 3;  //Number of semaphores
const int N = 2;  //Number of processes

//Names of semaphores

const int s = 0;
const int n = 1;
const int e = 2;

//Names of processes
const int producer = 0;
const int consumer = 1;

chan semWait[M][N];
chan semSignal[M][N];
chan semGo[M][N];

int buffer = 0;

</declaration><template><name x="5" y="5">Consumer</name><declaration>
void take(){buffer--;}

void consume(){}</declaration><location id="id0" x="320" y="96"></location><location id="id1" x="512" y="96"></location><location id="id2" x="704" y="96"></location><location id="id3" x="704" y="224"></location><location id="id4" x="704" y="352"><name x="728" y="336">cs</name></location><location id="id5" x="512" y="352"></location><location id="id6" x="320" y="352"></location><location id="id7" x="320" y="224"></location><init ref="id0"/><transition><source ref="id0"/><target ref="id1"/><label kind="synchronisation" x="344" y="72">semWait[n][consumer]!</label></transition><transition><source ref="id1"/><target ref="id2"/><label kind="synchronisation" x="536" y="72">semGo[n][consumer]?</label></transition><transition><source ref="id2"/><target ref="id3"/><label kind="synchronisation" x="712" y="144">semWait[s][consumer]!</label></transition><transition><source ref="id3"/><target ref="id4"/><label kind="synchronisation" x="712" y="272">semGo[s][consumer]?</label></transition><transition><source ref="id4"/><target ref="id5"/><label kind="assignment" x="592" y="328">take()</label></transition><transition><source ref="id5"/><target ref="id6"/><label kind="synchronisation" x="344" y="328">semSignal[s][consumer]!</label></transition><transition><source ref="id7"/><target ref="id0"/><label kind="assignment" x="328" y="144">consume()</label></transition><transition><source ref="id6"/><target ref="id7"/><label kind="synchronisation" x="328" y="272">semSignal[e][consumer]!</label></transition></template><template><name x="5" y="5">Producer</name><declaration>//Insert local declarations of clocks, variables and constants.

void produce(){}

void append(){buffer++;}



</declaration><location id="id8" x="-832" y="-96"></location><location id="id9" x="-832" y="-352"></location><location id="id10" x="-640" y="-352"></location><location id="id11" x="-448" y="-352"></location><location id="id12" x="-832" y="-224"></location><location id="id13" x="-448" y="-224"></location><location id="id14" x="-448" y="-96"></location><location id="id15" x="-640" y="-96"><name x="-648" y="-80">cs</name></location><init ref="id9"/><transition><source ref="id15"/><target ref="id8"/><label kind="assignment" x="-760" y="-120">append()</label></transition><transition><source ref="id9"/><target ref="id10"/><label kind="assignment" x="-776" y="-376">produce()</label></transition><transition><source ref="id10"/><target ref="id11"/><label kind="synchronisation" x="-608" y="-376">semWait[e][producer]!</label></transition><transition><source ref="id8"/><target ref="id12"/><label kind="synchronisation" x="-824" y="-176">semSignal[s][producer]!</label></transition><transition><source ref="id12"/><target ref="id9"/><label kind="synchronisation" x="-824" y="-288">semSignal[n][producer]!</label></transition><transition><source ref="id11"/><target ref="id13"/><label kind="synchronisation" x="-440" y="-304">semGo[e][producer]?</label></transition><transition><source ref="id13"/><target ref="id14"/><label kind="synchronisation" x="-440" y="-176">semWait[s][producer]!</label></transition><transition><source ref="id14"/><target ref="id15"/><label kind="synchronisation" x="-608" y="-120">semGo[s][producer]?</label></transition></template><template><name>Semaphore</name><parameter>const int id,  const int queue_size, const int init_val</parameter><declaration>//The value of the semaphore
int count = init_val;
//The queue of the semaphore
//value -1 denotes an empty array entry
int[-1,N-1] queue[queue_size];
//An auxiliary variable used to temporarily store process id
meta int[0,N-1] q;

void initialize ()
{
  for (i : int[0,queue_size-1])
      {queue[i] = -1;}
}

void deQueue ()
{
  for (i : int[1,queue_size-1])
    queue[i-1] = queue[i];
  queue[queue_size-1] = -1;
}

void enQueue (int p)
{
  int i = 0;
  while (queue[i]&gt;=0){i++;};
  queue[i]=p;
}

int[0,N-1] headQueue ( )
{
  return queue[0];
}

bool fullQueue ( )
{
  for (i : int[0,queue_size-1])
   {
     if (queue[i]==-1) {return false;}
   }
  return true;
}</declaration><location id="id16" x="384" y="64"><committed/></location><location id="id17" x="608" y="320"><committed/></location><location id="id18" x="352" y="96"><name x="288" y="64">overflow</name></location><location id="id19" x="480" y="192"></location><init ref="id16"/><transition><source ref="id16"/><target ref="id19"/><label kind="assignment" x="408" y="72">initialize()</label></transition><transition><source ref="id19"/><target ref="id19"/><label kind="select" x="272" y="192">p:int[0,N-1]</label><label kind="guard" x="272" y="208">count&gt;=0</label><label kind="synchronisation" x="272" y="224">semSignal[id][p]?</label><label kind="assignment" x="272" y="240">count++</label><nail x="352" y="192"/><nail x="352" y="224"/></transition><transition><source ref="id19"/><target ref="id17"/><label kind="select" x="552" y="104">p:int[0,N-1]</label><label kind="guard" x="552" y="120">count&gt;0</label><label kind="synchronisation" x="552" y="136">semWait[id][p]?</label><label kind="assignment" x="552" y="152">count--,
q=p</label><nail x="608" y="192"/></transition><transition><source ref="id19"/><target ref="id18"/><label kind="select" x="248" y="112">p:int[0,N-1]</label><label kind="guard" x="248" y="128">count&lt;=0 &amp;&amp; fullQueue()</label><label kind="synchronisation" x="248" y="144">semWait[id][p]?</label></transition><transition><source ref="id17"/><target ref="id19"/><label kind="synchronisation" x="512" y="208">semGo[id][q]!</label></transition><transition><source ref="id19"/><target ref="id17"/><label kind="select" x="360" y="280">p:int[0,N-1]</label><label kind="guard" x="360" y="296">count&lt;0</label><label kind="synchronisation" x="360" y="312">semSignal[id][p]?</label><label kind="assignment" x="360" y="328">count++,
q=headQueue(),
deQueue()</label><nail x="480" y="320"/></transition><transition><source ref="id19"/><target ref="id19"/><label kind="select" x="480" y="-24">p:int[0,N-1]</label><label kind="guard" x="480" y="-8">count&lt;=0 &amp;&amp; not fullQueue()</label><label kind="synchronisation" x="480" y="8">semWait[id][p]?</label><label kind="assignment" x="480" y="24">count--,
enQueue(p)</label><nail x="480" y="64"/><nail x="512" y="64"/></transition></template><system>//Insert process assignments.

//Semaphore s controls access to the critical section
Sem_s = Semaphore(s,1,1);
//Semaphore n (when nonnegative) counts the number of full buffer slots
Sem_n = Semaphore(n,1,0);
//Semaphore e counts the number of empty buffer slots
Sem_e = Semaphore(e,1,sizeofbuffer);

//Edit system definition.
system Consumer,Producer,Sem_s,Sem_n,Sem_e;</system></nta>