QP/C  7.2.1
Real-Time Embedded Framework
No Matches
Event Delivery

Active ObjectsTime Management

One of the main responsibilities of the QP Framework is to efficiently and safely deliver events from various producers to Active Objects. Any part of the system can produce events, not necessarily only the Active Objects. For example, ISRs, device drivers, or legacy code running outside the framework can produce events. On the other hand, only Active Objects can consume events, because only Active Objects have event queues.

Figure 220 Event delivery in the QP Framework

Direct Event Posting

The simplest mechanism lets producers post events directly to the event queue of the recipient Active Object. Figure 220 illustrates this form of communication as thick, solid arrows connecting event producers and the consumer Active Objects.

Direct event posting is a “push-style” communication mechanism, in which recipients receive unsolicited events whether they want them or not. Direct event posting is ideal in situations where a group of Active Objects, or an Active Object and an ISR, form a subsystem delivering a particular service, such as a communication stack, GPS capability, digital camera subsystem in a mobile phone, or the like. This style of event passing requires that the event producers “knows” the recipients and their interests in various events. The “knowledge” that a sender needs is, at a minimum, the handle (e.g., a pointer) to the recipient Active Object.

The direct event posting mechanism might increase the coupling among the components, especially when the recipients of the events are hard-coded inside the senders. However, one way of reducing the coupling is to allow the recipients to register with the producers at runtime, so that the event producer, so that the producer does not need to hard-code the recipient(s).


The publish–subscribe model is a popular way of decoupling the event producers from the event consumers. Publish-subscribe is a “pull-style” communication mechanism in which recipients receive only solicited events. The properties of the publish-subscribe model are:

  • Producers and consumers of events don’t need to know each other (loose coupling).
  • The events exchanged via this mechanism must be publicly known and must have the same semantics to all parties.
  • A mediator7 is required to accept published events and to deliver them to interested subscribers.
  • Many-to-many interactions (object-to-object) are replaced with one-to-many (object-to-mediator) interactions.

The publish-subscribe event delivery is shown in Figure 220 as a “software bus” into which Active Objects “plug in” through the specified interface. Active Objects interested in certain events subscribe to one or more srs_evt_sig "Event Signals" by the QP framework.

Event producers make event publication requests to the framework. Such requests can originate asynchronously from many sources, not necessarily just from Active Objects. For example, events can be published from interrupts or device drivers. The QP framework manages all these interactions by supplying the following services:

  • Provide a way for Active Objects to subscribe and unsubscribe to particular srs_evt_sig "Event Signals";
  • Provide a generally accessible interface for publishing events.
  • Define and implement a thread-safe event delivery policy (including multicasting events when an event is subscribed by multiple Active Objects).

One obvious implication of publish-subscribe is that the framework must store the subscriber information, whereas it must allow associating more than one subscriber Active Object with an srs_evt_sig "Event Signals". The framework must also allow modifying the subscriber information at runtime (dynamic subscribe and unsubscribe).

Event Memory Management

In any event-driven system, events are frequently produced and consumed, so by nature they are highly dynamic. One of the most critical aspects of every real-time framework is managing the memory used by events, because obviously this memory must be frequently reused as new events are constantly produced. The main challenge for the framework is to guarantee that the event memory is not reused until all Active Objects have finished their RTC processing of the event. In fact, as described in Section Run-to-Completion Processing, corrupting the current event while it is still in use constitutes a violation of the RTC semantics and is one of the hardest bugs to resolve.

Immutable Events

Not all event instances in the system have parameters or changing parameters. Some event instances, for example, can be constant with the permanently assigned signal and unchanging parameter(s). Such immutable event objects can be shared safely among any number of concurrent threads and interrupts, and can be allocated statically once, rather than being created and recycled every time. The QP Framework should support immutable events as an optimization and simplification of the event memory management.

Immutability is a desirable property of events, because exchanging such events is faster and safer compared to mutable events described in the next section.

Mutable Events

Many event instances, especially events with parameters cannot be easily made immutable. For example, event with just one 16-bit parameter can potentially have 64K values, and it is rather impractical to create that many immutable events (in an array, perhaps). For such cases, the QP framework needs to support mutable events.

Zero-Copy Event Delivery

The brute-force approach of copying entire events into message queues is the best a traditional RTOS can do, because an RTOS does not control the events after they leave the queue. A real-time framework, on the other hand, can be far more efficient because, due to inversion of control, the framework actually manages the whole life cycle of an event. As shown in Figures 6.5(B), 6.8, and 6.9(A) earlier in this chapter, a real-time framework is in charge of extracting an event from the active object’s event queue and then dispatching the event for RTC processing. After the RTC step completes, the framework regains control of the event. At this point, the framework “knows” that the event has been processed and so the framework can automatically recycle the event. Figure 6.12 shows the garbage collection step (event recycling) added to the active object life cycle.

A real-time framework can also easily control the allocation of events. The framework can simply provide an API function that application code must call to allocate new events. The QF framework, for example, provides the macro Q_NEW() for this purpose. With the addition of the event creation and automatic garbage collection steps, the framework controls the life cycle of an event from cradle to grave. This in turn permits the framework to implement controlled, thread-safe sharing of event memory, which from the application standpoint is indistinguishable from true event copying. Such memory management is called zero-copy event delivery.



QP Framework shall...


Active ObjectsTime Management