From f75ab6d2c11e8a8e18191b087564aedebbeb96c5 Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Mon, 11 Apr 2016 13:00:33 +0200 Subject: Imported Upstream version 1.0.3 --- Process.c | 334 +++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 222 insertions(+), 112 deletions(-) (limited to 'Process.c') diff --git a/Process.c b/Process.c index 99e9f13..4efd854 100644 --- a/Process.c +++ b/Process.c @@ -45,6 +45,12 @@ in the source distribution for its full text. #include "IOPriority.h" #include +#define PROCESS_FLAG_IO 1 +#define PROCESS_FLAG_IOPRIO 2 +#define PROCESS_FLAG_OPENVZ 4 +#define PROCESS_FLAG_VSERVER 8 +#define PROCESS_FLAG_CGROUP 16 + #ifndef Process_isKernelThread #define Process_isKernelThread(_process) (_process->pgrp == 0) #endif @@ -75,6 +81,9 @@ typedef enum ProcessField_ { #ifdef HAVE_CGROUP CGROUP, #endif + #ifdef HAVE_OOM + OOM, + #endif IO_PRIORITY, LAST_PROCESSFIELD } ProcessField; @@ -85,7 +94,6 @@ typedef struct Process_ { Object super; struct ProcessList_ *pl; - bool updated; pid_t pid; char* comm; @@ -101,12 +109,12 @@ typedef struct Process_ { pid_t tgid; int tpgid; unsigned long int flags; - #ifdef DEBUG - unsigned long int minflt; - unsigned long int cminflt; - unsigned long int majflt; - unsigned long int cmajflt; - #endif + + uid_t st_uid; + float percent_cpu; + float percent_mem; + char* user; + unsigned long long int utime; unsigned long long int stime; unsigned long long int cutime; @@ -117,6 +125,53 @@ typedef struct Process_ { IOPriority ioPriority; char starttime_show[8]; time_t starttime_ctime; + + #ifdef HAVE_TASKSTATS + unsigned long long io_rchar; + unsigned long long io_wchar; + unsigned long long io_syscr; + unsigned long long io_syscw; + unsigned long long io_read_bytes; + unsigned long long io_write_bytes; + unsigned long long io_cancelled_write_bytes; + double io_rate_read_bps; + unsigned long long io_rate_read_time; + double io_rate_write_bps; + unsigned long long io_rate_write_time; + #endif + + int processor; + long m_size; + long m_resident; + long m_share; + long m_trs; + long m_drs; + long m_lrs; + long m_dt; + + #ifdef HAVE_OPENVZ + unsigned int ctid; + unsigned int vpid; + #endif + #ifdef HAVE_VSERVER + unsigned int vxid; + #endif + + #ifdef HAVE_CGROUP + char* cgroup; + #endif + #ifdef HAVE_OOM + unsigned int oom; + #endif + + int exit_signal; + int basenameOffset; + bool updated; + + unsigned long int minflt; + unsigned long int cminflt; + unsigned long int majflt; + unsigned long int cmajflt; #ifdef DEBUG long int itrealvalue; unsigned long int vsize; @@ -135,52 +190,11 @@ typedef struct Process_ { unsigned long int nswap; unsigned long int cnswap; #endif - int exit_signal; - int processor; - int m_size; - int m_resident; - int m_share; - int m_trs; - int m_drs; - int m_lrs; - int m_dt; - uid_t st_uid; - float percent_cpu; - float percent_mem; - char* user; - #ifdef HAVE_OPENVZ - unsigned int ctid; - unsigned int vpid; - #endif - #ifdef HAVE_VSERVER - unsigned int vxid; - #endif - #ifdef HAVE_TASKSTATS - unsigned long long io_rchar; - unsigned long long io_wchar; - unsigned long long io_syscr; - unsigned long long io_syscw; - unsigned long long io_read_bytes; - unsigned long long io_write_bytes; - unsigned long long io_cancelled_write_bytes; - double io_rate_read_bps; - unsigned long long io_rate_read_time; - double io_rate_write_bps; - unsigned long long io_rate_write_time; - #endif - #ifdef HAVE_CGROUP - char* cgroup; - #endif + } Process; }*/ -#ifdef DEBUG -char* PROCESS_CLASS = "Process"; -#else -#define PROCESS_CLASS NULL -#endif - const char *Process_fieldNames[] = { "", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION", "TTY_NR", "TPGID", "FLAGS", "MINFLT", "CMINFLT", "MAJFLT", "CMAJFLT", @@ -202,14 +216,45 @@ const char *Process_fieldNames[] = { #endif #ifdef HAVE_CGROUP "CGROUP", +#endif +#ifdef HAVE_OOM + "OOM", #endif "IO_PRIORITY", "*** report bug! ***" }; +const int Process_fieldFlags[] = { + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, +#ifdef HAVE_OPENVZ + PROCESS_FLAG_OPENVZ, PROCESS_FLAG_OPENVZ, +#endif +#ifdef HAVE_VSERVER + PROCESS_FLAG_VSERVER, +#endif +#ifdef HAVE_TASKSTATS + PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, + PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, +#endif +#ifdef HAVE_CGROUP + PROCESS_FLAG_CGROUP, +#endif +#ifdef HAVE_OOM + 0, +#endif + PROCESS_FLAG_IOPRIO +}; + const char *Process_fieldTitles[] = { "", " PID ", "Command ", "S ", " PPID ", " PGRP ", " SESN ", - " TTY ", " TPGID ", "- ", "- ", "- ", "- ", "- ", + " TTY ", " TPGID ", "- ", " MINFLT ", " CMINFLT ", " MAJFLT ", " CMAJFLT ", " UTIME+ ", " STIME+ ", " CUTIME+ ", " CSTIME+ ", "PRI ", " NI ", "- ", "START ", "- ", "- ", "- ", "- ", "- ", "- ", "- ", "- ", "- ", "- ", "- ", "- ", "- ", @@ -223,11 +268,14 @@ const char *Process_fieldTitles[] = { " VXID ", #endif #ifdef HAVE_TASKSTATS - " RD_CHAR ", " WR_CHAR ", " RD_SYSC ", " WR_SYSC ", " IO_RBYTES ", " IO_WBYTES ", " IO_CANCEL ", - " IORR ", " IOWR ", " IO ", + " RD_CHAR ", " WR_CHAR ", " RD_SYSC ", " WR_SYSC ", " IO_RBYTES ", " IO_WBYTES ", " IO_CANCEL ", + " IORR ", " IOWR ", " IORW ", #endif #ifdef HAVE_CGROUP " CGROUP ", +#endif +#ifdef HAVE_OOM + " OOM ", #endif "IO ", "*** report bug! ***" @@ -251,6 +299,9 @@ void Process_getMaxPid() { Process_fieldTitles[TGID] = " TGID "; Process_fieldTitles[PGRP] = " PGRP "; Process_fieldTitles[SESSION] = " SESN "; + #ifdef HAVE_OOM + Process_fieldTitles[OOM] = " OOM "; + #endif Process_pidFormat = "%7u "; Process_tpgidFormat = "%7d "; } else { @@ -260,57 +311,94 @@ void Process_getMaxPid() { Process_fieldTitles[TGID] = " TGID "; Process_fieldTitles[PGRP] = " PGRP "; Process_fieldTitles[SESSION] = " SESN "; + #ifdef HAVE_OOM + Process_fieldTitles[OOM] = " OOM "; + #endif Process_pidFormat = "%5u "; Process_tpgidFormat = "%5d "; } } -#define ONE_K 1024 +#define ONE_K 1024L #define ONE_M (ONE_K * ONE_K) #define ONE_G (ONE_M * ONE_K) -static void Process_humanNumber(Process* this, RichString* str, unsigned long number) { +#define ONE_DECIMAL_K 1000L +#define ONE_DECIMAL_M (ONE_DECIMAL_K * ONE_DECIMAL_K) +#define ONE_DECIMAL_G (ONE_DECIMAL_M * ONE_DECIMAL_K) + +static void Process_humanNumber(RichString* str, unsigned long number, bool coloring) { char buffer[11]; int len; - if(number >= (10 * ONE_M)) { - if(number >= (100 * ONE_M)) { + + int largeNumberColor = CRT_colors[LARGE_NUMBER]; + int processMegabytesColor = CRT_colors[PROCESS_MEGABYTES]; + int processColor = CRT_colors[PROCESS]; + if (!coloring) { + largeNumberColor = CRT_colors[PROCESS]; + processMegabytesColor = CRT_colors[PROCESS]; + } + + if(number >= (10 * ONE_DECIMAL_M)) { + #ifdef __LP64__ + if(number >= (100 * ONE_DECIMAL_G)) { + len = snprintf(buffer, 10, "%4ldT ", number / ONE_G); + RichString_appendn(str, largeNumberColor, buffer, len); + return; + } else if (number >= (1000 * ONE_DECIMAL_M)) { + len = snprintf(buffer, 10, "%4.1lfT ", (double)number / ONE_G); + RichString_appendn(str, largeNumberColor, buffer, len); + return; + } + #endif + if(number >= (100 * ONE_DECIMAL_M)) { len = snprintf(buffer, 10, "%4ldG ", number / ONE_M); - RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, len); - } else { - len = snprintf(buffer, 10, "%3.1fG ", (float)number / ONE_M); - RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, len); + RichString_appendn(str, largeNumberColor, buffer, len); + return; } + len = snprintf(buffer, 10, "%4.1lfG ", (double)number / ONE_M); + RichString_appendn(str, largeNumberColor, buffer, len); + return; } else if (number >= 100000) { len = snprintf(buffer, 10, "%4ldM ", number / ONE_K); - int attr = this->pl->highlightMegabytes - ? CRT_colors[PROCESS_MEGABYTES] - : CRT_colors[PROCESS]; - RichString_appendn(str, attr, buffer, len); - } else if (this->pl->highlightMegabytes && number >= 1000) { + RichString_appendn(str, processMegabytesColor, buffer, len); + return; + } else if (number >= 1000) { len = snprintf(buffer, 10, "%2ld", number/1000); - RichString_appendn(str, CRT_colors[PROCESS_MEGABYTES], buffer, len); + RichString_appendn(str, processMegabytesColor, buffer, len); number %= 1000; - len = snprintf(buffer, 10, "%03ld ", number); - RichString_appendn(str, CRT_colors[PROCESS], buffer, len); - } else { - len = snprintf(buffer, 10, "%5ld ", number); - RichString_appendn(str, CRT_colors[PROCESS], buffer, len); + len = snprintf(buffer, 10, "%03lu ", number); + RichString_appendn(str, processColor, buffer, len); + return; } + len = snprintf(buffer, 10, "%5lu ", number); + RichString_appendn(str, processColor, buffer, len); } -static void Process_colorNumber(RichString* str, unsigned long long number) { +static void Process_colorNumber(RichString* str, unsigned long long number, bool coloring) { char buffer[14]; + + int largeNumberColor = CRT_colors[LARGE_NUMBER]; + int processMegabytesColor = CRT_colors[PROCESS_MEGABYTES]; + int processColor = CRT_colors[PROCESS]; + int processShadowColor = CRT_colors[PROCESS_SHADOW]; + if (!coloring) { + largeNumberColor = CRT_colors[PROCESS]; + processMegabytesColor = CRT_colors[PROCESS]; + processShadowColor = CRT_colors[PROCESS]; + } + if (number > 10000000000) { snprintf(buffer, 13, "%11lld ", number / 1000); - RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, 5); - RichString_appendn(str, CRT_colors[PROCESS_MEGABYTES], buffer+5, 3); - RichString_appendn(str, CRT_colors[PROCESS], buffer+8, 4); + RichString_appendn(str, largeNumberColor, buffer, 5); + RichString_appendn(str, processMegabytesColor, buffer+5, 3); + RichString_appendn(str, processColor, buffer+8, 4); } else { - snprintf(buffer, 13, "%11lld ", number); - RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, 2); - RichString_appendn(str, CRT_colors[PROCESS_MEGABYTES], buffer+2, 3); - RichString_appendn(str, CRT_colors[PROCESS], buffer+5, 3); - RichString_appendn(str, CRT_colors[PROCESS_SHADOW], buffer+8, 4); + snprintf(buffer, 13, "%11llu ", number); + RichString_appendn(str, largeNumberColor, buffer, 2); + RichString_appendn(str, processMegabytesColor, buffer+2, 3); + RichString_appendn(str, processColor, buffer+5, 3); + RichString_appendn(str, processShadowColor, buffer+8, 4); } } @@ -348,20 +436,24 @@ static inline void Process_writeCommand(Process* this, int attr, int baseattr, R RichString_append(str, attr, this->comm); if (this->pl->highlightBaseName) { int finish = RichString_size(str) - 1; - int space = RichString_findChar(str, ' ', start); - if (space != -1) - finish = space - 1; - for (;;) { - int slash = RichString_findChar(str, '/', start); - if (slash == -1 || slash > finish) - break; - start = slash + 1; + if (this->basenameOffset != -1) + finish = (start + this->basenameOffset) - 1; + int colon = RichString_findChar(str, ':', start); + if (colon != -1 && colon < finish) { + finish = colon; + } else { + for (int i = finish - start; i >= 0; i--) { + if (this->comm[i] == '/') { + start += i+1; + break; + } + } } RichString_setAttrn(str, baseattr, start, finish); } } -static inline void Process_outputRate(Process* this, RichString* str, int attr, char* buffer, int n, double rate) { +static inline void Process_outputRate(RichString* str, int attr, char* buffer, int n, double rate, int coloring) { rate = rate / 1024; if (rate < 0.01) snprintf(buffer, n, " 0 "); @@ -370,17 +462,18 @@ static inline void Process_outputRate(Process* this, RichString* str, int attr, else if (rate <= 100) snprintf(buffer, n, "%5.1f ", rate); else { - Process_humanNumber(this, str, rate); + Process_humanNumber(str, rate, coloring); return; } RichString_append(str, attr, buffer); } static void Process_writeField(Process* this, RichString* str, ProcessField field) { - char buffer[128]; buffer[127] = '\0'; + char buffer[256]; buffer[255] = '\0'; int attr = CRT_colors[DEFAULT_COLOR]; int baseattr = CRT_colors[PROCESS_BASENAME]; int n = sizeof(buffer) - 1; + bool coloring = this->pl->highlightMegabytes; switch (field) { case PID: snprintf(buffer, n, Process_pidFormat, this->pid); break; @@ -390,6 +483,10 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel case TTY_NR: snprintf(buffer, n, "%5u ", this->tty_nr); break; case TGID: snprintf(buffer, n, Process_pidFormat, this->tgid); break; case TPGID: snprintf(buffer, n, Process_tpgidFormat, this->tpgid); break; + case MINFLT: Process_colorNumber(str, this->minflt, coloring); return; + case CMINFLT: Process_colorNumber(str, this->cminflt, coloring); return; + case MAJFLT: Process_colorNumber(str, this->majflt, coloring); return; + case CMAJFLT: Process_colorNumber(str, this->cmajflt, coloring); return; case PROCESSOR: snprintf(buffer, n, "%3d ", ProcessList_cpuId(this->pl, this->processor)); break; case NLWP: snprintf(buffer, n, "%4ld ", this->nlwp); break; case COMM: { @@ -449,13 +546,13 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel : attr; break; } - case M_DRS: Process_humanNumber(this, str, this->m_drs * PAGE_SIZE_KB); return; - case M_DT: Process_humanNumber(this, str, this->m_dt * PAGE_SIZE_KB); return; - case M_LRS: Process_humanNumber(this, str, this->m_lrs * PAGE_SIZE_KB); return; - case M_TRS: Process_humanNumber(this, str, this->m_trs * PAGE_SIZE_KB); return; - case M_SIZE: Process_humanNumber(this, str, this->m_size * PAGE_SIZE_KB); return; - case M_RESIDENT: Process_humanNumber(this, str, this->m_resident * PAGE_SIZE_KB); return; - case M_SHARE: Process_humanNumber(this, str, this->m_share * PAGE_SIZE_KB); return; + case M_DRS: Process_humanNumber(str, this->m_drs * PAGE_SIZE_KB, coloring); return; + case M_DT: Process_humanNumber(str, this->m_dt * PAGE_SIZE_KB, coloring); return; + case M_LRS: Process_humanNumber(str, this->m_lrs * PAGE_SIZE_KB, coloring); return; + case M_TRS: Process_humanNumber(str, this->m_trs * PAGE_SIZE_KB, coloring); return; + case M_SIZE: Process_humanNumber(str, this->m_size * PAGE_SIZE_KB, coloring); return; + case M_RESIDENT: Process_humanNumber(str, this->m_resident * PAGE_SIZE_KB, coloring); return; + case M_SHARE: Process_humanNumber(str, this->m_share * PAGE_SIZE_KB, coloring); return; case ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break; case USER: { if (Process_getuid != (int) this->st_uid) @@ -503,20 +600,23 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel case VXID: snprintf(buffer, n, "%5u ", this->vxid); break; #endif #ifdef HAVE_TASKSTATS - case RCHAR: snprintf(buffer, n, "%12llu ", this->io_rchar); break; - case WCHAR: snprintf(buffer, n, "%12llu ", this->io_wchar); break; - case SYSCR: snprintf(buffer, n, "%10llu ", this->io_syscr); break; - case SYSCW: snprintf(buffer, n, "%10llu ", this->io_syscw); break; - case RBYTES: Process_colorNumber(str, this->io_read_bytes); return; - case WBYTES: Process_colorNumber(str, this->io_write_bytes); return; - case CNCLWB: snprintf(buffer, n, "%10llu ", this->io_cancelled_write_bytes); break; - case IO_READ_RATE: Process_outputRate(this, str, attr, buffer, n, this->io_rate_read_bps); return; - case IO_WRITE_RATE: Process_outputRate(this, str, attr, buffer, n, this->io_rate_write_bps); return; - case IO_RATE: Process_outputRate(this, str, attr, buffer, n, this->io_rate_read_bps + this->io_rate_write_bps); return; + case RCHAR: Process_colorNumber(str, this->io_rchar, coloring); return; + case WCHAR: Process_colorNumber(str, this->io_wchar, coloring); return; + case SYSCR: Process_colorNumber(str, this->io_syscr, coloring); return; + case SYSCW: Process_colorNumber(str, this->io_syscw, coloring); return; + case RBYTES: Process_colorNumber(str, this->io_read_bytes, coloring); return; + case WBYTES: Process_colorNumber(str, this->io_write_bytes, coloring); return; + case CNCLWB: Process_colorNumber(str, this->io_cancelled_write_bytes, coloring); return; + case IO_READ_RATE: Process_outputRate(str, attr, buffer, n, this->io_rate_read_bps, coloring); return; + case IO_WRITE_RATE: Process_outputRate(str, attr, buffer, n, this->io_rate_write_bps, coloring); return; + case IO_RATE: Process_outputRate(str, attr, buffer, n, this->io_rate_read_bps + this->io_rate_write_bps, coloring); return; #endif #ifdef HAVE_CGROUP case CGROUP: snprintf(buffer, n, "%-10s ", this->cgroup); break; #endif + #ifdef HAVE_OOM + case OOM: snprintf(buffer, n, Process_pidFormat, this->oom); break; + #endif case IO_PRIORITY: { int klass = IOPriority_class(this->ioPriority); if (klass == IOPRIO_CLASS_NONE) { @@ -564,11 +664,16 @@ void Process_delete(Object* cast) { free(this); } +ObjectClass Process_class = { + .extends = Class(Object), + .display = Process_display, + .delete = Process_delete, + .compare = Process_compare +}; + Process* Process_new(struct ProcessList_ *pl) { - Process* this = calloc(sizeof(Process), 1); - Object_setClass(this, PROCESS_CLASS); - ((Object*)this)->display = Process_display; - ((Object*)this)->delete = Process_delete; + Process* this = calloc(1, sizeof(Process)); + Object_setClass(this, Class(Process)); this->pid = 0; this->pl = pl; this->tag = false; @@ -578,6 +683,7 @@ Process* Process_new(struct ProcessList_ *pl) { this->utime = 0; this->stime = 0; this->comm = NULL; + this->basenameOffset = -1; this->indent = 0; #ifdef HAVE_CGROUP this->cgroup = NULL; @@ -781,6 +887,10 @@ int Process_compare(const void* v1, const void* v2) { case CGROUP: return strcmp(p1->cgroup ? p1->cgroup : "", p2->cgroup ? p2->cgroup : ""); #endif + #ifdef HAVE_OOM + case OOM: + return (p1->oom - p2->oom); + #endif case IO_PRIORITY: return Process_effectiveIOPriority(p1) - Process_effectiveIOPriority(p2); default: -- cgit v1.2.3