1174199Srwatson/*- 2174199Srwatson * Copyright (c) 2007 Robert N. M. Watson 3287486Sallanjude * Copyright (c) 2015 Allan Jude <allanjude@freebsd.org> 4174199Srwatson * All rights reserved. 5174199Srwatson * 6174199Srwatson * Redistribution and use in source and binary forms, with or without 7174199Srwatson * modification, are permitted provided that the following conditions 8174199Srwatson * are met: 9174199Srwatson * 1. Redistributions of source code must retain the above copyright 10174199Srwatson * notice, this list of conditions and the following disclaimer. 11174199Srwatson * 2. Redistributions in binary form must reproduce the above copyright 12174199Srwatson * notice, this list of conditions and the following disclaimer in the 13174199Srwatson * documentation and/or other materials provided with the distribution. 14174199Srwatson * 15174199Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16174199Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17174199Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18174199Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19174199Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20174199Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21174199Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22174199Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23174199Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24174199Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25174199Srwatson * SUCH DAMAGE. 26174199Srwatson * 27174199Srwatson * $FreeBSD: releng/11.0/usr.bin/procstat/procstat_threads.c 287486 2015-09-05 17:02:01Z allanjude $ 28174199Srwatson */ 29174199Srwatson 30186567Srwatson#include <sys/param.h> 31174199Srwatson#include <sys/sysctl.h> 32174199Srwatson#include <sys/user.h> 33174199Srwatson 34174199Srwatson#include <err.h> 35174199Srwatson#include <errno.h> 36221807Sstas#include <libprocstat.h> 37174199Srwatson#include <stdio.h> 38174199Srwatson#include <stdlib.h> 39174199Srwatson#include <string.h> 40174199Srwatson 41174199Srwatson#include "procstat.h" 42174199Srwatson 43174199Srwatsonvoid 44249668Strocinyprocstat_threads(struct procstat *procstat, struct kinfo_proc *kipp) 45174199Srwatson{ 46174199Srwatson struct kinfo_proc *kip; 47249668Strociny unsigned int count, i; 48174199Srwatson const char *str; 49287486Sallanjude char *threadid; 50174199Srwatson 51174199Srwatson if (!hflag) 52287486Sallanjude xo_emit("{T:/%5s %6s %-16s %-16s %2s %4s %-7s %-9s}\n", "PID", 53174230Srwatson "TID", "COMM", "TDNAME", "CPU", "PRI", "STATE", "WCHAN"); 54174199Srwatson 55287486Sallanjude xo_emit("{ek:process_id/%d}", kipp->ki_pid); 56287486Sallanjude xo_emit("{e:command/%s}", strlen(kipp->ki_comm) ? 57287486Sallanjude kipp->ki_comm : "-"); 58287486Sallanjude xo_open_container("threads"); 59287486Sallanjude 60249668Strociny kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD, 61249668Strociny kipp->ki_pid, &count); 62174199Srwatson if (kip == NULL) 63174199Srwatson return; 64249668Strociny kinfo_proc_sort(kip, count); 65249668Strociny for (i = 0; i < count; i++) { 66174199Srwatson kipp = &kip[i]; 67287486Sallanjude asprintf(&threadid, "%d", kipp->ki_tid); 68287486Sallanjude if (threadid == NULL) 69287486Sallanjude xo_errc(1, ENOMEM, "Failed to allocate memory in " 70287486Sallanjude "procstat_threads()"); 71287486Sallanjude xo_open_container(threadid); 72287486Sallanjude xo_emit("{dk:process_id/%5d/%d} ", kipp->ki_pid); 73287486Sallanjude xo_emit("{:thread_id/%6d/%d} ", kipp->ki_tid); 74287486Sallanjude xo_emit("{d:command/%-16s/%s} ", strlen(kipp->ki_comm) ? 75174199Srwatson kipp->ki_comm : "-"); 76287486Sallanjude xo_emit("{:thread_name/%-16s/%s} ", (strlen(kipp->ki_tdname) && 77224199Sbz (strcmp(kipp->ki_comm, kipp->ki_tdname) != 0)) ? 78224199Sbz kipp->ki_tdname : "-"); 79174199Srwatson if (kipp->ki_oncpu != 255) 80287486Sallanjude xo_emit("{:cpu/%3d/%d} ", kipp->ki_oncpu); 81174199Srwatson else if (kipp->ki_lastcpu != 255) 82287486Sallanjude xo_emit("{:cpu/%3d/%d} ", kipp->ki_lastcpu); 83174199Srwatson else 84287486Sallanjude xo_emit("{:cpu/%3s/%s} ", "-"); 85287486Sallanjude xo_emit("{:priority/%4d/%d} ", kipp->ki_pri.pri_level); 86174199Srwatson switch (kipp->ki_stat) { 87174199Srwatson case SRUN: 88174199Srwatson str = "run"; 89174199Srwatson break; 90174199Srwatson 91174199Srwatson case SSTOP: 92174199Srwatson str = "stop"; 93174199Srwatson break; 94174199Srwatson 95174199Srwatson case SSLEEP: 96174199Srwatson str = "sleep"; 97174199Srwatson break; 98174199Srwatson 99174199Srwatson case SLOCK: 100174199Srwatson str = "lock"; 101174199Srwatson break; 102174199Srwatson 103174199Srwatson case SWAIT: 104174199Srwatson str = "wait"; 105174199Srwatson break; 106174199Srwatson 107174199Srwatson case SZOMB: 108174199Srwatson str = "zomb"; 109174199Srwatson break; 110174199Srwatson 111174199Srwatson case SIDL: 112174199Srwatson str = "idle"; 113174199Srwatson break; 114174199Srwatson 115174199Srwatson default: 116174199Srwatson str = "??"; 117174199Srwatson break; 118174199Srwatson } 119287486Sallanjude xo_emit("{:run_state/%-7s/%s} ", str); 120174199Srwatson if (kipp->ki_kiflag & KI_LOCKBLOCK) { 121287486Sallanjude xo_emit("{:lock_name/*%-8s/%s} ", 122287486Sallanjude strlen(kipp->ki_lockname) ? 123174199Srwatson kipp->ki_lockname : "-"); 124174199Srwatson } else { 125287486Sallanjude xo_emit("{:wait_channel/%-9s/%s} ", 126287486Sallanjude strlen(kipp->ki_wmesg) ? kipp->ki_wmesg : "-"); 127174199Srwatson } 128287486Sallanjude xo_close_container(threadid); 129287486Sallanjude free(threadid); 130287486Sallanjude xo_emit("\n"); 131174199Srwatson } 132287486Sallanjude xo_close_container("threads"); 133249668Strociny procstat_freeprocs(procstat, kip); 134174199Srwatson} 135