#       $NetBSD: lwps,v 1.6 2019/07/17 09:14:24 skrll Exp $

define lwps
       set $i = 0

       while ($i < 2)
               if ($i == 0)
                       set $p = allproc.lh_first
               end
               if ($p)
                       printf "\t       lwp   pid   lid     flag              wchan\n"
               end
               while ($p)
                       set $l = $p->p_lwps.lh_first
                       set $j = 0
                       while ($j < $p->p_nlwps)
                               printf "0x%016lx %5d %5d %8x 0x%016lx", \
                                       $l, $p->p_pid, $l->l_lid, $l->l_flag, $l->l_wchan
                               if ($l->l_wmesg)
                                       printf " (%s)", (char *)$l->l_wmesg
# If the preceding command cannot dereference the pointer, use this instead:
#                                       printf " (%lx)", $l->l_wmesg
                               end
                               set $l = $l->l_sibling.le_next
                               printf "\n"
                               set $j++
                       end
                       set $p = $p->p_list.le_next
               end
               set $i++
       end
end
document lwps
ps for lwps
end

define threadinfo
       set $l = (struct lwp *)$arg0
       set $pid = $arg1

       set $j = 0
       set $n = $l->l_name
       #if ($n == 0)
       #       set $n = (char *)""
       #end
       printf "           laddr   pid   lid     flag                 wchan\n"
       printf "%16lx %5d %5d %8x      %16lx", \
               $l, $pid, $l->l_lid, $l->l_flag, $l->l_wchan
       if ($n != 0)
               printf "  %16s", $n
       end
       printf "\n\n"
       kvm proc $l
       where
       printf "\n"
end
document threadinfo
Print out the stack and other data of a single thread.
end

define procthreadsaddr
       set $p = (struct proc *)$arg0
       set $l = $p->p_lwps.lh_first
       set $nlwps = $p->p_nlwps
       set $pid = $p->p_pid

       printf "           paddr   pid     flag  stat    n         firstlwp          command\n"
       printf "%16lx %5d %8x %4x %5d %16lx %16s\n\n", \
               $p, $pid, $p->p_flag, $p->p_stat, \
               $nlwps, $p->p_lwps.lh_first, \
               (char *) $p->p_comm
       while ($l)
               threadinfo $l $pid
               set $l = $l->l_sibling.le_next
               set $j++
       end
end
document procthreadsaddr
Print out the stack of all threads in a particular process,
found via struct proc * address.
end

define procthreadspid
       set $pid = (unsigned)$arg0
       set $p = allproc.lh_first
       while ($p)
               if ($pid == $p->p_pid)
                       procthreadsaddr $p
                       loop_break
               end
               set $p = $p->p_list.le_next
       end
end
document procthreadspid
Print out the stack of all threads in a particular process,
found via PID.
end

define threadlist
       set $p = allproc.lh_first
       while ($p)
               procthreadsaddr $p
               set $p = $p->p_list.le_next
       end
end
document threadlist
Print out the stack of all threads in the system.
end

define lock
       set $ld = (struct lockdebug *)ld_rb_tree
       set $a = $ld->ld_lock
       set $b = (volatile void *)$arg0

       while ($ld && $a != $b)
               if ($a < $b)
                       set $ld = (struct lockdebug *)$ld->ld_rb_node.rb_nodes[1]
               end
               if ($a > $b)
                       set $ld = (struct lockdebug *)$ld->ld_rb_node.rb_nodes[0]
               end
               if ($ld == 0)
                       loop_break
               end
               set $a = $ld->ld_lock
# printf "a=%lx b=%lx ld=%lx a<b %d a>b %d\n", $a, $b, $ld,  ($a < $b), ($a > $b)
       end
       if ($ld)
               printf "lock address : %#018lx type     : ", \
                       (long)$ld->ld_lock
               if ($ld->ld_flags & 0x2)
                       printf "sleep/adaptive\n"
               else
                       printf "spin\n"
               end
               printf "initialized  : %#018lx", \
                       (long)$ld->ld_initaddr
               if ($ld->ld_lockops->lo_type == 0x2)
                       printf " interlock: %#018lx\n", $ld->ld_locked
               else
                       printf "\n"
                       printf "shared holds : %18u exclusive: ", \
                               $ld->ld_shares
                       if (($ld->ld_flags & 0x1) != 0)
                               printf "1\n"
                       else
                               printf "0\n"
                       end
                       printf "shares wanted: %18u exclusive: %18u\n", \
                               (unsigned)$ld->ld_shwant, (unsigned)$ld->ld_exwant
                       printf "cpu last held: %18u\n", \
                               (unsigned)$ld->ld_cpu
                       printf "current lwp  : %#018lx last held: %#018lx\n", \
                               (long)0, (long)$ld->ld_lwp
                       printf "last locked  : %#018lx unlocked : %#018lx\n", \
                               (long)$ld->ld_locked, (long)$ld->ld_unlocked
               end
       end
end
document lock
Print out lockdebug info like ddb does.
end