A producer/consumer model in SanA while back James Rogers proposed a programming "contest" in the comp.programming newsgroup. In this constest people would code solutions to programming tasks in the language of their choice, the objective being to get a comparison of how tasks would be handled in different languages. The first task was to effect a producer-buffer-consumer model. The task description was: The first problem in this contest is a simple producer / consumer problem. To keep things simple there should be one producer and one consumer. The producer will communicate with the consumer using a fixed length shared buffer containing no more than three data elements. When the buffer is full the producer must suspend its operations. When the buffer is empty the consumer must suspend its operations.There was further specifications about timing. An attempt to move an assembly from the producer to the buffer takes 1.0 seconds if successful and .75 seconds if it fails. An attempt to move an assembly from the buffer to the consumer takes .5 seconds if successful, and .45 seconds if it fails. Production starts at time t=0.0; consumption starts at time t=4.0; production stops at time t=19.0; and comsumption stops at time t=21.0.
Begin segment type=package label=producer/consumer
begin init
production | warehouse | consumer
bufmax = 3
p-start = 0
p-stop = 19
c-start = 4
c-stop = 21
f-put = .75
s-get = 1.0
f-get = .45
s-get = .50
end
begin proc get-time
msg to=scheduler, type=want-time, rsvp
return rsvp.time
end
begin agent main
msg to=scheduler, type=start-producer, time = p-start
msg to=scheduler, type=start-consumer, time = c-start
msg to=scheduler, type=stop-producer, time = p-stop
msg to=scheduler, type=stop-consumer, time = c-stop
begin agent production
init id = 0
begin on-msg
id += 1
item = id
print <get-time>: Produced item {item}
emit0-word item
end
end
begin agent warehouse
begin on-$0-word
begin loop until buffer$nrow lt? bufmax
msg to=scheduler, type=delay, delay=f-put, rsvp
print <get-time>: Warehouse is full
end
msg to=scheduler, type=delay, delay=s-put, rsvp
print <get-time>: Item {item} added to warehouse
append $0 to buffer[]
end
begin on-msg type=gimme
begin loop until buffer$nrow gt? 0
msg to=scheduler, type=delay, delay=f-get, rsvp
print <get-time>: Warehouse is empty
end
msg to=consumer, type=delay, delay=s-get, rsvp
buffer[] -> item, buffer[]
print <get-time>: Shipping {item} to consumer
emit0-word item
end
end warehouse
begin agent consumer
begin on-$0-word
print <get-time>: consuming {$0}
msg to=warehouse, type=gimme
end
end
begin agent scheduler
init clock = 0
begin on-msg switch msg.type
eq? want-time => reply time=clock
eq? delay => begin
$insert id=msg.id, label=delay, time=(clock + msg.delay)
$release
end
else => $insert msg.id {msg.type} msg.time
end switch
begin proc $insert
args: id, label, time
ev.id = id; ev.label = label; ev.time = time
begin loop i from [$rfirst...$rlast] switch ev.time
lt? $[i].time => $[i-1].[] <- $[i].[]
else begin
$[i].[] <- ev.[]
escape
end
end
end proc
begin proc $release
$[].[] -> ev.[] $[].[]
switch ev.type
eq? delay => reply id=ev.id
eq? start-producer => begin
print <get-time>: Starting production
msg to=producer
end
eq? start-consumer => begin
print <get-time>: Starting consumption
msg to=warehouse, type=gimme
end
eq? stop-producer => begin
print <get-time>: Halting production
deactivate production
end
eq? stop-consumer => begin
print <get-time>: Halting consumption
deactivate consumer
end
end
end
end scheduler
end producer/consumer
This page was last updated November 12, 2003. |