User guide
3.7. COROUTINE EXAMPLES 91
AND qitem(node) BE
// The message has reached this node
// It currently not busy, mark it as busy and return to process
// the message, other append it to the end of the work queue
// for this node.
{ // Make a queue item
LET link, co = 0, currco
LET p = wkqv!node
UNLESS p DO
{ // The node was not busy
wkqv!node := -1 // Mark node as busy
IF tracing DO
writef("%i8: node %i4: node not busy*n", simtime, node)
RETURN
}
// Append item to the end of this queue
IF tracing DO
writef("%i8: node %i4: busy so appending message to end of work queue*n",
simtime, node)
TEST p=-1
THEN wkqv!node := @link // Form a unit list
ELSE { WHILE !p DO p := !p // Find the end of the wkq
!p := @link // Append to end of wkq
}
cowait() // Wait to be activated (by dqitem)
}
AND dqitem(node) BE
// A message has just been processed by this node and is ready to process
// the next, if any.
{ LET item = wkqv!node // Current item (~=0)
UNLESS item DO abort(999)
TEST item=-1
THEN wkqv!node := 0 // The node is no longer busy
ELSE { LET next = item!0
AND co = item!1
wkqv!node := next -> next, -1 // De-queue the item
callco(co) // Process the next message
}
}
// ######################## Coroutine Bodies ##########################
AND stopcofn(arg) = VALOF
{ waitfor(stoptime)
IF tracing DO
writef("%i8: Stop time reached*n", simtime)
RESULTIS 0
}