aboutsummaryrefslogtreecommitdiffstats
path: root/schedstat.py
blob: f46f337d641e6ff610b803f5a0ef72f23eadbd2e (plain)
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python3
# GPLv2 license, spit out /proc/schedstat
# this works with schedstat v15

import sys,os, time

cpustat_txt = [ 'cpu zeros', # 0
                'sched_yied()', # 1
                'zeros',
                'schedule()', # 3
                'sched->idle()', #4
                'try_to_wake_up()', #5
                'try_to_wakeup(local)', #6
                'run time', #7
                'wait time', #8
                'timeslices,' #9
                ]
                
domain_txt = [ 'domain zeros', #0
               'IDLE lb_count', #1
               'IDLE lb_balanced', #2
               'IDLE lb_failed', #3
               'IDLE lb_imbalance', #4
               'IDLE lb_gained', #5
               'IDLE lb_hot_gained', #6
               'IDLE lb_nobusyq', #7
               'IDLE lb_nobusyg', #8
               'BUSY lb_count', #9
               'BUSY lb_balanced', #10
               'BUSY lb_failed', #11
               'BUSY lb_imbalance', #12
               'BUSY lb_gained', #13
               'BUSY lb_hot_gained', #14
               'BUSY lb_nobusyq', #15
               'BUSY lb_nobusyg', #16
               'NEW IDLE lb_count', #17
               'NEW IDLE lb_balanced', #18
               'NEW IDLE lb_failed', #19
               'NEW IDLE lb_imbalance', #20
               'NEW IDLE lb_gained', #21
               'NEW IDLE lb_hot_gained', #22
               'NEW IDLE lb_nobusyq', #23
               'NEW IDLE lb_nobusyg', #24
               'alb_count', #25
               'alb_failed', #26
               'alb_pushed', #27
               'sbe_count', #28
               'sbe_balanced', #29
               'sbe_pushed', #30
               'sbf_count', #31
               'sbf_balanced', #32
               'sbf_pushed', #33
               'ttwu_wake_remote', #34
               'ttwu_move_affine', #35
               'ttwu_move_balance', #36
               ]

def add_at_index(ar, index, val):
    while index >= len(ar):
        ar.append(0)
    ar[index] += val
    
def diff_arrays (start, now, seconds):
    results = []
    for i in range(0, len(start)):
        val = float(now[i] - start[i]) / seconds
        results.append(round(val, 2))
        if results[i] < 0:
            results[i] = 0
    return results

def read_schedstat():
    stats = open('/proc/schedstat', 'r')
    cpustat = []
    domainstat = []
    while True:
        l = stats.readline()
        if not l:
            break;

        if l.startswith('cpu'):
            words = l.split()
            for i in range(1, len(words)):
                add_at_index(cpustat, i, int(words[i]))

        if l.startswith('domain'):
            # the documentation starts counting assuming domainN cpumask are
            # one field
            words = l.split()[1:]
            for i in range(2, len(words)):
                add_at_index(domainstat, i, int(words[i]))
    return (cpustat, domainstat)
            
def print_stat(label, desc, ar):
    c = 0
    max_width = 0

    for x in desc:
        if len(x) > max_width:
            max_width = len(x)

    print(label)
    for i in range(0, len(ar)):
        print(f'#{i} {desc[i]:<{max_width}} {ar[i]:<20}', end=' ')
        c += 1
        if c % 1 == 0:
            print("")
    if c % 1 != 0:
            print("")

start_time = time.time()
last_cpustat, last_domainstat = read_schedstat()
sleep_time = 1

if len(sys.argv) > 1:
    sleep_time = int(sys.argv[1])

while True:
    time.sleep(sleep_time)
    now_time = time.time()
    cpustat, domainstat = read_schedstat()
    
    res_cpustat = diff_arrays(last_cpustat, cpustat, now_time - start_time)
    res_domainstat = diff_arrays(last_domainstat, domainstat, now_time - start_time)

    print_stat("cpu", cpustat_txt, res_cpustat)
    print_stat("domain", domain_txt, res_domainstat)

    last_cpustat = cpustat
    last_domainstat =  domainstat
    start_time = now_time