5 # TODO: write scheduler related macros here
7 # Macro: showinterrupts
9 @lldb_command('showinterrupts')
10 def ShowInterrupts(cmd_args
=None):
11 """ Prints IRQ, IPI and TMR counts for each CPU
13 base_address
= kern
.GetLoadAddressForSymbol('CpuDataEntries')
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
23 # Macro: showactiveinterrupts
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>
31 print "No arguments passed"
32 print ShowActiveInterrupts
.__doc
__
34 aic
= kern
.GetValueFromAddress(cmd_args
[0], 'AppleInterruptController *')
36 print "unknown arguments:", str(cmd_args
)
39 aic_base
= unsigned(aic
._aicBaseAddress
)
41 aic_imc_base
= aic_base
+ 0x4180
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 *'))
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):
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 *'))
59 # EndMacro: showactiveinterrupts
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
67 pset
= addressof(kern
.globals.pset0
)
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
)
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
)
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
)
85 print "Last dispatch time known: %d MATUs" % cur_abstime
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>
94 raise ArgumentError("Invalid argument")
95 timedata
= ArgumentStringToInt(cmd_args
[0])
96 print "%d ns" % kern
.GetNanotimeFromAbstime(timedata
)
98 # Macro: showschedhistory
100 def ShowThreadSchedHistory(thread
, most_recent_dispatch
):
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
)
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
)
120 mode
= str(thread
.sched_mode
)
121 if "TIMESHARE" in mode
:
122 sched_mode
+="timeshare"
123 elif "FIXED" in mode
:
125 elif "REALTIME" in mode
:
126 sched_mode
+="realtime"
128 if (unsigned(thread
.bound_processor
) != 0):
132 if (unsigned(thread
.sched_flags
) & 0x0004):
137 thread_state_chars
= {0x0:'', 0x1:'W', 0x2:'S', 0x4:'R', 0x8:'U', 0x10:'H', 0x20:'A', 0x40:'P', 0x80:'I'}
141 state_str
+= thread_state_chars
[int(state
& mask
)]
144 last_on
= thread
.computation_epoch
145 last_off
= thread
.last_run_time
147 time_on_abs
= unsigned(last_off
- last_on
)
148 time_on_us
= kern
.GetNanotimeFromAbstime(time_on_abs
) / 1000.0
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
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}"
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
)
165 @lldb_command('showschedhistory')
166 def ShowSchedHistory(cmd_args
=None):
167 """ Routine to print out thread scheduling history
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
)
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
)
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
)
179 processor_list
= kern
.GetGlobalVariable('processor_list')
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
)
190 last_dispatch
= unsigned(current_processor
.last_dispatch
)
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
)
194 if last_dispatch
> most_recent_dispatch
:
195 most_recent_dispatch
= last_dispatch
197 current_processor
= current_processor
.processor_list
199 print "Most recent dispatch: " + str(most_recent_dispatch
)
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")
204 for thread
in IterateQueue(kern
.globals.threads
, 'thread *', 'threads'):
205 print ShowThreadSchedHistory(thread
, most_recent_dispatch
)
209 # EndMacro: showschedhistory