mirror of
https://github.com/xzeldon/htop.git
synced 2024-12-23 22:55:46 +00:00
Major advances in FreeBSD port.
This commit is contained in:
parent
9ff5d2b243
commit
272e2d9b34
27
Process.c
27
Process.c
@ -6,8 +6,8 @@ in the source distribution for its full text.
|
||||
*/
|
||||
|
||||
#include "Process.h"
|
||||
|
||||
#include "Settings.h"
|
||||
|
||||
#include "CRT.h"
|
||||
#include "String.h"
|
||||
#include "RichString.h"
|
||||
@ -55,6 +55,7 @@ typedef enum ProcessFields {
|
||||
PRIORITY = 18,
|
||||
NICE = 19,
|
||||
STARTTIME = 21,
|
||||
PROCESSOR = 38,
|
||||
M_SIZE = 39,
|
||||
M_RESIDENT = 40,
|
||||
ST_UID = 46,
|
||||
@ -91,6 +92,7 @@ typedef struct Process_ {
|
||||
int tpgid;
|
||||
uid_t st_uid;
|
||||
unsigned long int flags;
|
||||
int processor;
|
||||
|
||||
float percent_cpu;
|
||||
float percent_mem;
|
||||
@ -147,6 +149,8 @@ extern ProcessFieldData Process_fields[];
|
||||
extern char* Process_pidFormat;
|
||||
extern char* Process_tpgidFormat;
|
||||
|
||||
typedef Process*(*Process_new_fn)(struct Settings_*);
|
||||
|
||||
}*/
|
||||
|
||||
static int Process_getuid = -1;
|
||||
@ -234,19 +238,13 @@ void Process_colorNumber(RichString* str, unsigned long long number, bool colori
|
||||
}
|
||||
}
|
||||
|
||||
static double jiffy = 0.0;
|
||||
void Process_printTime(RichString* str, unsigned long long totalHundredths) {
|
||||
unsigned long long totalSeconds = totalHundredths / 100;
|
||||
|
||||
void Process_printTime(RichString* str, unsigned long long t) {
|
||||
if(jiffy == 0.0) jiffy = sysconf(_SC_CLK_TCK);
|
||||
double jiffytime = 1.0 / jiffy;
|
||||
|
||||
double realTime = t * jiffytime;
|
||||
unsigned long long iRealTime = (unsigned long long) realTime;
|
||||
|
||||
unsigned long long hours = iRealTime / 3600;
|
||||
int minutes = (iRealTime / 60) % 60;
|
||||
int seconds = iRealTime % 60;
|
||||
int hundredths = (realTime - iRealTime) * 100;
|
||||
unsigned long long hours = totalSeconds / 3600;
|
||||
int minutes = (totalSeconds / 60) % 60;
|
||||
int seconds = totalSeconds % 60;
|
||||
int hundredths = totalHundredths - (totalSeconds * 100);
|
||||
char buffer[11];
|
||||
if (hours >= 100) {
|
||||
snprintf(buffer, 10, "%7lluh ", hours);
|
||||
@ -389,6 +387,7 @@ void Process_writeDefaultField(Process* this, RichString* str, ProcessField fiel
|
||||
snprintf(buffer, n, "%3ld ", this->priority);
|
||||
break;
|
||||
}
|
||||
case PROCESSOR: snprintf(buffer, n, "%3d ", Settings_cpuId(this->settings, this->processor)); break;
|
||||
case SESSION: snprintf(buffer, n, Process_pidFormat, this->session); break;
|
||||
case STARTTIME: snprintf(buffer, n, "%s", this->starttime_show); break;
|
||||
case STATE: {
|
||||
@ -527,6 +526,8 @@ long Process_defaultCompare(const void* v1, const void* v2) {
|
||||
return (p1->ppid - p2->ppid);
|
||||
case PRIORITY:
|
||||
return (p1->priority - p2->priority);
|
||||
case PROCESSOR:
|
||||
return (p1->processor - p2->processor);
|
||||
case SESSION:
|
||||
return (p1->session - p2->session);
|
||||
case STARTTIME: {
|
||||
|
@ -36,6 +36,7 @@ typedef enum ProcessFields {
|
||||
PRIORITY = 18,
|
||||
NICE = 19,
|
||||
STARTTIME = 21,
|
||||
PROCESSOR = 38,
|
||||
M_SIZE = 39,
|
||||
M_RESIDENT = 40,
|
||||
ST_UID = 46,
|
||||
@ -72,6 +73,7 @@ typedef struct Process_ {
|
||||
int tpgid;
|
||||
uid_t st_uid;
|
||||
unsigned long int flags;
|
||||
int processor;
|
||||
|
||||
float percent_cpu;
|
||||
float percent_mem;
|
||||
@ -128,6 +130,8 @@ extern ProcessFieldData Process_fields[];
|
||||
extern char* Process_pidFormat;
|
||||
extern char* Process_tpgidFormat;
|
||||
|
||||
typedef Process*(*Process_new_fn)(struct Settings_*);
|
||||
|
||||
|
||||
#define ONE_K 1024L
|
||||
#define ONE_M (ONE_K * ONE_K)
|
||||
@ -141,7 +145,7 @@ void Process_humanNumber(RichString* str, unsigned long number, bool coloring);
|
||||
|
||||
void Process_colorNumber(RichString* str, unsigned long long number, bool coloring);
|
||||
|
||||
void Process_printTime(RichString* str, unsigned long long t);
|
||||
void Process_printTime(RichString* str, unsigned long long totalHundredths);
|
||||
|
||||
void Process_outputRate(RichString* str, char* buffer, int n, double rate, int coloring);
|
||||
|
||||
|
@ -49,6 +49,11 @@ typedef struct ProcessList_ {
|
||||
bool topologyOk;
|
||||
#endif
|
||||
|
||||
int totalTasks;
|
||||
int runningTasks;
|
||||
int userlandThreads;
|
||||
int kernelThreads;
|
||||
|
||||
unsigned long long int totalMem;
|
||||
unsigned long long int usedMem;
|
||||
unsigned long long int freeMem;
|
||||
@ -65,7 +70,7 @@ typedef struct ProcessList_ {
|
||||
|
||||
ProcessList* ProcessList_new(UsersTable* ut, Hashtable* pidWhiteList, uid_t userId);
|
||||
void ProcessList_delete(ProcessList* pl);
|
||||
void ProcessList_scan(ProcessList* pl);
|
||||
void ProcessList_goThroughEntries(ProcessList* pl);
|
||||
|
||||
}*/
|
||||
|
||||
@ -282,3 +287,40 @@ void ProcessList_rebuildPanel(ProcessList* this) {
|
||||
}
|
||||
}
|
||||
|
||||
Process* ProcessList_getProcess(ProcessList* this, pid_t pid, bool* preExisting, Process_new_fn constructor) {
|
||||
Process* proc = (Process*) Hashtable_get(this->processTable, pid);
|
||||
*preExisting = proc;
|
||||
if (proc) {
|
||||
assert(Vector_indexOf(this->processes, proc, Process_pidCompare) != -1);
|
||||
assert(proc->pid == pid);
|
||||
} else {
|
||||
proc = constructor(this->settings);
|
||||
assert(proc->comm == NULL);
|
||||
proc->pid = pid;
|
||||
}
|
||||
return proc;
|
||||
}
|
||||
|
||||
void ProcessList_scan(ProcessList* this) {
|
||||
|
||||
// mark all process as "dirty"
|
||||
for (int i = 0; i < Vector_size(this->processes); i++) {
|
||||
Process* p = (Process*) Vector_get(this->processes, i);
|
||||
p->updated = false;
|
||||
}
|
||||
|
||||
this->totalTasks = 0;
|
||||
this->userlandThreads = 0;
|
||||
this->kernelThreads = 0;
|
||||
this->runningTasks = 0;
|
||||
|
||||
ProcessList_goThroughEntries(this);
|
||||
|
||||
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
|
||||
Process* p = (Process*) Vector_get(this->processes, i);
|
||||
if (p->updated == false)
|
||||
ProcessList_remove(this, p);
|
||||
else
|
||||
p->updated = false;
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,11 @@ typedef struct ProcessList_ {
|
||||
bool topologyOk;
|
||||
#endif
|
||||
|
||||
int totalTasks;
|
||||
int runningTasks;
|
||||
int userlandThreads;
|
||||
int kernelThreads;
|
||||
|
||||
unsigned long long int totalMem;
|
||||
unsigned long long int usedMem;
|
||||
unsigned long long int freeMem;
|
||||
@ -59,7 +64,7 @@ typedef struct ProcessList_ {
|
||||
|
||||
ProcessList* ProcessList_new(UsersTable* ut, Hashtable* pidWhiteList, uid_t userId);
|
||||
void ProcessList_delete(ProcessList* pl);
|
||||
void ProcessList_scan(ProcessList* pl);
|
||||
void ProcessList_goThroughEntries(ProcessList* pl);
|
||||
|
||||
|
||||
ProcessList* ProcessList_init(ProcessList* this, UsersTable* usersTable, Hashtable* pidWhiteList, uid_t userId);
|
||||
@ -86,5 +91,8 @@ void ProcessList_expandTree(ProcessList* this);
|
||||
|
||||
void ProcessList_rebuildPanel(ProcessList* this);
|
||||
|
||||
Process* ProcessList_getProcess(ProcessList* this, pid_t pid, bool* preExisting, Process_new_fn constructor);
|
||||
|
||||
void ProcessList_scan(ProcessList* this);
|
||||
|
||||
#endif
|
||||
|
@ -19,7 +19,14 @@ int TasksMeter_attributes[] = {
|
||||
};
|
||||
|
||||
static void TasksMeter_setValues(Meter* this, char* buffer, int len) {
|
||||
Platform_setTasksValues(this);
|
||||
ProcessList* pl = this->pl;
|
||||
this->values[0] = pl->kernelThreads;
|
||||
this->values[1] = pl->userlandThreads;
|
||||
this->values[2] = pl->totalTasks - pl->kernelThreads - pl->userlandThreads;
|
||||
this->values[3] = pl->runningTasks;
|
||||
if (pl->totalTasks > this->total) {
|
||||
this->total = pl->totalTasks;
|
||||
}
|
||||
if (this->pl->settings->hideKernelThreads) {
|
||||
this->values[0] = 0;
|
||||
}
|
||||
|
@ -26,6 +26,14 @@ typedef struct FreeBSDProcess_ {
|
||||
Process super;
|
||||
} FreeBSDProcess;
|
||||
|
||||
#ifndef Process_isKernelThread
|
||||
#define Process_isKernelThread(_process) (_process->pgrp == 0)
|
||||
#endif
|
||||
|
||||
#ifndef Process_isUserlandThread
|
||||
#define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
|
||||
#endif
|
||||
|
||||
}*/
|
||||
|
||||
ProcessFieldData Process_fields[] = {
|
||||
@ -44,6 +52,7 @@ 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_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, },
|
||||
@ -128,7 +137,5 @@ long Process_compare(const void* v1, const void* v2) {
|
||||
}
|
||||
|
||||
bool Process_isThread(Process* this) {
|
||||
(void) this;
|
||||
// TODO
|
||||
return false;
|
||||
return (Process_isKernelThread(this));
|
||||
}
|
||||
|
@ -19,6 +19,14 @@ typedef struct FreeBSDProcess_ {
|
||||
Process super;
|
||||
} FreeBSDProcess;
|
||||
|
||||
#ifndef Process_isKernelThread
|
||||
#define Process_isKernelThread(_process) (_process->pgrp == 0)
|
||||
#endif
|
||||
|
||||
#ifndef Process_isUserlandThread
|
||||
#define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
|
||||
#endif
|
||||
|
||||
|
||||
extern ProcessFieldData Process_fields[];
|
||||
|
||||
|
@ -7,12 +7,15 @@ in the source distribution for its full text.
|
||||
|
||||
#include "ProcessList.h"
|
||||
#include "FreeBSDProcessList.h"
|
||||
#include "FreeBSDProcess.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/user.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
/*{
|
||||
|
||||
@ -103,10 +106,101 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) {
|
||||
pl->buffersMem = 0; // not exposed to userspace
|
||||
}
|
||||
|
||||
void ProcessList_scan(ProcessList* this) {
|
||||
(void) this;
|
||||
|
||||
FreeBSDProcessList_scanMemoryInfo(this);
|
||||
|
||||
// stub!
|
||||
char* FreeBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, int* basenameEnd) {
|
||||
char** argv = kvm_getargv(kd, kproc, 0);
|
||||
if (!argv) {
|
||||
return strdup(kproc->ki_comm);
|
||||
}
|
||||
int len = 0;
|
||||
for (int i = 0; argv[i]; i++) {
|
||||
len += strlen(argv[i]) + 1;
|
||||
}
|
||||
char* comm = malloc(len * sizeof(char));
|
||||
char* at = comm;
|
||||
*basenameEnd = 0;
|
||||
for (int i = 0; argv[i]; i++) {
|
||||
at = stpcpy(at, argv[i]);
|
||||
if (!*basenameEnd) {
|
||||
*basenameEnd = at - comm;
|
||||
}
|
||||
*at = ' ';
|
||||
at++;
|
||||
}
|
||||
at--;
|
||||
*at = '\0';
|
||||
return comm;
|
||||
}
|
||||
|
||||
void ProcessList_goThroughEntries(ProcessList* this) {
|
||||
FreeBSDProcessList* fpl = (FreeBSDProcessList*) this;
|
||||
Settings* settings = this->settings;
|
||||
bool hideKernelThreads = settings->hideKernelThreads;
|
||||
bool hideUserlandThreads = settings->hideUserlandThreads;
|
||||
|
||||
FreeBSDProcessList_scanMemoryInfo(this);
|
||||
|
||||
int count = 0;
|
||||
struct kinfo_proc* kprocs = kvm_getprocs(fpl->kd, KERN_PROC_ALL, 0, &count);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
struct kinfo_proc* kproc = &kprocs[i];
|
||||
|
||||
bool preExisting = false;
|
||||
Process* proc = ProcessList_getProcess(this, kproc->ki_pid, &preExisting, (Process_new_fn) FreeBSDProcess_new);
|
||||
FreeBSDProcess* fp = (FreeBSDProcess*) proc;
|
||||
|
||||
proc->show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
|
||||
|
||||
if (!preExisting) {
|
||||
proc->ppid = kproc->ki_ppid;
|
||||
proc->tpgid = kproc->ki_tpgid;
|
||||
proc->tgid = kproc->ki_pid;
|
||||
proc->session = kproc->ki_sid;
|
||||
proc->tty_nr = kproc->ki_tdev;
|
||||
proc->pgrp = kproc->ki_pgid;
|
||||
proc->st_uid = kproc->ki_uid;
|
||||
proc->starttime_ctime = kproc->ki_start.tv_sec;
|
||||
proc->user = UsersTable_getRef(this->usersTable, proc->st_uid);
|
||||
ProcessList_add((ProcessList*)this, proc);
|
||||
proc->comm = FreeBSDProcessList_readProcessName(fpl->kd, kproc, &proc->basenameOffset);
|
||||
} else {
|
||||
if (settings->updateProcessNames) {
|
||||
free(proc->comm);
|
||||
proc->comm = FreeBSDProcessList_readProcessName(fpl->kd, kproc, &proc->basenameOffset);
|
||||
}
|
||||
}
|
||||
|
||||
proc->m_size = kproc->ki_size / pageSizeKb / 1000;
|
||||
proc->m_resident = kproc->ki_rssize; // * pageSizeKb;
|
||||
proc->nlwp = kproc->ki_numthreads;
|
||||
proc->time = (kproc->ki_runtime + 5000) / 10000;
|
||||
proc->priority = kproc->ki_pri.pri_level - PZERO;
|
||||
if (kproc->ki_pri.pri_class == PRI_TIMESHARE) {
|
||||
proc->nice = kproc->ki_nice - NZERO;
|
||||
} else if (PRI_IS_REALTIME(kproc->ki_pri.pri_class)) {
|
||||
proc->nice = PRIO_MIN - 1 - (PRI_MAX_REALTIME - kproc->ki_pri.pri_level);
|
||||
} else {
|
||||
proc->nice = PRIO_MAX + 1 + kproc->ki_pri.pri_level - PRI_MIN_IDLE;
|
||||
}
|
||||
|
||||
switch (kproc->ki_stat) {
|
||||
case SIDL: proc->state = 'I'; break;
|
||||
case SRUN: proc->state = 'R'; break;
|
||||
case SSLEEP: proc->state = 'S'; break;
|
||||
case SSTOP: proc->state = 'T'; break;
|
||||
case SZOMB: proc->state = 'Z'; break;
|
||||
case SWAIT: proc->state = 'D'; break;
|
||||
case SLOCK: proc->state = 'L'; break;
|
||||
default: proc->state = '?';
|
||||
}
|
||||
|
||||
if (Process_isKernelThread(proc)) {
|
||||
this->kernelThreads++;
|
||||
}
|
||||
|
||||
this->totalTasks++;
|
||||
if (proc->state == 'R')
|
||||
this->runningTasks++;
|
||||
proc->updated = true;
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui
|
||||
|
||||
void ProcessList_delete(ProcessList* this);
|
||||
|
||||
void ProcessList_scan(ProcessList* this);
|
||||
char* FreeBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, int* basenameEnd);
|
||||
|
||||
void ProcessList_goThroughEntries(ProcessList* this);
|
||||
|
||||
#endif
|
||||
|
@ -51,7 +51,6 @@ typedef enum LinuxProcessFields {
|
||||
STIME = 15,
|
||||
CUTIME = 16,
|
||||
CSTIME = 17,
|
||||
PROCESSOR = 38,
|
||||
M_SHARE = 41,
|
||||
M_TRS = 42,
|
||||
M_DRS = 43,
|
||||
@ -97,7 +96,6 @@ typedef struct LinuxProcess_ {
|
||||
unsigned long long int stime;
|
||||
unsigned long long int cutime;
|
||||
unsigned long long int cstime;
|
||||
int processor;
|
||||
long m_share;
|
||||
long m_trs;
|
||||
long m_drs;
|
||||
@ -309,7 +307,6 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
|
||||
switch ((int)field) {
|
||||
case CMINFLT: Process_colorNumber(str, lp->cminflt, coloring); return;
|
||||
case CMAJFLT: Process_colorNumber(str, lp->cmajflt, coloring); return;
|
||||
case PROCESSOR: snprintf(buffer, n, "%3d ", Settings_cpuId(this->settings, lp->processor)); break;
|
||||
case M_DRS: Process_humanNumber(str, lp->m_drs * PAGE_SIZE_KB, coloring); return;
|
||||
case M_DT: Process_humanNumber(str, lp->m_dt * PAGE_SIZE_KB, coloring); return;
|
||||
case M_LRS: Process_humanNumber(str, lp->m_lrs * PAGE_SIZE_KB, coloring); return;
|
||||
@ -381,8 +378,6 @@ long Process_compare(const void* v1, const void* v2) {
|
||||
}
|
||||
long long diff;
|
||||
switch ((int)settings->sortKey) {
|
||||
case PROCESSOR:
|
||||
return (p1->processor - p2->processor);
|
||||
case M_DRS:
|
||||
return (p2->m_drs - p1->m_drs);
|
||||
case M_DT:
|
||||
|
@ -61,11 +61,6 @@ typedef struct CPUData_ {
|
||||
|
||||
typedef struct LinuxProcessList_ {
|
||||
ProcessList super;
|
||||
|
||||
int totalTasks;
|
||||
int userlandThreads;
|
||||
int kernelThreads;
|
||||
int runningTasks;
|
||||
|
||||
CPUData* cpus;
|
||||
|
||||
@ -141,6 +136,14 @@ static ssize_t xread(int fd, void *buf, size_t count) {
|
||||
}
|
||||
}
|
||||
|
||||
static double jiffy = 0.0;
|
||||
|
||||
static inline unsigned long long LinuxProcess_adjustTime(unsigned long long t) {
|
||||
if(jiffy == 0.0) jiffy = sysconf(_SC_CLK_TCK);
|
||||
double jiffytime = 1.0 / jiffy;
|
||||
return (unsigned long long) t * jiffytime * 100;
|
||||
}
|
||||
|
||||
static bool LinuxProcessList_readStatFile(Process *process, const char* dirname, const char* name, char* command) {
|
||||
LinuxProcess* lp = (LinuxProcess*) process;
|
||||
char filename[MAX_NAME+1];
|
||||
@ -191,13 +194,13 @@ static bool LinuxProcessList_readStatFile(Process *process, const char* dirname,
|
||||
location += 1;
|
||||
lp->cmajflt = strtoull(location, &location, 10);
|
||||
location += 1;
|
||||
lp->utime = strtoull(location, &location, 10);
|
||||
lp->utime = LinuxProcess_adjustTime(strtoull(location, &location, 10));
|
||||
location += 1;
|
||||
lp->stime = strtoull(location, &location, 10);
|
||||
lp->stime = LinuxProcess_adjustTime(strtoull(location, &location, 10));
|
||||
location += 1;
|
||||
lp->cutime = strtoull(location, &location, 10);
|
||||
lp->cutime = LinuxProcess_adjustTime(strtoull(location, &location, 10));
|
||||
location += 1;
|
||||
lp->cstime = strtoull(location, &location, 10);
|
||||
lp->cstime = LinuxProcess_adjustTime(strtoull(location, &location, 10));
|
||||
location += 1;
|
||||
process->priority = strtol(location, &location, 10);
|
||||
location += 1;
|
||||
@ -474,11 +477,11 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, const char* dirna
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool LinuxProcessList_processEntries(LinuxProcessList* this, const char* dirname, Process* parent, double period, struct timeval tv) {
|
||||
static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char* dirname, Process* parent, double period, struct timeval tv) {
|
||||
ProcessList* pl = (ProcessList*) this;
|
||||
DIR* dir;
|
||||
struct dirent* entry;
|
||||
Settings* settings = this->super.settings;
|
||||
Settings* settings = pl->settings;
|
||||
|
||||
time_t curTime = tv.tv_sec;
|
||||
#ifdef HAVE_TASKSTATS
|
||||
@ -487,7 +490,7 @@ static bool LinuxProcessList_processEntries(LinuxProcessList* this, const char*
|
||||
|
||||
dir = opendir(dirname);
|
||||
if (!dir) return false;
|
||||
int cpus = this->super.cpuCount;
|
||||
int cpus = pl->cpuCount;
|
||||
bool hideKernelThreads = settings->hideKernelThreads;
|
||||
bool hideUserlandThreads = settings->hideUserlandThreads;
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
@ -513,25 +516,15 @@ static bool LinuxProcessList_processEntries(LinuxProcessList* this, const char*
|
||||
if (pid <= 0)
|
||||
continue;
|
||||
|
||||
Process* proc = NULL;
|
||||
Process* existingProc = (Process*) Hashtable_get(this->super.processTable, pid);
|
||||
|
||||
if (existingProc) {
|
||||
assert(Vector_indexOf(this->processes, existingProc, Process_pidCompare) != -1);
|
||||
proc = existingProc;
|
||||
assert(proc->pid == pid);
|
||||
} else {
|
||||
proc = (Process*) LinuxProcess_new(settings);
|
||||
assert(proc->comm == NULL);
|
||||
proc->pid = pid;
|
||||
proc->tgid = parent ? parent->pid : pid;
|
||||
}
|
||||
bool preExisting = false;
|
||||
Process* proc = ProcessList_getProcess(pl, pid, &preExisting, (Process_new_fn) LinuxProcess_new);
|
||||
proc->tgid = parent ? parent->pid : pid;
|
||||
|
||||
LinuxProcess* lp = (LinuxProcess*) proc;
|
||||
|
||||
char subdirname[MAX_NAME+1];
|
||||
snprintf(subdirname, MAX_NAME, "%s/%s/task", dirname, name);
|
||||
LinuxProcessList_processEntries(this, subdirname, proc, period, tv);
|
||||
LinuxProcessList_recurseProcTree(this, subdirname, proc, period, tv);
|
||||
|
||||
#ifdef HAVE_TASKSTATS
|
||||
if (settings->flags & PROCESS_FLAG_IO)
|
||||
@ -554,12 +547,12 @@ static bool LinuxProcessList_processEntries(LinuxProcessList* this, const char*
|
||||
if (isnan(proc->percent_cpu)) proc->percent_cpu = 0.0;
|
||||
proc->percent_mem = (proc->m_resident * PAGE_SIZE_KB) / (double)(pl->totalMem) * 100.0;
|
||||
|
||||
if(!existingProc) {
|
||||
if(!preExisting) {
|
||||
|
||||
if (! LinuxProcessList_statProcessDir(proc, dirname, name, curTime))
|
||||
goto errorReadingProcess;
|
||||
|
||||
proc->user = UsersTable_getRef(this->super.usersTable, proc->st_uid);
|
||||
proc->user = UsersTable_getRef(pl->usersTable, proc->st_uid);
|
||||
|
||||
#ifdef HAVE_OPENVZ
|
||||
LinuxProcessList_readOpenVZData(this, lp, dirname, name);
|
||||
@ -573,7 +566,7 @@ static bool LinuxProcessList_processEntries(LinuxProcessList* this, const char*
|
||||
if (! LinuxProcessList_readCmdlineFile(proc, dirname, name))
|
||||
goto errorReadingProcess;
|
||||
|
||||
ProcessList_add((ProcessList*)this, proc);
|
||||
ProcessList_add(pl, proc);
|
||||
} else {
|
||||
if (settings->updateProcessNames) {
|
||||
if (! LinuxProcessList_readCmdlineFile(proc, dirname, name))
|
||||
@ -614,20 +607,15 @@ static bool LinuxProcessList_processEntries(LinuxProcessList* this, const char*
|
||||
if (proc->state == 'R')
|
||||
this->runningTasks++;
|
||||
proc->updated = true;
|
||||
|
||||
continue;
|
||||
|
||||
// Exception handler.
|
||||
errorReadingProcess: {
|
||||
if (proc->comm) {
|
||||
free(proc->comm);
|
||||
proc->basenameOffset = -1;
|
||||
proc->comm = NULL;
|
||||
}
|
||||
if (existingProc)
|
||||
ProcessList_remove((ProcessList*)this, proc);
|
||||
else
|
||||
if (preExisting) {
|
||||
ProcessList_remove((pl, proc);
|
||||
} else {
|
||||
Process_delete((Object*)proc);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
@ -752,35 +740,13 @@ static inline double LinuxProcessList_scanCPUTime(LinuxProcessList* this) {
|
||||
return period;
|
||||
}
|
||||
|
||||
void ProcessList_scan(ProcessList* super) {
|
||||
void ProcessList_goThroughEntries(ProcessList* super) {
|
||||
LinuxProcessList* this = (LinuxProcessList*) super;
|
||||
|
||||
LinuxProcessList_scanMemoryInfo(super);
|
||||
|
||||
double period = LinuxProcessList_scanCPUTime(this);
|
||||
|
||||
// mark all process as "dirty"
|
||||
for (int i = 0; i < Vector_size(super->processes); i++) {
|
||||
Process* p = (Process*) Vector_get(super->processes, i);
|
||||
p->updated = false;
|
||||
}
|
||||
|
||||
this->totalTasks = 0;
|
||||
this->userlandThreads = 0;
|
||||
this->kernelThreads = 0;
|
||||
this->runningTasks = 0;
|
||||
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
LinuxProcessList_processEntries(this, PROCDIR, NULL, period, tv);
|
||||
|
||||
for (int i = Vector_size(this->super.processes) - 1; i >= 0; i--) {
|
||||
Process* p = (Process*) Vector_get(this->super.processes, i);
|
||||
if (p->updated == false)
|
||||
ProcessList_remove(super, p);
|
||||
else
|
||||
p->updated = false;
|
||||
}
|
||||
|
||||
LinuxProcessList_recurseProcTree(this, PROCDIR, NULL, period, tv);
|
||||
}
|
||||
|
||||
|
@ -165,13 +165,3 @@ void Platform_setSwapValues(Meter* this) {
|
||||
this->total = pl->totalSwap;
|
||||
this->values[0] = pl->usedSwap;
|
||||
}
|
||||
|
||||
void Platform_setTasksValues(Meter* this) {
|
||||
LinuxProcessList* pl = (LinuxProcessList*) this->pl;
|
||||
this->values[0] = pl->kernelThreads;
|
||||
this->values[1] = pl->userlandThreads;
|
||||
this->values[2] = pl->totalTasks - pl->kernelThreads - pl->userlandThreads;
|
||||
this->values[3] = pl->runningTasks;
|
||||
if (pl->totalTasks > this->total)
|
||||
this->total = pl->totalTasks;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user