**4. RELTEQ**

To implement the desired extensions in *μ*C/OS-II we needed a general mechanism for different kinds of timed events, exhibiting low runtime overheads. This mechanism should be expressive enough to easily implement higher level primitives, such as periodic tasks, fixed-priority servers and two-level fixed-priority scheduling.

## **4.1 RELTEQ time model**

RELTEQ stores the arrival times of future events relative to each other, by expressing their time *relative to their previous event*. The arrival time of the head event is relative to the current time1, as shown in Figure 2.

<sup>1</sup> Later in this chapter we will use RELTEQ queues as an underlying data structure for different purposes. We will relax the queue definition: all event times will be expressed relative to their previous event, but the head event will not necessarily be relative to "now".

Fig. 2. Example of the RELTEQ event queue.

8 Will-be-set-by-IN-TECH

When a depleted server is replenished it moves to the ready state and becomes eligible to run.

When the idling periodic server Davis & Burns (2005) is replenished and none of its tasks are ready, then it idles its budget away until either a proper task arrives or the budget depletes. An idling periodic server follows the state transition diagram in Figure 1, however, due to its idling nature it will never reach the waiting state (and can therefore be regarded as created in

In two-level hierarchical scheduling one can identify a global scheduler which is responsible for selecting a component. The component is then free to use any local scheduler to select a

In order to facilitate the reuse of existing components when integrating them to form larger systems, the platform should support (at least) fixed-priority preemptive scheduling at the local level within components (since it is a de-facto standard in the industry). To give the system designer the most freedom it should support arbitrary schedulers at the global level. In this paper we will focus on a fixed-priority scheduler on both local and global level.

The platform needs to support at least the following timed events: task delay, arrival of a

Events local to server *σi*, such as the arrival of periodic tasks *τ<sup>j</sup>* ∈ *γ*(*σi*), should not interfere with other servers, unless they wake a server, i.e. the time required to handle them should be accounted to *σi*, rather than the currently running server. In particular, handling the events local to inactive servers should not interfere with the currently active server and should be

To implement the desired extensions in *μ*C/OS-II we needed a general mechanism for different kinds of timed events, exhibiting low runtime overheads. This mechanism should be expressive enough to easily implement higher level primitives, such as periodic tasks,

RELTEQ stores the arrival times of future events relative to each other, by expressing their time *relative to their previous event*. The arrival time of the head event is relative to the current

<sup>1</sup> Later in this chapter we will use RELTEQ queues as an underlying data structure for different purposes. We will relax the queue definition: all event times will be expressed relative to their previous event, but

periodic task, server replenishment and server depletion.

deferred until the corresponding server is switched in.

fixed-priority servers and two-level fixed-priority scheduling.

the head event will not necessarily be relative to "now".

A waiting server may be woken up by a newly arrived periodic task or a delay event.

**3.2.2 Idling periodic server**

**3.3 Hierarchical scheduling**

ready state).

task to run.

**3.4 Timed events**

**4. RELTEQ**

**4.1 RELTEQ time model**

time1, as shown in Figure 2.

### **Unbounded interarrival time between events**

One of our requirements is for long event interarrival times with respect to time representation. In other words, given *d* as the largest value that can be represented for a fixed bit-length time representation, we want to be able to express events which are *kd* time units apart, for some parameter *k* > 1.

For an *n*-bit time representation, the maximum interval between two consecutive events in the queue is 2*<sup>n</sup>* <sup>−</sup> 1 time units2. Using *<sup>k</sup>* events, we can therefore represent event interarrival time of at most *<sup>k</sup>*(2*<sup>n</sup>* <sup>−</sup> <sup>1</sup>). RELTEQ improves this interval even further and allows for an *arbitrarily long interval* between *any* two events by inserting "dummy" events, as shown in Figure 3.

Fig. 3. Example of (a) an overflowing relative event time (b) RELTEQ inserting a dummy event with time 2*<sup>n</sup>* <sup>−</sup> 1 to handle the overflow.

If *t* represents the event time of the last event in the queue, then an event *ei* with a time larger than 2*<sup>n</sup>* <sup>−</sup> 1 relative to *<sup>t</sup>* can be inserted by first inserting dummy events with time 2*<sup>n</sup>* <sup>−</sup> 1 at the end of the queue until the remaining relative time of *ei* is smaller or equal to 2*<sup>n</sup>* <sup>−</sup> 1.

In general, dummy events act as placeholders in queues and can be assigned any time in the interval [0, 2*<sup>n</sup>* <sup>−</sup> <sup>1</sup>].

#### **4.2 RELTEQ data structures**

A RELTEQ *event* is specified by the tuple (*kind*, *time*, *data*). The *kind* field identifies the event kind, e.g. a delay or the arrival of a periodic task. *time* is the event time. *data* points to additional data that may be required to handle the event and depends on the event kind. For example, a delay event will point to the task which is to be resumed after the delay event expires. Decrementing an event means decrementing its event time and incrementing an event means incrementing its event time. We will use a dot notation to represent individual fields in the data structures, e.g. *ei*.*time* is the event time of event *ei*.

A RELTEQ *queue* is a list of RELTEQ events. *Head(qi)* represents the head event in queue *qi*.

<sup>2</sup> With *<sup>n</sup>* bits we can represent 2*<sup>n</sup>* distinct numbers. Since we start at 0, the largest one is 2*<sup>n</sup>* <sup>−</sup> 1.

*PopEvent(qi)* When an event is popped from a queue it is simply removed from the head of

An Efficient Hierarchical Scheduling Framework for the Automotive Domain 77

*DeleteEvent(qi, ej)* Since all events in a queue are stored relative to each other, the time *ej*.*time* of any event *ej* ∈ *qi* is critical for the integrity of the events later in the queue. Therefore, before an event *ej* is removed from *qi*, its event time *ej*.*time* is added to the following event

Note that the addition could overflow. In such case, instead of adding *ej*.*time* to the following event in *qi*, the kind of *ej* is set to a dummy event and the event is not removed. If *ej* is the last event in *qi* then it is simply removed, together with any dummy events

The most straightforward queue implementation is probably a doubly linked list. The time complexity of the *InsertEvent()* operation is then linear in the number of events in the queue,

The linear time complexity of the insert operation may be inconvenient for large event queues. An alternative implementation based on a heap or a balanced binary tree may seem more appropriate, as it promises logarithmic time operations. However, as the following theorem states, the relative time representation coupled with the requirement for long event interarrival times (compared to the time representation) make such an implementation

**Theorem 4.1.** *Assume that the maximum value we can represent in the time representation is d and also assume that we store times in a tree using relative values no greater than d. Finally, assume that any two events in the tree are at most kd apart in real time, for some parameter k. Then a logarithmic*

*Proof.* If there are *k* events, the largest time span these *k* events can represent is *kd* time units, i.e., the time difference between the first and last event can be at most *kd* units. If we are to obtain this value by summing over a path this path has to be of length *k* which leads to a linear representation. This argument pertains to any representation that sums contributions over a

We can illustrate Theorem 4.1 using dummy events: assuming that we start at time 0, the real time of a newly inserted event is at most *kd*. We would need to insert dummy events until a root path can contain this value. This means we would need to add dummy events until there

Conversely, if we assume a tree representation, then we would like to obtain *kd* as a sum of log(*k*) events. If we assume an even distribution over all events, which is the best case with respect to the number of bits required for the time representation, then each event time will

implementation one cannot limit the time representation to a given fixed value, independent

extra bits are needed. Therefore, in a tree

log *<sup>k</sup>* log(*k*)

while the complexity of the *DeleteEvent()* and *PopEvent()* operations is constant.

the queue *qi*. It is not handled at this point.

in *qi*.

impossible.

path.

is a root path of length *k*.

of *kd* (i.e. the tree span).

be equal to *<sup>k</sup>*

preceding it.

**4.5 Event queue implementation**

*time retrieval of an event from a tree is not possible.*

log(*k*) *<sup>d</sup>*. This means that
