Queues for inter-task communication

Now that the simple behaviors of queues have been covered, we'll take a look at how they can be used to move data between tasks. A very common use case for queues is to have one task populate the queue while another is reading from the same queue. This is generally straightforward but may have some nuances, depending on how the system is set up:

In the preceding example, Task 1 and Task 2 are both interacting with the same Queue. Task 1 will send an item to the Queue. As long as Task 2 has a higher priority than Task 1, it will immediately receive the item.

Let's consider another instance that often occurs in practice when multiple tasks are interacting with queues. Since a preemptive scheduler always runs the task with the highest priority, if that task always has data to write to the queue, the queue will fill before another task is given a chance to read from the queue. Here is an example of how this may play out:

The following numbers correspond to indexes along the time axis:

  1. Task2 attempts to receive an item from the empty queue. No items are available, so Task2 blocks.
  2. Task1 adds items to queue. Since it is the highest priority task in the system, Task1 adds items to the queue until it doesn't have any more items to add, or until the queue is full.
  3. The queue is filled, so Task1 is blocked.
  4. Task2 is given context by the scheduler since it is now the highest priority task that may run.
  5. As soon as an item is removed from the Queue, Task1 is given context again (this is the highest priority task in the system and it is now able to run because it was blocking while waiting for space to become available in the queue). After adding a single item, the queue is full and Task1 is blocked.
  6. Task2 is given context and receives an item from the queue:
A real-world example of the preceding situation is covered in Chapter 9, Intertask Communication, in the section Passing data through queues. Chapter_9/src/mainQueueCompositePassByValue.c illustrates the exact setup and a thorough empirical execution analysis is performed using SystemView.

Another extremely common use case for queues is to have a single queue accept input from many different sources. This is especially useful for something like a debug serial port or a log file. Many different tasks can be writing to the queue, with a single task responsible for receiving data from the queue and pushing it out to the shared resource. 

While queues are generally used for passing data between tasks, semaphores can be used for signaling and synchronizing tasks. Let's learn more about this next.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.172.249