2014-11-24 20:55:49 +00:00
/*
htop - LinuxProcess . c
( C ) 2014 Hisham H . Muhammad
2020-08-19 23:35:24 +00:00
( C ) 2020 Red Hat , Inc . All Rights Reserved .
2020-10-05 07:51:32 +00:00
Released under the GNU GPLv2 , see the COPYING file
2014-11-24 20:55:49 +00:00
in the source distribution for its full text .
*/
2014-11-24 21:22:50 +00:00
# include "LinuxProcess.h"
2020-09-19 11:55:23 +00:00
# include <math.h>
# include <stdio.h>
2015-02-20 16:52:10 +00:00
# include <stdlib.h>
2020-09-19 11:55:23 +00:00
# include <syscall.h>
# include <unistd.h>
# include "CRT.h"
2020-11-18 13:26:30 +00:00
# include "Macros.h"
2020-09-19 11:55:23 +00:00
# include "Process.h"
# include "ProvideCurses.h"
2020-11-18 13:26:30 +00:00
# include "RichString.h"
2020-09-19 11:55:23 +00:00
# include "XUtils.h"
2014-11-24 20:55:49 +00:00
2020-10-14 18:21:09 +00:00
2020-07-10 00:35:32 +00:00
/* semi-global */
long long btime ;
2018-08-19 04:29:03 +00:00
2015-03-15 23:29:13 +00:00
ProcessFieldData Process_fields [ ] = {
2015-03-16 04:43:04 +00:00
[ 0 ] = { . name = " " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ PID ] = { . name = " PID " , . title = " PID " , . description = " Process/thread ID " , . flags = 0 , } ,
[ COMM ] = { . name = " Command " , . title = " Command " , . description = " Command line " , . flags = 0 , } ,
2018-01-14 09:08:20 +00:00
[ STATE ] = { . name = " STATE " , . title = " S " , . description = " Process state (S sleeping, R running, D disk, Z zombie, T traced, W paging, I idle) " , . flags = 0 , } ,
2015-03-16 04:43:04 +00:00
[ PPID ] = { . name = " PPID " , . title = " PPID " , . description = " Parent process ID " , . flags = 0 , } ,
[ PGRP ] = { . name = " PGRP " , . title = " PGRP " , . description = " Process group ID " , . flags = 0 , } ,
2017-02-04 23:10:29 +00:00
[ SESSION ] = { . name = " SESSION " , . title = " SID " , . description = " Process's session ID " , . flags = 0 , } ,
2016-10-01 06:09:04 +00:00
[ TTY_NR ] = { . name = " TTY_NR " , . title = " TTY " , . description = " Controlling terminal " , . flags = 0 , } ,
2015-03-16 04:43:04 +00:00
[ TPGID ] = { . name = " TPGID " , . title = " TPGID " , . description = " Process ID of the fg process group of the controlling terminal " , . flags = 0 , } ,
[ FLAGS ] = { . name = " FLAGS " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ MINFLT ] = { . name = " MINFLT " , . title = " MINFLT " , . description = " Number of minor faults which have not required loading a memory page from disk " , . flags = 0 , } ,
[ CMINFLT ] = { . name = " CMINFLT " , . title = " CMINFLT " , . description = " Children processes' minor faults " , . flags = 0 , } ,
[ MAJFLT ] = { . name = " MAJFLT " , . title = " MAJFLT " , . description = " Number of major faults which have required loading a memory page from disk " , . flags = 0 , } ,
[ CMAJFLT ] = { . name = " CMAJFLT " , . title = " CMAJFLT " , . description = " Children processes' major faults " , . flags = 0 , } ,
[ UTIME ] = { . name = " UTIME " , . title = " UTIME+ " , . description = " User CPU time - time the process spent executing in user mode " , . flags = 0 , } ,
[ STIME ] = { . name = " STIME " , . title = " STIME+ " , . description = " System CPU time - time the kernel spent running system calls for this process " , . flags = 0 , } ,
[ CUTIME ] = { . name = " CUTIME " , . title = " CUTIME+ " , . description = " Children processes' user CPU time " , . flags = 0 , } ,
[ CSTIME ] = { . name = " CSTIME " , . title = " CSTIME+ " , . description = " Children processes' system CPU time " , . flags = 0 , } ,
[ PRIORITY ] = { . name = " PRIORITY " , . title = " PRI " , . description = " Kernel's internal priority for the process " , . flags = 0 , } ,
[ NICE ] = { . name = " NICE " , . title = " NI " , . description = " Nice value (the higher the value, the more it lets other processes take priority) " , . flags = 0 , } ,
[ ITREALVALUE ] = { . name = " ITREALVALUE " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ STARTTIME ] = { . name = " STARTTIME " , . title = " START " , . description = " Time the process was started " , . flags = 0 , } ,
[ VSIZE ] = { . name = " VSIZE " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ RSS ] = { . name = " RSS " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ RLIM ] = { . name = " RLIM " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ STARTCODE ] = { . name = " STARTCODE " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ ENDCODE ] = { . name = " ENDCODE " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ STARTSTACK ] = { . name = " STARTSTACK " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ KSTKESP ] = { . name = " KSTKESP " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ KSTKEIP ] = { . name = " KSTKEIP " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ SIGNAL ] = { . name = " SIGNAL " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ BLOCKED ] = { . name = " BLOCKED " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ SSIGIGNORE ] = { . name = " SIGIGNORE " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ SIGCATCH ] = { . name = " SIGCATCH " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ WCHAN ] = { . name = " WCHAN " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ NSWAP ] = { . name = " NSWAP " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ CNSWAP ] = { . name = " CNSWAP " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ EXIT_SIGNAL ] = { . name = " EXIT_SIGNAL " , . title = NULL , . description = NULL , . flags = 0 , } ,
[ PROCESSOR ] = { . name = " PROCESSOR " , . title = " CPU " , . description = " Id of the CPU the process last executed on " , . flags = 0 , } ,
[ M_SIZE ] = { . name = " M_SIZE " , . title = " VIRT " , . description = " Total program size in virtual memory " , . flags = 0 , } ,
[ M_RESIDENT ] = { . name = " M_RESIDENT " , . title = " RES " , . description = " Resident set size, size of the text and data sections, plus stack usage " , . flags = 0 , } ,
[ M_SHARE ] = { . name = " M_SHARE " , . title = " SHR " , . description = " Size of the process's shared pages " , . flags = 0 , } ,
[ M_TRS ] = { . name = " M_TRS " , . title = " CODE " , . description = " Size of the text segment of the process " , . flags = 0 , } ,
[ M_DRS ] = { . name = " M_DRS " , . title = " DATA " , . description = " Size of the data segment plus stack usage of the process " , . flags = 0 , } ,
2020-09-28 10:01:56 +00:00
[ M_LRS ] = { . name = " M_LRS " , . title = " LIB " , . description = " The library size of the process (unused since Linux 2.6; always 0) " , . flags = 0 , } ,
[ M_DT ] = { . name = " M_DT " , . title = " DIRTY " , . description = " Size of the dirty pages of the process (unused since Linux 2.6; always 0) " , . flags = 0 , } ,
2018-10-07 09:16:12 +00:00
[ ST_UID ] = { . name = " ST_UID " , . title = " UID " , . description = " User ID of the process owner " , . flags = 0 , } ,
2015-03-16 04:43:04 +00:00
[ PERCENT_CPU ] = { . name = " PERCENT_CPU " , . title = " CPU% " , . description = " Percentage of the CPU time the process used in the last sampling " , . flags = 0 , } ,
2020-10-30 16:02:20 +00:00
[ PERCENT_NORM_CPU ] = { . name = " PERCENT_NORM_CPU " , . title = " NCPU% " , . description = " Normalized percentage of the CPU time the process used in the last sampling (normalized by cpu count) " , . flags = 0 , } ,
2015-03-16 04:43:04 +00:00
[ PERCENT_MEM ] = { . name = " PERCENT_MEM " , . title = " MEM% " , . description = " Percentage of the memory the process is using, based on resident memory size " , . flags = 0 , } ,
[ USER ] = { . name = " USER " , . title = " USER " , . description = " Username of the process owner (or user ID if name cannot be determined) " , . flags = 0 , } ,
[ TIME ] = { . name = " TIME " , . title = " TIME+ " , . description = " Total time the process has spent in user and system time " , . flags = 0 , } ,
[ NLWP ] = { . name = " NLWP " , . title = " NLWP " , . description = " Number of threads in the process " , . flags = 0 , } ,
[ TGID ] = { . name = " TGID " , . title = " TGID " , . description = " Thread group ID (i.e. process ID) " , . flags = 0 , } ,
2015-03-15 23:29:13 +00:00
# ifdef HAVE_OPENVZ
2020-09-30 21:46:52 +00:00
[ CTID ] = { . name = " CTID " , . title = " CTID " , . description = " OpenVZ container ID (a.k.a. virtual environment ID) " , . flags = PROCESS_FLAG_LINUX_OPENVZ , } ,
[ VPID ] = { . name = " VPID " , . title = " VPID " , . description = " OpenVZ process ID " , . flags = PROCESS_FLAG_LINUX_OPENVZ , } ,
2015-03-15 23:29:13 +00:00
# endif
# ifdef HAVE_VSERVER
2015-03-16 04:43:04 +00:00
[ VXID ] = { . name = " VXID " , . title = " VXID " , . description = " VServer process ID " , . flags = PROCESS_FLAG_LINUX_VSERVER , } ,
2015-03-15 23:29:13 +00:00
# endif
# ifdef HAVE_TASKSTATS
2015-03-16 04:43:04 +00:00
[ RCHAR ] = { . name = " RCHAR " , . title = " RD_CHAR " , . description = " Number of bytes the process has read " , . flags = PROCESS_FLAG_IO , } ,
[ WCHAR ] = { . name = " WCHAR " , . title = " WR_CHAR " , . description = " Number of bytes the process has written " , . flags = PROCESS_FLAG_IO , } ,
[ SYSCR ] = { . name = " SYSCR " , . title = " RD_SYSC " , . description = " Number of read(2) syscalls for the process " , . flags = PROCESS_FLAG_IO , } ,
[ SYSCW ] = { . name = " SYSCW " , . title = " WR_SYSC " , . description = " Number of write(2) syscalls for the process " , . flags = PROCESS_FLAG_IO , } ,
[ RBYTES ] = { . name = " RBYTES " , . title = " IO_RBYTES " , . description = " Bytes of read(2) I/O for the process " , . flags = PROCESS_FLAG_IO , } ,
[ WBYTES ] = { . name = " WBYTES " , . title = " IO_WBYTES " , . description = " Bytes of write(2) I/O for the process " , . flags = PROCESS_FLAG_IO , } ,
[ CNCLWB ] = { . name = " CNCLWB " , . title = " IO_CANCEL " , . description = " Bytes of cancelled write(2) I/O " , . flags = PROCESS_FLAG_IO , } ,
[ IO_READ_RATE ] = { . name = " IO_READ_RATE " , . title = " DISK READ " , . description = " The I/O rate of read(2) in bytes per second for the process " , . flags = PROCESS_FLAG_IO , } ,
[ IO_WRITE_RATE ] = { . name = " IO_WRITE_RATE " , . title = " DISK WRITE " , . description = " The I/O rate of write(2) in bytes per second for the process " , . flags = PROCESS_FLAG_IO , } ,
[ IO_RATE ] = { . name = " IO_RATE " , . title = " DISK R/W " , . description = " Total I/O rate in bytes per second " , . flags = PROCESS_FLAG_IO , } ,
2015-03-15 23:29:13 +00:00
# endif
# ifdef HAVE_CGROUP
2015-03-16 04:43:04 +00:00
[ CGROUP ] = { . name = " CGROUP " , . title = " CGROUP " , . description = " Which cgroup the process is in " , . flags = PROCESS_FLAG_LINUX_CGROUP , } ,
2015-03-15 23:29:13 +00:00
# endif
2020-08-28 12:24:40 +00:00
[ OOM ] = { . name = " OOM " , . title = " OOM " , . description = " OOM (Out-of-Memory) killer score " , . flags = PROCESS_FLAG_LINUX_OOM , } ,
2015-03-16 04:43:04 +00:00
[ IO_PRIORITY ] = { . name = " IO_PRIORITY " , . title = " IO " , . description = " I/O priority " , . flags = PROCESS_FLAG_LINUX_IOPRIO , } ,
2017-12-04 02:15:29 +00:00
# ifdef HAVE_DELAYACCT
[ PERCENT_CPU_DELAY ] = { . name = " PERCENT_CPU_DELAY " , . title = " CPUD% " , . description = " CPU delay % " , . flags = 0 , } ,
[ PERCENT_IO_DELAY ] = { . name = " PERCENT_IO_DELAY " , . title = " IOD% " , . description = " Block I/O delay % " , . flags = 0 , } ,
[ PERCENT_SWAP_DELAY ] = { . name = " PERCENT_SWAP_DELAY " , . title = " SWAPD% " , . description = " Swapin delay % " , . flags = 0 , } ,
# endif
2018-10-09 19:49:29 +00:00
[ M_PSS ] = { . name = " M_PSS " , . title = " PSS " , . description = " proportional set size, same as M_RESIDENT but each page is divided by the number of processes sharing it. " , . flags = PROCESS_FLAG_LINUX_SMAPS , } ,
[ M_SWAP ] = { . name = " M_SWAP " , . title = " SWAP " , . description = " Size of the process's swapped pages " , . flags = PROCESS_FLAG_LINUX_SMAPS , } ,
[ M_PSSWP ] = { . name = " M_PSSWP " , . title = " PSSWP " , . description = " shows proportional swap share of this mapping, Unlike \" Swap \" , this does not take into account swapped out page of underlying shmem objects. " , . flags = PROCESS_FLAG_LINUX_SMAPS , } ,
2020-09-11 13:02:00 +00:00
[ CTXT ] = { . name = " CTXT " , . title = " CTXT " , . description = " Context switches (incremental sum of voluntary_ctxt_switches and nonvoluntary_ctxt_switches) " , . flags = PROCESS_FLAG_LINUX_CTXT , } ,
2020-09-28 10:06:13 +00:00
[ SECATTR ] = { . name = " SECATTR " , . title = " Security Attribute " , . description = " Security attribute of the process (e.g. SELinux or AppArmor) " , . flags = PROCESS_FLAG_LINUX_SECATTR , } ,
2015-03-16 04:43:04 +00:00
[ LAST_PROCESSFIELD ] = { . name = " *** report bug! *** " , . title = NULL , . description = NULL , . flags = 0 , } ,
2015-03-15 23:29:13 +00:00
} ;
2015-08-20 03:32:47 +00:00
ProcessPidColumn Process_pidColumns [ ] = {
{ . id = PID , . label = " PID " } ,
{ . id = PPID , . label = " PPID " } ,
# ifdef HAVE_OPENVZ
{ . id = VPID , . label = " VPID " } ,
# endif
{ . id = TPGID , . label = " TPGID " } ,
{ . id = TGID , . label = " TGID " } ,
{ . id = PGRP , . label = " PGRP " } ,
2017-01-31 23:03:55 +00:00
{ . id = SESSION , . label = " SID " } ,
2015-08-20 03:32:47 +00:00
{ . id = 0 , . label = NULL } ,
} ;
2015-03-15 23:29:13 +00:00
2020-10-21 19:26:05 +00:00
Process * LinuxProcess_new ( const Settings * settings ) {
2016-02-02 14:53:02 +00:00
LinuxProcess * this = xCalloc ( 1 , sizeof ( LinuxProcess ) ) ;
2015-04-01 02:23:10 +00:00
Object_setClass ( this , Class ( LinuxProcess ) ) ;
2015-02-20 16:52:10 +00:00
Process_init ( & this - > super , settings ) ;
2020-10-21 19:26:05 +00:00
return & this - > super ;
2015-02-20 16:52:10 +00:00
}
2015-03-16 04:43:04 +00:00
void Process_delete ( Object * cast ) {
2015-03-08 22:45:56 +00:00
LinuxProcess * this = ( LinuxProcess * ) cast ;
2015-02-20 16:52:10 +00:00
Process_done ( ( Process * ) cast ) ;
2015-03-16 04:43:04 +00:00
# ifdef HAVE_CGROUP
free ( this - > cgroup ) ;
2020-09-30 21:46:52 +00:00
# endif
# ifdef HAVE_OPENVZ
free ( this - > ctid ) ;
2015-03-16 04:43:04 +00:00
# endif
2020-09-28 10:06:13 +00:00
free ( this - > secattr ) ;
2016-10-01 06:09:04 +00:00
free ( this - > ttyDevice ) ;
2015-02-20 16:52:10 +00:00
free ( this ) ;
}
2014-11-24 20:55:49 +00:00
/*
[ 1 ] Note that before kernel 2.6 .26 a process that has not asked for
an io priority formally uses " none " as scheduling class , but the
io scheduler will treat such processes as if it were in the best
effort class . The priority within the best effort class will be
dynamically derived from the cpu nice level of the process :
io_priority = ( cpu_nice + 20 ) / 5. - - From ionice ( 1 ) man page
*/
2020-10-27 20:26:39 +00:00
static int LinuxProcess_effectiveIOPriority ( const LinuxProcess * this ) {
2020-11-01 00:09:51 +00:00
if ( IOPriority_class ( this - > ioPriority ) = = IOPRIO_CLASS_NONE ) {
2020-10-27 20:26:39 +00:00
return IOPriority_tuple ( IOPRIO_CLASS_BE , ( this - > super . nice + 20 ) / 5 ) ;
2020-11-01 00:09:51 +00:00
}
2020-10-27 20:26:39 +00:00
return this - > ioPriority ;
}
2014-11-24 20:55:49 +00:00
2014-11-24 21:22:50 +00:00
IOPriority LinuxProcess_updateIOPriority ( LinuxProcess * this ) {
2016-02-14 14:05:35 +00:00
IOPriority ioprio = 0 ;
// Other OSes masquerading as Linux (NetBSD?) don't have this syscall
# ifdef SYS_ioprio_get
ioprio = syscall ( SYS_ioprio_get , IOPRIO_WHO_PROCESS , this - > super . pid ) ;
# endif
2014-11-24 20:55:49 +00:00
this - > ioPriority = ioprio ;
return ioprio ;
}
2020-10-27 10:46:29 +00:00
bool LinuxProcess_setIOPriority ( Process * this , Arg ioprio ) {
2016-02-14 14:05:35 +00:00
// Other OSes masquerading as Linux (NetBSD?) don't have this syscall
# ifdef SYS_ioprio_set
2020-10-27 10:46:29 +00:00
syscall ( SYS_ioprio_set , IOPRIO_WHO_PROCESS , this - > pid , ioprio . i ) ;
2016-02-14 14:05:35 +00:00
# endif
2020-10-27 10:46:29 +00:00
return ( LinuxProcess_updateIOPriority ( ( LinuxProcess * ) this ) = = ioprio . i ) ;
2014-11-24 20:55:49 +00:00
}
2017-12-04 02:15:29 +00:00
# ifdef HAVE_DELAYACCT
2020-11-19 13:43:04 +00:00
static void LinuxProcess_printDelay ( float delay_percent , char * buffer , int n ) {
2020-10-31 21:14:27 +00:00
if ( isnan ( delay_percent ) ) {
xSnprintf ( buffer , n , " N/A " ) ;
} else {
xSnprintf ( buffer , n , " %4.1f " , delay_percent ) ;
}
2017-12-04 02:15:29 +00:00
}
# endif
2020-11-04 16:46:14 +00:00
static void LinuxProcess_writeField ( const Process * this , RichString * str , ProcessField field ) {
2020-10-21 19:26:01 +00:00
const LinuxProcess * lp = ( const LinuxProcess * ) this ;
2015-03-16 04:43:04 +00:00
bool coloring = this - > settings - > highlightMegabytes ;
2014-11-24 21:22:50 +00:00
char buffer [ 256 ] ; buffer [ 255 ] = ' \0 ' ;
int attr = CRT_colors [ DEFAULT_COLOR ] ;
int n = sizeof ( buffer ) - 1 ;
2015-03-16 04:43:04 +00:00
switch ( ( int ) field ) {
2016-10-01 06:09:04 +00:00
case TTY_NR : {
if ( lp - > ttyDevice ) {
2017-07-27 19:07:50 +00:00
xSnprintf ( buffer , n , " %-9s " , lp - > ttyDevice + 5 /* skip "/dev/" */ ) ;
2016-10-01 06:09:04 +00:00
} else {
attr = CRT_colors [ PROCESS_SHADOW ] ;
2017-07-27 19:07:50 +00:00
xSnprintf ( buffer , n , " ? " ) ;
2016-10-01 06:09:04 +00:00
}
break ;
}
2015-03-16 04:43:04 +00:00
case CMINFLT : Process_colorNumber ( str , lp - > cminflt , coloring ) ; return ;
case CMAJFLT : Process_colorNumber ( str , lp - > cmajflt , coloring ) ; return ;
2020-10-15 20:37:02 +00:00
case M_DRS : Process_humanNumber ( str , lp - > m_drs * CRT_pageSizeKB , coloring ) ; return ;
case M_DT : Process_humanNumber ( str , lp - > m_dt * CRT_pageSizeKB , coloring ) ; return ;
case M_LRS : Process_humanNumber ( str , lp - > m_lrs * CRT_pageSizeKB , coloring ) ; return ;
case M_TRS : Process_humanNumber ( str , lp - > m_trs * CRT_pageSizeKB , coloring ) ; return ;
case M_SHARE : Process_humanNumber ( str , lp - > m_share * CRT_pageSizeKB , coloring ) ; return ;
2018-10-09 19:49:29 +00:00
case M_PSS : Process_humanNumber ( str , lp - > m_pss , coloring ) ; return ;
case M_SWAP : Process_humanNumber ( str , lp - > m_swap , coloring ) ; return ;
case M_PSSWP : Process_humanNumber ( str , lp - > m_psswp , coloring ) ; return ;
2015-03-16 04:43:04 +00:00
case UTIME : Process_printTime ( str , lp - > utime ) ; return ;
case STIME : Process_printTime ( str , lp - > stime ) ; return ;
case CUTIME : Process_printTime ( str , lp - > cutime ) ; return ;
case CSTIME : Process_printTime ( str , lp - > cstime ) ; return ;
# ifdef HAVE_TASKSTATS
case RCHAR : Process_colorNumber ( str , lp - > io_rchar , coloring ) ; return ;
case WCHAR : Process_colorNumber ( str , lp - > io_wchar , coloring ) ; return ;
case SYSCR : Process_colorNumber ( str , lp - > io_syscr , coloring ) ; return ;
case SYSCW : Process_colorNumber ( str , lp - > io_syscw , coloring ) ; return ;
case RBYTES : Process_colorNumber ( str , lp - > io_read_bytes , coloring ) ; return ;
case WBYTES : Process_colorNumber ( str , lp - > io_write_bytes , coloring ) ; return ;
case CNCLWB : Process_colorNumber ( str , lp - > io_cancelled_write_bytes , coloring ) ; return ;
case IO_READ_RATE : Process_outputRate ( str , buffer , n , lp - > io_rate_read_bps , coloring ) ; return ;
case IO_WRITE_RATE : Process_outputRate ( str , buffer , n , lp - > io_rate_write_bps , coloring ) ; return ;
2016-02-20 04:22:57 +00:00
case IO_RATE : {
2020-09-07 09:53:58 +00:00
double totalRate = NAN ;
2020-10-31 19:52:20 +00:00
if ( ! isnan ( lp - > io_rate_read_bps ) & & ! isnan ( lp - > io_rate_write_bps ) )
2020-09-07 09:53:58 +00:00
totalRate = lp - > io_rate_read_bps + lp - > io_rate_write_bps ;
2020-10-31 19:52:20 +00:00
else if ( ! isnan ( lp - > io_rate_read_bps ) )
2020-09-07 09:53:58 +00:00
totalRate = lp - > io_rate_read_bps ;
2020-10-31 19:52:20 +00:00
else if ( ! isnan ( lp - > io_rate_write_bps ) )
2020-09-07 09:53:58 +00:00
totalRate = lp - > io_rate_write_bps ;
else
totalRate = NAN ;
2016-02-20 04:22:57 +00:00
Process_outputRate ( str , buffer , n , totalRate , coloring ) ; return ;
}
2015-03-16 04:43:04 +00:00
# endif
# ifdef HAVE_OPENVZ
2020-09-30 21:46:52 +00:00
case CTID : xSnprintf ( buffer , n , " %-8s " , lp - > ctid ? lp - > ctid : " " ) ; break ;
2017-07-27 19:07:50 +00:00
case VPID : xSnprintf ( buffer , n , Process_pidFormat , lp - > vpid ) ; break ;
2015-03-16 04:43:04 +00:00
# endif
# ifdef HAVE_VSERVER
2017-07-27 19:07:50 +00:00
case VXID : xSnprintf ( buffer , n , " %5u " , lp - > vxid ) ; break ;
2015-03-16 04:43:04 +00:00
# endif
# ifdef HAVE_CGROUP
2020-09-21 11:47:39 +00:00
case CGROUP : xSnprintf ( buffer , n , " %-10s " , lp - > cgroup ? lp - > cgroup : " " ) ; break ;
2015-03-16 04:43:04 +00:00
# endif
2020-08-28 12:24:40 +00:00
case OOM : xSnprintf ( buffer , n , " %4u " , lp - > oom ) ; break ;
2014-11-24 20:55:49 +00:00
case IO_PRIORITY : {
2015-01-22 01:27:31 +00:00
int klass = IOPriority_class ( lp - > ioPriority ) ;
2014-11-24 20:55:49 +00:00
if ( klass = = IOPRIO_CLASS_NONE ) {
// see note [1] above
2017-07-27 19:07:50 +00:00
xSnprintf ( buffer , n , " B%1d " , ( int ) ( this - > nice + 20 ) / 5 ) ;
2014-11-24 20:55:49 +00:00
} else if ( klass = = IOPRIO_CLASS_BE ) {
2017-07-27 19:07:50 +00:00
xSnprintf ( buffer , n , " B%1d " , IOPriority_data ( lp - > ioPriority ) ) ;
2014-11-24 20:55:49 +00:00
} else if ( klass = = IOPRIO_CLASS_RT ) {
attr = CRT_colors [ PROCESS_HIGH_PRIORITY ] ;
2017-07-27 19:07:50 +00:00
xSnprintf ( buffer , n , " R%1d " , IOPriority_data ( lp - > ioPriority ) ) ;
2017-07-05 18:18:02 +00:00
} else if ( klass = = IOPRIO_CLASS_IDLE ) {
2019-10-31 16:39:12 +00:00
attr = CRT_colors [ PROCESS_LOW_PRIORITY ] ;
2017-07-27 19:07:50 +00:00
xSnprintf ( buffer , n , " id " ) ;
2014-11-24 20:55:49 +00:00
} else {
2017-07-27 19:07:50 +00:00
xSnprintf ( buffer , n , " ?? " ) ;
2014-11-24 20:55:49 +00:00
}
break ;
}
2017-12-04 02:15:29 +00:00
# ifdef HAVE_DELAYACCT
case PERCENT_CPU_DELAY : LinuxProcess_printDelay ( lp - > cpu_delay_percent , buffer , n ) ; break ;
case PERCENT_IO_DELAY : LinuxProcess_printDelay ( lp - > blkio_delay_percent , buffer , n ) ; break ;
case PERCENT_SWAP_DELAY : LinuxProcess_printDelay ( lp - > swapin_delay_percent , buffer , n ) ; break ;
# endif
2020-09-11 13:02:00 +00:00
case CTXT :
2020-11-01 00:09:51 +00:00
if ( lp - > ctxt_diff > 1000 ) {
2020-09-11 13:02:00 +00:00
attr | = A_BOLD ;
2020-11-01 00:09:51 +00:00
}
2020-09-11 13:02:00 +00:00
xSnprintf ( buffer , n , " %5lu " , lp - > ctxt_diff ) ;
break ;
2020-09-28 10:06:13 +00:00
case SECATTR : snprintf ( buffer , n , " %-30s " , lp - > secattr ? lp - > secattr : " ? " ) ; break ;
2014-11-24 20:55:49 +00:00
default :
2020-09-28 10:17:52 +00:00
Process_writeField ( this , str , field ) ;
2015-01-22 01:27:31 +00:00
return ;
2014-11-24 20:55:49 +00:00
}
RichString_append ( str , attr , buffer ) ;
}
2020-11-04 16:46:14 +00:00
static long LinuxProcess_compare ( const void * v1 , const void * v2 ) {
2020-09-23 12:15:51 +00:00
const LinuxProcess * p1 , * p2 ;
const Settings * settings = ( ( const Process * ) v1 ) - > settings ;
2020-11-04 16:46:24 +00:00
2015-01-22 01:27:31 +00:00
if ( settings - > direction = = 1 ) {
2020-09-23 12:15:51 +00:00
p1 = ( const LinuxProcess * ) v1 ;
p2 = ( const LinuxProcess * ) v2 ;
2014-11-24 20:55:49 +00:00
} else {
2020-09-23 12:15:51 +00:00
p2 = ( const LinuxProcess * ) v1 ;
p1 = ( const LinuxProcess * ) v2 ;
2014-11-24 20:55:49 +00:00
}
2020-11-04 16:46:24 +00:00
2015-03-16 04:43:04 +00:00
switch ( ( int ) settings - > sortKey ) {
case M_DRS :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > m_drs , p1 - > m_drs ) ;
2015-03-16 04:43:04 +00:00
case M_DT :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > m_dt , p1 - > m_dt ) ;
2015-03-16 04:43:04 +00:00
case M_LRS :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > m_lrs , p1 - > m_lrs ) ;
2015-03-16 04:43:04 +00:00
case M_TRS :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > m_trs , p1 - > m_trs ) ;
2015-03-16 04:43:04 +00:00
case M_SHARE :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > m_share , p1 - > m_share ) ;
2018-10-09 19:49:29 +00:00
case M_PSS :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > m_pss , p1 - > m_pss ) ;
2018-10-09 19:49:29 +00:00
case M_SWAP :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > m_swap , p1 - > m_swap ) ;
2018-10-09 19:49:29 +00:00
case M_PSSWP :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > m_psswp , p1 - > m_psswp ) ;
case UTIME :
return SPACESHIP_NUMBER ( p2 - > utime , p1 - > utime ) ;
case CUTIME :
return SPACESHIP_NUMBER ( p2 - > cutime , p1 - > cutime ) ;
case STIME :
return SPACESHIP_NUMBER ( p2 - > stime , p1 - > stime ) ;
case CSTIME :
return SPACESHIP_NUMBER ( p2 - > cstime , p1 - > cstime ) ;
2015-03-16 04:43:04 +00:00
# ifdef HAVE_TASKSTATS
2020-11-04 16:46:24 +00:00
case RCHAR :
return SPACESHIP_NUMBER ( p2 - > io_rchar , p1 - > io_rchar ) ;
case WCHAR :
return SPACESHIP_NUMBER ( p2 - > io_wchar , p1 - > io_wchar ) ;
case SYSCR :
return SPACESHIP_NUMBER ( p2 - > io_syscr , p1 - > io_syscr ) ;
case SYSCW :
return SPACESHIP_NUMBER ( p2 - > io_syscw , p1 - > io_syscw ) ;
case RBYTES :
return SPACESHIP_NUMBER ( p2 - > io_read_bytes , p1 - > io_read_bytes ) ;
case WBYTES :
return SPACESHIP_NUMBER ( p2 - > io_write_bytes , p1 - > io_write_bytes ) ;
case CNCLWB :
return SPACESHIP_NUMBER ( p2 - > io_cancelled_write_bytes , p1 - > io_cancelled_write_bytes ) ;
case IO_READ_RATE :
return SPACESHIP_NUMBER ( p2 - > io_rate_read_bps , p1 - > io_rate_read_bps ) ;
case IO_WRITE_RATE :
return SPACESHIP_NUMBER ( p2 - > io_rate_write_bps , p1 - > io_rate_write_bps ) ;
case IO_RATE :
return SPACESHIP_NUMBER ( p2 - > io_rate_read_bps + p2 - > io_rate_write_bps , p1 - > io_rate_read_bps + p1 - > io_rate_write_bps ) ;
2015-03-16 04:43:04 +00:00
# endif
# ifdef HAVE_OPENVZ
case CTID :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NULLSTR ( p1 - > ctid , p2 - > ctid ) ;
2015-03-16 04:43:04 +00:00
case VPID :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > vpid , p1 - > vpid ) ;
2015-03-16 04:43:04 +00:00
# endif
# ifdef HAVE_VSERVER
case VXID :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > vxid , p1 - > vxid ) ;
2015-03-16 04:43:04 +00:00
# endif
# ifdef HAVE_CGROUP
case CGROUP :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NULLSTR ( p1 - > cgroup , p2 - > cgroup ) ;
2015-03-16 04:43:04 +00:00
# endif
case OOM :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > oom , p1 - > oom ) ;
2017-12-04 02:15:29 +00:00
# ifdef HAVE_DELAYACCT
case PERCENT_CPU_DELAY :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > cpu_delay_percent , p1 - > cpu_delay_percent ) ;
2017-12-04 02:15:29 +00:00
case PERCENT_IO_DELAY :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > blkio_delay_percent , p1 - > blkio_delay_percent ) ;
2017-12-04 02:15:29 +00:00
case PERCENT_SWAP_DELAY :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > swapin_delay_percent , p1 - > swapin_delay_percent ) ;
2017-12-04 02:15:29 +00:00
# endif
2014-11-24 20:55:49 +00:00
case IO_PRIORITY :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( LinuxProcess_effectiveIOPriority ( p1 ) , LinuxProcess_effectiveIOPriority ( p2 ) ) ;
2020-09-11 13:02:00 +00:00
case CTXT :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NUMBER ( p2 - > ctxt_diff , p1 - > ctxt_diff ) ;
2020-09-28 10:06:13 +00:00
case SECATTR :
2020-11-04 16:46:24 +00:00
return SPACESHIP_NULLSTR ( p1 - > secattr , p2 - > secattr ) ;
2014-11-24 20:55:49 +00:00
default :
2015-04-01 02:23:10 +00:00
return Process_compare ( v1 , v2 ) ;
2014-11-24 20:55:49 +00:00
}
2015-03-16 04:43:04 +00:00
}
2020-10-07 17:02:15 +00:00
bool Process_isThread ( const Process * this ) {
2015-03-16 04:43:04 +00:00
return ( Process_isUserlandThread ( this ) | | Process_isKernelThread ( this ) ) ;
2014-11-24 20:55:49 +00:00
}
2020-11-04 16:46:14 +00:00
const ProcessClass LinuxProcess_class = {
. super = {
. extends = Class ( Process ) ,
. display = Process_display ,
. delete = Process_delete ,
. compare = LinuxProcess_compare
} ,
. writeField = LinuxProcess_writeField
} ;