From 65357c8c46154de4e4eca14075bfe5523bb5fc14 Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Mon, 7 Dec 2020 10:26:01 +0100 Subject: New upstream version 3.0.3 --- solaris/Battery.c | 7 -- solaris/Battery.h | 6 -- solaris/Platform.c | 147 ++++++++++++++++++++--------- solaris/Platform.h | 45 ++++++--- solaris/SolarisCRT.c | 32 ------- solaris/SolarisCRT.h | 13 --- solaris/SolarisProcess.c | 60 ++++++------ solaris/SolarisProcess.h | 10 +- solaris/SolarisProcessList.c | 217 +++++++++++++++++++++++++------------------ solaris/SolarisProcessList.h | 10 +- 10 files changed, 305 insertions(+), 242 deletions(-) delete mode 100644 solaris/Battery.c delete mode 100644 solaris/Battery.h delete mode 100644 solaris/SolarisCRT.c delete mode 100644 solaris/SolarisCRT.h (limited to 'solaris') diff --git a/solaris/Battery.c b/solaris/Battery.c deleted file mode 100644 index 080cf54..0000000 --- a/solaris/Battery.c +++ /dev/null @@ -1,7 +0,0 @@ - -#include "BatteryMeter.h" - -void Battery_getData(double* level, ACPresence* isOnAC) { - *level = -1; - *isOnAC = AC_ERROR; -} diff --git a/solaris/Battery.h b/solaris/Battery.h deleted file mode 100644 index 21a1579..0000000 --- a/solaris/Battery.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef HEADER_Battery -#define HEADER_Battery - -void Battery_getData(double* level, ACPresence* isOnAC); - -#endif diff --git a/solaris/Platform.c b/solaris/Platform.c index 436c9ce..014eaf5 100644 --- a/solaris/Platform.c +++ b/solaris/Platform.c @@ -3,11 +3,12 @@ htop - solaris/Platform.c (C) 2014 Hisham H. Muhammad (C) 2015 David C. Hunt (C) 2017,2018 Guy M. Broome -Released under the GNU GPL, see the COPYING file +Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ #include "Platform.h" +#include "Macros.h" #include "Meter.h" #include "CPUMeter.h" #include "MemoryMeter.h" @@ -15,6 +16,8 @@ in the source distribution for its full text. #include "TasksMeter.h" #include "LoadAverageMeter.h" #include "ClockMeter.h" +#include "DateMeter.h" +#include "DateTimeMeter.h" #include "HostnameMeter.h" #include "UptimeMeter.h" #include "zfs/ZfsArcMeter.h" @@ -81,13 +84,15 @@ const SignalItem Platform_signals[] = { { .name = "41 SIGINFO", .number = 41 }, }; -const unsigned int Platform_numberOfSignals = sizeof(Platform_signals)/sizeof(SignalItem); +const unsigned int Platform_numberOfSignals = ARRAYSIZE(Platform_signals); -ProcessField Platform_defaultFields[] = { PID, LWPID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 }; +ProcessField Platform_defaultFields[] = { PID, LWPID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 }; -MeterClass* Platform_meterTypes[] = { +const MeterClass* const Platform_meterTypes[] = { &CPUMeter_class, &ClockMeter_class, + &DateMeter_class, + &DateTimeMeter_class, &LoadAverageMeter_class, &LoadMeter_class, &MemoryMeter_class, @@ -98,28 +103,43 @@ MeterClass* Platform_meterTypes[] = { &UptimeMeter_class, &AllCPUsMeter_class, &AllCPUs2Meter_class, + &AllCPUs4Meter_class, + &AllCPUs8Meter_class, &LeftCPUsMeter_class, &RightCPUsMeter_class, &LeftCPUs2Meter_class, &RightCPUs2Meter_class, + &LeftCPUs4Meter_class, + &RightCPUs4Meter_class, + &LeftCPUs8Meter_class, + &RightCPUs8Meter_class, &ZfsArcMeter_class, &ZfsCompressedArcMeter_class, &BlankMeter_class, NULL }; -void Platform_setBindings(Htop_Action* keys) { - (void) keys; -} - int Platform_numberOfFields = LAST_PROCESSFIELD; extern char Process_pidFormat[20]; +void Platform_init(void) { + /* no platform-specific setup needed */ +} + +void Platform_done(void) { + /* no platform-specific cleanup needed */ +} + +void Platform_setBindings(Htop_Action* keys) { + /* no platform-specific key bindings */ + (void) keys; +} + int Platform_getUptime() { int boot_time = 0; int curr_time = time(NULL); - struct utmpx * ent; + struct utmpx* ent; while (( ent = getutxent() )) { if ( !strcmp("system boot", ent->ut_line )) { @@ -129,7 +149,7 @@ int Platform_getUptime() { endutxent(); - return (curr_time-boot_time); + return (curr_time - boot_time); } void Platform_getLoadAverage(double* one, double* five, double* fifteen) { @@ -140,31 +160,35 @@ void Platform_getLoadAverage(double* one, double* five, double* fifteen) { } int Platform_getMaxPid() { - kstat_ctl_t *kc = NULL; - kstat_t *kshandle = NULL; - kvar_t *ksvar = NULL; int vproc = 32778; // Reasonable Solaris default - kc = kstat_open(); - if (kc != NULL) { kshandle = kstat_lookup(kc,"unix",0,"var"); } - if (kshandle != NULL) { kstat_read(kc,kshandle,NULL); } - ksvar = kshandle->ks_data; - if (ksvar->v_proc > 0 ) { - vproc = ksvar->v_proc; + + kstat_ctl_t* kc = kstat_open(); + if (kc != NULL) { + kstat_t* kshandle = kstat_lookup(kc, "unix", 0, "var"); + if (kshandle != NULL) { + kstat_read(kc, kshandle, NULL); + + kvar_t* ksvar = kshandle->ks_data; + if (ksvar && ksvar->v_proc > 0) { + vproc = ksvar->v_proc; + } + } + kstat_close(kc); } - if (kc != NULL) { kstat_close(kc); } + return vproc; } double Platform_setCPUValues(Meter* this, int cpu) { - SolarisProcessList* spl = (SolarisProcessList*) this->pl; + const SolarisProcessList* spl = (const SolarisProcessList*) this->pl; int cpus = this->pl->cpuCount; - CPUData* cpuData = NULL; + const CPUData* cpuData = NULL; if (cpus == 1) { - // single CPU box has everything in spl->cpus[0] - cpuData = &(spl->cpus[0]); + // single CPU box has everything in spl->cpus[0] + cpuData = &(spl->cpus[0]); } else { - cpuData = &(spl->cpus[cpu]); + cpuData = &(spl->cpus[cpu]); } double percent; @@ -175,24 +199,24 @@ double Platform_setCPUValues(Meter* this, int cpu) { if (this->pl->settings->detailedCPUTime) { v[CPU_METER_KERNEL] = cpuData->systemPercent; v[CPU_METER_IRQ] = cpuData->irqPercent; - Meter_setItems(this, 4); - percent = v[0]+v[1]+v[2]+v[3]; + this->curItems = 4; + percent = v[0] + v[1] + v[2] + v[3]; } else { v[2] = cpuData->systemAllPercent; - Meter_setItems(this, 3); - percent = v[0]+v[1]+v[2]; + this->curItems = 3; + percent = v[0] + v[1] + v[2]; } - percent = CLAMP(percent, 0.0, 100.0); - if (isnan(percent)) percent = 0.0; + percent = isnan(percent) ? 0.0 : CLAMP(percent, 0.0, 100.0); - v[CPU_METER_FREQUENCY] = -1; + v[CPU_METER_FREQUENCY] = NAN; + v[CPU_METER_TEMPERATURE] = NAN; return percent; } void Platform_setMemoryValues(Meter* this) { - ProcessList* pl = (ProcessList*) this->pl; + const ProcessList* pl = this->pl; this->total = pl->totalMem; this->values[0] = pl->usedMem; this->values[1] = pl->buffersMem; @@ -200,32 +224,34 @@ void Platform_setMemoryValues(Meter* this) { } void Platform_setSwapValues(Meter* this) { - ProcessList* pl = (ProcessList*) this->pl; + const ProcessList* pl = this->pl; this->total = pl->totalSwap; this->values[0] = pl->usedSwap; } void Platform_setZfsArcValues(Meter* this) { - SolarisProcessList* spl = (SolarisProcessList*) this->pl; + const SolarisProcessList* spl = (const SolarisProcessList*) this->pl; ZfsArcMeter_readStats(this, &(spl->zfs)); } void Platform_setZfsCompressedArcValues(Meter* this) { - SolarisProcessList* spl = (SolarisProcessList*) this->pl; + const SolarisProcessList* spl = (const SolarisProcessList*) this->pl; ZfsCompressedArcMeter_readStats(this, &(spl->zfs)); } -static int Platform_buildenv(void *accum, struct ps_prochandle *Phandle, uintptr_t addr, const char *str) { - envAccum *accump = accum; +static int Platform_buildenv(void* accum, struct ps_prochandle* Phandle, uintptr_t addr, const char* str) { + envAccum* accump = accum; (void) Phandle; (void) addr; size_t thissz = strlen(str); - if ((thissz + 2) > (accump->capacity - accump->size)) + if ((thissz + 2) > (accump->capacity - accump->size)) { accump->env = xRealloc(accump->env, accump->capacity *= 2); - if ((thissz + 2) > (accump->capacity - accump->size)) + } + if ((thissz + 2) > (accump->capacity - accump->size)) { return 1; + } strlcpy( accump->env + accump->size, str, (accump->capacity - accump->size)); strncpy( accump->env + accump->size + thissz + 1, "\n", 1); accump->size = accump->size + thissz + 1; @@ -236,19 +262,54 @@ char* Platform_getProcessEnv(pid_t pid) { envAccum envBuilder; pid_t realpid = pid / 1024; int graberr; - struct ps_prochandle *Phandle; + struct ps_prochandle* Phandle; - if ((Phandle = Pgrab(realpid,PGRAB_RDONLY,&graberr)) == NULL) + if ((Phandle = Pgrab(realpid, PGRAB_RDONLY, &graberr)) == NULL) { return "Unable to read process environment."; + } envBuilder.capacity = 4096; envBuilder.size = 0; envBuilder.env = xMalloc(envBuilder.capacity); - (void) Penv_iter(Phandle,Platform_buildenv,&envBuilder); + (void) Penv_iter(Phandle, Platform_buildenv, &envBuilder); Prelease(Phandle, 0); strncpy( envBuilder.env + envBuilder.size, "\0", 1); return envBuilder.env; } + +char* Platform_getInodeFilename(pid_t pid, ino_t inode) { + (void)pid; + (void)inode; + return NULL; +} + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { + (void)pid; + return NULL; +} + +bool Platform_getDiskIO(DiskIOData* data) { + // TODO + (void)data; + return false; +} + +bool Platform_getNetworkIO(unsigned long int* bytesReceived, + unsigned long int* packetsReceived, + unsigned long int* bytesTransmitted, + unsigned long int* packetsTransmitted) { + // TODO + *bytesReceived = 0; + *packetsReceived = 0; + *bytesTransmitted = 0; + *packetsTransmitted = 0; + return false; +} + +void Platform_getBattery(double* percent, ACPresence* isOnAC) { + *percent = NAN; + *isOnAC = AC_ERROR; +} diff --git a/solaris/Platform.h b/solaris/Platform.h index dd8614d..c338115 100644 --- a/solaris/Platform.h +++ b/solaris/Platform.h @@ -5,17 +5,23 @@ htop - solaris/Platform.h (C) 2014 Hisham H. Muhammad (C) 2015 David C. Hunt (C) 2017,2018 Guy M. Broome -Released under the GNU GPL, see the COPYING file +Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ -#include "Action.h" -#include "BatteryMeter.h" -#include "SignalsPanel.h" +#include #include +#include #include #include -#include +#include + +#include "Action.h" +#include "BatteryMeter.h" +#include "DiskIOMeter.h" +#include "ProcessLocksScreen.h" +#include "SignalsPanel.h" + #define kill(pid, signal) kill(pid / 1024, signal) @@ -26,7 +32,7 @@ typedef struct envAccum_ { size_t capacity; size_t size; size_t bytes; - char *env; + char* env; } envAccum; extern double plat_loadavg[3]; @@ -37,19 +43,23 @@ extern const unsigned int Platform_numberOfSignals; extern ProcessField Platform_defaultFields[]; -extern MeterClass* Platform_meterTypes[]; - -void Platform_setBindings(Htop_Action* keys); +extern const MeterClass* const Platform_meterTypes[]; extern int Platform_numberOfFields; extern char Process_pidFormat[20]; -int Platform_getUptime(); +void Platform_init(void); + +void Platform_done(void); + +void Platform_setBindings(Htop_Action* keys); + +int Platform_getUptime(void); void Platform_getLoadAverage(double* one, double* five, double* fifteen); -int Platform_getMaxPid(); +int Platform_getMaxPid(void); double Platform_setCPUValues(Meter* this, int cpu); @@ -63,4 +73,17 @@ void Platform_setZfsCompressedArcValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); +char* Platform_getInodeFilename(pid_t pid, ino_t inode); + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid); + +bool Platform_getDiskIO(DiskIOData* data); + +bool Platform_getNetworkIO(unsigned long int* bytesReceived, + unsigned long int* packetsReceived, + unsigned long int* bytesTransmitted, + unsigned long int* packetsTransmitted); + +void Platform_getBattery(double* percent, ACPresence* isOnAC); + #endif diff --git a/solaris/SolarisCRT.c b/solaris/SolarisCRT.c deleted file mode 100644 index 13e82d7..0000000 --- a/solaris/SolarisCRT.c +++ /dev/null @@ -1,32 +0,0 @@ -/* -htop - SolarisCRT.c -(C) 2014 Hisham H. Muhammad -(C) 2018 Guy M. Broome -Released under the GNU GPL, see the COPYING file -in the source distribution for its full text. -*/ - -#include "config.h" -#include "CRT.h" -#include -#include -#ifdef HAVE_EXECINFO_H -#include -#endif - -void CRT_handleSIGSEGV(int sgn) { - (void) sgn; - CRT_done(); - fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at https://htop.dev\n"); - #ifdef HAVE_EXECINFO_H - size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *)); - fprintf(stderr, "\n Please include in your report the following backtrace: \n"); - backtrace_symbols_fd(backtraceArray, size, 2); - fprintf(stderr, "\nAdditionally, in order to make the above backtrace useful,"); - fprintf(stderr, "\nplease also run the following command to generate a disassembly of your binary:"); - fprintf(stderr, "\n\n objdump -d `which htop` > ~/htop.objdump"); - fprintf(stderr, "\n\nand then attach the file ~/htop.objdump to your bug report."); - fprintf(stderr, "\n\nThank you for helping to improve htop!\n\n"); - #endif - abort(); -} diff --git a/solaris/SolarisCRT.h b/solaris/SolarisCRT.h deleted file mode 100644 index 4e37b7f..0000000 --- a/solaris/SolarisCRT.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef HEADER_SolarisCRT -#define HEADER_SolarisCRT -/* -htop - SolarisCRT.h -(C) 2014 Hisham H. Muhammad -(C) 2018 Guy M. Broome -Released under the GNU GPL, see the COPYING file -in the source distribution for its full text. -*/ - -void CRT_handleSIGSEGV(int sgn); - -#endif diff --git a/solaris/SolarisProcess.c b/solaris/SolarisProcess.c index ab0bcab..e0a3db2 100644 --- a/solaris/SolarisProcess.c +++ b/solaris/SolarisProcess.c @@ -2,7 +2,7 @@ htop - SolarisProcess.c (C) 2015 Hisham H. Muhammad (C) 2017,2018 Guy M. Broome -Released under the GNU GPL, see the COPYING file +Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ @@ -18,14 +18,14 @@ in the source distribution for its full text. #include -ProcessClass SolarisProcess_class = { +const ProcessClass SolarisProcess_class = { .super = { .extends = Class(Process), .display = Process_display, .delete = Process_delete, .compare = SolarisProcess_compare }, - .writeField = (Process_WriteField) SolarisProcess_writeField, + .writeField = SolarisProcess_writeField, }; ProcessFieldData Process_fields[] = { @@ -44,10 +44,11 @@ ProcessFieldData Process_fields[] = { [NICE] = { .name = "NICE", .title = " NI ", .description = "Nice value (the higher the value, the more it lets other processes take priority)", .flags = 0, }, [STARTTIME] = { .name = "STARTTIME", .title = "START ", .description = "Time the process was started", .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_VIRT] = { .name = "M_VIRT", .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, }, [ST_UID] = { .name = "ST_UID", .title = " UID ", .description = "User ID of the process owner", .flags = 0, }, [PERCENT_CPU] = { .name = "PERCENT_CPU", .title = "CPU% ", .description = "Percentage of the CPU time the process used in the last sampling", .flags = 0, }, + [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, }, [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, }, @@ -79,11 +80,11 @@ ProcessPidColumn Process_pidColumns[] = { { .id = 0, .label = NULL }, }; -SolarisProcess* SolarisProcess_new(Settings* settings) { +Process* SolarisProcess_new(const Settings* settings) { SolarisProcess* this = xCalloc(1, sizeof(SolarisProcess)); Object_setClass(this, Class(SolarisProcess)); Process_init(&this->super, settings); - return this; + return &this->super; } void Process_delete(Object* cast) { @@ -93,8 +94,8 @@ void Process_delete(Object* cast) { free(sp); } -void SolarisProcess_writeField(Process* this, RichString* str, ProcessField field) { - SolarisProcess* sp = (SolarisProcess*) this; +void SolarisProcess_writeField(const Process* this, RichString* str, ProcessField field) { + const SolarisProcess* sp = (const SolarisProcess*) this; char buffer[256]; buffer[255] = '\0'; int attr = CRT_colors[DEFAULT_COLOR]; int n = sizeof(buffer) - 1; @@ -105,14 +106,7 @@ void SolarisProcess_writeField(Process* this, RichString* str, ProcessField fiel case TASKID: xSnprintf(buffer, n, Process_pidFormat, sp->taskid); break; case POOLID: xSnprintf(buffer, n, Process_pidFormat, sp->poolid); break; case CONTID: xSnprintf(buffer, n, Process_pidFormat, sp->contid); break; - case ZONE:{ - xSnprintf(buffer, n, "%-*s ", ZONENAME_MAX/4, sp->zname); break; - if (buffer[ZONENAME_MAX/4] != '\0') { - buffer[ZONENAME_MAX/4] = ' '; - buffer[(ZONENAME_MAX/4)+1] = '\0'; - } - break; - } + case ZONE: xSnprintf(buffer, n, "%-*s ", ZONENAME_MAX/4, sp->zname); break; case PID: xSnprintf(buffer, n, Process_pidFormat, sp->realpid); break; case PPID: xSnprintf(buffer, n, Process_pidFormat, sp->realppid); break; case LWPID: xSnprintf(buffer, n, Process_pidFormat, sp->lwpid); break; @@ -124,41 +118,43 @@ void SolarisProcess_writeField(Process* this, RichString* str, ProcessField fiel } long SolarisProcess_compare(const void* v1, const void* v2) { - SolarisProcess *p1, *p2; - Settings* settings = ((Process*)v1)->settings; + const SolarisProcess *p1, *p2; + const Settings* settings = ((const Process*)v1)->settings; + if (settings->direction == 1) { - p1 = (SolarisProcess*)v1; - p2 = (SolarisProcess*)v2; + p1 = (const SolarisProcess*)v1; + p2 = (const SolarisProcess*)v2; } else { - p2 = (SolarisProcess*)v1; - p1 = (SolarisProcess*)v2; + p2 = (const SolarisProcess*)v1; + p1 = (const SolarisProcess*)v2; } + switch ((int) settings->sortKey) { case ZONEID: - return (p1->zoneid - p2->zoneid); + return SPACESHIP_NUMBER(p1->zoneid, p2->zoneid); case PROJID: - return (p1->projid - p2->projid); + return SPACESHIP_NUMBER(p1->projid, p2->projid); case TASKID: - return (p1->taskid - p2->taskid); + return SPACESHIP_NUMBER(p1->taskid, p2->taskid); case POOLID: - return (p1->poolid - p2->poolid); + return SPACESHIP_NUMBER(p1->poolid, p2->poolid); case CONTID: - return (p1->contid - p2->contid); + return SPACESHIP_NUMBER(p1->contid, p2->contid); case ZONE: return strcmp(p1->zname ? p1->zname : "global", p2->zname ? p2->zname : "global"); case PID: - return (p1->realpid - p2->realpid); + return SPACESHIP_NUMBER(p1->realpid, p2->realpid); case PPID: - return (p1->realppid - p2->realppid); + return SPACESHIP_NUMBER(p1->realppid, p2->realppid); case LWPID: - return (p1->lwpid - p2->lwpid); + return SPACESHIP_NUMBER(p1->lwpid, p2->lwpid); default: return Process_compare(v1, v2); } } -bool Process_isThread(Process* this) { - SolarisProcess* fp = (SolarisProcess*) this; +bool Process_isThread(const Process* this) { + const SolarisProcess* fp = (const SolarisProcess*) this; if (fp->kernel == 1 ) { return 1; diff --git a/solaris/SolarisProcess.h b/solaris/SolarisProcess.h index d36dea3..4756634 100644 --- a/solaris/SolarisProcess.h +++ b/solaris/SolarisProcess.h @@ -4,7 +4,7 @@ htop - SolarisProcess.h (C) 2015 Hisham H. Muhammad (C) 2017,2018 Guy M. Broome -Released under the GNU GPL, see the COPYING file +Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ @@ -44,20 +44,20 @@ typedef struct SolarisProcess_ { #define Process_isUserlandThread(_process) (_process->pid != _process->tgid) -extern ProcessClass SolarisProcess_class; +extern const ProcessClass SolarisProcess_class; extern ProcessFieldData Process_fields[]; extern ProcessPidColumn Process_pidColumns[]; -SolarisProcess* SolarisProcess_new(Settings* settings); +Process* SolarisProcess_new(const Settings* settings); void Process_delete(Object* cast); -void SolarisProcess_writeField(Process* this, RichString* str, ProcessField field); +void SolarisProcess_writeField(const Process* this, RichString* str, ProcessField field); long SolarisProcess_compare(const void* v1, const void* v2); -bool Process_isThread(Process* this); +bool Process_isThread(const Process* this); #endif diff --git a/solaris/SolarisProcessList.c b/solaris/SolarisProcessList.c index 4e4d282..4249fa6 100644 --- a/solaris/SolarisProcessList.c +++ b/solaris/SolarisProcessList.c @@ -2,7 +2,7 @@ htop - SolarisProcessList.c (C) 2014 Hisham H. Muhammad (C) 2017,2018 Guy M. Broome -Released under the GNU GPL, see the COPYING file +Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ @@ -23,19 +23,24 @@ in the source distribution for its full text. #include #include +#include "CRT.h" + + #define MAXCMDLINE 255 char* SolarisProcessList_readZoneName(kstat_ctl_t* kd, SolarisProcess* sproc) { - char* zname; - if ( sproc->zoneid == 0 ) { - zname = xStrdup(GZONE); - } else if ( kd == NULL ) { - zname = xStrdup(UZONE); - } else { - kstat_t* ks = kstat_lookup( kd, "zones", sproc->zoneid, NULL ); - zname = xStrdup(ks == NULL ? UZONE : ks->ks_name); - } - return zname; + char* zname; + + if ( sproc->zoneid == 0 ) { + zname = xStrdup(GZONE); + } else if ( kd == NULL ) { + zname = xStrdup(UZONE); + } else { + kstat_t* ks = kstat_lookup( kd, "zones", sproc->zoneid, NULL ); + zname = xStrdup(ks == NULL ? UZONE : ks->ks_name); + } + + return zname; } ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { @@ -59,46 +64,51 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui static inline void SolarisProcessList_scanCPUTime(ProcessList* pl) { const SolarisProcessList* spl = (SolarisProcessList*) pl; int cpus = pl->cpuCount; - kstat_t *cpuinfo = NULL; + kstat_t* cpuinfo = NULL; int kchain = 0; - kstat_named_t *idletime = NULL; - kstat_named_t *intrtime = NULL; - kstat_named_t *krnltime = NULL; - kstat_named_t *usertime = NULL; + kstat_named_t* idletime = NULL; + kstat_named_t* intrtime = NULL; + kstat_named_t* krnltime = NULL; + kstat_named_t* usertime = NULL; double idlebuf = 0; double intrbuf = 0; double krnlbuf = 0; double userbuf = 0; - uint64_t totaltime = 0; int arrskip = 0; assert(cpus > 0); if (cpus > 1) { - // Store values for the stats loop one extra element up in the array - // to leave room for the average to be calculated afterwards - arrskip++; + // Store values for the stats loop one extra element up in the array + // to leave room for the average to be calculated afterwards + arrskip++; } // Calculate per-CPU statistics first for (int i = 0; i < cpus; i++) { - if (spl->kd != NULL) { cpuinfo = kstat_lookup(spl->kd,"cpu",i,"sys"); } - if (cpuinfo != NULL) { kchain = kstat_read(spl->kd,cpuinfo,NULL); } + if (spl->kd != NULL) { + cpuinfo = kstat_lookup(spl->kd, "cpu", i, "sys"); + } + if (cpuinfo != NULL) { + kchain = kstat_read(spl->kd, cpuinfo, NULL); + } if (kchain != -1 ) { - idletime = kstat_data_lookup(cpuinfo,"cpu_nsec_idle"); - intrtime = kstat_data_lookup(cpuinfo,"cpu_nsec_intr"); - krnltime = kstat_data_lookup(cpuinfo,"cpu_nsec_kernel"); - usertime = kstat_data_lookup(cpuinfo,"cpu_nsec_user"); + idletime = kstat_data_lookup(cpuinfo, "cpu_nsec_idle"); + intrtime = kstat_data_lookup(cpuinfo, "cpu_nsec_intr"); + krnltime = kstat_data_lookup(cpuinfo, "cpu_nsec_kernel"); + usertime = kstat_data_lookup(cpuinfo, "cpu_nsec_user"); } assert( (idletime != NULL) && (intrtime != NULL) && (krnltime != NULL) && (usertime != NULL) ); - CPUData* cpuData = &(spl->cpus[i+arrskip]); - totaltime = (idletime->value.ui64 - cpuData->lidle) - + (intrtime->value.ui64 - cpuData->lintr) - + (krnltime->value.ui64 - cpuData->lkrnl) - + (usertime->value.ui64 - cpuData->luser); + CPUData* cpuData = &(spl->cpus[i + arrskip]); + + uint64_t totaltime = (idletime->value.ui64 - cpuData->lidle) + + (intrtime->value.ui64 - cpuData->lintr) + + (krnltime->value.ui64 - cpuData->lkrnl) + + (usertime->value.ui64 - cpuData->luser); + // Calculate percentages of deltas since last reading cpuData->userPercent = ((usertime->value.ui64 - cpuData->luser) / (double)totaltime) * 100.0; cpuData->nicePercent = (double)0.0; // Not implemented on Solaris @@ -133,10 +143,10 @@ static inline void SolarisProcessList_scanCPUTime(ProcessList* pl) { static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) { SolarisProcessList* spl = (SolarisProcessList*) pl; - kstat_t *meminfo = NULL; + static kstat_t *meminfo = NULL; int ksrphyserr = -1; kstat_named_t *totalmem_pgs = NULL; - kstat_named_t *lockedmem_pgs = NULL; + kstat_named_t *freemem_pgs = NULL; kstat_named_t *pages = NULL; struct swaptable *sl = NULL; struct swapent *swapdev = NULL; @@ -147,32 +157,45 @@ static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) { char *spathbase = NULL; // Part 1 - physical memory - if (spl->kd != NULL) { meminfo = kstat_lookup(spl->kd,"unix",0,"system_pages"); } - if (meminfo != NULL) { ksrphyserr = kstat_read(spl->kd,meminfo,NULL); } + if (spl->kd != NULL && meminfo == NULL) { + // Look up the kstat chain just one, it never changes + meminfo = kstat_lookup(spl->kd, "unix", 0, "system_pages"); + } + if (meminfo != NULL) { + ksrphyserr = kstat_read(spl->kd, meminfo, NULL); + } if (ksrphyserr != -1) { - totalmem_pgs = kstat_data_lookup( meminfo, "physmem" ); - lockedmem_pgs = kstat_data_lookup( meminfo, "pageslocked" ); - pages = kstat_data_lookup( meminfo, "pagestotal" ); + totalmem_pgs = kstat_data_lookup(meminfo, "physmem"); + freemem_pgs = kstat_data_lookup(meminfo, "freemem"); + pages = kstat_data_lookup(meminfo, "pagestotal"); - pl->totalMem = totalmem_pgs->value.ui64 * PAGE_SIZE_KB; - pl->usedMem = lockedmem_pgs->value.ui64 * PAGE_SIZE_KB; + pl->totalMem = totalmem_pgs->value.ui64 * CRT_pageSizeKB; + if (pl->totalMem > freemem_pgs->value.ui64 * CRT_pageSizeKB) { + pl->usedMem = pl->totalMem - freemem_pgs->value.ui64 * CRT_pageSizeKB; + } else { + pl->usedMem = 0; // This can happen in non-global zone (in theory) + } // Not sure how to implement this on Solaris - suggestions welcome! pl->cachedMem = 0; // Not really "buffers" but the best Solaris analogue that I can find to // "memory in use but not by programs or the kernel itself" - pl->buffersMem = (totalmem_pgs->value.ui64 - pages->value.ui64) * PAGE_SIZE_KB; - } else { + pl->buffersMem = (totalmem_pgs->value.ui64 - pages->value.ui64) * CRT_pageSizeKB; + } else { // Fall back to basic sysconf if kstat isn't working - pl->totalMem = sysconf(_SC_PHYS_PAGES) * PAGE_SIZE; + pl->totalMem = sysconf(_SC_PHYS_PAGES) * CRT_pageSize; pl->buffersMem = 0; pl->cachedMem = 0; - pl->usedMem = pl->totalMem - (sysconf(_SC_AVPHYS_PAGES) * PAGE_SIZE); + pl->usedMem = pl->totalMem - (sysconf(_SC_AVPHYS_PAGES) * CRT_pageSize); } // Part 2 - swap nswap = swapctl(SC_GETNSWP, NULL); - if (nswap > 0) { sl = xMalloc((nswap * sizeof(swapent_t)) + sizeof(int)); } - if (sl != NULL) { spathbase = xMalloc( nswap * MAXPATHLEN ); } + if (nswap > 0) { + sl = xMalloc((nswap * sizeof(swapent_t)) + sizeof(int)); + } + if (sl != NULL) { + spathbase = xMalloc( nswap * MAXPATHLEN ); + } if (spathbase != NULL) { spath = spathbase; swapdev = sl->swt_ent; @@ -192,8 +215,8 @@ static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) { } free(spathbase); free(sl); - pl->totalSwap = totalswap * PAGE_SIZE_KB; - pl->usedSwap = pl->totalSwap - (totalfree * PAGE_SIZE_KB); + pl->totalSwap = totalswap * CRT_pageSizeKB; + pl->usedSwap = pl->totalSwap - (totalfree * CRT_pageSizeKB); } static inline void SolarisProcessList_scanZfsArcstats(ProcessList* pl) { @@ -202,8 +225,12 @@ static inline void SolarisProcessList_scanZfsArcstats(ProcessList* pl) { int ksrphyserr = -1; kstat_named_t *cur_kstat = NULL; - if (spl->kd != NULL) { arcstats = kstat_lookup(spl->kd,"zfs",0,"arcstats"); } - if (arcstats != NULL) { ksrphyserr = kstat_read(spl->kd,arcstats,NULL); } + if (spl->kd != NULL) { + arcstats = kstat_lookup(spl->kd, "zfs", 0, "arcstats"); + } + if (arcstats != NULL) { + ksrphyserr = kstat_read(spl->kd, arcstats, NULL); + } if (ksrphyserr != -1) { cur_kstat = kstat_data_lookup( arcstats, "size" ); spl->zfs.size = cur_kstat->value.ui64 / 1024; @@ -213,19 +240,19 @@ static inline void SolarisProcessList_scanZfsArcstats(ProcessList* pl) { spl->zfs.max = cur_kstat->value.ui64 / 1024; cur_kstat = kstat_data_lookup( arcstats, "mfu_size" ); - spl->zfs.MFU = cur_kstat->value.ui64 / 1024; + spl->zfs.MFU = cur_kstat != NULL ? cur_kstat->value.ui64 / 1024 : 0; cur_kstat = kstat_data_lookup( arcstats, "mru_size" ); - spl->zfs.MRU = cur_kstat->value.ui64 / 1024; + spl->zfs.MRU = cur_kstat != NULL ? cur_kstat->value.ui64 / 1024 : 0; cur_kstat = kstat_data_lookup( arcstats, "anon_size" ); - spl->zfs.anon = cur_kstat->value.ui64 / 1024; + spl->zfs.anon = cur_kstat != NULL ? cur_kstat->value.ui64 / 1024 : 0; cur_kstat = kstat_data_lookup( arcstats, "hdr_size" ); - spl->zfs.header = cur_kstat->value.ui64 / 1024; + spl->zfs.header = cur_kstat != NULL ? cur_kstat->value.ui64 / 1024 : 0; cur_kstat = kstat_data_lookup( arcstats, "other_size" ); - spl->zfs.other = cur_kstat->value.ui64 / 1024; + spl->zfs.other = cur_kstat != NULL ? cur_kstat->value.ui64 / 1024 : 0; if ((cur_kstat = kstat_data_lookup( arcstats, "compressed_size" )) != NULL) { spl->zfs.compressed = cur_kstat->value.ui64 / 1024; @@ -243,7 +270,9 @@ void ProcessList_delete(ProcessList* pl) { SolarisProcessList* spl = (SolarisProcessList*) pl; ProcessList_done(pl); free(spl->cpus); - if (spl->kd) kstat_close(spl->kd); + if (spl->kd) { + kstat_close(spl->kd); + } free(spl); } @@ -253,18 +282,19 @@ void ProcessList_delete(ProcessList* pl) { * system for more info. */ -int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void *listptr) { - struct timeval tv; - struct tm date; +int SolarisProcessList_walkproc(psinfo_t* _psinfo, lwpsinfo_t* _lwpsinfo, void* listptr) { bool preExisting; pid_t getpid; // Setup process list - ProcessList *pl = (ProcessList*) listptr; - SolarisProcessList *spl = (SolarisProcessList*) listptr; + ProcessList* pl = (ProcessList*) listptr; + SolarisProcessList* spl = (SolarisProcessList*) listptr; id_t lwpid_real = _lwpsinfo->pr_lwpid; - if (lwpid_real > 1023) return 0; + if (lwpid_real > 1023) { + return 0; + } + pid_t lwpid = (_psinfo->pr_pid * 1024) + lwpid_real; bool onMasterLWP = (_lwpsinfo->pr_lwpid == _psinfo->pr_lwp.pr_lwpid); if (onMasterLWP) { @@ -272,10 +302,8 @@ int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void * } else { getpid = lwpid; } - Process *proc = ProcessList_getProcess(pl, getpid, &preExisting, (Process_New) SolarisProcess_new); - SolarisProcess *sproc = (SolarisProcess*) proc; - - gettimeofday(&tv, NULL); + Process* proc = ProcessList_getProcess(pl, getpid, &preExisting, SolarisProcess_new); + SolarisProcess* sproc = (SolarisProcess*) proc; // Common code pass 1 proc->show = false; @@ -290,22 +318,22 @@ int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void * // NOTE: This 'percentage' is a 16-bit BINARY FRACTIONS where 1.0 = 0x8000 // Source: https://docs.oracle.com/cd/E19253-01/816-5174/proc-4/index.html // (accessed on 18 November 2017) - proc->percent_mem = ((uint16_t)_psinfo->pr_pctmem/(double)32768)*(double)100.0; + proc->percent_mem = ((uint16_t)_psinfo->pr_pctmem / (double)32768) * (double)100.0; proc->st_uid = _psinfo->pr_euid; proc->pgrp = _psinfo->pr_pgid; proc->nlwp = _psinfo->pr_nlwp; proc->tty_nr = _psinfo->pr_ttydev; - proc->m_resident = _psinfo->pr_rssize/PAGE_SIZE_KB; - proc->m_size = _psinfo->pr_size/PAGE_SIZE_KB; + proc->m_resident = _psinfo->pr_rssize / CRT_pageSizeKB; + proc->m_virt = _psinfo->pr_size / CRT_pageSizeKB; if (!preExisting) { sproc->realpid = _psinfo->pr_pid; sproc->lwpid = lwpid_real; sproc->zoneid = _psinfo->pr_zoneid; - sproc->zname = SolarisProcessList_readZoneName(spl->kd,sproc); + sproc->zname = SolarisProcessList_readZoneName(spl->kd, sproc); proc->user = UsersTable_getRef(pl->usersTable, proc->st_uid); proc->comm = xStrdup(_psinfo->pr_fname); - proc->commLen = strnlen(_psinfo->pr_fname,PRFNSZ); + proc->commLen = strnlen(_psinfo->pr_fname, PRFNSZ); } // End common code pass 1 @@ -315,9 +343,9 @@ int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void * proc->tgid = (_psinfo->pr_ppid * 1024); sproc->realppid = _psinfo->pr_ppid; // See note above (in common section) about this BINARY FRACTION - proc->percent_cpu = ((uint16_t)_psinfo->pr_pctcpu/(double)32768)*(double)100.0; + proc->percent_cpu = ((uint16_t)_psinfo->pr_pctcpu / (double)32768) * (double)100.0; proc->time = _psinfo->pr_time.tv_sec; - if(!preExisting) { // Tasks done only for NEW processes + if (!preExisting) { // Tasks done only for NEW processes sproc->is_lwp = false; proc->starttime_ctime = _psinfo->pr_start.tv_sec; } @@ -325,20 +353,24 @@ int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void * // Update proc and thread counts based on settings if (sproc->kernel && !pl->settings->hideKernelThreads) { pl->kernelThreads += proc->nlwp; - pl->totalTasks += proc->nlwp+1; - if (proc->state == 'O') pl->runningTasks++; + pl->totalTasks += proc->nlwp + 1; + if (proc->state == 'O') { + pl->runningTasks++; + } } else if (!sproc->kernel) { - if (proc->state == 'O') pl->runningTasks++; + if (proc->state == 'O') { + pl->runningTasks++; + } if (pl->settings->hideUserlandThreads) { pl->totalTasks++; } else { pl->userlandThreads += proc->nlwp; - pl->totalTasks += proc->nlwp+1; + pl->totalTasks += proc->nlwp + 1; } } proc->show = !(pl->settings->hideKernelThreads && sproc->kernel); } else { // We are not in the master LWP, so jump to the LWP handling code - proc->percent_cpu = ((uint16_t)_lwpsinfo->pr_pctcpu/(double)32768)*(double)100.0; + proc->percent_cpu = ((uint16_t)_lwpsinfo->pr_pctcpu / (double)32768) * (double)100.0; proc->time = _lwpsinfo->pr_time.tv_sec; if (!preExisting) { // Tasks done only for NEW LWPs sproc->is_lwp = true; @@ -350,8 +382,12 @@ int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void * } // Top-level process only gets this for the representative LWP - if (sproc->kernel && !pl->settings->hideKernelThreads) proc->show = true; - if (!sproc->kernel && !pl->settings->hideUserlandThreads) proc->show = true; + if (sproc->kernel && !pl->settings->hideKernelThreads) { + proc->show = true; + } + if (!sproc->kernel && !pl->settings->hideUserlandThreads) { + proc->show = true; + } } // Top-level LWP or subordinate LWP // Common code pass 2 @@ -362,8 +398,7 @@ int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void * } else { sproc->kernel = false; } - (void) localtime_r((time_t*) &proc->starttime_ctime, &date); - strftime(proc->starttime_show, 7, ((proc->starttime_ctime > tv.tv_sec - 86400) ? "%R " : "%b%d "), &date); + Process_fillStarttimeBuffer(proc); ProcessList_add(pl, proc); } proc->updated = true; @@ -373,10 +408,16 @@ int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void * return 0; } -void ProcessList_goThroughEntries(ProcessList* this) { - SolarisProcessList_scanCPUTime(this); - SolarisProcessList_scanMemoryInfo(this); - SolarisProcessList_scanZfsArcstats(this); - this->kernelThreads = 1; - proc_walk(&SolarisProcessList_walkproc, this, PR_WALK_LWP); +void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { + SolarisProcessList_scanCPUTime(super); + SolarisProcessList_scanMemoryInfo(super); + SolarisProcessList_scanZfsArcstats(super); + + // in pause mode only gather global data for meters (CPU/memory/...) + if (pauseProcessUpdate) { + return; + } + + super->kernelThreads = 1; + proc_walk(&SolarisProcessList_walkproc, super, PR_WALK_LWP); } diff --git a/solaris/SolarisProcessList.h b/solaris/SolarisProcessList.h index 9da39b4..f800d9d 100644 --- a/solaris/SolarisProcessList.h +++ b/solaris/SolarisProcessList.h @@ -4,14 +4,14 @@ htop - SolarisProcessList.h (C) 2014 Hisham H. Muhammad (C) 2017,2018 Guy M. Broome -Released under the GNU GPL, see the COPYING file +Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ #define MAXCMDLINE 255 -#define GZONE "global " -#define UZONE "unknown " +#define GZONE "global " +#define UZONE "unknown " #include "zfs/ZfsArcStats.h" @@ -58,8 +58,8 @@ void ProcessList_delete(ProcessList* pl); * system for more info. */ -int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void *listptr); +int SolarisProcessList_walkproc(psinfo_t* _psinfo, lwpsinfo_t* _lwpsinfo, void* listptr); -void ProcessList_goThroughEntries(ProcessList* this); +void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate); #endif -- cgit v1.2.3