mirror of https://github.com/xzeldon/htop.git
Move kernel/userland thread handling to platform-independent implementation
This commit is contained in:
parent
1a1fddae85
commit
7224d0e083
19
Process.h
19
Process.h
|
@ -110,6 +110,12 @@ typedef struct Process_ {
|
||||||
/* Foreground group identifier of the controlling terminal */
|
/* Foreground group identifier of the controlling terminal */
|
||||||
int tpgid;
|
int tpgid;
|
||||||
|
|
||||||
|
/* This is a kernel (helper) task */
|
||||||
|
bool isKernelThread;
|
||||||
|
|
||||||
|
/* This is a userland thread / LWP */
|
||||||
|
bool isUserlandThread;
|
||||||
|
|
||||||
/* Controlling terminal identifier of the process */
|
/* Controlling terminal identifier of the process */
|
||||||
unsigned long int tty_nr;
|
unsigned long int tty_nr;
|
||||||
|
|
||||||
|
@ -260,7 +266,6 @@ typedef struct ProcessFieldData_ {
|
||||||
void Process_writeField(const Process* this, RichString* str, ProcessField field);
|
void Process_writeField(const Process* this, RichString* str, ProcessField field);
|
||||||
int Process_compare(const void* v1, const void* v2);
|
int Process_compare(const void* v1, const void* v2);
|
||||||
void Process_delete(Object* cast);
|
void Process_delete(Object* cast);
|
||||||
bool Process_isThread(const Process* this);
|
|
||||||
extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
|
extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
|
||||||
#define PROCESS_MAX_PID_DIGITS 19
|
#define PROCESS_MAX_PID_DIGITS 19
|
||||||
extern int Process_pidDigits;
|
extern int Process_pidDigits;
|
||||||
|
@ -290,6 +295,18 @@ static inline bool Process_isChildOf(const Process* this, pid_t pid) {
|
||||||
return pid == Process_getParentPid(this);
|
return pid == Process_getParentPid(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool Process_isKernelThread(const Process *this) {
|
||||||
|
return this->isKernelThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool Process_isUserlandThread(const Process *this) {
|
||||||
|
return this->isUserlandThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool Process_isThread(const Process *this) {
|
||||||
|
return Process_isUserlandThread(this) || Process_isKernelThread(this);
|
||||||
|
}
|
||||||
|
|
||||||
#define CMDLINE_HIGHLIGHT_FLAG_SEPARATOR 0x00000001
|
#define CMDLINE_HIGHLIGHT_FLAG_SEPARATOR 0x00000001
|
||||||
#define CMDLINE_HIGHLIGHT_FLAG_BASENAME 0x00000002
|
#define CMDLINE_HIGHLIGHT_FLAG_BASENAME 0x00000002
|
||||||
#define CMDLINE_HIGHLIGHT_FLAG_COMM 0x00000004
|
#define CMDLINE_HIGHLIGHT_FLAG_COMM 0x00000004
|
||||||
|
|
|
@ -96,11 +96,6 @@ static int DarwinProcess_compareByKey(const Process* v1, const Process* v2, Proc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Process_isThread(const Process* this) {
|
|
||||||
(void) this;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char* DarwinProcess_getCmdLine(const struct kinfo_proc* k, int* cmdlineBasenameEnd) {
|
static char* DarwinProcess_getCmdLine(const struct kinfo_proc* k, int* cmdlineBasenameEnd) {
|
||||||
/* This function is from the old Mac version of htop. Originally from ps? */
|
/* This function is from the old Mac version of htop. Originally from ps? */
|
||||||
int mib[3], argmax, nargs, c = 0;
|
int mib[3], argmax, nargs, c = 0;
|
||||||
|
@ -272,6 +267,8 @@ void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps,
|
||||||
proc->session = 0; /* TODO Get the session id */
|
proc->session = 0; /* TODO Get the session id */
|
||||||
proc->tpgid = ps->kp_eproc.e_tpgid;
|
proc->tpgid = ps->kp_eproc.e_tpgid;
|
||||||
proc->tgid = proc->pid;
|
proc->tgid = proc->pid;
|
||||||
|
proc->isKernelThread = false;
|
||||||
|
proc->isUserlandThread = false;
|
||||||
proc->st_uid = ps->kp_eproc.e_ucred.cr_uid;
|
proc->st_uid = ps->kp_eproc.e_ucred.cr_uid;
|
||||||
dp->translated = ps->kp_proc.p_flag & P_TRANSLATED;
|
dp->translated = ps->kp_proc.p_flag & P_TRANSLATED;
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,6 @@ Process* DarwinProcess_new(const Settings* settings);
|
||||||
|
|
||||||
void Process_delete(Object* cast);
|
void Process_delete(Object* cast);
|
||||||
|
|
||||||
bool Process_isThread(const Process* this);
|
|
||||||
|
|
||||||
void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps, bool exists);
|
void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps, bool exists);
|
||||||
|
|
||||||
void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList* dpl, double time_interval);
|
void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList* dpl, double time_interval);
|
||||||
|
|
|
@ -94,16 +94,6 @@ static int DragonFlyBSDProcess_compareByKey(const Process* v1, const Process* v2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Process_isThread(const Process* this) {
|
|
||||||
const DragonFlyBSDProcess* fp = (const DragonFlyBSDProcess*) this;
|
|
||||||
|
|
||||||
if (fp->kernel == 1 ) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return (Process_isUserlandThread(this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const ProcessClass DragonFlyBSDProcess_class = {
|
const ProcessClass DragonFlyBSDProcess_class = {
|
||||||
.super = {
|
.super = {
|
||||||
.extends = Class(Process),
|
.extends = Class(Process),
|
||||||
|
|
|
@ -17,16 +17,10 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
typedef struct DragonFlyBSDProcess_ {
|
typedef struct DragonFlyBSDProcess_ {
|
||||||
Process super;
|
Process super;
|
||||||
int kernel;
|
|
||||||
int jid;
|
int jid;
|
||||||
char* jname;
|
char* jname;
|
||||||
} DragonFlyBSDProcess;
|
} DragonFlyBSDProcess;
|
||||||
|
|
||||||
#define Process_isKernelThread(_process) (_process->kernel == 1)
|
|
||||||
|
|
||||||
//#define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
|
|
||||||
#define Process_isUserlandThread(_process) (_process->nlwp > 1)
|
|
||||||
|
|
||||||
extern const ProcessClass DragonFlyBSDProcess_class;
|
extern const ProcessClass DragonFlyBSDProcess_class;
|
||||||
|
|
||||||
extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
|
extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
|
||||||
|
@ -35,6 +29,4 @@ Process* DragonFlyBSDProcess_new(const Settings* settings);
|
||||||
|
|
||||||
void Process_delete(Object* cast);
|
void Process_delete(Object* cast);
|
||||||
|
|
||||||
bool Process_isThread(const Process* this);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -390,11 +390,12 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
if (kproc->kp_ktaddr && kproc->kp_flags & P_SYSTEM) {
|
if (kproc->kp_ktaddr && kproc->kp_flags & P_SYSTEM) {
|
||||||
// dfb kernel threads all have the same pid, so we misuse the kernel thread address to give them a unique identifier
|
// dfb kernel threads all have the same pid, so we misuse the kernel thread address to give them a unique identifier
|
||||||
proc->pid = (pid_t)kproc->kp_ktaddr;
|
proc->pid = (pid_t)kproc->kp_ktaddr;
|
||||||
dfp->kernel = 1;
|
proc->isKernelThread = true;
|
||||||
} else {
|
} else {
|
||||||
proc->pid = kproc->kp_pid; // process ID
|
proc->pid = kproc->kp_pid; // process ID
|
||||||
dfp->kernel = 0;
|
proc->isKernelThread = false;
|
||||||
}
|
}
|
||||||
|
proc->isUserlandThread = kproc->kp_nthreads > 1;
|
||||||
proc->ppid = kproc->kp_ppid; // parent process id
|
proc->ppid = kproc->kp_ppid; // parent process id
|
||||||
proc->tpgid = kproc->kp_tpgid; // tty process group id
|
proc->tpgid = kproc->kp_tpgid; // tty process group id
|
||||||
//proc->tgid = kproc->kp_lwp.kl_tid; // thread group id
|
//proc->tgid = kproc->kp_lwp.kl_tid; // thread group id
|
||||||
|
|
|
@ -96,10 +96,6 @@ static int FreeBSDProcess_compareByKey(const Process* v1, const Process* v2, Pro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Process_isThread(const Process* this) {
|
|
||||||
return Process_isKernelThread(this) || Process_isUserlandThread(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ProcessClass FreeBSDProcess_class = {
|
const ProcessClass FreeBSDProcess_class = {
|
||||||
.super = {
|
.super = {
|
||||||
.extends = Class(Process),
|
.extends = Class(Process),
|
||||||
|
|
|
@ -16,19 +16,10 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
typedef struct FreeBSDProcess_ {
|
typedef struct FreeBSDProcess_ {
|
||||||
Process super;
|
Process super;
|
||||||
bool isKernelThread;
|
|
||||||
int jid;
|
int jid;
|
||||||
char* jname;
|
char* jname;
|
||||||
} FreeBSDProcess;
|
} FreeBSDProcess;
|
||||||
|
|
||||||
static inline bool Process_isKernelThread(const Process* this) {
|
|
||||||
return ((const FreeBSDProcess*)this)->isKernelThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool Process_isUserlandThread(const Process* this) {
|
|
||||||
return this->pid != this->tgid;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern const ProcessClass FreeBSDProcess_class;
|
extern const ProcessClass FreeBSDProcess_class;
|
||||||
|
|
||||||
extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
|
extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
|
||||||
|
@ -37,6 +28,4 @@ Process* FreeBSDProcess_new(const Settings* settings);
|
||||||
|
|
||||||
void Process_delete(Object* cast);
|
void Process_delete(Object* cast);
|
||||||
|
|
||||||
bool Process_isThread(const Process* this);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -456,7 +456,8 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
if (!preExisting) {
|
if (!preExisting) {
|
||||||
fp->jid = kproc->ki_jid;
|
fp->jid = kproc->ki_jid;
|
||||||
proc->pid = kproc->ki_pid;
|
proc->pid = kproc->ki_pid;
|
||||||
fp->isKernelThread = kproc->ki_pid != 0 && kproc->ki_pid != 1 && (kproc->ki_flag & P_SYSTEM);
|
proc->isKernelThread = kproc->ki_pid != 0 && kproc->ki_pid != 1 && (kproc->ki_flag & P_SYSTEM);
|
||||||
|
proc->isUserlandThread = false;
|
||||||
proc->ppid = kproc->ki_ppid;
|
proc->ppid = kproc->ki_ppid;
|
||||||
proc->tpgid = kproc->ki_tpgid;
|
proc->tpgid = kproc->ki_tpgid;
|
||||||
proc->tgid = kproc->ki_pid;
|
proc->tgid = kproc->ki_pid;
|
||||||
|
|
|
@ -685,7 +685,7 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
|
||||||
procComm = this->procComm;
|
procComm = this->procComm;
|
||||||
} else {
|
} else {
|
||||||
attr = CRT_colors[PROCESS_SHADOW];
|
attr = CRT_colors[PROCESS_SHADOW];
|
||||||
procComm = Process_isKernelThread(lp) ? kthreadID : "N/A";
|
procComm = Process_isKernelThread(this) ? kthreadID : "N/A";
|
||||||
}
|
}
|
||||||
/* 15 being (TASK_COMM_LEN - 1) */
|
/* 15 being (TASK_COMM_LEN - 1) */
|
||||||
Process_printLeftAlignedField(str, attr, procComm, 15);
|
Process_printLeftAlignedField(str, attr, procComm, 15);
|
||||||
|
@ -700,7 +700,7 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
|
||||||
procExe = this->procExe + this->procExeBasenameOffset;
|
procExe = this->procExe + this->procExeBasenameOffset;
|
||||||
} else {
|
} else {
|
||||||
attr = CRT_colors[PROCESS_SHADOW];
|
attr = CRT_colors[PROCESS_SHADOW];
|
||||||
procExe = Process_isKernelThread(lp) ? kthreadID : "N/A";
|
procExe = Process_isKernelThread(this) ? kthreadID : "N/A";
|
||||||
}
|
}
|
||||||
Process_printLeftAlignedField(str, attr, procExe, 15);
|
Process_printLeftAlignedField(str, attr, procExe, 15);
|
||||||
return;
|
return;
|
||||||
|
@ -811,13 +811,13 @@ static int LinuxProcess_compareByKey(const Process* v1, const Process* v2, Proce
|
||||||
case SECATTR:
|
case SECATTR:
|
||||||
return SPACESHIP_NULLSTR(p1->secattr, p2->secattr);
|
return SPACESHIP_NULLSTR(p1->secattr, p2->secattr);
|
||||||
case PROC_COMM: {
|
case PROC_COMM: {
|
||||||
const char *comm1 = v1->procComm ? v1->procComm : (Process_isKernelThread(p1) ? kthreadID : "");
|
const char *comm1 = v1->procComm ? v1->procComm : (Process_isKernelThread(v1) ? kthreadID : "");
|
||||||
const char *comm2 = v2->procComm ? v2->procComm : (Process_isKernelThread(p2) ? kthreadID : "");
|
const char *comm2 = v2->procComm ? v2->procComm : (Process_isKernelThread(v2) ? kthreadID : "");
|
||||||
return strcmp(comm1, comm2);
|
return strcmp(comm1, comm2);
|
||||||
}
|
}
|
||||||
case PROC_EXE: {
|
case PROC_EXE: {
|
||||||
const char *exe1 = v1->procExe ? (v1->procExe + v1->procExeBasenameOffset) : (Process_isKernelThread(p1) ? kthreadID : "");
|
const char *exe1 = v1->procExe ? (v1->procExe + v1->procExeBasenameOffset) : (Process_isKernelThread(v1) ? kthreadID : "");
|
||||||
const char *exe2 = v2->procExe ? (v2->procExe + v2->procExeBasenameOffset) : (Process_isKernelThread(p2) ? kthreadID : "");
|
const char *exe2 = v2->procExe ? (v2->procExe + v2->procExeBasenameOffset) : (Process_isKernelThread(v2) ? kthreadID : "");
|
||||||
return strcmp(exe1, exe2);
|
return strcmp(exe1, exe2);
|
||||||
}
|
}
|
||||||
case CWD:
|
case CWD:
|
||||||
|
@ -827,10 +827,6 @@ static int LinuxProcess_compareByKey(const Process* v1, const Process* v2, Proce
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Process_isThread(const Process* this) {
|
|
||||||
return (Process_isUserlandThread(this) || Process_isKernelThread(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
const ProcessClass LinuxProcess_class = {
|
const ProcessClass LinuxProcess_class = {
|
||||||
.super = {
|
.super = {
|
||||||
.extends = Class(Process),
|
.extends = Class(Process),
|
||||||
|
|
|
@ -32,8 +32,6 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
typedef struct LinuxProcess_ {
|
typedef struct LinuxProcess_ {
|
||||||
Process super;
|
Process super;
|
||||||
bool isKernelThread;
|
|
||||||
bool isUserlandThread;
|
|
||||||
IOPriority ioPriority;
|
IOPriority ioPriority;
|
||||||
unsigned long int cminflt;
|
unsigned long int cminflt;
|
||||||
unsigned long int cmajflt;
|
unsigned long int cmajflt;
|
||||||
|
@ -105,10 +103,6 @@ typedef struct LinuxProcess_ {
|
||||||
char* cwd;
|
char* cwd;
|
||||||
} LinuxProcess;
|
} LinuxProcess;
|
||||||
|
|
||||||
#define Process_isKernelThread(_process) (((const LinuxProcess*)(_process))->isKernelThread)
|
|
||||||
|
|
||||||
#define Process_isUserlandThread(_process) (((const LinuxProcess *)(_process))->isUserlandThread)
|
|
||||||
|
|
||||||
extern int pageSize;
|
extern int pageSize;
|
||||||
|
|
||||||
extern int pageSizeKB;
|
extern int pageSizeKB;
|
||||||
|
|
|
@ -1015,7 +1015,7 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, openat_arg_t proc
|
||||||
if (process->state == 'Z') {
|
if (process->state == 'Z') {
|
||||||
process->cmdlineBasenameEnd = 0;
|
process->cmdlineBasenameEnd = 0;
|
||||||
} else {
|
} else {
|
||||||
((LinuxProcess*)process)->isKernelThread = true;
|
process->isKernelThread = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1315,7 +1315,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||||
LinuxProcess* lp = (LinuxProcess*) proc;
|
LinuxProcess* lp = (LinuxProcess*) proc;
|
||||||
|
|
||||||
proc->tgid = parent ? parent->pid : pid;
|
proc->tgid = parent ? parent->pid : pid;
|
||||||
lp->isUserlandThread = proc->pid != proc->tgid;
|
proc->isUserlandThread = proc->pid != proc->tgid;
|
||||||
|
|
||||||
#ifdef HAVE_OPENAT
|
#ifdef HAVE_OPENAT
|
||||||
int procFd = openat(dirFd, entry->d_name, O_PATH | O_DIRECTORY | O_NOFOLLOW);
|
int procFd = openat(dirFd, entry->d_name, O_PATH | O_DIRECTORY | O_NOFOLLOW);
|
||||||
|
|
|
@ -234,7 +234,3 @@ const ProcessClass OpenBSDProcess_class = {
|
||||||
.writeField = OpenBSDProcess_writeField,
|
.writeField = OpenBSDProcess_writeField,
|
||||||
.compareByKey = OpenBSDProcess_compareByKey
|
.compareByKey = OpenBSDProcess_compareByKey
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Process_isThread(const Process* this) {
|
|
||||||
return Process_isKernelThread(this) || Process_isUserlandThread(this);
|
|
||||||
}
|
|
||||||
|
|
|
@ -22,14 +22,6 @@ typedef struct OpenBSDProcess_ {
|
||||||
uint64_t addr;
|
uint64_t addr;
|
||||||
} OpenBSDProcess;
|
} OpenBSDProcess;
|
||||||
|
|
||||||
static inline bool Process_isKernelThread(const Process* this) {
|
|
||||||
return this->pgrp == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool Process_isUserlandThread(const Process* this) {
|
|
||||||
return this->pid != this->tgid;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern const ProcessClass OpenBSDProcess_class;
|
extern const ProcessClass OpenBSDProcess_class;
|
||||||
|
|
||||||
extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
|
extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
|
||||||
|
@ -38,6 +30,4 @@ Process* OpenBSDProcess_new(const Settings* settings);
|
||||||
|
|
||||||
void Process_delete(Object* cast);
|
void Process_delete(Object* cast);
|
||||||
|
|
||||||
bool Process_isThread(const Process* this);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -252,6 +252,8 @@ static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) {
|
||||||
proc->tgid = kproc->p_pid;
|
proc->tgid = kproc->p_pid;
|
||||||
proc->session = kproc->p_sid;
|
proc->session = kproc->p_sid;
|
||||||
proc->pgrp = kproc->p__pgid;
|
proc->pgrp = kproc->p__pgid;
|
||||||
|
proc->isKernelThread = proc->pgrp == 0;
|
||||||
|
proc->isUserlandThread = kproc->p_tid != -1;
|
||||||
proc->st_uid = kproc->p_uid;
|
proc->st_uid = kproc->p_uid;
|
||||||
proc->starttime_ctime = kproc->p_ustart_sec;
|
proc->starttime_ctime = kproc->p_ustart_sec;
|
||||||
Process_fillStarttimeBuffer(proc);
|
Process_fillStarttimeBuffer(proc);
|
||||||
|
|
|
@ -121,18 +121,6 @@ static int SolarisProcess_compareByKey(const Process* v1, const Process* v2, Pro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Process_isThread(const Process* this) {
|
|
||||||
const SolarisProcess* fp = (const SolarisProcess*) this;
|
|
||||||
|
|
||||||
if (fp->kernel == 1 ) {
|
|
||||||
return 1;
|
|
||||||
} else if (fp->is_lwp) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const ProcessClass SolarisProcess_class = {
|
const ProcessClass SolarisProcess_class = {
|
||||||
.super = {
|
.super = {
|
||||||
.extends = Class(Process),
|
.extends = Class(Process),
|
||||||
|
|
|
@ -26,24 +26,18 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
typedef struct SolarisProcess_ {
|
typedef struct SolarisProcess_ {
|
||||||
Process super;
|
Process super;
|
||||||
int kernel;
|
|
||||||
zoneid_t zoneid;
|
zoneid_t zoneid;
|
||||||
char* zname;
|
char* zname;
|
||||||
taskid_t taskid;
|
taskid_t taskid;
|
||||||
projid_t projid;
|
projid_t projid;
|
||||||
poolid_t poolid;
|
poolid_t poolid;
|
||||||
ctid_t contid;
|
ctid_t contid;
|
||||||
bool is_lwp;
|
|
||||||
pid_t realpid;
|
pid_t realpid;
|
||||||
pid_t realppid;
|
pid_t realppid;
|
||||||
pid_t realtgid;
|
pid_t realtgid;
|
||||||
pid_t lwpid;
|
pid_t lwpid;
|
||||||
} SolarisProcess;
|
} SolarisProcess;
|
||||||
|
|
||||||
#define Process_isKernelThread(_process) (_process->kernel == 1)
|
|
||||||
|
|
||||||
#define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
|
|
||||||
|
|
||||||
extern const ProcessClass SolarisProcess_class;
|
extern const ProcessClass SolarisProcess_class;
|
||||||
|
|
||||||
extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
|
extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
|
||||||
|
@ -52,6 +46,4 @@ Process* SolarisProcess_new(const Settings* settings);
|
||||||
|
|
||||||
void Process_delete(Object* cast);
|
void Process_delete(Object* cast);
|
||||||
|
|
||||||
bool Process_isThread(const Process* this);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -322,6 +322,7 @@ static int SolarisProcessList_walkproc(psinfo_t* _psinfo, lwpsinfo_t* _lwpsinfo,
|
||||||
} else {
|
} else {
|
||||||
getpid = lwpid;
|
getpid = lwpid;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* proc = ProcessList_getProcess(pl, getpid, &preExisting, SolarisProcess_new);
|
Process* proc = ProcessList_getProcess(pl, getpid, &preExisting, SolarisProcess_new);
|
||||||
SolarisProcess* sproc = (SolarisProcess*) proc;
|
SolarisProcess* sproc = (SolarisProcess*) proc;
|
||||||
|
|
||||||
|
@ -376,18 +377,18 @@ static int SolarisProcessList_walkproc(psinfo_t* _psinfo, lwpsinfo_t* _lwpsinfo,
|
||||||
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;
|
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->isUserlandThread = false;
|
||||||
proc->starttime_ctime = _psinfo->pr_start.tv_sec;
|
proc->starttime_ctime = _psinfo->pr_start.tv_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update proc and thread counts based on settings
|
// Update proc and thread counts based on settings
|
||||||
if (sproc->kernel && !pl->settings->hideKernelThreads) {
|
if (proc->isKernelThread && !pl->settings->hideKernelThreads) {
|
||||||
pl->kernelThreads += proc->nlwp;
|
pl->kernelThreads += proc->nlwp;
|
||||||
pl->totalTasks += proc->nlwp + 1;
|
pl->totalTasks += proc->nlwp + 1;
|
||||||
if (proc->state == 'O') {
|
if (proc->state == 'O') {
|
||||||
pl->runningTasks++;
|
pl->runningTasks++;
|
||||||
}
|
}
|
||||||
} else if (!sproc->kernel) {
|
} else if (!proc->isKernelThread) {
|
||||||
if (proc->state == 'O') {
|
if (proc->state == 'O') {
|
||||||
pl->runningTasks++;
|
pl->runningTasks++;
|
||||||
}
|
}
|
||||||
|
@ -398,12 +399,12 @@ static int SolarisProcessList_walkproc(psinfo_t* _psinfo, lwpsinfo_t* _lwpsinfo,
|
||||||
pl->totalTasks += proc->nlwp + 1;
|
pl->totalTasks += proc->nlwp + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
proc->show = !(pl->settings->hideKernelThreads && sproc->kernel);
|
proc->show = !(pl->settings->hideKernelThreads && proc->isKernelThread);
|
||||||
} else { // We are not in the master LWP, so jump to the LWP handling code
|
} 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;
|
proc->time = _lwpsinfo->pr_time.tv_sec;
|
||||||
if (!preExisting) { // Tasks done only for NEW LWPs
|
if (!preExisting) { // Tasks done only for NEW LWPs
|
||||||
sproc->is_lwp = true;
|
proc->isUserlandThread = true;
|
||||||
proc->cmdlineBasenameEnd = -1;
|
proc->cmdlineBasenameEnd = -1;
|
||||||
proc->ppid = _psinfo->pr_pid * 1024;
|
proc->ppid = _psinfo->pr_pid * 1024;
|
||||||
proc->tgid = _psinfo->pr_pid * 1024;
|
proc->tgid = _psinfo->pr_pid * 1024;
|
||||||
|
@ -413,10 +414,10 @@ static int SolarisProcessList_walkproc(psinfo_t* _psinfo, lwpsinfo_t* _lwpsinfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Top-level process only gets this for the representative LWP
|
// Top-level process only gets this for the representative LWP
|
||||||
if (sproc->kernel && !pl->settings->hideKernelThreads) {
|
if (proc->isKernelThread && !pl->settings->hideKernelThreads) {
|
||||||
proc->show = true;
|
proc->show = true;
|
||||||
}
|
}
|
||||||
if (!sproc->kernel && !pl->settings->hideUserlandThreads) {
|
if (!proc->isKernelThread && !pl->settings->hideUserlandThreads) {
|
||||||
proc->show = true;
|
proc->show = true;
|
||||||
}
|
}
|
||||||
} // Top-level LWP or subordinate LWP
|
} // Top-level LWP or subordinate LWP
|
||||||
|
@ -425,10 +426,11 @@ static int SolarisProcessList_walkproc(psinfo_t* _psinfo, lwpsinfo_t* _lwpsinfo,
|
||||||
|
|
||||||
if (!preExisting) {
|
if (!preExisting) {
|
||||||
if ((sproc->realppid <= 0) && !(sproc->realpid <= 1)) {
|
if ((sproc->realppid <= 0) && !(sproc->realpid <= 1)) {
|
||||||
sproc->kernel = true;
|
proc->isKernelThread = true;
|
||||||
} else {
|
} else {
|
||||||
sproc->kernel = false;
|
proc->isKernelThread = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process_fillStarttimeBuffer(proc);
|
Process_fillStarttimeBuffer(proc);
|
||||||
ProcessList_add(pl, proc);
|
ProcessList_add(pl, proc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,8 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
proc->updated = true;
|
proc->updated = true;
|
||||||
|
|
||||||
proc->state = 'R';
|
proc->state = 'R';
|
||||||
|
proc->isKernelThread = false;
|
||||||
|
proc->isUserlandThread = false;
|
||||||
proc->show = true; /* Reflected in proc->settings-> "hideXXX" really */
|
proc->show = true; /* Reflected in proc->settings-> "hideXXX" really */
|
||||||
proc->pgrp = 0;
|
proc->pgrp = 0;
|
||||||
proc->session = 0;
|
proc->session = 0;
|
||||||
|
|
Loading…
Reference in New Issue