]> git.saurik.com Git - apple/xnu.git/blobdiff - tools/lldbmacros/workqueue.py
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tools / lldbmacros / workqueue.py
index dae699f277f1bd1de9abfbc1a645d8b120e35f61..a3b91bf26a182386729f1fcf848e00c807034eb9 100755 (executable)
@@ -68,17 +68,20 @@ def GetWQThreadSummary(th, uth):
     kqr = uth.uu_kqr_bound
     if not kqr:
         kq = 0
-    elif kqr.kqr_state & 0x1: # workloop
+    elif kqr.tr_flags & 0x1: # kevent
+        kq = p.p_fd.fd_wqkqueue
+        kind = "kqwq[%s]" % (xnudefines.thread_qos_short_strings[int(kqr.tr_kq_qos_index)])
+    elif kqr.tr_flags & 0x2: # workloop
         kq = ContainerOf(kqr, 'struct kqworkloop', 'kqwl_request')
         kind = "workloop"
     else:
-        kq = p.p_fd.fd_wqkqueue
-        kind = "kqwq[%s]" % (xnudefines.thread_qos_short_strings[int(kqr.kqr_qos_index)])
+        kq = 0
+        kind = "???"
 
     return "{th: <#020x} {uth: <#020x} {thport: >#010x}  {kind: <9s} {kq: <#020x} {idle: <10s} {uu_workq_flags: <30s}".format(th=th, uth=uth, thport=uth.uu_workq_thport, kind=kind, kq=kq, idle=idle, uu_workq_flags=" ".join(uu_workq_flags))
 
-@header("{:<20s} {:<20s} {:<10s} {:<3s} {:<4s} {:<30s}".format(
-    'request', 'kqueue', 'state', '#', 'qos', 'tr_flags'))
+@header("{:<20s} {:<20s} {:<20s} {:<10s} {:<4s} {:<6s} {:<6s} {:<6s} {:<30s}".format(
+    'request', 'kqueue', 'thread', 'state', '#', 'qos', 'kq_qos', 'kq_ovr', 'tr_flags'))
 def GetWorkqueueThreadRequestSummary(proc, req):
     kq = 0
     tr_flags = []
@@ -88,12 +91,17 @@ def GetWorkqueueThreadRequestSummary(proc, req):
         kq = proc.p_fd.fd_wqkqueue
     if req.tr_flags & 0x02:
         tr_flags.append("WORKLOOP")
-        kq = ContainerOf(req, 'struct kqworkloop', 'kqwl_request.kqr_req')
+        kq = ContainerOf(req, 'struct kqworkloop', 'kqwl_request')
     if req.tr_flags & 0x04: tr_flags.append("OVERCOMMIT")
     if req.tr_flags & 0x08: tr_flags.append("PARAMS")
     if req.tr_flags & 0x10: tr_flags.append("OUTSIDE_QOS")
 
-    state = {0: "IDLE", 1: "NEW", 2: "QUEUED", 4: "BINDING" }[int(req.tr_state)]
+    state = {0: "IDLE", 1: "NEW", 2: "QUEUED", 3: "CANCELED", 4: "BINDING", 5: "BOUND" }[int(req.tr_state)]
+    if req.tr_kq_wakeup: state += "*"
+
+    thread = 0
+    if int(req.tr_state) in [4, 5]: # BINDING or BOUND
+        thread = req.tr_thread
 
     qos = int(req.tr_qos)
     if qos == 8:
@@ -103,74 +111,80 @@ def GetWorkqueueThreadRequestSummary(proc, req):
     else:
         qos = xnudefines.thread_qos_short_strings[qos]
 
-    return "{req: <#020x} {kq: <#020x} {state: <10s} {req.tr_count: <3d} {qos: <4s} {tr_flags: <30s}".format(req=req, kq=kq, state=state, qos=qos, tr_flags=" ".join(tr_flags))
+    kq_qos = xnudefines.thread_qos_short_strings[int(req.tr_kq_qos_index)]
+    kq_ovr = xnudefines.thread_qos_short_strings[int(req.tr_kq_override_index)]
+    req_addr = unsigned(addressof(req))
 
-@lldb_command('showwqthread')
-def ShowWQThread(cmd_args=None):
+    return "{req_addr: <#020x} {kq: <#020x} {thread: <#020x} {state: <10s} {req.tr_count: <4d} {qos: <6s} {kq_qos: <6s} {kq_ovr: <6s} {tr_flags: <30s}".format(
+            req_addr=req_addr, req=req, kq=kq, thread=thread, state=state, qos=qos, kq_qos=kq_qos, kq_ovr=kq_ovr, tr_flags=" ".join(tr_flags))
+
+@lldb_command('showwqthread', fancy=True)
+def ShowWQThread(cmd_args=None, cmd_options={}, O=None):
     """ Shows info about a workqueue thread
 
         usage: showworkqthread <thread_t>
     """
 
     if not cmd_args:
-        raise ArgumentError('missing struct proc * argument')
+        return O.error('missing struct proc * argument')
 
     th = kern.GetValueFromAddress(cmd_args[0], "struct thread *")
     if not (th.thread_tag & 0x20):
         raise ArgumentError('not a workqueue thread')
 
-    print GetWQThreadSummary.header
-    print GetWQThreadSummary(th, Cast(th.uthread, 'struct uthread *'))
+    with O.table(GetWQThreadSummary.header):
+        print GetWQThreadSummary(th, Cast(th.uthread, 'struct uthread *'))
 
 
-@lldb_command('showprocworkqueue')
-def ShowProcWorkqueue(cmd_args=None):
+@lldb_command('showprocworkqueue', fancy=True)
+def ShowProcWorkqueue(cmd_args=None, cmd_options={}, O=None):
     """ Shows the process workqueue
 
         usage: showprocworkqueue <proc_t>
     """
 
     if not cmd_args:
-        raise ArgumentError('missing struct proc * argument')
+        return O.error('missing struct proc * argument')
 
     proc = kern.GetValueFromAddress(cmd_args[0], "proc_t")
     wq = Cast(proc.p_wqptr, "struct workqueue *");
-    if wq:
-        print GetWorkqueueSummary.header
+    if not wq:
+        return O.error("{:#x} doesn't have a workqueue", proc)
+
+    with O.table(GetWorkqueueSummary.header):
         print GetWorkqueueSummary(proc, wq)
 
-        if wq.wq_reqcount:
-            print "    "
-            print "    " + GetWorkqueueThreadRequestSummary.header
+        with O.table(GetWorkqueueThreadRequestSummary.header, indent=True):
+            if wq.wq_reqcount:
+                print ""
             if wq.wq_event_manager_threadreq:
-                print "    " + GetWorkqueueThreadRequestSummary(proc, wq.wq_event_manager_threadreq)
-            for req in IteratePriorityQueueEntry(wq.wq_overcommit_queue, 'struct workq_threadreq_s', 'tr_entry'):
-                print "    " + GetWorkqueueThreadRequestSummary(proc, req)
-            for req in IteratePriorityQueueEntry(wq.wq_constrained_queue, 'struct workq_threadreq_s', 'tr_entry'):
-                print "    " + GetWorkqueueThreadRequestSummary(proc, req)
-            for req in IteratePriorityQueueEntry(wq.wq_special_queue, 'struct workq_threadreq_s', 'tr_entry'):
-                print "    " + GetWorkqueueThreadRequestSummary(proc, req)
-
-        print "    "
-        print "    " + GetWQThreadSummary.header
-        for uth in IterateTAILQ_HEAD(wq.wq_thrunlist, "uu_workq_entry"):
-            print "    " + GetWQThreadSummary(Cast(uth.uu_thread, 'struct thread *'), uth)
-        for uth in IterateTAILQ_HEAD(wq.wq_thidlelist, "uu_workq_entry"):
-            print "    " + GetWQThreadSummary(Cast(uth.uu_thread, 'struct thread *'), uth)
-        for uth in IterateTAILQ_HEAD(wq.wq_thnewlist, "uu_workq_entry"):
-            print "    " + GetWQThreadSummary(Cast(uth.uu_thread, 'struct thread *'), uth)
-
-@lldb_command('showallworkqueues')
-def ShowAllWorkqueues(cmd_args=None):
+                print GetWorkqueueThreadRequestSummary(proc, wq.wq_event_manager_threadreq)
+            for req in IterateSchedPriorityQueue(wq.wq_overcommit_queue, 'struct workq_threadreq_s', 'tr_entry'):
+                print GetWorkqueueThreadRequestSummary(proc, req)
+            for req in IterateSchedPriorityQueue(wq.wq_constrained_queue, 'struct workq_threadreq_s', 'tr_entry'):
+                print GetWorkqueueThreadRequestSummary(proc, req)
+            for req in IterateSchedPriorityQueue(wq.wq_special_queue, 'struct workq_threadreq_s', 'tr_entry'):
+                print GetWorkqueueThreadRequestSummary(proc, req)
+
+        with O.table(GetWQThreadSummary.header, indent=True):
+            print ""
+            for uth in IterateTAILQ_HEAD(wq.wq_thrunlist, "uu_workq_entry"):
+                print GetWQThreadSummary(Cast(uth.uu_thread, 'struct thread *'), uth)
+            for uth in IterateTAILQ_HEAD(wq.wq_thidlelist, "uu_workq_entry"):
+                print GetWQThreadSummary(Cast(uth.uu_thread, 'struct thread *'), uth)
+            for uth in IterateTAILQ_HEAD(wq.wq_thnewlist, "uu_workq_entry"):
+                print GetWQThreadSummary(Cast(uth.uu_thread, 'struct thread *'), uth)
+
+@lldb_command('showallworkqueues', fancy=True)
+def ShowAllWorkqueues(cmd_args=None, cmd_options={}, O=None):
     """ Display a summary of all the workqueues in the system
 
         usage: showallworkqueues
     """
 
-    print GetWorkqueueSummary.header
-
-    for t in kern.tasks:
-        proc = Cast(t.bsd_info, 'proc *')
-        wq = Cast(proc.p_wqptr, "struct workqueue *");
-        if wq:
-            print GetWorkqueueSummary(proc, wq)
+    with O.table(GetWorkqueueSummary.header):
+        for t in kern.tasks:
+            proc = Cast(t.bsd_info, 'proc *')
+            wq = Cast(proc.p_wqptr, "struct workqueue *");
+            if wq:
+                print GetWorkqueueSummary(proc, wq)