Consumers, Producers and Critical Regions

Using the paradigm of layering for modularisation, we have a natural model for building communications protocols where a service is provided by a layer to a layer above. Layering is described in more detail in Chapter six. There are only three external interfaces to a protocol layer - lower layer input events, upper layer request events and timer events. Corresponding to these, there are requests from this layer to the layer below, and indications (events to them) from this layer to the layer above. There are internal events (e.g. timers) and control events (e.g. network resets..., user aborts etc.) We have modeled a layer as a set of cooperating tasks, processes, threads of control or whatever, which are essentially concurrent. Although this concurrency is usually fictional (i.e. interleaved execution by a single processor, rather than multiprocessor), it is convenient for designing and implementing protocols - a thread for each stream of events is easier to program than a calculated polling loop, with the fraction of time almost impossible to calculate for which event stream (to take just one poor alternative approach). This is discussed in more detail in chapter six. Having chosen to implement most protocols as a set of cooperating concurrent threads of control, we are left with the problem that the cooperation is often by means of shared memory. This leads to one main problem, and subsequently to a set of safe structures that can be employed to avoid the problem:- This chain of producers and consumers is almost always bi-directional. In other words, each producer is also a consumer of events and information in the other direction. This is illustrated in figures #fnpcc1#336>, #fnpcc2#337>, #fnpcc3#338> and #fnpcc4#339>.

#figure340#
Figure: Producer Consumer Chain - User to Net

#figure343#
Figure: Producer Consumer Chain - consumer

#figure346#
Figure: Producer Consumer Chain - Key

Corresponding to figure #fnpcc1#349> one, is a consumer of network events (TS2) and producer of transport service events to the user. For figure #fnpcc2#350>, there is a consumer of link events, producing network input to the this transport task (NS2). Thus for a full system from one host (user) to another, we have a chain of production and consumption which contains at least 8 tasks, as in figure #fnpcc4#351>!

#figure352#
Figure: Flow of Information in Producer Consumer Chain

The mutual exclusion plus synchronisation prevents inconsistency or deadlock across the entire system. However, it is possible for a producer to produce more than a consumer can handle at any point in this system, as we have no model for flow control. Flow control of resources is usually achieved by counting the numbers of buffers being queued and dequeued at each producer/consumer boundary, and bounding this number (i.e. stopping production when we have queued some given number of events for a consumer who has not yet managed them. Of course, the same relationship between a process ;SPM_quot;above;SPM_quot; another process exists for ;SPM_quot;peer;SPM_quot; processes across the network.