**6.4 Switching servers**

16 Will-be-set-by-IN-TECH

When the workload of a deferrable server *σ<sup>i</sup>* is exhausted, i.e. there are no ready tasks in *γ*(*σi*), then the server is switched out and its server queue *σi*.*sq* is deactivated. Consequently, any periodic task which could wake up the server to consume any remaining budget cannot be noticed. One could alleviate this problem by keeping its server queue active when *σ<sup>i</sup>* is switched out. This, however, would make the tick handler overhead linear in the number of deferrable servers, since a tick handler decrements the head events in all active queues (see

Instead, in order to limit the interference of inactive deferrable servers, when a deferrable server *σ<sup>i</sup>* is switched out and it has no workload pending (i.e. no tasks in *γ*(*σi*) are ready), we deactivate the *σi*'s server queue, change its state to waiting, and insert a *wakeup event*, denoted as *σi*.*we*, into the system queue. The wakeup event has its *data* pointing to *σ<sup>i</sup>* and time equal to the arrival of the first event in *σi*.*sq*. When the wakeup event expires, the *σi*'s state is set to the ready state. This way handling the events inside *σi*.*sq* is deferred until *σ<sup>i</sup>* is switched in. When a deferrable server is switched in while it is in the waiting state, its wakeup event *σi*.*we*

An idling periodic server is a special kind of a deferrable server containing an idle task (with lowest priority). The idle task is switched in if no higher priority task is ready, effectively idling away the remaining capacity. In order to save memory needed for storing the task control block and the stack of the idle task, one idle task is shared between all idling periodic

When the server budget is depleted an event must be triggered, to guarantee that a server does not exceed its budget. We present a general approach for handling budget depletion and introduce the notion of *virtual timers*, which are events relative to server's budget

We can implement virtual timers by adding a *virtual server queue* for *each* server, denoted by *σi*.*vq*. Similarly to the server queues introduced earlier, when a server is switched in, its virtual server queue is activated. The difference is that the virtual server queue is not synchronized with the stopwatch queue, since during the inactive period a server does not consume any of

The relative time representation by RELTEQ allows for a more efficient virtual queue activation than an absolute time representation does. An absolute time representation (e.g. in (Behnam et al., 2008; Inam et al., 2011)) requires to recompute the expiration time for *all* the events in a virtual server queue upon switching in the corresponding server, which is linear in the number of events. In our RELTEQ-based virtual queues the events are stored relative to each other and their expiration times do not need to be recomputed upon queue activation. Note that it will never be necessary to handle an expired virtual event upon queue activation, since such an event would have been already handled before the corresponding server was switched out. Therefore, our HSF design exhibits a constant time activation of a virtual server

its budget. When a server is switched out, its virtual server queue is deactivated.

**6.2.2 Deferrable server**

is removed from the system queue.

**6.2.3 Idling periodic server**

servers in the system.

**6.3 Virtual timers**

consumption.

queue.

Section 6.6).

The methods for switching servers in and out are summarized in Figures 7 and 8.

```
SyncQueuesUntilEvent(σi.sq, stopwatch, σi.se);
ActivateQueue(σi.sq);
ActivateQueue(σi.vq);
if σi.we  ∅ then
  DeleteEvent(system, σi.we);
  σi.we = ∅;
end if
```
Fig. 7. Pseudocode for *ServerSwitchIn(σi)*.

```
DeleteEvent(stopwatch, σi.se);
σi.se = NewEvent(stopwatch, 0, σi);
InsertEvent(stopwatch, σi.se);
DeactivateQueue(σi.sq);
DeactivateQueue(σi.vq);
if σi.readyTasks = ∅ then
  σi.we = NewEvent(wakeup, Head(σi.sq).time, σi);
  InsertEvent(system, σi.we);
end if
```
Fig. 8. Pseudocode for *ServerSwitchOut(σi)*.

## **6.5 Server replenishment and depletion**

We introduce two additional RELTEQ event kinds to support servers: *budget replenishment* and *budget depletion*. When a server *σ<sup>i</sup>* is created, a replenishment event *ej* is inserted into the *system queue*, with *ej.data* pointing to *σ<sup>i</sup>* and *ej.time* equal to the server's replenishment period Π*i*. When *ej* expires, *ej.time* is updated to Π*<sup>i</sup>* and it is inserted into the system queue.

Upon replenishment, the server's depletion event *ej* is inserted into its *virtual server queue*, with *ej.data* pointing to *σ<sup>i</sup>* and *ej.time* equal to the server's capacity Θ*i*. If the server was not depleted yet, then the old depletion event is removed from the virtual server queue using *DeleteEvent(σi.vq, ej)*.
