"Fossies" - the Fresh Open Source Software Archive

Member "atop-2.8.1/showlinux.c" (7 Jan 2023, 89772 Bytes) of package /linux/misc/atop-2.8.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "showlinux.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.7.1_vs_2.8.0.

    1 /*
    2 ** ATOP - System & Process Monitor 
    3 **
    4 ** The program 'atop' offers the possibility to view the activity of
    5 ** the system on system-level as well as process-level.
    6 **
    7 ** This source-file contains the Linux-specific functions to calculate
    8 ** figures to be visualized.
    9 ** ==========================================================================
   10 ** Author:      Gerlof Langeveld
   11 **              Original version.
   12 ** E-mail:      gerlof.langeveld@atoptool.nl
   13 ** Date:        July 2002
   14 **
   15 ** Author:  JC van Winkel - AT Computing, Nijmegen, Holland
   16 **              Complete redesign.
   17 ** Date:        November 2009
   18 ** --------------------------------------------------------------------------
   19 ** Copyright (C) 2009-2010 JC van Winkel
   20 **
   21 ** This program is free software; you can redistribute it and/or modify it
   22 ** under the terms of the GNU General Public License as published by the
   23 ** Free Software Foundation; either version 2, or (at your option) any
   24 ** later version.
   25 **
   26 ** This program is distributed in the hope that it will be useful, but
   27 ** WITHOUT ANY WARRANTY; without even the implied warranty of
   28 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   29 ** See the GNU General Public License for more details.
   30 **
   31 ** You should have received a copy of the GNU General Public License
   32 ** along with this program; if not, write to the Free Software
   33 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   34 ** --------------------------------------------------------------------------
   35 **
   36 ** $Log: showlinux.c,v $
   37 ** Revision 1.70  2010/10/23 14:04:12  gerlof
   38 ** Counters for total number of running and sleep threads (JC van Winkel).
   39 **
   40 ** Revision 1.69  2010/05/18 19:20:08  gerlof
   41 ** Introduce CPU frequency and scaling (JC van Winkel).
   42 **
   43 ** Revision 1.68  2010/04/23 12:19:35  gerlof
   44 ** Modified mail-address in header.
   45 **
   46 ** Revision 1.67  2010/04/17 17:20:33  gerlof
   47 ** Allow modifying the layout of the columns in the system lines.
   48 **
   49 ** Revision 1.66  2010/03/16 21:14:46  gerlof
   50 ** Program and user selection can be combined with program and user
   51 ** accumulation.
   52 **
   53 ** Revision 1.65  2010/03/04 10:53:26  gerlof
   54 ** Support I/O-statistics on logical volumes and MD devices.
   55 **
   56 ** Revision 1.64  2010/01/18 18:06:28  gerlof
   57 ** Modified priorities for system-level columns.
   58 **
   59 ** Revision 1.63  2010/01/16 12:54:33  gerlof
   60 ** Corrected order of columns.
   61 **
   62 ** Revision 1.62  2010/01/16 11:38:02  gerlof
   63 ** Corrected counters for patched kernels (JC van Winkel).
   64 **
   65 ** Revision 1.61  2010/01/08 11:25:56  gerlof
   66 ** Corrected column-width and priorities of network-stats.
   67 **
   68 ** Revision 1.60  2010/01/03 18:27:19  gerlof
   69 ** *** empty log message ***
   70 **
   71 ** Revision 1.59  2009/12/19 21:01:28  gerlof
   72 ** Improved syntax checking for ownprocline keyword (JC van Winkel).
   73 **
   74 ** Revision 1.58  2009/12/17 11:59:28  gerlof
   75 ** Gather and display new counters: dirty cache and guest cpu usage.
   76 **
   77 ** Revision 1.57  2009/12/17 10:51:19  gerlof
   78 ** Allow own defined process line with key 'o' and a definition
   79 ** in the atoprc file.
   80 **
   81 ** Revision 1.56  2009/12/17 09:13:19  gerlof
   82 ** Reformatted some fields for better grouping of info.
   83 **
   84 ** Revision 1.55  2009/12/12 10:11:18  gerlof
   85 ** Register and display end date and end time for process.
   86 **
   87 ** Revision 1.54  2009/12/12 09:06:48  gerlof
   88 ** \Corrected cumulated disk I/O per user/program (JC van Winkel).
   89 **
   90 ** Revision 1.53  2009/12/10 14:02:39  gerlof
   91 ** Add EUID, SUID and FSUID (and similar for GID's).
   92 **
   93 ** Revision 1.52  2009/12/10 11:56:34  gerlof
   94 ** Various bug-solutions.
   95 **
   96 ** Revision 1.51  2009/12/10 10:08:01  gerlof
   97 ** Major redesign for improved user interface (variable number of columns).
   98 ** Made by JC van Winkel.
   99 **
  100 ** Revision 1.49  2008/03/06 08:38:28  gerlof
  101 ** Register/show ppid of a process.
  102 **
  103 ** Revision 1.48  2008/01/18 07:37:05  gerlof
  104 ** Show information about the state of the individual threads
  105 ** in the scheduling report shown with keystroke 's'.
  106 **
  107 ** Revision 1.47  2008/01/07 11:34:18  gerlof
  108 ** Correct the sort-order of network-interfaces (on busy-percentage).
  109 **
  110 ** Revision 1.46  2007/11/07 09:23:29  gerlof
  111 ** Modified format for avg1, avg5 and avg15 (CPL) when counters too large.
  112 **
  113 ** Revision 1.45  2007/11/05 11:43:25  gerlof
  114 ** Bug-solution for new-process indicator on 64-bits machines.
  115 **
  116 ** Revision 1.44  2007/11/05 10:57:56  gerlof
  117 ** Bug-solution for huge exit code on 64-bits machines.
  118 **
  119 ** Revision 1.43  2007/08/17 09:45:57  gerlof
  120 ** Experimental: gather info about HTTP statistics.
  121 **
  122 ** Revision 1.42  2007/08/16 12:02:04  gerlof
  123 ** Add support for atopsar reporting.
  124 ** Concerns modification of networking-counters.
  125 **
  126 ** Revision 1.41  2007/07/04 10:18:16  gerlof
  127 ** Bug-solution for division by zero.
  128 **
  129 ** Revision 1.40  2007/07/03 09:02:29  gerlof
  130 ** Support Apache-statistics.
  131 **
  132 ** Revision 1.39  2007/03/22 10:12:54  gerlof
  133 ** Support for io counters (>= kernel 2.6.20).
  134 **
  135 ** Revision 1.38  2007/03/21 14:22:24  gerlof
  136 ** Handle io counters maintained from 2.6.20
  137 **
  138 ** Revision 1.37  2007/02/13 10:36:09  gerlof
  139 ** Removal of external declarations.
  140 ** Use of hertz variable instead of HZ.
  141 **
  142 ** Revision 1.36  2007/01/26 12:11:07  gerlof
  143 ** Add configuration-value 'swoutcritsec'.
  144 **
  145 ** Revision 1.35  2007/01/26 10:25:42  gerlof
  146 ** Introduce steal percentage for virtual machines.
  147 ** Correct bug: when one interface is colored all subsequent interfaces
  148 **              are colored.
  149 **
  150 ** Revision 1.34  2007/01/18 10:58:45  gerlof
  151 ** Only check for committed limit if it is not zero.
  152 **
  153 ** Revision 1.33  2007/01/18 10:37:09  gerlof
  154 ** Add support for colors.
  155 ** Add support for automatic determination of most critical resource.
  156 ** Add support for parsing of new arguments in ~/.atoprc
  157 **
  158 ** Revision 1.32  2006/11/13 13:48:46  gerlof
  159 ** Implement load-average counters, context-switches and interrupts.
  160 **
  161 ** Revision 1.31  2006/02/07 08:38:49  gerlof
  162 ** Swapped the zombie counter and exit counter in the PRC-line.
  163 **
  164 ** Revision 1.30  2006/02/07 08:30:07  gerlof
  165 ** Add possibility to show counters per second.
  166 ** Ease parsing of output-lines by fixed number of columns per line.
  167 **
  168 ** Revision 1.29  2006/01/30 09:24:12  gerlof
  169 ** PRC-line: 'exits' modified to 'exit' to save space.
  170 **
  171 ** Revision 1.28  2006/01/30 09:14:26  gerlof
  172 ** Extend memory counters (a.o. page scans).
  173 **
  174 ** Revision 1.27  2005/11/04 14:16:45  gerlof
  175 ** Minor bug-solutions.
  176 **
  177 ** Revision 1.26  2005/10/28 09:51:29  gerlof
  178 ** All flags/subcommands are defined as macro's.
  179 ** Subcommand 'p' has been changed to 'z' (pause).
  180 **
  181 ** Revision 1.25  2005/10/21 09:51:11  gerlof
  182 ** Per-user accumulation of resource consumption.
  183 **
  184 ** Revision 1.24  2004/12/14 15:06:48  gerlof
  185 ** Implementation of patch-recognition for disk and network-statistics.
  186 **
  187 ** Revision 1.23  2004/10/28 08:31:41  gerlof
  188 ** New counter: vm committed space
  189 **
  190 ** Revision 1.22  2004/09/24 10:02:46  gerlof
  191 ** Wrong cpu-numbers for system level statistics.
  192 **
  193 ** Revision 1.21  2004/09/23 08:21:10  gerlof
  194 ** Added wait-percentage per cpu.
  195 **
  196 ** Revision 1.20  2004/09/23 07:37:34  gerlof
  197 ** Consistent handling of CPU percentages on system-level and process-level.
  198 **
  199 ** Revision 1.19  2004/09/13 09:20:21  gerlof
  200 ** Modify subcommands (former 's' -> 'v', 'v' -> 'V', new 's').
  201 **
  202 ** Revision 1.18  2004/09/02 10:55:21  root
  203 ** Added sleep-average to process-info.
  204 **
  205 ** Revision 1.17  2004/08/31 09:53:31  gerlof
  206 ** Show information about underlying threads.
  207 **
  208 ** Revision 1.16  2004/06/01 11:58:34  gerlof
  209 ** Regular expressions for selections on process-name and user-name.
  210 **
  211 ** Revision 1.15  2004/05/06 09:47:59  gerlof
  212 ** Ported to kernel-version 2.6.
  213 **
  214 ** Revision 1.14  2003/07/07 09:27:34  gerlof
  215 ** Cleanup code (-Wall proof).
  216 **
  217 ** Revision 1.13  2003/07/03 12:04:25  gerlof
  218 ** Minor bug fixes.
  219 **
  220 ** Revision 1.12  2003/06/30 11:29:57  gerlof
  221 ** Enlarge counters to 'long long'.
  222 **
  223 ** Revision 1.11  2003/06/24 06:22:10  gerlof
  224 ** Limit number of system resource lines.
  225 **
  226 ** Revision 1.10  2003/02/07 10:43:22  gerlof
  227 ** Solved a division-by-zero bug for process-percentage.
  228 **
  229 ** Revision 1.9  2003/01/24 14:20:57  gerlof
  230 ** If possible, also show commandline when process has exited.
  231 **
  232 ** Revision 1.8  2003/01/17 07:32:49  gerlof
  233 ** Show the full command-line per process (option 'c').
  234 **
  235 ** Revision 1.7  2002/10/04 10:05:54  gerlof
  236 ** Bug-solution: New process indicator in static output set when needed.
  237 **
  238 ** Revision 1.6  2002/10/03 11:14:42  gerlof
  239 ** Modify (effective) uid/gid to real uid/gid.
  240 **
  241 ** Revision 1.5  2002/09/26 13:52:51  gerlof
  242 ** Limit header lines by not showing disks.
  243 ** Limit header lines by not showing disks.
  244 **
  245 ** Revision 1.4  2002/09/16 08:59:13  gerlof
  246 ** Change field EXCODE to STATUS for support of indicator of newly created
  247 ** processes.
  248 **
  249 ** Revision 1.3  2002/09/02 08:42:44  gerlof
  250 ** Bug-solution: blank line after header when more than 999 screens of
  251 ** process-list information.
  252 **
  253 ** Revision 1.2  2002/08/30 07:11:20  gerlof
  254 ** Minor changes in the header-line of the process list.
  255 **
  256 ** Revision 1.1  2002/07/24 11:14:16  gerlof
  257 ** Initial revision
  258 **
  259 **
  260 ** Initial
  261 **
  262 */
  263 
  264 #include <sys/types.h>
  265 #include <sys/param.h>
  266 #include <sys/stat.h>
  267 #include <signal.h>
  268 #include <time.h>
  269 #include <stdio.h>
  270 #include <stdlib.h>
  271 #include <string.h>
  272 #include <errno.h>
  273 #include <fcntl.h>
  274 #include <unistd.h>
  275 #include <stdarg.h>
  276 #include <curses.h>
  277 #include <pwd.h>
  278 #include <grp.h>
  279 #include <regex.h>
  280 
  281 #include "atop.h"
  282 #include "photoproc.h"
  283 #include "photosyst.h"
  284 #include "showgeneric.h"
  285 #include "showlinux.h"
  286 
  287 static void make_proc_dynamicgen(void);
  288 
  289 /*
  290 ** critical percentages for occupation-percentage;
  291 ** these defaults can be overruled via the config-file
  292 */
  293 int   cpubadness = 90;        /* percentage           */
  294 int   gpubadness = 100;       /* percentage           */
  295 int   membadness = 90;        /* percentage           */
  296 int   swpbadness = 80;        /* percentage           */
  297 int   dskbadness = 70;        /* percentage           */
  298 int   netbadness = 90;        /* percentage           */
  299 int   pagbadness = 10;        /* number per second    */
  300 
  301 int   almostcrit = 80;        /* percentage           */
  302 
  303 /*
  304  * tables with all sys_printdefs
  305  */
  306 sys_printdef *prcsyspdefs[] = {
  307     &syspdef_PRCSYS,
  308     &syspdef_PRCUSER,
  309     &syspdef_PRCNPROC,
  310         &syspdef_PRCNRUNNING,
  311         &syspdef_PRCNSLEEPING,
  312         &syspdef_PRCNDSLEEPING,
  313     &syspdef_PRCNZOMBIE,
  314     &syspdef_PRCCLONES,
  315     &syspdef_PRCNNEXIT,
  316     &syspdef_BLANKBOX,
  317         0
  318 };
  319 sys_printdef *cpusyspdefs[] = {
  320     &syspdef_CPUSYS,
  321     &syspdef_CPUUSER,
  322     &syspdef_CPUIRQ,
  323     &syspdef_CPUIDLE,
  324     &syspdef_CPUWAIT,
  325     &syspdef_BLANKBOX,
  326     &syspdef_CPUIPC,
  327     &syspdef_CPUCYCLE,
  328     &syspdef_CPUFREQ,
  329     &syspdef_CPUSCALE,
  330     &syspdef_CPUSTEAL,
  331     &syspdef_CPUGUEST,
  332     &syspdef_BLANKBOX,
  333         0
  334 };
  335 sys_printdef *cpisyspdefs[] = {
  336     &syspdef_CPUISYS,
  337     &syspdef_CPUIUSER,
  338     &syspdef_CPUIIRQ,
  339     &syspdef_CPUIIDLE,
  340     &syspdef_CPUIWAIT,
  341     &syspdef_BLANKBOX,
  342     &syspdef_CPUIIPC,
  343     &syspdef_CPUICYCLE,
  344     &syspdef_CPUIFREQ,
  345     &syspdef_CPUISCALE,
  346     &syspdef_CPUISTEAL,
  347     &syspdef_CPUIGUEST,
  348     &syspdef_BLANKBOX,
  349         0
  350 };
  351 sys_printdef *cplsyspdefs[] = {
  352     &syspdef_CPLNUMCPU,
  353     &syspdef_CPLAVG1,
  354     &syspdef_CPLAVG5,
  355     &syspdef_CPLAVG15,
  356     &syspdef_CPLCSW,
  357     &syspdef_CPLINTR,
  358     &syspdef_BLANKBOX,
  359         0
  360 };
  361 sys_printdef *gpusyspdefs[] = {
  362     &syspdef_GPUBUS,
  363     &syspdef_GPUGPUPERC,
  364     &syspdef_GPUMEMPERC,
  365     &syspdef_GPUMEMOCC,
  366     &syspdef_GPUMEMTOT,
  367     &syspdef_GPUMEMUSE,
  368     &syspdef_GPUMEMAVG,
  369     &syspdef_GPUTYPE,
  370     &syspdef_GPUNRPROC,
  371     &syspdef_BLANKBOX,
  372         0
  373 };
  374 sys_printdef *memsyspdefs1[] = {
  375     &syspdef_MEMTOT,
  376     &syspdef_MEMFREE,
  377     &syspdef_BLANKBOX,
  378     &syspdef_MEMCACHE,
  379     &syspdef_MEMDIRTY,
  380     &syspdef_MEMBUFFER,
  381     &syspdef_BLANKBOX,
  382     &syspdef_MEMSLAB,
  383     &syspdef_RECSLAB,
  384     &syspdef_BLANKBOX,
  385     &syspdef_PAGETABS,
  386     &syspdef_BLANKBOX,
  387     &syspdef_HUPTOT,
  388     &syspdef_HUPUSE,
  389         0
  390 };
  391 sys_printdef *memsyspdefs2[] = {
  392     &syspdef_NUMNUMA,
  393     &syspdef_BLANKBOX,
  394     &syspdef_TCPSOCK,
  395     &syspdef_UDPSOCK,
  396     &syspdef_BLANKBOX,
  397     &syspdef_SHMEM,
  398     &syspdef_SHMRSS,
  399     &syspdef_SHMSWP,
  400     &syspdef_BLANKBOX,
  401     &syspdef_VMWBAL,
  402     &syspdef_BLANKBOX,
  403     &syspdef_ZFSARC,
  404         0
  405 };
  406 sys_printdef *swpsyspdefs[] = {
  407     &syspdef_SWPTOT,
  408     &syspdef_SWPFREE,
  409     &syspdef_SWPCACHE,
  410     &syspdef_BLANKBOX,
  411     &syspdef_ZSWTOTAL,
  412     &syspdef_ZSWSTORED,
  413     &syspdef_KSMSHARING,
  414     &syspdef_KSMSHARED,
  415     &syspdef_BLANKBOX,
  416     &syspdef_SWPCOMMITTED,
  417     &syspdef_SWPCOMMITLIM,
  418     &syspdef_BLANKBOX,
  419         0
  420 };
  421 sys_printdef *pagsyspdefs[] = {
  422     &syspdef_PAGSCAN,
  423     &syspdef_PAGSTEAL,
  424     &syspdef_PAGSTALL,
  425     &syspdef_PAGCOMPACT,
  426     &syspdef_PGMIGRATE,
  427     &syspdef_NUMAMIGRATE,
  428     &syspdef_PAGSWIN,
  429     &syspdef_PAGSWOUT,
  430     &syspdef_OOMKILLS,
  431     &syspdef_PAGPGIN,
  432     &syspdef_PAGPGOUT,
  433     &syspdef_BLANKBOX,
  434         0
  435 };
  436 sys_printdef *memnumasyspdefs[] = {
  437     &syspdef_NUMATOT,
  438     &syspdef_NUMAFREE,
  439     &syspdef_NUMAFILEPAGE,
  440     &syspdef_NUMANR,
  441     &syspdef_NUMADIRTY,
  442     &syspdef_NUMAACTIVE,
  443     &syspdef_NUMAINACTIVE,
  444     &syspdef_NUMASLAB,
  445     &syspdef_NUMASLABRECLAIM,
  446     &syspdef_NUMASHMEM,
  447     &syspdef_NUMAFRAG,
  448     &syspdef_NUMAHUPTOT,
  449         0
  450 };
  451 sys_printdef *cpunumasyspdefs[] = {
  452     &syspdef_NUMACPUSYS,
  453     &syspdef_NUMACPUUSER,
  454     &syspdef_NUMACPUNICE,
  455     &syspdef_NUMACPUIRQ,
  456     &syspdef_NUMACPUSOFTIRQ,
  457     &syspdef_NUMACPUIDLE,
  458     &syspdef_NUMACPUWAIT,
  459     &syspdef_NUMACPUSTEAL,
  460     &syspdef_NUMACPUGUEST,
  461     &syspdef_NUMANUMCPU,
  462         0
  463 };
  464 sys_printdef *llcsyspdefs[] = {
  465     &syspdef_LLCMBMTOTAL,
  466     &syspdef_LLCMBMLOCAL,
  467     &syspdef_NUMLLC,
  468     &syspdef_BLANKBOX,
  469         0
  470 };
  471 sys_printdef *psisyspdefs[] = {
  472     &syspdef_PSICPUSTOT,
  473     &syspdef_PSIMEMSTOT,
  474     &syspdef_PSIMEMFTOT,
  475     &syspdef_PSIIOSTOT,
  476     &syspdef_PSIIOFTOT,
  477     &syspdef_PSICPUS,
  478     &syspdef_PSIMEMS,
  479     &syspdef_PSIMEMF,
  480     &syspdef_PSIIOS,
  481     &syspdef_PSIIOF,
  482     &syspdef_BLANKBOX,
  483         0
  484 };
  485 sys_printdef *contsyspdefs[] = {
  486     &syspdef_CONTNAME,
  487     &syspdef_CONTNPROC,
  488     &syspdef_CONTCPU,
  489     &syspdef_CONTMEM,
  490     &syspdef_BLANKBOX,
  491     0
  492 };
  493 sys_printdef *dsksyspdefs[] = {
  494     &syspdef_DSKNAME,
  495     &syspdef_DSKBUSY,
  496     &syspdef_DSKNREAD,
  497     &syspdef_DSKNWRITE,
  498     &syspdef_DSKNDISC,
  499     &syspdef_DSKMBPERSECWR,
  500     &syspdef_DSKMBPERSECRD,
  501     &syspdef_DSKKBPERRD,
  502     &syspdef_DSKKBPERWR,
  503     &syspdef_DSKKBPERDS,
  504     &syspdef_DSKINFLIGHT,
  505     &syspdef_DSKAVQUEUE,
  506     &syspdef_DSKAVIO,
  507     &syspdef_BLANKBOX,
  508         0
  509 };
  510 sys_printdef *nfsmntsyspdefs[] = {
  511     &syspdef_NFMPATH,
  512     &syspdef_NFMSERVER,
  513     &syspdef_NFMTOTREAD,
  514     &syspdef_NFMTOTWRITE,
  515     &syspdef_NFMNREAD,
  516     &syspdef_NFMNWRITE,
  517     &syspdef_NFMDREAD,
  518     &syspdef_NFMDWRITE,
  519     &syspdef_NFMMREAD,
  520     &syspdef_NFMMWRITE,
  521     &syspdef_BLANKBOX,
  522         0
  523 };
  524 sys_printdef *nfcsyspdefs[] = {
  525     &syspdef_NFCRPCCNT,
  526     &syspdef_NFCRPCREAD,
  527     &syspdef_NFCRPCWRITE,
  528     &syspdef_NFCRPCRET,
  529     &syspdef_NFCRPCARF,
  530     &syspdef_BLANKBOX,
  531         0
  532 };
  533 sys_printdef *nfssyspdefs[] = {
  534     &syspdef_NFSRPCCNT,
  535     &syspdef_NFSRPCREAD,
  536     &syspdef_NFSRPCWRITE,
  537     &syspdef_NFSNRBYTES,
  538     &syspdef_NFSNWBYTES,
  539     &syspdef_NFSNETTCP,
  540     &syspdef_NFSNETUDP,
  541     &syspdef_NFSBADFMT,
  542     &syspdef_NFSBADAUT,
  543     &syspdef_NFSBADCLN,
  544     &syspdef_NFSRCHITS,
  545     &syspdef_NFSRCMISS,
  546     &syspdef_NFSRCNOCA,
  547     &syspdef_BLANKBOX,
  548         0
  549 };
  550 sys_printdef *nettranssyspdefs[] = {
  551     &syspdef_NETTRANSPORT,
  552     &syspdef_NETTCPI,
  553     &syspdef_NETTCPO,
  554     &syspdef_NETUDPI,
  555     &syspdef_NETUDPO,
  556     &syspdef_NETTCPACTOPEN,
  557     &syspdef_NETTCPPASVOPEN,
  558     &syspdef_NETTCPRETRANS,
  559     &syspdef_NETTCPINERR,
  560     &syspdef_NETTCPORESET,
  561     &syspdef_NETUDPNOPORT,
  562     &syspdef_NETUDPINERR,
  563     &syspdef_BLANKBOX,
  564         0
  565 };
  566 sys_printdef *netnetsyspdefs[] = {
  567     &syspdef_NETNETWORK,
  568     &syspdef_NETIPI,
  569     &syspdef_NETIPO,
  570     &syspdef_NETIPFRW,
  571     &syspdef_NETIPDELIV,
  572     &syspdef_NETICMPIN,
  573     &syspdef_NETICMPOUT,
  574     &syspdef_BLANKBOX,
  575         0
  576 };
  577 sys_printdef *netintfsyspdefs[] = {
  578     &syspdef_NETNAME,
  579     &syspdef_NETPCKI,
  580     &syspdef_NETPCKO,
  581     &syspdef_NETSPEEDMAX,
  582     &syspdef_NETSPEEDIN,
  583     &syspdef_NETSPEEDOUT,
  584     &syspdef_NETCOLLIS,
  585     &syspdef_NETMULTICASTIN,
  586     &syspdef_NETRCVERR,
  587     &syspdef_NETSNDERR,
  588     &syspdef_NETRCVDROP,
  589     &syspdef_NETSNDDROP,
  590     &syspdef_BLANKBOX,
  591         0
  592 };
  593 
  594 sys_printdef *infinisyspdefs[] = {
  595     &syspdef_IFBNAME,
  596     &syspdef_IFBPCKI,
  597     &syspdef_IFBPCKO,
  598     &syspdef_IFBSPEEDMAX,
  599     &syspdef_IFBSPEEDIN,
  600     &syspdef_IFBSPEEDOUT,
  601     &syspdef_IFBLANES,
  602     &syspdef_BLANKBOX,
  603         0
  604 };
  605 
  606 /*
  607  * table with all proc_printdefs
  608  */
  609 proc_printdef *allprocpdefs[]= 
  610 {
  611     &procprt_PID,
  612     &procprt_TID,
  613     &procprt_PPID,
  614     &procprt_SYSCPU,
  615     &procprt_USRCPU,
  616     &procprt_RUNDELAY,
  617     &procprt_BLKDELAY,
  618     &procprt_WCHAN,
  619     &procprt_VGROW,
  620     &procprt_RGROW,
  621     &procprt_MINFLT,
  622     &procprt_MAJFLT,
  623     &procprt_VSTEXT,
  624     &procprt_VSIZE,
  625     &procprt_RSIZE,
  626     &procprt_PSIZE,
  627     &procprt_VSLIBS,
  628     &procprt_VDATA,
  629     &procprt_VSTACK,
  630     &procprt_SWAPSZ,
  631     &procprt_LOCKSZ,
  632     &procprt_CMD,
  633     &procprt_RUID,
  634     &procprt_EUID,
  635     &procprt_SUID,
  636     &procprt_FSUID,
  637     &procprt_RGID,
  638     &procprt_EGID,
  639     &procprt_SGID,
  640     &procprt_FSGID,
  641     &procprt_CTID,
  642     &procprt_VPID,
  643     &procprt_CID,
  644     &procprt_STDATE,
  645     &procprt_STTIME,
  646     &procprt_ENDATE,
  647     &procprt_ENTIME,
  648     &procprt_THR,
  649     &procprt_TRUN,
  650     &procprt_TSLPI,
  651     &procprt_TSLPU,
  652     &procprt_POLI,
  653     &procprt_NICE,
  654     &procprt_PRI,
  655     &procprt_RTPR,
  656     &procprt_CURCPU,
  657     &procprt_ST,
  658     &procprt_EXC,
  659     &procprt_S,
  660     &procprt_COMMAND_LINE,
  661     &procprt_NPROCS,
  662     &procprt_RDDSK,
  663     &procprt_WRDSK,
  664     &procprt_CWRDSK,
  665     &procprt_WCANCEL,
  666     &procprt_TCPRCV,
  667     &procprt_TCPRASZ,
  668     &procprt_TCPSND,
  669     &procprt_TCPSASZ,
  670     &procprt_UDPRCV,
  671     &procprt_UDPRASZ,
  672     &procprt_UDPSND,
  673     &procprt_UDPSASZ,
  674     &procprt_RNET,
  675     &procprt_SNET,
  676     &procprt_BANDWI,
  677     &procprt_BANDWO,
  678     &procprt_GPULIST,
  679     &procprt_GPUMEMNOW,
  680     &procprt_GPUMEMAVG,
  681     &procprt_GPUGPUBUSY,
  682     &procprt_GPUMEMBUSY,
  683     &procprt_CGROUP_PATH,
  684     &procprt_CGRCPUWGT,
  685     &procprt_CGRCPUMAX,
  686     &procprt_CGRCPUMAXR,
  687     &procprt_CGRMEMMAX,
  688     &procprt_CGRMEMMAXR,
  689     &procprt_CGRSWPMAX,
  690     &procprt_CGRSWPMAXR,
  691     &procprt_SORTITEM,
  692         0
  693 };
  694 
  695 /*
  696  * table with all proc_printdefs with PID/TID width to be initialized
  697  */
  698 proc_printdef *idprocpdefs[]= 
  699 {
  700     &procprt_PID,
  701     &procprt_TID,
  702     &procprt_PPID,
  703     &procprt_VPID,
  704     0
  705 };
  706 
  707 
  708 /***************************************************************/
  709 /*
  710  * output definitions for process data
  711  * these should be user configurable
  712  */
  713 proc_printpair userprocs[MAXITEMS];
  714 proc_printpair memprocs[MAXITEMS];
  715 proc_printpair schedprocs[MAXITEMS];
  716 proc_printpair genprocs[MAXITEMS];
  717 proc_printpair dskprocs[MAXITEMS];
  718 proc_printpair netprocs[MAXITEMS];
  719 proc_printpair gpuprocs[MAXITEMS];
  720 proc_printpair varprocs[MAXITEMS];
  721 proc_printpair cmdprocs[MAXITEMS];
  722 proc_printpair cgrprocs[MAXITEMS];
  723 proc_printpair ownprocs[MAXITEMS];
  724 proc_printpair totusers[MAXITEMS];
  725 proc_printpair totprocs[MAXITEMS];
  726 proc_printpair totconts[MAXITEMS];
  727 
  728 
  729 /*****************************************************************/
  730 /*
  731  * output definitions for system data
  732  * these should be user configurable
  733  */
  734 sys_printpair sysprcline[MAXITEMS];
  735 sys_printpair allcpuline[MAXITEMS];
  736 sys_printpair indivcpuline[MAXITEMS];
  737 sys_printpair cplline[MAXITEMS];
  738 sys_printpair gpuline[MAXITEMS];
  739 sys_printpair memline1[MAXITEMS];
  740 sys_printpair memline2[MAXITEMS];
  741 sys_printpair swpline[MAXITEMS];
  742 sys_printpair memnumaline[MAXITEMS];
  743 sys_printpair cpunumaline[MAXITEMS];
  744 sys_printpair llcline[MAXITEMS];
  745 sys_printpair pagline[MAXITEMS];
  746 sys_printpair psiline[MAXITEMS];
  747 sys_printpair contline[MAXITEMS];
  748 sys_printpair dskline[MAXITEMS];
  749 sys_printpair nettransportline[MAXITEMS];
  750 sys_printpair netnetline[MAXITEMS];
  751 sys_printpair netinterfaceline[MAXITEMS];
  752 sys_printpair infinibandline[MAXITEMS];
  753 sys_printpair nfsmountline[MAXITEMS];
  754 sys_printpair nfcline[MAXITEMS];
  755 sys_printpair nfsline[MAXITEMS];
  756 
  757 typedef struct {
  758         const char *name;
  759         int        prio;
  760 } name_prio;
  761 
  762 /*
  763 ** make an string,int pair array from a string.  chop based on spaces/tabs
  764 ** example: input: "ABCD:3  EFG:1   QWE:16"
  765 **         output: { { "ABCD", 3 }, {"EFG", 1},  { "QWE", 16}, { 0, 0 }  }
  766 */
  767 static void
  768 makeargv(char *line, const char *linename, name_prio *vec) 
  769 {
  770         int   i=0;
  771         char *p=line;
  772         char *name=0;
  773         char *prio=0;
  774 
  775         // find pair and scan it
  776         while (*p && i<MAXITEMS-1) 
  777         {
  778                 // skip initial spaces
  779                 while (*p && (*p==' ' || *p=='\t'))
  780                 {
  781                         ++p;
  782                 }
  783                 if (! *p) 
  784                 {
  785                         break;
  786                 }
  787                 name=p;
  788                 // found a new word; let's chop!
  789                 while (*p && *p !=':')
  790                 {
  791                         ++p;
  792                 }
  793                 if (*p==':')
  794                 {
  795                         *p=0;
  796                 }
  797                 else
  798                         mcleanstop(1,   "atoprc - %s: no name:prio pair for "
  799                                 "`%s'\n", name, linename);
  800 
  801                 /* now get number */
  802                 p++;
  803                 prio=p;
  804                 errno = 0;    /* To distinguish success/failure after call */
  805 
  806                 long lprio=strtol(p, &p, 10);
  807 
  808                 if (prio==p || errno == ERANGE || lprio >= INT_MAX || lprio <0)
  809                 {
  810                 fprintf(stderr,
  811             "atoprc - %s: item `%s` has "
  812                         "invalid priority `", linename, name);
  813                         while (*prio && *prio !=' ') {
  814                             fputc(*prio, stderr);
  815                             prio++;
  816                         }
  817                         fprintf(stderr, "'\n");
  818                         cleanstop(1);
  819                 }
  820                 vec[i].name=name;
  821                 vec[i].prio=lprio;
  822 
  823                 ++i;
  824         }
  825                 
  826         vec[i].name=0;
  827 }
  828 
  829 
  830 /*
  831  * make_sys_prints: make array of sys_printpairs
  832  * input: string, sys_printpair array, maxentries
  833  */
  834 static void
  835 make_sys_prints(sys_printpair *ar, int maxn, const char *pairs, 
  836                 sys_printdef *permissables[], const char *linename,
  837         struct sstat *sstat, extraparam *extra)
  838 {
  839         name_prio   items[MAXITEMS];
  840         int     i, a, n=strlen(pairs);
  841         char        str[n+1];
  842 
  843         strcpy(str, pairs);
  844 
  845         makeargv(str, linename, items);
  846 
  847         for(i=a=0; items[i].name && i<maxn-1; i++) 
  848         {
  849                 const char *name=items[i].name;
  850                 int j;
  851 
  852                 for (j=0; permissables[j] != 0; ++j)
  853                 {
  854                         if (strcmp(permissables[j]->configname, name) == 0)
  855                         {
  856                 // call validate function to see if this 
  857                 // counter is relevant
  858                 //
  859                 if (sstat != NULL && 
  860                     permissables[j]->dovalidate != NULL &&
  861                     permissables[j]->dovalidate(sstat) == 0)
  862                     break;
  863 
  864                                 ar[a].f    = permissables[j];
  865                                 ar[a].prio = items[i].prio;
  866                 a++;
  867                                 break;
  868                         }
  869                 }
  870 
  871                 if (permissables[j]==0)
  872         {
  873             mcleanstop(1,
  874             "atoprc - own system line: item %s invalid in %s line\n",
  875             name, linename);
  876         }
  877         }
  878 
  879         ar[a].f=0;
  880         ar[a].prio=0;
  881 }
  882 
  883 
  884 
  885 /*
  886  * init_proc_prints: determine width of columns that are
  887  *                   dependent of dynamic values 
  888  */
  889 static void 
  890 init_proc_prints(count_t numcpu)
  891 {
  892     char    linebuf[64];
  893     int i;
  894 
  895     /*
  896     ** fill number of digits for various PID/TID columns
  897     ** and reformat header to new width
  898     */
  899     for (i=0; idprocpdefs[i] != 0; i++)
  900     {
  901         idprocpdefs[i]->width = pidwidth;
  902 
  903         if ( strlen(idprocpdefs[i]->head) < pidwidth)
  904         {
  905             char *p = malloc(pidwidth+1);
  906 
  907             ptrverify(p, "Malloc failed for formatted header\n");
  908 
  909             sprintf(p, "%*s", pidwidth, idprocpdefs[i]->head);
  910             idprocpdefs[i]->head = p;
  911         }
  912     }
  913 
  914     /*
  915     ** fill number of positions for the SORTITEM (percentage),
  916     ** depending on the number of CPUs (e.g. with 10+ CPUs a process
  917     ** can reach a CPU percentage of 1000% and with 100+ CPUs a
  918     ** CPU percentage of 10000%).
  919     */
  920     procprt_SORTITEM.width =
  921         snprintf(linebuf, sizeof linebuf, "%lld", numcpu*100) + 1;
  922 }
  923 
  924 /*
  925  * make_proc_prints: make array of proc_printpairs
  926  * input: string, proc_printpair array, maxentries
  927  */
  928 void 
  929 make_proc_prints(proc_printpair *ar, int maxn, const char *pairs, 
  930 const char *linename)
  931 {
  932         name_prio items[MAXITEMS];
  933         int n=strlen(pairs);
  934 
  935         char str[n+1];
  936         strcpy(str, pairs);
  937 
  938         makeargv(str, linename, items);
  939 
  940         int i;
  941         for(i=0; items[i].name && i<maxn-1; ++i) 
  942         {
  943                 const char *name=items[i].name;
  944                 int j;
  945                 for (j=0; allprocpdefs[j] != 0; ++j)
  946                 {
  947                         if (strcmp(allprocpdefs[j]->configname, name)==0)
  948                         {
  949                                 ar[i].f=allprocpdefs[j];
  950                                 ar[i].prio=items[i].prio;
  951                                 break;
  952                         }
  953                 }
  954                 if (allprocpdefs[j]==0)
  955                 {
  956                         mcleanstop(1,
  957                 "atoprc - ownprocline: item %s invalid!\n",
  958                 name);
  959                 }
  960         }
  961         ar[i].f=0;
  962         ar[i].prio=0;
  963 }
  964 
  965 /*
  966 ** calculate the total consumption on system-level for the 
  967 ** four main resources
  968 */
  969 void
  970 totalcap(struct syscap *psc, struct sstat *sstat,
  971                              struct tstat **proclist, int nactproc)
  972 {
  973         register int    i;
  974 
  975         psc->nrcpu      = sstat->cpu.nrcpu;
  976 
  977         psc->availcpu   = sstat->cpu.all.stime +
  978                           sstat->cpu.all.utime +
  979                           sstat->cpu.all.ntime +
  980                           sstat->cpu.all.itime +
  981                           sstat->cpu.all.wtime +
  982                           sstat->cpu.all.Itime +
  983                           sstat->cpu.all.Stime +
  984                           sstat->cpu.all.steal;
  985 
  986         psc->availmem   = sstat->mem.physmem * pagesize/1024;
  987 
  988     /*
  989     ** calculate total transfer issued by the active processes
  990     ** for disk and for network
  991     */
  992     for (psc->availnet=psc->availdsk=0, i=0; i < nactproc; i++) 
  993     {
  994         struct tstat    *curstat = *(proclist+i);
  995         count_t     nett_wsz;
  996 
  997         psc->availnet += curstat->net.tcpssz;
  998         psc->availnet += curstat->net.tcprsz;
  999         psc->availnet += curstat->net.udpssz;
 1000         psc->availnet += curstat->net.udprsz;
 1001 
 1002         if (curstat->dsk.wsz > curstat->dsk.cwsz)
 1003             nett_wsz = curstat->dsk.wsz -
 1004                        curstat->dsk.cwsz;
 1005         else
 1006             nett_wsz = 0;
 1007 
 1008         psc->availdsk += curstat->dsk.rsz;
 1009         psc->availdsk += nett_wsz;
 1010     }
 1011 
 1012     for (psc->availgpumem=i=0; i < sstat->gpu.nrgpus; i++)
 1013         psc->availgpumem += sstat->gpu.gpu[i].memtotnow;
 1014 
 1015     psc->nrgpu = sstat->gpu.nrgpus;
 1016 
 1017     psc->nrmemnuma = sstat->memnuma.nrnuma;
 1018     psc->nrcpunuma = sstat->cpunuma.nrnuma;
 1019 }
 1020 
 1021 /*
 1022 ** calculate cumulative system- and user-time for all active processes
 1023 ** besides, initialize all counter lines on system level
 1024 */
 1025 void
 1026 pricumproc(struct sstat *sstat, struct devtstat *devtstat,
 1027            int nexit, unsigned int noverflow, int avgval, int nsecs)
 1028 {
 1029         static int  firsttime=1;
 1030         int         i;
 1031         extraparam  extra;
 1032 
 1033         for (i=0, extra.totut=extra.totst=0; i < devtstat->nprocactive; i++)
 1034         {
 1035         struct tstat *curstat = *(devtstat->procactive+i);
 1036 
 1037                 extra.totut += curstat->cpu.utime;
 1038                 extra.totst     += curstat->cpu.stime;
 1039         }
 1040 
 1041         extra.nproc = devtstat->nprocall;
 1042     extra.ntrun = devtstat->totrun;
 1043     extra.ntslpi    = devtstat->totslpi;
 1044     extra.ntslpu    = devtstat->totslpu;
 1045         extra.nzomb = devtstat->totzombie;
 1046         extra.nexit = nexit;
 1047         extra.noverflow = noverflow;
 1048         extra.avgval    = avgval;
 1049         extra.nsecs = nsecs;
 1050         extra.index = 0;
 1051 
 1052         if (firsttime)
 1053         {
 1054                 firsttime=0;
 1055 
 1056                 if (sysprcline[0].f == 0)
 1057                 {
 1058                     make_sys_prints(sysprcline, MAXITEMS,
 1059                         "PRCSYS:8 "
 1060                         "PRCUSER:8 "
 1061                     "BLANKBOX:0 "
 1062                         "PRCNPROC:7 "
 1063                         "PRCNRUNNING:5 "
 1064                         "PRCNSLEEPING:5 "
 1065                         "PRCNDSLEEPING:5 "
 1066                         "PRCNZOMBIE:5 "
 1067                         "PRCCLONES:4 "
 1068                     "BLANKBOX:0 "
 1069                         "PRCNNEXIT:6",
 1070             prcsyspdefs, "builtin sysprcline",
 1071             sstat, &extra);
 1072                 }
 1073 
 1074                 if (allcpuline[0].f == 0)
 1075                 {
 1076                     make_sys_prints(allcpuline, MAXITEMS,
 1077                     "CPUSYS:9 "
 1078                     "CPUUSER:8 "
 1079                     "CPUIRQ:6 "
 1080                     "BLANKBOX:0 "
 1081                     "CPUIDLE:7 "
 1082                     "CPUWAIT:7 "
 1083                         "CPUSTEAL:2 "
 1084                         "CPUGUEST:3 "
 1085                     "BLANKBOX:0 "
 1086                         "CPUIPC:5 "
 1087                         "CPUCYCLE:4 "
 1088                         "CPUFREQ:4 "
 1089                         "CPUSCALE:4 ",
 1090             cpusyspdefs, "builtin allcpuline",
 1091             sstat, &extra);
 1092                 }
 1093 
 1094                 if (indivcpuline[0].f == 0)
 1095                 {
 1096                     make_sys_prints(indivcpuline, MAXITEMS,
 1097                     "CPUISYS:9 "
 1098                         "CPUIUSER:8 "
 1099                     "CPUIIRQ:6 "
 1100                     "BLANKBOX:0 "
 1101                     "CPUIIDLE:7 "
 1102                     "CPUIWAIT:7 "
 1103                         "CPUISTEAL:2 "
 1104                         "CPUIGUEST:3 "
 1105                     "BLANKBOX:0 "
 1106                         "CPUIIPC:5 "
 1107                         "CPUICYCLE:4 "
 1108                         "CPUIFREQ:4 "
 1109                         "CPUISCALE:4 ",
 1110             cpisyspdefs, "builtin indivcpuline",
 1111             sstat, &extra);
 1112                 }
 1113 
 1114                 if (cplline[0].f == 0)
 1115                 {
 1116                     make_sys_prints(cplline, MAXITEMS,
 1117                     "CPLNUMCPU:7"
 1118                     "BLANKBOX:0 "
 1119                     "CPLAVG1:4 "
 1120                     "CPLAVG5:3 "
 1121                     "CPLAVG15:2 "
 1122                     "BLANKBOX:0 "
 1123                     "CPLCSW:6 "
 1124                     "CPLINTR:5 ",
 1125             cplsyspdefs, "builtin cplline",
 1126             sstat, &extra);
 1127                 }
 1128 
 1129                 if (gpuline[0].f == 0)
 1130                 {
 1131                     make_sys_prints(gpuline, MAXITEMS,
 1132                     "GPUBUS:8 "
 1133                     "GPUGPUPERC:7 "
 1134                     "GPUMEMPERC:6 "
 1135                     "GPUMEMOCC:5 "
 1136                     "GPUMEMTOT:3 "
 1137                     "GPUMEMUSE:4 "
 1138                     "GPUMEMAVG:2 "
 1139                     "GPUNRPROC:2 "
 1140                     "BLANKBOX:0 "
 1141                     "GPUTYPE:1 ",
 1142             gpusyspdefs, "builtin gpuline",
 1143             NULL, NULL);
 1144                 }
 1145 
 1146                 if (memline1[0].f == 0)
 1147                 {
 1148                     make_sys_prints(memline1, MAXITEMS,
 1149                     "MEMTOT:8 "
 1150                     "MEMFREE:9 "
 1151                     "BLANKBOX:0 "
 1152                     "MEMCACHE:8 "
 1153                     "MEMDIRTY:6 "
 1154                     "MEMBUFFER:7 "
 1155                     "BLANKBOX:0 "
 1156                     "MEMSLAB:7 "
 1157                     "RECSLAB:3 "
 1158                     "BLANKBOX:0 "
 1159                     "PAGETABS:4 "
 1160                     "BLANKBOX:0 "
 1161                     "HUPTOT:5 "
 1162                     "HUPUSE:2 ",
 1163             memsyspdefs1, "builtin memline1",
 1164             sstat, &extra);
 1165                 }
 1166 
 1167                 if (memline2[0].f == 0)
 1168                 {
 1169                     make_sys_prints(memline2, MAXITEMS,
 1170                     "NUMNUMA:6 "
 1171                     "BLANKBOX:1 "
 1172                     "SHMEM:3 "
 1173                     "SHMRSS:3 "
 1174                     "SHMSWP:2 "
 1175                     "BLANKBOX:0 "
 1176                     "TCPSOCK:5 "
 1177                     "UDPSOCK:2 "
 1178                     "BLANKBOX:0 "
 1179                     "VMWBAL:4 "
 1180                     "BLANKBOX:0 "
 1181                     "ZFSARC:5 ",
 1182             memsyspdefs2, "builtin memline2",
 1183             sstat, &extra);
 1184                 }
 1185 
 1186                 if (swpline[0].f == 0)
 1187                 {
 1188                     make_sys_prints(swpline, MAXITEMS,
 1189                     "SWPTOT:5 "
 1190                     "SWPFREE:6 "
 1191                     "SWPCACHE:4 "
 1192                     "BLANKBOX:0 "
 1193                     "ZSWTOTAL:3 "
 1194                     "ZSWSTORED:3 "
 1195                     "BLANKBOX:0 "
 1196                     "KSMSHARED:2 "
 1197                     "KSMSHARING:2 "
 1198                     "BLANKBOX:0 "
 1199                     "SWPCOMMITTED:7 "
 1200                     "SWPCOMMITLIM:8",
 1201             swpsyspdefs, "builtin swpline",
 1202             sstat, &extra);
 1203                 }
 1204 
 1205                 if (memnumaline[0].f == 0)
 1206                 {
 1207                     make_sys_prints(memnumaline, MAXITEMS,
 1208                     "NUMATOT:8 "
 1209                     "NUMAFREE:9 "
 1210                     "NUMAFILEPAGE:9 "
 1211                     "NUMANR:7 "
 1212                     "NUMADIRTY:5 "
 1213                     "NUMAACTIVE:5 "
 1214                     "NUMAINACTIVE:5 "
 1215                     "NUMASLAB:7 "
 1216                     "NUMASLABRECLAIM:4 "
 1217                     "NUMASHMEM:4 "
 1218                     "NUMAFRAG:6 "
 1219                     "NUMAHUPTOT:3 ",
 1220             memnumasyspdefs, "builtin memnumaline",
 1221             sstat, &extra);
 1222                 }
 1223 
 1224                 if (cpunumaline[0].f == 0)
 1225                 {
 1226                     make_sys_prints(cpunumaline, MAXITEMS,
 1227                     "NUMACPUSYS:9 "
 1228                     "NUMACPUUSER:8 "
 1229                     "NUMACPUNICE:8 "
 1230                     "NUMACPUIRQ:6 "
 1231                     "NUMACPUSOFTIRQ:6 "
 1232                     "NUMACPUIDLE:7 "
 1233                     "NUMACPUWAIT:7 "
 1234                     "NUMACPUSTEAL:2 "
 1235                     "NUMACPUGUEST:3 "
 1236                     "NUMANUMCPU:5",
 1237             cpunumasyspdefs, "builtin cpunumaline",
 1238             NULL, NULL);
 1239                 }
 1240 
 1241                 if (llcline[0].f == 0)
 1242                 {
 1243                     make_sys_prints(llcline, MAXITEMS,
 1244                     "LLCMBMTOTAL:9 "
 1245                     "LLCMBMLOCAL:8 "
 1246                     "NUMLLC:7 "
 1247                     "BLANKBOX:0 ",
 1248             llcsyspdefs, "builtin llcline",
 1249             sstat, &extra);
 1250                 }
 1251 
 1252                 if (pagline[0].f == 0)
 1253                 {
 1254                     make_sys_prints(pagline, MAXITEMS,
 1255                     "PAGSCAN:3 "
 1256                     "PAGSTEAL:2 "
 1257                     "PAGSTALL:1 "
 1258                     "PAGCOMPACT:5 "
 1259             "NUMAMIGRATE:5"
 1260             "PGMIGRATE:6"
 1261                     "PAGPGIN:7 "
 1262                     "PAGPGOUT:7 "
 1263                     "PAGSWIN:5 "
 1264                     "PAGSWOUT:8 "
 1265             "OOMKILLS:9 ",
 1266             pagsyspdefs, "builtin pagline",
 1267             sstat, &extra);
 1268                 }
 1269 
 1270                 if (psiline[0].f == 0)
 1271                 {
 1272                     make_sys_prints(psiline, MAXITEMS,
 1273                     "PSICPUSTOT:7 "
 1274                     "PSIMEMSTOT:7 "
 1275                     "PSIMEMFTOT:8 "
 1276                     "PSIIOSTOT:7 "
 1277                     "PSIIOFTOT:8 "
 1278                     "PSICPUS:6 "
 1279                     "PSIMEMS:5 "
 1280                     "PSIMEMF:3 "
 1281                     "PSIIOS:4 "
 1282                     "PSIIOF:2 "
 1283                     "BLANKBOX:0 ",
 1284             psisyspdefs, "builtin psiline",
 1285             sstat, &extra);
 1286                 }
 1287 
 1288                 if (contline[0].f == 0)
 1289                 {
 1290                     make_sys_prints(contline, MAXITEMS,
 1291                     "CONTNAME:8 "
 1292                     "CONTNPROC:7 "
 1293                     "CONTCPU:6 "
 1294                     "CONTMEM:6 "
 1295                     "BLANKBOX:0 "
 1296                     "BLANKBOX:0 ",
 1297             contsyspdefs, "builtin contline",
 1298             NULL, NULL);
 1299                 }
 1300 
 1301                 if (dskline[0].f == 0)
 1302                 {
 1303                     make_sys_prints(dskline, MAXITEMS,
 1304                     "DSKNAME:9 "
 1305                     "DSKBUSY:8 "
 1306                     "DSKNREAD:7 "
 1307                     "DSKNWRITE:7 "
 1308                     "DSKNDISC:6 "
 1309                     "DSKKBPERRD:5 "
 1310                     "DSKKBPERWR:5 "
 1311                     "DSKKBPERDS:4 "
 1312                         "DSKMBPERSECRD:6 "
 1313                         "DSKMBPERSECWR:6 "
 1314                     "DSKINFLIGHT:2 "
 1315                     "DSKAVQUEUE:1 "
 1316                     "DSKAVIO:6",
 1317             dsksyspdefs, "builtin dskline",
 1318             sstat, &extra);
 1319                 }
 1320 
 1321                 if (nfsmountline[0].f == 0)
 1322                 {
 1323                     make_sys_prints(nfsmountline, MAXITEMS,
 1324                     "NFMPATH:8 "
 1325                     "NFMSERVER:8 "
 1326             "NFMTOTREAD:8 "
 1327             "NFMTOTWRITE:8 "
 1328                     "BLANKBOX:0 "
 1329             "NFMNREAD:7 "
 1330             "NFMNWRITE:6 "
 1331                     "BLANKBOX:0 "
 1332             "NFMDREAD:5 "
 1333             "NFMDWRITE:4 "
 1334                     "BLANKBOX:0 "
 1335             "NFMMREAD:3 "
 1336             "NFMMWRITE:2 "
 1337                     "BLANKBOX:0 "
 1338                         "BLANKBOX:0",
 1339             nfsmntsyspdefs, "builtin nfsmountline",
 1340             NULL, NULL);
 1341                 }
 1342 
 1343                 if (nfcline[0].f == 0)
 1344                 {
 1345                     make_sys_prints(nfcline, MAXITEMS,
 1346                     "NFCRPCCNT:8 "
 1347                     "NFCRPCREAD:7 "
 1348                     "NFCRPCWRITE:7 "
 1349                     "NFCRPCRET:5 "
 1350                     "NFCRPCARF:5 "
 1351                     "BLANKBOX:0 "
 1352                     "BLANKBOX:0 "
 1353                     "BLANKBOX:0 "
 1354                     "BLANKBOX:0 "
 1355                     "BLANKBOX:0 ",
 1356             nfcsyspdefs, "builtin nfcline",
 1357             sstat, &extra);
 1358         }
 1359 
 1360                 if (nfsline[0].f == 0)
 1361                 {
 1362                     make_sys_prints(nfsline, MAXITEMS,
 1363                     "NFSRPCCNT:8 "
 1364                     "NFSRPCREAD:6 "
 1365                     "NFSRPCWRITE:6 "
 1366                     "BLANKBOX:0 "
 1367                     "NFSNRBYTES:7 "
 1368                     "NFSNWBYTES:7 "
 1369                     "BLANKBOX:0 "
 1370                     "NFSNETTCP:5 "
 1371                     "NFSNETUDP:5 "
 1372                     "BLANKBOX:0 "
 1373                     "NFSRCHITS:3 "
 1374                     "NFSRCMISS:2 "
 1375                     "NFSRCNOCA:1 "
 1376                     "BLANKBOX:0 "
 1377                     "NFSBADFMT:4 "
 1378                     "NFSBADAUT:4 "
 1379                     "NFSBADCLN:4 ",
 1380             nfssyspdefs, "builtin nfsline",
 1381             sstat, &extra);
 1382         }
 1383 
 1384                 if (nettransportline[0].f == 0)
 1385                 {
 1386                     make_sys_prints(nettransportline, MAXITEMS,
 1387                     "NETTRANSPORT:9 "
 1388                     "NETTCPI:8 "
 1389                     "NETTCPO:8 "
 1390                     "NETUDPI:8 "
 1391                     "NETUDPO:8 "
 1392                         "NETTCPACTOPEN:6 "
 1393                         "NETTCPPASVOPEN:5 "
 1394                         "NETTCPRETRANS:4 "
 1395                         "NETTCPINERR:3 "
 1396                         "NETTCPORESET:2 "
 1397                         "NETUDPNOPORT:1 "
 1398                         "NETUDPINERR:3",
 1399             nettranssyspdefs, "builtin nettransportline",
 1400             sstat, &extra);
 1401                 }
 1402 
 1403                 if (netnetline[0].f == 0)
 1404                 {
 1405                     make_sys_prints(netnetline, MAXITEMS,
 1406                         "NETNETWORK:5 "
 1407                         "NETIPI:4 "
 1408                         "NETIPO:4 "
 1409                         "NETIPFRW:4 "
 1410                         "NETIPDELIV:4 "
 1411                     "BLANKBOX:0 "
 1412                     "BLANKBOX:0 "
 1413                     "BLANKBOX:0 "
 1414                         "NETICMPIN:1 "
 1415                         "NETICMPOUT:1 ",
 1416             netnetsyspdefs, "builtin netnetline",
 1417             sstat, &extra);
 1418                 }
 1419 
 1420                 if (netinterfaceline[0].f == 0)
 1421                 {
 1422                     make_sys_prints(netinterfaceline, MAXITEMS,
 1423                     "NETNAME:8 "
 1424                     "BLANKBOX:0 "
 1425                     "NETPCKI:7 "
 1426                     "NETPCKO:7 "
 1427                     "BLANKBOX:0 "
 1428                     "NETSPEEDMAX:5 "
 1429                     "NETSPEEDIN:6 "
 1430                     "NETSPEEDOUT:6 "
 1431                     "BLANKBOX:0 "
 1432                         "NETCOLLIS:2 "
 1433                         "NETMULTICASTIN:2 "
 1434                         "NETRCVERR:4 "
 1435                         "NETSNDERR:4 "
 1436                         "NETRCVDROP:3 "
 1437                         "NETSNDDROP:3",
 1438             netintfsyspdefs, "builtin netinterfaceline",
 1439             NULL, NULL);
 1440                 }
 1441 
 1442                 if (infinibandline[0].f == 0)
 1443                 {
 1444                     make_sys_prints(infinibandline, MAXITEMS,
 1445                     "IFBNAME:8 "
 1446                     "BLANKBOX:0 "
 1447                     "IFBPCKI:7 "
 1448                     "IFBPCKO:7 "
 1449                     "BLANKBOX:0 "
 1450                     "IFBSPEEDMAX:5 "
 1451                     "IFBSPEEDIN:6 "
 1452                     "IFBSPEEDOUT:6 "
 1453                     "IFBLANES:4 "
 1454                     "BLANKBOX:0 "
 1455                     "BLANKBOX:0 "
 1456                     "BLANKBOX:0 "
 1457                     "BLANKBOX:0 "
 1458                     "BLANKBOX:0 "
 1459                     "BLANKBOX:0 ",
 1460             infinisyspdefs, "builtin infinibandline",
 1461             NULL, NULL);
 1462                 }
 1463         }  // firsttime
 1464 
 1465         move(1, 0);
 1466         showsysline(sysprcline, sstat, &extra, "PRC", 0);
 1467 }
 1468 
 1469 /*
 1470 ** print the header for the process list
 1471 */
 1472 void
 1473 priphead(int curlist, int totlist, char *showtype, char *showorder,
 1474                     char autosort, count_t numcpu)
 1475 {
 1476         static int      firsttime=1;
 1477         static int      prev_supportflags = -1, prev_threadview = -1;
 1478 
 1479     /*
 1480     ** determine once the layout of all per-process reports
 1481     ** except for the generic report (might change dynamically)
 1482     */
 1483         if (firsttime) 
 1484         {
 1485         init_proc_prints(numcpu);
 1486 
 1487                 make_proc_prints(memprocs, MAXITEMS, 
 1488                         "PID:10 TID:3 MINFLT:2 MAJFLT:2 VSTEXT:4 VSLIBS:4 "
 1489             "VDATA:4 VSTACK:4 LOCKSZ:3 VSIZE:6 RSIZE:7 PSIZE:5 "
 1490                         "VGROW:7 RGROW:8 SWAPSZ:5 RUID:1 EUID:0 "
 1491                         "SORTITEM:9 CMD:10", 
 1492                         "built-in memprocs");
 1493 
 1494                 make_proc_prints(schedprocs, MAXITEMS, 
 1495                         "PID:10 TID:6 CID:4 VPID:3 CTID:3 TRUN:7 TSLPI:7 "
 1496             "TSLPU:7 POLI:8 NICE:9 PRI:5 RTPR:9 CPUNR:8 ST:8 "
 1497             "EXC:8 S:8 RDELAY:8 BDELAY:7 WCHAN:5 SORTITEM:10 CMD:10",
 1498                         "built-in schedprocs");
 1499 
 1500                 make_proc_prints(dskprocs, MAXITEMS, 
 1501                         "PID:10 TID:4 RDDSK:9 "
 1502                         "WRDSK:9 WCANCL:8 "
 1503                         "SORTITEM:10 CMD:10", 
 1504                         "built-in dskprocs");
 1505 
 1506                 make_proc_prints(netprocs, MAXITEMS, 
 1507                         "PID:10 TID:6 "
 1508             "TCPRCV:9 TCPRASZ:4 TCPSND:9 TCPSASZ:4 "
 1509             "UDPRCV:8 UDPRASZ:3 UDPSND:8 UDPSASZ:3 "
 1510             "BANDWI:10 BANDWO:10 "
 1511                         "SORTITEM:10 CMD:10", 
 1512                         "built-in netprocs");
 1513 
 1514                 make_proc_prints(gpuprocs, MAXITEMS, 
 1515                         "PID:10 TID:5 CID:4 GPULIST:8 GPUGPUBUSY:8 GPUMEMBUSY:8 "
 1516             "GPUMEM:7 GPUMEMAVG:6 S:8 SORTITEM:10 CMD:10", 
 1517                         "built-in gpuprocs");
 1518 
 1519                 make_proc_prints(varprocs, MAXITEMS,
 1520                         "PID:10 TID:4 PPID:9 CID:2 VPID:1 CTID:1 "
 1521             "RUID:8 RGID:8 EUID:5 EGID:4 "
 1522                 "SUID:3 SGID:2 FSUID:3 FSGID:2 "
 1523                         "STDATE:7 STTIME:7 ENDATE:5 ENTIME:5 "
 1524             "ST:6 EXC:6 S:6 SORTITEM:10 CMD:10", 
 1525                         "built-in varprocs");
 1526 
 1527                 make_proc_prints(cmdprocs, MAXITEMS,
 1528                         "PID:10 TID:4 S:8 SORTITEM:10 COMMAND-LINE:10", 
 1529                         "built-in cmdprocs");
 1530 
 1531                 make_proc_prints(cgrprocs, MAXITEMS, 
 1532                         "PID:10 CPUWGT:9 CPUMAX:9 CPUMAXR:9 MEMMAX:8 MMMAXR:8 "
 1533             "SWPMAX:7 SWMAXR:7 SORTITEM:6 CMD:9 CGROUP-PATH:10", 
 1534                         "built-in cgrprocs");
 1535 
 1536                 make_proc_prints(totusers, MAXITEMS, 
 1537                         "NPROCS:10 SYSCPU:9 USRCPU:9 VSIZE:6 "
 1538                         "RSIZE:8 PSIZE:8 LOCKSZ:3 SWAPSZ:5 RDDSK:7 CWRDSK:7 "
 1539             "RNET:6 SNET:6 SORTITEM:10 RUID:10", 
 1540                         "built-in totusers");
 1541 
 1542                 make_proc_prints(totprocs, MAXITEMS, 
 1543                         "NPROCS:10 SYSCPU:9 USRCPU:9 VSIZE:6 "
 1544                         "RSIZE:8 PSIZE:8 LOCKSZ:3 SWAPSZ:5 RDDSK:7 CWRDSK:7 "
 1545             "RNET:6 SNET:6 SORTITEM:10 CMD:10", 
 1546                         "built-in totprocs");
 1547 
 1548                 make_proc_prints(totconts, MAXITEMS, 
 1549                         "NPROCS:10 SYSCPU:9 USRCPU:9 VSIZE:6 "
 1550                         "RSIZE:8 PSIZE:8 LOCKSZ:3 SWAPSZ:5 RDDSK:7 CWRDSK:7 "
 1551             "RNET:6 SNET:6 SORTITEM:10 CID:10", 
 1552                         "built-in totconts");
 1553         }
 1554 
 1555     /*
 1556     ** update the generic report if needed
 1557     */
 1558     if (prev_supportflags != supportflags || prev_threadview != threadview)
 1559     {
 1560         make_proc_dynamicgen();
 1561 
 1562         prev_supportflags = supportflags;
 1563         prev_threadview   = threadview;
 1564 
 1565         if (*showtype == MPROCNET && !(supportflags&NETATOP) )
 1566         {
 1567             *showtype  = MPROCGEN;
 1568             *showorder = MSORTCPU;
 1569         }
 1570     }
 1571 
 1572         /*
 1573         ** print the header line
 1574         */
 1575         switch (*showtype)
 1576         {
 1577            case MPROCGEN:
 1578                 showhdrline(genprocs, curlist, totlist, *showorder, autosort);
 1579                 break;
 1580 
 1581            case MPROCMEM:
 1582                 showhdrline(memprocs, curlist, totlist, *showorder, autosort);
 1583                 break;
 1584 
 1585            case MPROCDSK:
 1586                 showhdrline(dskprocs, curlist, totlist, *showorder, autosort);
 1587                 break;
 1588 
 1589            case MPROCNET:
 1590                 showhdrline(netprocs, curlist, totlist, *showorder, autosort);
 1591                 break;
 1592 
 1593            case MPROCGPU:
 1594                 showhdrline(gpuprocs, curlist, totlist, *showorder, autosort);
 1595                 break;
 1596 
 1597            case MPROCVAR:
 1598                 showhdrline(varprocs, curlist, totlist, *showorder, autosort);
 1599                 break;
 1600 
 1601            case MPROCARG:
 1602                 showhdrline(cmdprocs, curlist, totlist, *showorder, autosort);
 1603                 break;
 1604 
 1605            case MPROCCGR:
 1606                 showhdrline(cgrprocs, curlist, totlist, *showorder, autosort);
 1607                 break;
 1608 
 1609            case MPROCOWN:
 1610                 showhdrline(ownprocs, curlist, totlist, *showorder, autosort);
 1611                 break;
 1612 
 1613            case MPROCSCH:
 1614                 showhdrline(schedprocs, curlist, totlist, *showorder, autosort);
 1615                 break;
 1616 
 1617            case MCUMUSER:
 1618                 showhdrline(totusers, curlist, totlist, *showorder, autosort);
 1619                 break;
 1620 
 1621            case MCUMPROC:
 1622                 showhdrline(totprocs, curlist, totlist, *showorder, autosort);
 1623                 break;
 1624 
 1625            case MCUMCONT:
 1626                 showhdrline(totconts, curlist, totlist, *showorder, autosort);
 1627                 break;
 1628         }
 1629 }
 1630 
 1631 /*
 1632 ** assemble the layout of the generic line,
 1633 ** depending on the supported features (like
 1634 ** I/O stats, network stats) and current view
 1635 */
 1636 #define FORMPID "PID:10 "
 1637 #define FORMTID "TID:6 "
 1638 #define FORMCID "CID:5 "
 1639 #define FORMCPU "SYSCPU:9 USRCPU:9 "
 1640 #define FORMDEL "RDELAY:4 "
 1641 #define FORMBDL "BDELAY:4 "
 1642 #define FORMMEM "VGROW:8 RGROW:8 "
 1643 #define FORMDSK "RDDSK:7 CWRDSK:7 "
 1644 #define FORMNET "RNET:6 SNET:6 "
 1645 #define FORMMSC "RUID:2 EUID:1 ST:3 EXC:3 THR:3 S:3 CPUNR:3 "
 1646 #define FORMEND "SORTITEM:10 CMD:10"
 1647 
 1648 static void
 1649 make_proc_dynamicgen()
 1650 {
 1651     char format[300], *p = format;
 1652 
 1653     memcpy(p, FORMPID, sizeof FORMPID -1);
 1654     p += sizeof FORMPID -1;
 1655 
 1656     if (threadview)
 1657     {
 1658         memcpy(p, FORMTID, sizeof FORMTID -1);
 1659         p += sizeof FORMTID -1;
 1660     }
 1661 
 1662     if (supportflags & DOCKSTAT)
 1663     {
 1664         memcpy(p, FORMCID, sizeof FORMCID -1);
 1665         p += sizeof FORMCID -1;
 1666     }
 1667 
 1668     memcpy(p, FORMCPU, sizeof FORMCPU -1);
 1669     p += sizeof FORMCPU -1;
 1670 
 1671     memcpy(p, FORMDEL, sizeof FORMDEL -1);
 1672     p += sizeof FORMDEL -1;
 1673 
 1674     memcpy(p, FORMBDL, sizeof FORMBDL -1);
 1675     p += sizeof FORMBDL -1;
 1676 
 1677     memcpy(p, FORMMEM, sizeof FORMMEM -1);
 1678     p += sizeof FORMMEM -1;
 1679 
 1680     if (supportflags & IOSTAT)
 1681     {
 1682         memcpy(p, FORMDSK, sizeof FORMDSK -1);
 1683         p += sizeof FORMDSK -1;
 1684     }
 1685 
 1686     if (supportflags & NETATOP)
 1687     {
 1688         memcpy(p, FORMNET, sizeof FORMNET -1);
 1689         p += sizeof FORMNET -1;
 1690     }
 1691 
 1692     memcpy(p, FORMMSC, sizeof FORMMSC -1);
 1693     p += sizeof FORMMSC -1;
 1694 
 1695     memcpy(p, FORMEND, sizeof FORMEND);
 1696     p += sizeof FORMEND;
 1697 
 1698     make_proc_prints(genprocs, MAXITEMS, format, "built-in genprocs");
 1699 }
 1700 
 1701 /*
 1702 ** print the list of processes from the deviation-list
 1703 */
 1704 int
 1705 priproc(struct tstat **proclist, int firstproc, int lastproc, int curline,
 1706         int curlist, int totlist, char showtype, char showorder,
 1707         struct syscap *sb, int nsecs, int avgval)
 1708 {
 1709         register int            i;
 1710         register struct tstat   *curstat;
 1711         double                  perc;
 1712 
 1713         /*
 1714         ** print info per actual process and maintain totals
 1715         */
 1716         for (i=firstproc; i < lastproc; i++)
 1717         {
 1718                 curstat = *(proclist+i);
 1719 
 1720                 if (screen && curline >= LINES) /* screen filled entirely ? */
 1721                         break;
 1722 
 1723                 /*
 1724                 ** calculate occupation-percentage of this process
 1725                 ** depending on selected resource
 1726                 */
 1727                 switch (showorder) 
 1728                 {
 1729                    case MSORTCPU:
 1730                         perc = 0.0;
 1731 
 1732                         if (sb->availcpu)
 1733                         {
 1734                                 perc = (double)(curstat->cpu.stime +
 1735                                                 curstat->cpu.utime  ) * 100 /
 1736                                                 (sb->availcpu / sb->nrcpu);
 1737 
 1738                                 if (perc > 100.0 * sb->nrcpu)
 1739                                         perc = 100.0 * sb->nrcpu;
 1740 
 1741                                 if (perc > 100.0 * curstat->gen.nthr)
 1742                                         perc = 100.0 * curstat->gen.nthr;
 1743                         }
 1744                         break;
 1745 
 1746                    case MSORTMEM:
 1747                         perc = 0.0;
 1748 
 1749                         if (sb->availmem)
 1750                         {
 1751                                 perc = (double)curstat->mem.rmem *
 1752                                                100.0 / sb->availmem;
 1753 
 1754                                 if (perc > 100.0)
 1755                                         perc = 100.0;
 1756                         }
 1757                         break;
 1758 
 1759                    case MSORTDSK:
 1760                         perc = 0.0;
 1761 
 1762             if (sb->availdsk)
 1763                         {
 1764                 count_t nett_wsz;
 1765 
 1766 
 1767                 if (curstat->dsk.wsz > curstat->dsk.cwsz)
 1768                     nett_wsz = curstat->dsk.wsz -
 1769                                curstat->dsk.cwsz;
 1770                 else
 1771                     nett_wsz = 0;
 1772 
 1773                 perc = (double)(curstat->dsk.rsz + nett_wsz) *
 1774                         100.0 / sb->availdsk;
 1775 
 1776                 if (perc > 100.0)
 1777                     perc = 100.0;
 1778                         }
 1779                         break;
 1780 
 1781                    case MSORTNET:
 1782                         perc = 0.0;
 1783 
 1784                         if (sb->availnet)
 1785                         {
 1786                                 perc = (double)(curstat->net.tcpssz +
 1787                                                 curstat->net.tcprsz +
 1788                                                 curstat->net.udpssz +
 1789                                                 curstat->net.udprsz  ) *
 1790                                                 100.0 / sb->availnet;
 1791 
 1792                                 if (perc > 100.0)
 1793                                         perc = 100.0;
 1794                         }
 1795                         break;
 1796 
 1797                    case MSORTGPU:
 1798                         perc = 0.0;
 1799 
 1800             if (!curstat->gpu.state)
 1801                 break;
 1802 
 1803                         if (curstat->gpu.gpubusy != -1)
 1804             {
 1805                             perc = curstat->gpu.gpubusy;
 1806             }
 1807             else
 1808             {
 1809                             perc = curstat->gpu.memnow*100 *
 1810                        sb->nrgpu / sb->availgpumem;
 1811             }
 1812                         break;
 1813 
 1814                    default:
 1815                         perc = 0.0;
 1816                 }
 1817 
 1818                 /*
 1819                 ** now do the formatting of output
 1820                 */
 1821                 if (screen) {
 1822                         move(curline,0);
 1823                 }
 1824 
 1825                 switch (showtype)
 1826                 {
 1827                    case MPROCGEN:
 1828                         showprocline(genprocs, curstat, perc, nsecs, avgval);
 1829                         break;
 1830 
 1831                    case MPROCMEM:
 1832                         showprocline(memprocs, curstat, perc, nsecs, avgval);
 1833                         break;
 1834 
 1835                    case MPROCDSK:
 1836                         showprocline(dskprocs, curstat, perc, nsecs, avgval);
 1837                         break;
 1838 
 1839                    case MPROCNET:
 1840                         showprocline(netprocs, curstat, perc, nsecs, avgval);
 1841                         break;
 1842 
 1843                    case MPROCGPU:
 1844                         showprocline(gpuprocs, curstat, perc, nsecs, avgval);
 1845                         break;
 1846 
 1847                    case MPROCVAR:
 1848                         showprocline(varprocs, curstat, perc, nsecs, avgval);
 1849                         break;
 1850 
 1851                    case MPROCARG:
 1852                         showprocline(cmdprocs, curstat, perc, nsecs, avgval);
 1853                         break;
 1854 
 1855                    case MPROCCGR:
 1856                         showprocline(cgrprocs, curstat, perc, nsecs, avgval);
 1857                         break;
 1858 
 1859                    case MPROCOWN:
 1860                         showprocline(ownprocs, curstat, perc, nsecs, avgval);
 1861                         break;
 1862 
 1863                    case MPROCSCH:
 1864                         showprocline(schedprocs, curstat, perc, nsecs, avgval);
 1865                         break;
 1866 
 1867                    case MCUMUSER:
 1868                         showprocline(totusers, curstat, perc, nsecs, avgval);
 1869                         break;
 1870 
 1871                    case MCUMPROC:
 1872                         showprocline(totprocs, curstat, perc, nsecs, avgval);
 1873                         break;
 1874 
 1875                    case MCUMCONT:
 1876                         showprocline(totconts, curstat, perc, nsecs, avgval);
 1877                         break;
 1878                 }
 1879 
 1880                 curline++;
 1881         }
 1882 
 1883         return curline;
 1884 }
 1885 
 1886 
 1887 /*
 1888 ** print the system-wide statistics
 1889 */
 1890 static void pridisklike(extraparam *, struct perdsk *, char *,
 1891               char *, int, unsigned int *, int *, int, regex_t *);
 1892 
 1893 int
 1894 prisyst(struct sstat *sstat, int curline, int nsecs, int avgval,
 1895         int fixedhead, struct sselection *selp, char *highorderp,
 1896         int maxcpulines, int maxgpulines, int maxdsklines, int maxmddlines,
 1897     int maxlvmlines, int maxintlines, int maxifblines,
 1898     int maxnfslines, int maxcontlines, int maxnumalines, int maxllclines)
 1899 {
 1900         extraparam      extra;
 1901         int             lin;
 1902         count_t         busy;
 1903         unsigned int    badness, highbadness=0;
 1904 
 1905         extra.nsecs = nsecs;
 1906         extra.avgval    = avgval;
 1907 
 1908         /*
 1909         ** CPU statistics
 1910         */
 1911         extra.cputot = sstat->cpu.all.stime + sstat->cpu.all.utime +
 1912                        sstat->cpu.all.ntime + sstat->cpu.all.itime +
 1913                        sstat->cpu.all.wtime + sstat->cpu.all.Itime +
 1914                        sstat->cpu.all.Stime + sstat->cpu.all.steal;
 1915 
 1916         busy   = (extra.cputot - sstat->cpu.all.itime - sstat->cpu.all.wtime)
 1917                                 * 100.0 / extra.cputot;
 1918 
 1919         if (cpubadness)
 1920                 badness = busy * 100 / cpubadness;
 1921         else
 1922                 badness = 0;
 1923 
 1924         if (highbadness < badness)
 1925         {
 1926                 highbadness = badness;
 1927                 *highorderp = MSORTCPU;
 1928         }
 1929 
 1930         if (extra.cputot == 0)
 1931                 extra.cputot = 1;             /* avoid divide-by-zero */
 1932 
 1933         extra.percputot = extra.cputot / sstat->cpu.nrcpu;
 1934 
 1935         if (extra.percputot == 0)
 1936                 extra.percputot = 1;          /* avoid divide-by-zero */
 1937 
 1938     if (screen)
 1939            move(curline, 0);
 1940 
 1941         showsysline(allcpuline, sstat, &extra, "CPU", badness);
 1942         curline++;
 1943 
 1944         if (sstat->cpu.nrcpu > 1)
 1945         {
 1946                 for (extra.index=lin=0;
 1947              extra.index < sstat->cpu.nrcpu && lin < maxcpulines;
 1948              extra.index++)
 1949                 {
 1950                         extra.percputot =  sstat->cpu.cpu[extra.index].stime +
 1951                                      sstat->cpu.cpu[extra.index].utime +
 1952                                      sstat->cpu.cpu[extra.index].ntime +
 1953                                      sstat->cpu.cpu[extra.index].itime +
 1954                                      sstat->cpu.cpu[extra.index].wtime +
 1955                                      sstat->cpu.cpu[extra.index].Itime +
 1956                                      sstat->cpu.cpu[extra.index].Stime +
 1957                                      sstat->cpu.cpu[extra.index].steal;
 1958 
 1959                         if (extra.percputot ==
 1960                 (sstat->cpu.cpu[extra.index].itime +
 1961                                  sstat->cpu.cpu[extra.index].wtime  ) &&
 1962                                  !fixedhead                             )
 1963                                 continue;       /* inactive cpu */
 1964 
 1965                         busy   = (extra.percputot -
 1966                     sstat->cpu.cpu[extra.index].itime -
 1967                                         sstat->cpu.cpu[extra.index].wtime)
 1968                                                   * 100.0 / extra.percputot;
 1969 
 1970                         if (cpubadness)
 1971                                 badness = busy * 100 / cpubadness;
 1972                         else
 1973                                 badness = 0;
 1974 
 1975                         if (highbadness < badness)
 1976                         {
 1977                                 highbadness = badness;
 1978                                 *highorderp = MSORTCPU;
 1979                         }
 1980 
 1981                         if (extra.percputot == 0)
 1982                                 extra.percputot = 1; /* avoid divide-by-zero */
 1983 
 1984 
 1985             if (screen)
 1986                             move(curline, 0);
 1987 
 1988                         showsysline(indivcpuline, sstat, &extra, "cpu",
 1989                                 badness);
 1990                         curline++;
 1991                         lin++;
 1992                 }
 1993         }
 1994 
 1995         /*
 1996         ** other CPU-related statistics
 1997         */
 1998     if (screen)
 1999          move(curline, 0);
 2000 
 2001         showsysline(cplline, sstat, &extra, "CPL", 0);
 2002         curline++;
 2003 
 2004         /*
 2005         ** GPU statistics
 2006         */
 2007     if (sstat->gpu.nrgpus)
 2008     {
 2009             for (extra.index=0, lin=0;
 2010              extra.index < sstat->gpu.nrgpus && lin < maxgpulines;
 2011              extra.index++)
 2012             {
 2013             int totbusy;
 2014             count_t avgmemuse;
 2015 
 2016             // notice that GPU percentage and memory percentage
 2017             // are not always available; in that case both
 2018             // values have the value -1
 2019             //
 2020             totbusy = sstat->gpu.gpu[extra.index].gpuperccum +
 2021                       sstat->gpu.gpu[extra.index].memperccum;
 2022 
 2023             if (totbusy == -2)  // metrics available?
 2024                 totbusy= 0;
 2025 
 2026             if (sstat->gpu.gpu[extra.index].samples == 0)
 2027             {
 2028                 totbusy =
 2029                     sstat->gpu.gpu[extra.index].gpupercnow +
 2030                         sstat->gpu.gpu[extra.index].mempercnow;
 2031 
 2032                 avgmemuse =
 2033                     sstat->gpu.gpu[extra.index].memusenow;
 2034             }
 2035             else
 2036             {
 2037                 totbusy = totbusy /
 2038                         sstat->gpu.gpu[extra.index].samples;
 2039 
 2040                 avgmemuse =
 2041                      sstat->gpu.gpu[extra.index].memusecum/
 2042                              sstat->gpu.gpu[extra.index].samples;
 2043             }
 2044 
 2045                 if (gpubadness)
 2046                         badness = totbusy * 100 / gpubadness;
 2047                 else
 2048                         badness = 0;
 2049 
 2050             if (    totbusy > 0             ||
 2051                     // memusage > 512 MiB (rather arbitrary)?
 2052                     avgmemuse > 512*1024        ||
 2053                     fixedhead             )
 2054             {
 2055                     showsysline(gpuline, sstat,
 2056                             &extra, "GPU", badness);
 2057                     curline++;
 2058                     lin++;
 2059             }
 2060         }
 2061     }
 2062 
 2063         /*
 2064         ** MEMORY statistics
 2065         */
 2066         busy   = (sstat->mem.physmem - sstat->mem.freemem
 2067                                      - sstat->mem.cachemem
 2068                                      - sstat->mem.buffermem
 2069                                      - sstat->mem.slabreclaim
 2070                                      + sstat->mem.shmem)
 2071                                                 * 100.0 / sstat->mem.physmem;
 2072 
 2073         if (membadness)
 2074                 badness = busy * 100 / membadness;
 2075         else
 2076                 badness = 0;
 2077 
 2078         if (highbadness < badness)
 2079         {
 2080                 highbadness = badness;
 2081                 *highorderp = MSORTMEM;
 2082         }
 2083 
 2084     if (screen)
 2085             move(curline, 0);
 2086 
 2087         showsysline(memline1, sstat, &extra, "MEM", badness);
 2088         curline++;
 2089 
 2090         showsysline(memline2, sstat, &extra, "MEM", badness);
 2091         curline++;
 2092 
 2093         /*
 2094         ** SWAP statistics
 2095         */
 2096         busy   = (sstat->mem.totswap - sstat->mem.freeswap)
 2097                                 * 100.0 / sstat->mem.totswap;
 2098 
 2099         if (swpbadness)
 2100         {
 2101                 badness = busy * 100 / swpbadness;
 2102         }
 2103         else
 2104         {
 2105                 badness = 0;
 2106         }
 2107 
 2108         if (highbadness < badness)
 2109         {
 2110                 highbadness = badness;
 2111                 *highorderp = MSORTMEM;
 2112         }
 2113 
 2114     if (screen)
 2115             move(curline, 0);
 2116 
 2117         showsysline(swpline, sstat, &extra, "SWP", badness);
 2118         curline++;
 2119 
 2120     /*
 2121     ** memory info related for per NUMA
 2122     */
 2123     if (sstat->memnuma.nrnuma > 1)
 2124     {
 2125         for (extra.index=lin=0;
 2126              extra.index < sstat->memnuma.nrnuma && lin < maxnumalines;
 2127              extra.index++)
 2128         {
 2129             busy = (sstat->memnuma.numa[extra.index].totmem
 2130                 - sstat->memnuma.numa[extra.index].freemem
 2131                 - sstat->memnuma.numa[extra.index].filepage
 2132                 - sstat->memnuma.numa[extra.index].slabreclaim
 2133                 + sstat->memnuma.numa[extra.index].shmem)
 2134                     * 100.0 / sstat->memnuma.numa[extra.index].totmem;
 2135 
 2136             if (membadness)
 2137                 badness = busy * 100 / membadness;
 2138             else
 2139                 badness = 0;
 2140 
 2141             if (highbadness < badness)
 2142             {
 2143                 highbadness = badness;
 2144                 *highorderp = MSORTMEM;
 2145             }
 2146 
 2147             if (screen)
 2148                 move(curline, 0);
 2149 
 2150             showsysline(memnumaline, sstat, &extra, "NUM", badness);
 2151             curline++;
 2152             lin++;
 2153         }
 2154     }
 2155 
 2156     /*
 2157     ** Accumulate each cpu statistic for per NUMA
 2158     */
 2159     if (sstat->cpunuma.nrnuma > 1)
 2160     {
 2161         for (extra.index=lin=0;
 2162              extra.index < sstat->cpunuma.nrnuma && lin < maxnumalines;
 2163              extra.index++)
 2164         {
 2165             extra.pernumacputot = sstat->cpunuma.numa[extra.index].stime +
 2166                           sstat->cpunuma.numa[extra.index].utime +
 2167                           sstat->cpunuma.numa[extra.index].ntime +
 2168                           sstat->cpunuma.numa[extra.index].itime +
 2169                           sstat->cpunuma.numa[extra.index].wtime +
 2170                           sstat->cpunuma.numa[extra.index].Itime +
 2171                           sstat->cpunuma.numa[extra.index].Stime +
 2172                           sstat->cpunuma.numa[extra.index].steal;
 2173 
 2174             if (extra.pernumacputot ==
 2175                 (sstat->cpunuma.numa[extra.index].itime +
 2176                  sstat->cpunuma.numa[extra.index].wtime  ) &&
 2177                  !fixedhead                             )
 2178                 continue;       /* inactive cpu */
 2179 
 2180             if (extra.pernumacputot == 0)
 2181                 extra.pernumacputot = 1; /* avoid divide-by-zero */
 2182 
 2183             busy = (extra.pernumacputot -
 2184                     sstat->cpunuma.numa[extra.index].itime -
 2185                     sstat->cpunuma.numa[extra.index].wtime)
 2186                     * 100.0 / extra.pernumacputot;
 2187 
 2188             if (cpubadness)
 2189                 badness = busy * 100 / cpubadness;
 2190             else
 2191                 badness = 0;
 2192 
 2193             if (highbadness < badness)
 2194             {
 2195                 highbadness = badness;
 2196                 *highorderp = MSORTCPU;
 2197             }
 2198 
 2199             extra.percputot = extra.pernumacputot /
 2200                         (sstat->cpu.nrcpu/sstat->cpunuma.nrnuma);
 2201             if (extra.percputot == 0)
 2202                 extra.percputot = 1; /* avoid divide-by-zero */
 2203 
 2204             if (screen)
 2205                 move(curline, 0);
 2206 
 2207             showsysline(cpunumaline, sstat, &extra, "NUC", badness);
 2208             curline++;
 2209             lin++;
 2210         }
 2211     }
 2212 
 2213     /*
 2214     ** LLC statistics (if supported by kernel and
 2215     ** pseudo filesystem mounted)
 2216     */
 2217     for (extra.index=0, lin=0;
 2218             extra.index < sstat->llc.nrllcs && lin < maxllclines;
 2219             extra.index++)
 2220     {
 2221         if (fixedhead                       ||
 2222             sstat->llc.perllc[extra.index].mbm_local    ||
 2223             sstat->llc.perllc[extra.index].mbm_total      )
 2224         {
 2225             if (screen)
 2226                 move(curline, 0);
 2227 
 2228             showsysline(llcline, sstat, &extra, "LLC", 0);
 2229             curline++;
 2230             lin++;
 2231         }
 2232     }
 2233 
 2234         /*
 2235         ** PAGING statistics
 2236         */
 2237         if (fixedhead               ||
 2238             sstat->mem.pgscans      ||
 2239             sstat->mem.pgsteal      ||
 2240             sstat->mem.allocstall   ||
 2241             sstat->mem.compactstall     ||
 2242             sstat->mem.pgins        ||
 2243             sstat->mem.pgouts       ||
 2244             sstat->mem.tcpsock      ||
 2245             sstat->mem.udpsock      ||
 2246             sstat->mem.swins        ||
 2247             sstat->mem.swouts       ||
 2248             sstat->mem.oomkills > 0     ||
 2249             sstat->mem.pgmigrate        ||
 2250             sstat->mem.numamigrate        )
 2251         {
 2252                 busy = sstat->mem.swouts / nsecs * pagbadness;
 2253 
 2254                 if (busy > 100)
 2255                         busy = 100;
 2256 
 2257                 if (membadness)
 2258                         badness = busy * 100 / membadness;
 2259                 else
 2260                         badness = 0;
 2261 
 2262                 if (highbadness < badness)
 2263                 {
 2264                         highbadness = badness;
 2265                         *highorderp = MSORTMEM;
 2266                 }
 2267 
 2268                 /*
 2269                 ** take care that this line is anyhow colored for
 2270                 ** 'almost critical' in case of swapouts > 1 per second
 2271                 */
 2272                 if (sstat->mem.swouts / nsecs > 0  &&
 2273                     pagbadness && almostcrit && badness < almostcrit)
 2274                         badness = almostcrit;
 2275 
 2276         if (screen)
 2277                     move(curline, 0);
 2278 
 2279                 showsysline(pagline, sstat, &extra, "PAG", badness);
 2280                 curline++;
 2281         }
 2282 
 2283         /*
 2284         ** Pressure statistics
 2285         */
 2286     if (sstat->psi.present)
 2287     {
 2288             if (fixedhead                 ||
 2289                 sstat->psi.cpusome.avg10  || sstat->psi.memsome.avg10  ||
 2290                 sstat->psi.iosome.avg10   ||
 2291                 sstat->psi.cpusome.avg60  || sstat->psi.memsome.avg60  ||
 2292                 sstat->psi.iosome.avg60   ||
 2293                 sstat->psi.cpusome.avg300 || sstat->psi.memsome.avg300 ||
 2294                 sstat->psi.iosome.avg300    )
 2295             {
 2296             badness = sstat->psi.cpusome.avg10 >
 2297                       sstat->psi.cpusome.avg60 ?
 2298                       sstat->psi.cpusome.avg10 :
 2299                       sstat->psi.cpusome.avg60;
 2300 
 2301             if (badness < sstat->psi.cpusome.avg300)
 2302                 badness = sstat->psi.cpusome.avg300;
 2303 
 2304             if (screen)
 2305                         move(curline, 0);
 2306 
 2307                     showsysline(psiline, sstat, &extra,"PSI", badness);
 2308                     curline++;
 2309         }
 2310     }
 2311 
 2312     /*
 2313     ** Container statistics (if any)
 2314     */
 2315         for (extra.index=0, lin=0;
 2316          extra.index < sstat->cfs.nrcontainer && lin < maxcontlines;
 2317              extra.index++)
 2318     {
 2319             if (fixedhead                   ||
 2320                 sstat->cfs.cont[extra.index].system ||
 2321                 sstat->cfs.cont[extra.index].user   ||
 2322                 sstat->cfs.cont[extra.index].nice     )
 2323         {
 2324             if (screen)
 2325                         move(curline, 0);
 2326 
 2327                         showsysline(contline, sstat, &extra, "CON", 0);
 2328                         curline++;
 2329                         lin++;
 2330         }
 2331     }
 2332 
 2333         /*
 2334         ** DISK statistics
 2335         */
 2336         extra.mstot = extra.cputot * 1000 / hertz / sstat->cpu.nrcpu; 
 2337 
 2338     pridisklike(&extra, sstat->dsk.lvm, "LVM", highorderp, maxlvmlines,
 2339             &highbadness, &curline, fixedhead,
 2340             selp->lvmnamesz ? &(selp->lvmregex) : (void *) 0);
 2341 
 2342     pridisklike(&extra, sstat->dsk.mdd, "MDD", highorderp, maxmddlines,
 2343             &highbadness, &curline, fixedhead, (void *) 0);
 2344 
 2345     pridisklike(&extra, sstat->dsk.dsk, "DSK", highorderp, maxdsklines,
 2346             &highbadness, &curline, fixedhead,
 2347             selp->dsknamesz ? &(selp->dskregex) : (void *) 0);
 2348 
 2349         /*
 2350         ** NFS server and client statistics
 2351         */
 2352     for (extra.index=0, lin=0;
 2353          extra.index < sstat->nfs.nfsmounts.nrmounts && lin < maxnfslines;
 2354                                 extra.index++)
 2355     {
 2356         int i = extra.index;
 2357 
 2358         if ( (sstat->nfs.nfsmounts.nfsmnt[i].bytesread     +
 2359               sstat->nfs.nfsmounts.nfsmnt[i].byteswrite    +
 2360               sstat->nfs.nfsmounts.nfsmnt[i].bytesdread    +
 2361               sstat->nfs.nfsmounts.nfsmnt[i].bytesdwrite   +
 2362               sstat->nfs.nfsmounts.nfsmnt[i].bytestotread  +
 2363               sstat->nfs.nfsmounts.nfsmnt[i].bytestotwrite +
 2364               sstat->nfs.nfsmounts.nfsmnt[i].pagesmread    +
 2365               sstat->nfs.nfsmounts.nfsmnt[i].pagesmwrite    ) ||
 2366               sstat->nfs.nfsmounts.nfsmnt[i].age < nsecs      ||
 2367               fixedhead                                         )
 2368         {
 2369             if (screen)
 2370                         move(curline, 0);
 2371 
 2372                         showsysline(nfsmountline, sstat, &extra, "NFM", 0);
 2373                         curline++;
 2374                         lin++;
 2375         }
 2376     }
 2377 
 2378         if (sstat->nfs.client.rpccnt || fixedhead )
 2379         {
 2380         if (screen)
 2381                     move(curline, 0);
 2382 
 2383                 showsysline(nfcline, sstat, &extra, "NFC", 0);
 2384                 curline++;
 2385         }
 2386 
 2387         if (sstat->nfs.server.rpccnt || fixedhead )
 2388         {
 2389         if (screen)
 2390                     move(curline, 0);
 2391 
 2392                 showsysline(nfsline, sstat, &extra, "NFS", 0);
 2393                 curline++;
 2394         }
 2395 
 2396         /*
 2397         ** NET statistics: transport
 2398         */
 2399         if (sstat->net.tcp.InSegs             ||
 2400             sstat->net.tcp.OutSegs            ||
 2401             sstat->net.udpv4.InDatagrams      ||
 2402             sstat->net.udpv6.Udp6InDatagrams  ||
 2403             sstat->net.udpv4.OutDatagrams     ||
 2404             sstat->net.udpv6.Udp6OutDatagrams ||
 2405             fixedhead )
 2406         {
 2407         if (screen)
 2408                     move(curline, 0);
 2409 
 2410                 showsysline(nettransportline, sstat, &extra, "NET", 0);
 2411                 curline++;
 2412         }
 2413 
 2414         /*
 2415         ** NET statistics: network
 2416         */
 2417         if (sstat->net.ipv4.InReceives ||
 2418             sstat->net.ipv6.Ip6InReceives ||
 2419             sstat->net.ipv4.OutRequests ||
 2420             sstat->net.ipv6.Ip6OutRequests ||
 2421             fixedhead )
 2422         {
 2423         if (screen)
 2424                     move(curline, 0);
 2425 
 2426                 showsysline(netnetline, sstat, &extra, "NET", 0);
 2427                 curline++;
 2428         }
 2429 
 2430         /*
 2431         ** NET statistics: interfaces
 2432         */
 2433         for (extra.index=0, lin=0;
 2434          sstat->intf.intf[extra.index].name[0] && lin < maxintlines;
 2435              extra.index++)
 2436         {
 2437                 if (sstat->intf.intf[extra.index].rpack ||
 2438                     sstat->intf.intf[extra.index].spack || fixedhead)
 2439                 {
 2440             if (selp->itfnamesz && regexec(&(selp->itfregex),
 2441                    sstat->intf.intf[extra.index].name, 0, NULL, 0))
 2442                 continue;   // suppress (not selected)
 2443 
 2444                         /*
 2445                         ** calculate busy-percentage for interface
 2446                         */
 2447 
 2448                        count_t ival, oval;
 2449 
 2450                         /*
 2451                         ** convert byte-transfers to bit-transfers     (*    8)
 2452                         ** convert bit-transfers  to kilobit-transfers (/ 1000)
 2453                         ** per second
 2454                         */
 2455                         ival    = sstat->intf.intf[extra.index].rbyte/125/nsecs;
 2456                         oval    = sstat->intf.intf[extra.index].sbyte/125/nsecs;
 2457 
 2458             /* speed known? */
 2459                         if (sstat->intf.intf[extra.index].speed) 
 2460                         {
 2461                                 if (sstat->intf.intf[extra.index].duplex)
 2462                                        busy = (ival > oval ? ival : oval) /
 2463                        (sstat->intf.intf[extra.index].speed
 2464                                     *10);
 2465                                 else
 2466                                        busy = (ival + oval) /
 2467                                            (sstat->intf.intf[extra.index].speed
 2468                                     *10);
 2469 
 2470                         }
 2471                         else
 2472                         {
 2473                                 busy = 0;
 2474                         }
 2475 
 2476                         if (netbadness)
 2477                                 badness = busy * 100 / netbadness;
 2478                         else
 2479                                 badness = 0;
 2480 
 2481                         if (highbadness < badness && (supportflags & NETATOP) )
 2482                         {
 2483                                 highbadness = badness;
 2484                                 *highorderp = MSORTNET;
 2485                         }
 2486 
 2487             if (screen)
 2488                         move(curline, 0);
 2489 
 2490                         showsysline(netinterfaceline, sstat, &extra, 
 2491                                                 "NET", badness);
 2492                         curline++;
 2493                         lin++;
 2494                 }
 2495         }
 2496 
 2497         /*
 2498         ** NET statistics: InfiniBand
 2499         */
 2500         for (extra.index=0, lin=0;
 2501          extra.index < sstat->ifb.nrports && lin < maxifblines;
 2502              extra.index++)
 2503         {
 2504                 if (sstat->ifb.ifb[extra.index].rcvb ||
 2505                     sstat->ifb.ifb[extra.index].sndb || fixedhead)
 2506                 {
 2507                         /*
 2508                         ** calculate busy-percentage for IB port
 2509                         */
 2510                        count_t ival, oval;
 2511 
 2512                         /*
 2513                         ** convert byte-transfers to bit-transfers     (*    8)
 2514                         ** convert bit-transfers  to kilobit-transfers (/ 1000)
 2515                         ** per second
 2516                         */
 2517                         ival    = sstat->ifb.ifb[extra.index].rcvb/125/nsecs;
 2518                         oval    = sstat->ifb.ifb[extra.index].sndb/125/nsecs;
 2519 
 2520             busy = (ival > oval ? ival : oval) *
 2521                              sstat->ifb.ifb[extra.index].lanes /
 2522                     (sstat->ifb.ifb[extra.index].rate * 10);
 2523 
 2524                         if (netbadness)
 2525                                 badness = busy * 100 / netbadness;
 2526                         else
 2527                                 badness = 0;
 2528 
 2529                         if (highbadness < badness)
 2530                         {
 2531                                 highbadness = badness;
 2532                                 *highorderp = MSORTNET;
 2533                         }
 2534 
 2535             if (screen)
 2536                         move(curline, 0);
 2537 
 2538                         showsysline(infinibandline, sstat, &extra, 
 2539                                                 "IFB", badness);
 2540                         curline++;
 2541                         lin++;
 2542                 }
 2543         }
 2544 
 2545         /*
 2546         ** application statistics
 2547         **
 2548         ** WWW: notice that we cause one access ourselves by fetching
 2549         **      the statistical counters
 2550         */
 2551 #if     HTTPSTATS
 2552         if (sstat->www.accesses > 1 || fixedhead )
 2553         {
 2554         char format1[8], format2[8], format3[8], format4[8], format5[8];
 2555 
 2556         if (screen)
 2557                     move(curline, 0);
 2558 
 2559                 printg("WWW | reqs  %s | totKB %s | byt/rq %s | iwork %s |"
 2560                        " bwork %s |",
 2561                         val2valstr(sstat->www.accesses,  format1, 6,
 2562                                                          avgval, nsecs),
 2563                         val2valstr(sstat->www.totkbytes, format2, 6,
 2564                                                          avgval, nsecs),
 2565                         val2valstr(sstat->www.accesses ?
 2566                             sstat->www.totkbytes*1024/sstat->www.accesses : 0,
 2567                                                          format3, 5, 0, 0),
 2568                         val2valstr(sstat->www.iworkers,  format4, 6, 0, 0),
 2569                         val2valstr(sstat->www.bworkers,  format5, 6, 0, 0) );
 2570                 if (!screen) 
 2571                 {
 2572                         printg("\n");
 2573                 }
 2574                 curline++;
 2575         }
 2576 #endif
 2577 
 2578         /*
 2579         ** if the system is hardly loaded, still CPU-ordering of
 2580         ** processes is most interesting (instead of memory)
 2581         */
 2582         if (highbadness < 70 && *highorderp == MSORTMEM)
 2583                 *highorderp = MSORTCPU;
 2584 
 2585         return curline;
 2586 }
 2587 
 2588 /*
 2589 ** handle all instances of a specific disk-like device
 2590 */
 2591 static void
 2592 pridisklike(extraparam *ep, struct perdsk *dp, char *lp, char *highorderp,
 2593     int maxlines, unsigned int *highbadp, int *curlinp, int fixedhead,
 2594     regex_t *rep)
 2595 {
 2596     int         lin;
 2597         count_t         busy;
 2598         unsigned int    badness;
 2599 
 2600         for (ep->perdsk = dp, ep->index=0, lin=0;
 2601          ep->perdsk[ep->index].name[0] && lin < maxlines; ep->index++)
 2602         {
 2603         if (rep && regexec(rep, ep->perdsk[ep->index].name, 0, NULL, 0))
 2604             continue;   // suppress (not selected)
 2605 
 2606                 ep->iotot =  ep->perdsk[ep->index].nread +
 2607                      ep->perdsk[ep->index].nwrite;
 2608 
 2609                 busy        = (double)(ep->perdsk[ep->index].io_ms *
 2610                         100.0 / ep->mstot);
 2611 
 2612                 if (dskbadness)
 2613                         badness = busy * 100 / dskbadness;
 2614                 else
 2615                         badness = 0;
 2616 
 2617                 if (*highbadp < badness && (supportflags & IOSTAT) )
 2618                 {
 2619                         *highbadp   = badness;
 2620                         *highorderp     = MSORTDSK;
 2621                 }
 2622 
 2623                 if (ep->iotot || fixedhead)
 2624                 {
 2625                         move(*curlinp, 0);
 2626                         showsysline(dskline, 0, ep, lp, badness);
 2627                         (*curlinp)++;
 2628                         lin++;
 2629                 }
 2630         }
 2631 }
 2632 
 2633 
 2634 /*
 2635 ** process-level sort functions
 2636 */
 2637 int
 2638 compcpu(const void *a, const void *b)
 2639 {
 2640         register count_t acpu = (*(struct tstat **)a)->cpu.stime +
 2641                                 (*(struct tstat **)a)->cpu.utime;
 2642         register count_t bcpu = (*(struct tstat **)b)->cpu.stime +
 2643                                 (*(struct tstat **)b)->cpu.utime;
 2644 
 2645         if (acpu < bcpu)
 2646                 return  1;
 2647 
 2648         if (acpu > bcpu)
 2649                 return -1;
 2650 
 2651         return compmem(a, b);
 2652 }
 2653 
 2654 int
 2655 compdsk(const void *a, const void *b)
 2656 {
 2657     struct tstat    *ta = *(struct tstat **)a;
 2658     struct tstat    *tb = *(struct tstat **)b;
 2659 
 2660         count_t adsk;
 2661         count_t bdsk;
 2662 
 2663     if (ta->dsk.wsz > ta->dsk.cwsz)
 2664         adsk = ta->dsk.rio + ta->dsk.wsz - ta->dsk.cwsz;
 2665     else
 2666         adsk = ta->dsk.rio;
 2667 
 2668     if (tb->dsk.wsz > tb->dsk.cwsz)
 2669         bdsk = tb->dsk.rio + tb->dsk.wsz - tb->dsk.cwsz;
 2670     else
 2671         bdsk = tb->dsk.rio;
 2672 
 2673         if (adsk < bdsk)
 2674                 return  1;
 2675 
 2676         if (adsk > bdsk)
 2677                 return -1;
 2678 
 2679         return compcpu(a, b);
 2680 }
 2681 
 2682 int
 2683 compmem(const void *a, const void *b)
 2684 {
 2685         register count_t amem = (*(struct tstat **)a)->mem.rmem;
 2686         register count_t bmem = (*(struct tstat **)b)->mem.rmem;
 2687 
 2688         if (amem < bmem)
 2689                 return  1;
 2690 
 2691         if (amem > bmem)
 2692                 return -1;
 2693 
 2694         return  0;
 2695 }
 2696 
 2697 int
 2698 compgpu(const void *a, const void *b)
 2699 {
 2700         register char    astate = (*(struct tstat **)a)->gpu.state;
 2701         register char    bstate = (*(struct tstat **)b)->gpu.state;
 2702         register count_t abusy  = (*(struct tstat **)a)->gpu.gpubusy;
 2703         register count_t bbusy  = (*(struct tstat **)b)->gpu.gpubusy;
 2704         register count_t amem   = (*(struct tstat **)a)->gpu.memnow;
 2705         register count_t bmem   = (*(struct tstat **)b)->gpu.memnow;
 2706 
 2707         if (!astate)        // no GPU usage?
 2708         abusy = amem = -2; 
 2709 
 2710         if (!bstate)        // no GPU usage?
 2711         bbusy = bmem = -2; 
 2712 
 2713     if (abusy == -1 || bbusy == -1)
 2714     {
 2715                 if (amem < bmem)
 2716                         return  1;
 2717 
 2718                 if (amem > bmem)
 2719                         return -1;
 2720 
 2721                 return  0;
 2722     }
 2723     else
 2724     {
 2725                 if (abusy < bbusy)
 2726                         return  1;
 2727 
 2728                 if (abusy > bbusy)
 2729                         return -1;
 2730 
 2731             return  0;
 2732     }
 2733 }
 2734 
 2735 int
 2736 compnet(const void *a, const void *b)
 2737 {
 2738         register count_t anet = (*(struct tstat **)a)->net.tcpssz +
 2739                                 (*(struct tstat **)a)->net.tcprsz +
 2740                                 (*(struct tstat **)a)->net.udpssz +
 2741                                 (*(struct tstat **)a)->net.udprsz  ;
 2742         register count_t bnet = (*(struct tstat **)b)->net.tcpssz +
 2743                                 (*(struct tstat **)b)->net.tcprsz +
 2744                                 (*(struct tstat **)b)->net.udpssz +
 2745                                 (*(struct tstat **)b)->net.udprsz  ;
 2746 
 2747         if (anet < bnet)
 2748                 return  1;
 2749 
 2750         if (anet > bnet)
 2751                 return -1;
 2752 
 2753     return compcpu(a, b);
 2754 }
 2755 
 2756 int
 2757 compusr(const void *a, const void *b)
 2758 {
 2759         register int uida = (*(struct tstat **)a)->gen.ruid;
 2760         register int uidb = (*(struct tstat **)b)->gen.ruid;
 2761 
 2762         if (uida > uidb)
 2763                 return  1;
 2764 
 2765         if (uida < uidb)
 2766                 return -1;
 2767 
 2768         return  0;
 2769 }
 2770 
 2771 int
 2772 compnam(const void *a, const void *b)
 2773 {
 2774         register char *nama = (*(struct tstat **)a)->gen.name;
 2775         register char *namb = (*(struct tstat **)b)->gen.name;
 2776 
 2777         return strcmp(nama, namb);
 2778 }
 2779 
 2780 int
 2781 compcon(const void *a, const void *b)
 2782 {
 2783         register char *containera = (*(struct tstat **)a)->gen.container;
 2784         register char *containerb = (*(struct tstat **)b)->gen.container;
 2785 
 2786        return strcmp(containera, containerb);
 2787 }
 2788 
 2789 /*
 2790 ** system-level sort functions
 2791 */
 2792 int
 2793 cpucompar(const void *a, const void *b)
 2794 {
 2795         register count_t aidle = ((struct percpu *)a)->itime +
 2796                                  ((struct percpu *)a)->wtime;
 2797         register count_t bidle = ((struct percpu *)b)->itime +
 2798                                  ((struct percpu *)b)->wtime;
 2799 
 2800         if (aidle < bidle)
 2801                 return -1;
 2802 
 2803         if (aidle > bidle)
 2804                 return  1;
 2805 
 2806     return  0;
 2807 }
 2808 
 2809 int
 2810 gpucompar(const void *a, const void *b)
 2811 {
 2812         register count_t agpuperc  = ((struct pergpu *)a)->gpuperccum;
 2813         register count_t bgpuperc  = ((struct pergpu *)b)->gpuperccum;
 2814         register count_t amemuse   = ((struct pergpu *)a)->memusenow;
 2815         register count_t bmemuse   = ((struct pergpu *)b)->memusenow;
 2816 
 2817     if (agpuperc == -1 || bgpuperc == -1)
 2818     {
 2819                 if (amemuse < bmemuse)
 2820                         return  1;
 2821 
 2822                 if (amemuse > bmemuse)
 2823                         return -1;
 2824 
 2825         return  0;
 2826     }
 2827     else
 2828     {
 2829                 if (agpuperc < bgpuperc)
 2830                         return  1;
 2831 
 2832                 if (agpuperc > bgpuperc)
 2833                         return -1;
 2834 
 2835         return  0;
 2836     }
 2837 }
 2838 
 2839 int
 2840 diskcompar(const void *a, const void *b)
 2841 {
 2842         register count_t amsio = ((struct perdsk *)a)->io_ms;
 2843         register count_t bmsio = ((struct perdsk *)b)->io_ms;
 2844 
 2845         if (amsio < bmsio)
 2846                 return  1;
 2847 
 2848         if (amsio > bmsio)
 2849                 return -1;
 2850 
 2851         return  0;
 2852 }
 2853 
 2854 int
 2855 intfcompar(const void *a, const void *b)
 2856 {
 2857         register count_t afactor=0, bfactor=0;
 2858 
 2859         count_t aspeed         = ((struct perintf *)a)->speed;
 2860         count_t bspeed         = ((struct perintf *)b)->speed;
 2861         char    aduplex        = ((struct perintf *)a)->duplex;
 2862         char    bduplex        = ((struct perintf *)b)->duplex;
 2863         count_t arbyte         = ((struct perintf *)a)->rbyte;
 2864         count_t brbyte         = ((struct perintf *)b)->rbyte;
 2865         count_t asbyte         = ((struct perintf *)a)->sbyte;
 2866         count_t bsbyte         = ((struct perintf *)b)->sbyte;
 2867 
 2868         /*
 2869         ** if speed of first interface known, calculate busy factor
 2870         */
 2871         if (aspeed)
 2872         {
 2873                 if (aduplex)
 2874                         afactor = (arbyte > asbyte ? arbyte : asbyte) 
 2875                                                                 * 10 / aspeed;
 2876                 else
 2877                         afactor = (arbyte + asbyte)             * 10 / aspeed;
 2878         }
 2879 
 2880         /*
 2881         ** if speed of second interface known, calculate busy factor
 2882         */
 2883         if (bspeed)
 2884         {
 2885                 if (bduplex)
 2886                         bfactor = (brbyte > bsbyte ? brbyte : bsbyte)
 2887                                                                 * 10 / bspeed;
 2888                 else
 2889                         bfactor = (brbyte + bsbyte)             * 10 / bspeed;
 2890         }
 2891 
 2892         /*
 2893         ** compare interfaces
 2894         */
 2895         if (aspeed && bspeed)
 2896         {
 2897                 if (afactor < bfactor)
 2898                         return  1;
 2899 
 2900                 if (afactor > bfactor)
 2901                         return -1;
 2902 
 2903                 return  0;
 2904         }
 2905 
 2906         if (!aspeed && !bspeed)
 2907         {
 2908                 if ((arbyte + asbyte) < (brbyte + bsbyte))
 2909                         return  1;
 2910 
 2911                 if ((arbyte + asbyte) > (brbyte + bsbyte))
 2912                         return -1;
 2913 
 2914                 return  0;
 2915         }
 2916 
 2917         if (aspeed)
 2918                 return -1;
 2919         else
 2920                 return  1;
 2921 }
 2922 
 2923 
 2924 int
 2925 ifbcompar(const void *a, const void *b)
 2926 {
 2927         count_t atransfer  = ((struct perifb *)a)->rcvb +
 2928                              ((struct perifb *)a)->sndb;
 2929         count_t btransfer  = ((struct perifb *)b)->rcvb +
 2930                              ((struct perifb *)b)->sndb;
 2931 
 2932     if (atransfer < btransfer)
 2933                 return  1;
 2934 
 2935     if (atransfer > btransfer)
 2936                 return -1;
 2937 
 2938     return  0;
 2939 }
 2940 
 2941 
 2942 int
 2943 nfsmcompar(const void *a, const void *b)
 2944 {
 2945         const struct pernfsmount *na = a;
 2946         const struct pernfsmount *nb = b;
 2947 
 2948         register count_t aused = na->bytesread    + na->byteswrite    + 
 2949                              na->bytesdread   + na->bytesdwrite   +
 2950                              na->bytestotread + na->bytestotwrite +
 2951                                  na->pagesmread   + na->pagesmwrite;
 2952         register count_t bused = nb->bytesread    + nb->byteswrite    + 
 2953                              nb->bytesdread   + nb->bytesdwrite   +
 2954                              nb->bytestotread + nb->bytestotwrite +
 2955                                  nb->pagesmread   + nb->pagesmwrite;
 2956 
 2957         if (aused < bused)
 2958                 return  1;
 2959 
 2960         if (aused > bused)
 2961                 return -1;
 2962 
 2963         return  0;
 2964 }
 2965 
 2966 int
 2967 contcompar(const void *a, const void *b)
 2968 {
 2969         const struct percontainer *ca = a;
 2970         const struct percontainer *cb = b;
 2971 
 2972         register count_t aused = ca->system + ca->user + ca->nice;
 2973         register count_t bused = cb->system + cb->user + cb->nice;
 2974 
 2975         if (aused < bused) 
 2976                 return  1;
 2977 
 2978         if (aused > bused)
 2979                 return -1;
 2980 
 2981         return  0;
 2982 }
 2983 
 2984 int
 2985 memnumacompar(const void *a, const void *b)
 2986 {
 2987         register count_t aused = ((struct mempernuma *)a)->totmem -
 2988                                  ((struct mempernuma *)a)->freemem;
 2989         register count_t bused = ((struct mempernuma *)b)->totmem -
 2990                                  ((struct mempernuma *)b)->freemem;
 2991 
 2992         if (aused < bused)
 2993                 return  1;
 2994 
 2995         if (aused > bused)
 2996                 return -1;
 2997 
 2998         return  0;
 2999 }
 3000 
 3001 int
 3002 cpunumacompar(const void *a, const void *b)
 3003 {
 3004         register count_t aidle = ((struct cpupernuma *)a)->itime +
 3005                                  ((struct cpupernuma *)a)->wtime;
 3006         register count_t bidle = ((struct cpupernuma *)b)->itime +
 3007                                  ((struct cpupernuma *)b)->wtime;
 3008 
 3009         if (aidle < bidle)
 3010                 return -1;
 3011 
 3012         if (aidle > bidle)
 3013                 return  1;
 3014 
 3015     return  0;
 3016 }
 3017 
 3018 int
 3019 llccompar(const void *a, const void *b)
 3020 {
 3021         const struct perllc *ca = a;
 3022         const struct perllc *cb = b;
 3023 
 3024         register count_t aused = ca->mbm_local + ca->mbm_total;
 3025         register count_t bused = cb->mbm_local + cb->mbm_total;
 3026 
 3027         if (aused < bused)
 3028                 return  1;
 3029 
 3030         if (aused > bused)
 3031                 return -1;
 3032 
 3033         return  0;
 3034 }
 3035 
 3036 /*
 3037 ** handle modifications from the /etc/atoprc and ~/.atoprc file
 3038 */
 3039 int
 3040 get_posval(char *name, char *val)
 3041 {
 3042         int     value = atoi(val);
 3043 
 3044         if ( !numeric(val))
 3045         {
 3046                 fprintf(stderr, "atoprc: %s value %s not a (positive) numeric\n", 
 3047                 name, val);
 3048                 exit(1);
 3049         }
 3050 
 3051         if (value < 0)
 3052         {
 3053                 fprintf(stderr,
 3054                         "atoprc: %s value %d not positive\n", 
 3055                         name, value);
 3056                 exit(1);
 3057         }
 3058 
 3059         return value;
 3060 }
 3061 
 3062 int
 3063 get_perc(char *name, char *val)
 3064 {
 3065         int     value = get_posval(name, val);
 3066 
 3067         if (value < 0 || value > 100)
 3068         {
 3069                 fprintf(stderr, "atoprc: %s value %d not in range 0-100\n", 
 3070                         name, value);
 3071                 exit(1);
 3072         }
 3073 
 3074         return value;
 3075 }
 3076 
 3077 void
 3078 do_cpucritperc(char *name, char *val)
 3079 {
 3080         cpubadness = get_perc(name, val);
 3081 }
 3082 
 3083 void
 3084 do_gpucritperc(char *name, char *val)
 3085 {
 3086         gpubadness = get_perc(name, val);
 3087 }
 3088 
 3089 void
 3090 do_memcritperc(char *name, char *val)
 3091 {
 3092         membadness = get_perc(name, val);
 3093 }
 3094 
 3095 void
 3096 do_swpcritperc(char *name, char *val)
 3097 {
 3098         swpbadness = get_perc(name, val);
 3099 }
 3100 
 3101 void
 3102 do_dskcritperc(char *name, char *val)
 3103 {
 3104         dskbadness = get_perc(name, val);
 3105 }
 3106 
 3107 void
 3108 do_netcritperc(char *name, char *val)
 3109 {
 3110         netbadness = get_perc(name, val);
 3111 }
 3112 
 3113 void
 3114 do_swoutcritsec(char *name, char *val)
 3115 {
 3116         pagbadness = get_posval(name, val);
 3117 }
 3118 
 3119 void
 3120 do_almostcrit(char *name, char *val)
 3121 {
 3122         almostcrit = get_perc(name, val);
 3123 }
 3124 
 3125 void
 3126 do_ownsysprcline(char *name, char *val)
 3127 {
 3128         make_sys_prints(sysprcline, MAXITEMS, val, prcsyspdefs, name,
 3129                     NULL, NULL);
 3130 }
 3131 
 3132 void
 3133 do_ownallcpuline(char *name, char *val)
 3134 {
 3135         make_sys_prints(allcpuline, MAXITEMS, val, cpusyspdefs, name,
 3136                     NULL, NULL);
 3137 }
 3138 
 3139 void
 3140 do_ownindivcpuline(char *name, char *val)
 3141 {
 3142         make_sys_prints(indivcpuline, MAXITEMS, val, cpisyspdefs, name,
 3143                     NULL, NULL);
 3144 }
 3145 
 3146 void
 3147 do_owncplline(char *name, char *val)
 3148 {
 3149         make_sys_prints(cplline, MAXITEMS, val, cplsyspdefs, name,
 3150                     NULL, NULL);
 3151 }
 3152 
 3153 void
 3154 do_owngpuline(char *name, char *val)
 3155 {
 3156         make_sys_prints(gpuline, MAXITEMS, val, gpusyspdefs, name,
 3157                     NULL, NULL);
 3158 }
 3159 
 3160 void
 3161 do_ownmemline(char *name, char *val)
 3162 {
 3163         make_sys_prints(memline1, MAXITEMS, val, memsyspdefs1, name,
 3164                     NULL, NULL);
 3165 }
 3166 
 3167 void
 3168 do_ownswpline(char *name, char *val)
 3169 {
 3170         make_sys_prints(swpline, MAXITEMS, val, swpsyspdefs, name,
 3171                     NULL, NULL);
 3172 }
 3173 
 3174 void
 3175 do_ownpagline(char *name, char *val)
 3176 {
 3177         make_sys_prints(pagline, MAXITEMS, val, pagsyspdefs, name,
 3178                     NULL, NULL);
 3179 }
 3180 
 3181 void
 3182 do_ownmemnumaline(char *name, char *val)
 3183 {
 3184         make_sys_prints(memnumaline, MAXITEMS, val, memnumasyspdefs, name,
 3185                     NULL, NULL);
 3186 }
 3187 
 3188 void
 3189 do_owncpunumaline(char *name, char *val)
 3190 {
 3191         make_sys_prints(cpunumaline, MAXITEMS, val, cpunumasyspdefs, name,
 3192                     NULL, NULL);
 3193 }
 3194 
 3195 void
 3196 do_ownllcline(char *name, char *val)
 3197 {
 3198         make_sys_prints(llcline, MAXITEMS, val, llcsyspdefs, name,
 3199                     NULL, NULL);
 3200 }
 3201 
 3202 void
 3203 do_owndskline(char *name, char *val)
 3204 {
 3205         make_sys_prints(dskline, MAXITEMS, val, dsksyspdefs, name,
 3206                     NULL, NULL);
 3207 }
 3208 
 3209 void
 3210 do_ownnettransportline(char *name, char *val)
 3211 {
 3212         make_sys_prints(nettransportline, MAXITEMS, val, nettranssyspdefs, name,
 3213                     NULL, NULL);
 3214 }
 3215 
 3216 void
 3217 do_ownnetnetline(char *name, char *val)
 3218 {
 3219         make_sys_prints(netnetline, MAXITEMS, val, netnetsyspdefs, name,
 3220                     NULL, NULL);
 3221 }
 3222 
 3223 void
 3224 do_ownnetinterfaceline(char *name, char *val)
 3225 {
 3226         make_sys_prints(netinterfaceline, MAXITEMS, val, netintfsyspdefs, name,
 3227                     NULL, NULL);
 3228 }
 3229 
 3230 void
 3231 do_owninfinibandline(char *name, char *val)
 3232 {
 3233         make_sys_prints(infinibandline, MAXITEMS, val, infinisyspdefs, name,
 3234                     NULL, NULL);
 3235 }
 3236 
 3237 void
 3238 do_ownprocline(char *name, char *val)
 3239 {
 3240     make_proc_prints(ownprocs, MAXITEMS, val, name);
 3241 }