Flow Control

Task-to-task communication often involves data transfer from one task to another. One task produces data while the other consumes it. However, data processing takes time and consumers might not consume data as fast as it is produced. In other words, it is possible for the producer to overflow the message queue if a higher-priority task preempts the consumer. One way to solve this problem is to add flow control in the process as shown in the figure below.

Producer and Consumer Tasks with Flow Control

Here, a counting semaphore is used, initialized with the number of allowable messages that can be sent by the consumer. If the consumer cannot queue more than 10 messages, the counting semaphore contains a count of 10.

As shown in the pseudo code of the listing below, the producer must wait on the semaphore before it is allowed to send a message. The consumer waits for messages and, when processed, signals the semaphore.

Producer and Consumer Flow Control
Producer Task:
    Pend on Semaphore;
    Send message to message queue;
           
Consumer Task:
    Wait for message from message queue;
    Signal the semaphore;

Combining the task message queue and task semaphores (see Synchronization), it is easy to implement flow control as shown in the figure below. In this case, however, OSTaskSemSet() must be called immediately after creating the task to set the value of the task semaphore to the same value as the maximum number of allowable messages in the task message queue.

Flow Control with Task Semaphore and Task Message Queue