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. |