Single-element producer-consumer

Description

The single-element producer-consumer is a simpler variant of the classic producer-consumer problem. A producer produces products, in this case integers, into a single-element inventory. The products are then consumed from inventory by a consumer. The producer, consumer, and inventory are managed by separate processors, so any access they have to one another must be synchronized through scoop mechanisms.

Highlights

In the single-element producer-consumer only a single producer and single consumer are created, and there is only storage allowing for a single instance of the product. So, effectively in this example, the bounded buffer of the classic producer-consumer problem has a size of one.

The classes modeling the different actors have obvious names: PRODUCER, CONSUMER, and INVENTORY. The root class of the example creates one separate instance of each of these, and then brings the producer and consumer to life.

The PRODUCER class supports a procedure produce in which a product is produced and stored in the single-element INVENTORY. The producer can only produce an element if the inventory is currently empty. Class INVENTORY exports a boolean query has_item which is the indicator of whether a product has been produced and is available for consumption. So {PRODUCER}.produce has a precondition that depends upon {INVENTORY}.has_item being false. Because the inventory is handled by a separate processor, this precondition is uncontrolled and will cause the producer to wait until the condition is true to proceed.

The CONSUMER class works in a way that is largely the symmetrical opposite of PRODUCER. The consumer tries to consume the item from the INVENTORY. But this only possible if an item has been produced and is available. So {CONSUMER}.consume has a "wait" precondition based on the query {INVENTORY}.has_item.

So the heart of the problem is the synchronization between producer and consumer sharing a single inventory. If there's already a product in inventory, the producer cannot produce more and must wait. Only when the consumer consumes the current product can the producer produce again. For the consumer's part, if there's a product currently in inventory, then the consumer can consume that product. Otherwise, the consumer must wait until the producer produces a new product. The synchronization is handled by the SCOOP mechanism of uncontrolled (wait) preconditions on the inventory.