]> git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/scheduler.py
xnu-3248.20.55.tar.gz
[apple/xnu.git] / tools / lldbmacros / scheduler.py
1 from xnu import *
2 from utils import *
3 from process import *
4
5 # TODO: write scheduler related macros here
6
7 # Macro: showinterrupts
8
9 @lldb_command('showinterrupts')
10 def ShowInterrupts(cmd_args=None):
11 """ Prints IRQ, IPI and TMR counts for each CPU
12 """
13 base_address = kern.GetLoadAddressForSymbol('CpuDataEntries')
14 struct_size = 16
15 for x in range (0, unsigned(kern.globals.machine_info.physical_cpu)):
16 element = kern.GetValueFromAddress(base_address + (x * struct_size), 'uintptr_t *')[1]
17 cpu_data_entry = Cast(element, 'cpu_data_t *')
18 print "CPU {} IRQ: {:d}\n".format(x, cpu_data_entry.cpu_stat.irq_ex_cnt)
19 print "CPU {} IPI: {:d}\n".format(x, cpu_data_entry.cpu_stat.ipi_cnt)
20 print "CPU {} TMR: {:d}\n".format(x, cpu_data_entry.cpu_stat.timer_cnt)
21 # EndMacro: showinterrupts
22
23 # Macro: showactiveinterrupts
24
25 @lldb_command('showactiveinterrupts')
26 def ShowActiveInterrupts(cmd_args=None):
27 """ Prints the interrupts that are unmasked & active with the Interrupt Controller
28 Usage: showactiveinterrupts <address of Interrupt Controller object>
29 """
30 if not cmd_args:
31 print "No arguments passed"
32 print ShowActiveInterrupts.__doc__
33 return False
34 aic = kern.GetValueFromAddress(cmd_args[0], 'AppleInterruptController *')
35 if not aic:
36 print "unknown arguments:", str(cmd_args)
37 return False
38
39 aic_base = unsigned(aic._aicBaseAddress)
40 current_interrupt = 0
41 aic_imc_base = aic_base + 0x4180
42 aic_him_offset = 0x80
43 current_pointer = aic_imc_base
44 unmasked = dereference(kern.GetValueFromAddress(current_pointer, 'uintptr_t *'))
45 active = dereference(kern.GetValueFromAddress(current_pointer + aic_him_offset, 'uintptr_t *'))
46 group_count = 0
47 mask = 1
48 while current_interrupt < 192:
49 if (((unmasked & mask) == 0) and (active & mask)):
50 print "Interrupt {:d} unmasked and active\n".format(current_interrupt)
51 current_interrupt = current_interrupt + 1
52 if (current_interrupt % 32 == 0):
53 mask = 1
54 group_count = group_count + 1
55 unmasked = dereference(kern.GetValueFromAddress(current_pointer + (4 * group_count), 'uintptr_t *'))
56 active = dereference(kern.GetValueFromAddress((current_pointer + aic_him_offset) + (4 * group_count), 'uintptr_t *'))
57 else:
58 mask = mask << 1
59 # EndMacro: showactiveinterrupts
60
61
62 @lldb_command('showcurrentabstime')
63 def ShowCurremtAbsTime(cmd_args=None):
64 """ Routine to print latest absolute time known to system before being stopped.
65 Usage: showcurrentabstime
66 """
67 pset = addressof(kern.globals.pset0)
68 cur_abstime = 0
69
70 while unsigned(pset) != 0:
71 for processor in IterateQueue(pset.active_queue, "processor_t", "processor_queue"):
72 if unsigned(processor.last_dispatch) > cur_abstime:
73 cur_abstime = unsigned(processor.last_dispatch)
74
75 for processor in IterateQueue(pset.idle_queue, "processor_t", "processor_queue"):
76 if unsigned(processor.last_dispatch) > cur_abstime:
77 cur_abstime = unsigned(processor.last_dispatch)
78
79 for processor in IterateQueue(pset.idle_secondary_queue, "processor_t", "processor_queue"):
80 if unsigned(processor.last_dispatch) > cur_abstime:
81 cur_abstime = unsigned(processor.last_dispatch)
82
83 pset = pset.pset_list
84
85 print "Last dispatch time known: %d MATUs" % cur_abstime
86
87
88 @lldb_command('abs2nano')
89 def ShowAbstimeToNanoTime(cmd_args=[]):
90 """ convert mach_absolute_time units to nano seconds
91 Usage: (lldb) abs2nano <timestamp in MATUs>
92 """
93 if not cmd_args:
94 raise ArgumentError("Invalid argument")
95 timedata = ArgumentStringToInt(cmd_args[0])
96 print "%d ns" % kern.GetNanotimeFromAbstime(timedata)
97
98 # Macro: showschedhistory
99
100 def ShowThreadSchedHistory(thread, most_recent_dispatch):
101 out_str = ""
102 thread_name = ""
103
104 if int(thread.uthread) != 0:
105 uthread = Cast(thread.uthread, 'uthread *')
106 #check for thread name
107 if int(uthread.pth_name) != 0 :
108 th_name_strval = Cast(uthread.pth_name, 'char *')
109 if len(str(th_name_strval)) > 0 :
110 thread_name = str(th_name_strval)
111
112 task = thread.task
113 task_name = "unknown"
114 if task and unsigned(task.bsd_info):
115 p = Cast(task.bsd_info, 'proc *')
116 task_name = str(p.p_name)
117
118 sched_mode = ""
119
120 mode = str(thread.sched_mode)
121 if "TIMESHARE" in mode:
122 sched_mode+="timeshare"
123 elif "FIXED" in mode:
124 sched_mode+="fixed"
125 elif "REALTIME" in mode:
126 sched_mode+="realtime"
127
128 if (unsigned(thread.bound_processor) != 0):
129 sched_mode+="-bound"
130
131 # TH_SFLAG_THROTTLED
132 if (unsigned(thread.sched_flags) & 0x0004):
133 sched_mode+="-BG"
134
135 state = thread.state
136
137 thread_state_chars = {0x0:'', 0x1:'W', 0x2:'S', 0x4:'R', 0x8:'U', 0x10:'H', 0x20:'A', 0x40:'P', 0x80:'I'}
138 state_str = ''
139 mask = 0x1
140 while mask <= 0x80 :
141 state_str += thread_state_chars[int(state & mask)]
142 mask = mask << 1
143
144 last_on = thread.computation_epoch
145 last_off = thread.last_run_time
146
147 time_on_abs = unsigned(last_off - last_on)
148 time_on_us = kern.GetNanotimeFromAbstime(time_on_abs) / 1000.0
149
150 time_since_off_abs = unsigned(most_recent_dispatch - last_off)
151 time_since_off_us = kern.GetNanotimeFromAbstime(time_since_off_abs) / 1000.0
152 time_since_on_abs = unsigned(most_recent_dispatch - last_on)
153 time_since_on_us = kern.GetNanotimeFromAbstime(time_since_on_abs) / 1000.0
154
155 fmt = "0x{t:<16x} 0x{t.thread_id:<8x} {t.computation_epoch:16d} {t.last_run_time:16d} {time_on_us:16.3f} {time_since_off_us:16.3f} {time_since_on_us:16.3f}"
156 fmt2 = " {t.base_pri:2d} {t.sched_pri:2d} {t.task_priority:2d} {t.max_priority:2d} {sched_mode:19s}"
157 fmt3 = " {state:9s} {t.cpu_usage:10d} {t.cpu_delta:10d} {t.sched_usage:10d} {t.sched_stamp:10d} {t.pri_shift:10d} {name:s} {thread_name:s}"
158
159 out_str = fmt.format(t=thread, sched_mode=sched_mode, time_on_us=time_on_us, time_since_off_us=time_since_off_us, time_since_on_us=time_since_on_us)
160 out_str += fmt2.format(t=thread, sched_mode=sched_mode)
161 out_str += fmt3.format(t=thread, state=state_str, name=task_name, thread_name=thread_name)
162
163 return out_str
164
165 @lldb_command('showschedhistory')
166 def ShowSchedHistory(cmd_args=None):
167 """ Routine to print out thread scheduling history
168 """
169
170 print "Processors: {:d} Runnable threads: {:d} Timeshare threads: {:d} Background threads {:d}\n".format(
171 kern.globals.processor_avail_count, kern.globals.sched_run_count, kern.globals.sched_share_count, kern.globals.sched_background_count)
172
173 print "Mach factor: {:d} Load factor: {:d} Last sched tick {:d}\n".format(
174 kern.globals.sched_mach_factor, kern.globals.sched_load_average, kern.globals.sched_tick_last_abstime)
175
176 print "Sched tick: {:d} Fixed shift: {:d} Pri shift: {:d} Background pri shift {:d}\n".format(
177 kern.globals.sched_tick, kern.globals.sched_fixed_shift, kern.globals.sched_pri_shift, kern.globals.sched_background_pri_shift)
178
179 processor_list = kern.GetGlobalVariable('processor_list')
180
181 most_recent_dispatch = 0
182 current_processor = processor_list
183 while unsigned(current_processor) > 0:
184 active_thread = current_processor.active_thread
185 if unsigned(active_thread) != 0 :
186 task_val = active_thread.task
187 proc_val = Cast(task_val.bsd_info, 'proc *')
188 proc_name = str(proc_val.p_name)
189
190 last_dispatch = unsigned(current_processor.last_dispatch)
191
192 print "Processor last dispatch: {last_dispatch:16d} Active thread: 0x{t:<16x} 0x{t.thread_id:<8x} {proc_name:s}".format(t=active_thread, last_dispatch=last_dispatch, proc_name=proc_name)
193
194 if last_dispatch > most_recent_dispatch :
195 most_recent_dispatch = last_dispatch
196
197 current_processor = current_processor.processor_list
198
199 print "Most recent dispatch: " + str(most_recent_dispatch)
200
201 print "{:<18s} {:<10s} {:>16s} {:>16s} {:>16s} {:>16s} {:>16s} {:2s} {:2s} {:2s} {:>2s} {:<19s} {:<9s} {:>10s} {:>10s} {:>10s} {:>10s} {:>10s} {:>16s} {:>16s}".format(
202 "thread", "id", "on-core", "off-core", "last-duration", "since-off", "since-on", "BP", "SP", "TP", "MP", "sched-mode", "state", "cpu-usage", "delta", "sch-usage", "stamp", "shift", "task", "thread-name")
203
204 for thread in IterateQueue(kern.globals.threads, 'thread *', 'threads'):
205 print ShowThreadSchedHistory(thread, most_recent_dispatch)
206
207 return
208
209 # EndMacro: showschedhistory
210