aboutsummaryrefslogtreecommitdiffstats
path: root/schedcat/overheads/pfair.py
blob: 48872f1345063c95f5b7140f4c4b050c53aba811 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
from __future__ import division

from .quanta import quantize_wcet, quantize_period, account_for_delayed_release, stagger_latency

def charge_scheduling_overheads(oheads, num_cpus, dedicated_irq, taskset,
                                staggered=False, total_cpus=None,
                                aligned_periodic_releases=False):
    if not oheads or not taskset:
        return taskset

    qlen   = oheads.quantum_length
    ev_lat = oheads.release_latency(taskset)
    rel_oh = oheads.release(taskset)

    # account for reduced effective quantum length
    qeff = qlen \
        - ev_lat \
        - oheads.tick(taskset) \
        - oheads.schedule(taskset) \
        - oheads.ctx_switch(taskset) \
        - oheads.cache_affinity_loss(taskset)

    if not dedicated_irq:
        # account for release interrupts
        qeff -= (len(taskset) - 1) * rel_oh

    # Is any useful time left in the quantum? With short quanta and high
    # overheads, this may not be the case (in the analyzed worst case).
    if qeff <= 0:
        return False

    # apply reduction
    taskset = quantize_wcet(qlen, taskset, qeff)
    if not taskset:
        return False

    # Account for release delay.
    if not aligned_periodic_releases:
        # Default sporadic mode: job releases are triggered sporadically,
        # but newly released jobs are not considered for scheduling until
        # the next quantum boundary.
        release_delay = qlen + ev_lat + rel_oh
    else:
        # "Polling" mode. Periodic job releases are triggered
        # at each quantum boundary without any delays.
        release_delay = 0

    # shortcut: we roll staggering into release delay
    if staggered:
        if total_cpus is None:
            total_cpus = num_cpus;
        release_delay += stagger_latency(total_cpus, qlen)

    taskset = account_for_delayed_release(release_delay, taskset)
    if not taskset:
        return False

    return quantize_period(qlen, taskset, deadline=True)