Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
htop
Commits
475798e8
Commit
475798e8
authored
Mar 28, 2018
by
Guy M. Broome
Committed by
Hisham Muhammad
Apr 06, 2018
Browse files
Solaris: condense separate process vs lwp handling down to a single workflow
parent
7689c5c3
Changes
2
Hide whitespace changes
Inline
Side-by-side
solaris/SolarisProcessList.c
View file @
475798e8
...
...
@@ -15,13 +15,11 @@ in the source distribution for its full text.
#include <sys/types.h>
#include <sys/user.h>
#include <err.h>
#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <procfs.h>
#include <errno.h>
#include <pwd.h>
#include <dirent.h>
#include <math.h>
#include <time.h>
...
...
@@ -238,139 +236,96 @@ void ProcessList_delete(ProcessList* this) {
free
(
this
);
}
void
ProcessList_enumerateLWPs
(
Process
*
proc
,
ProcessList
*
pl
,
lwpsinfo_t
*
_lwpsinfo
,
struct
timeval
tv
)
{
Process
*
lwp
;
SolarisProcess
*
slwp
;
SolarisProcess
*
sproc
=
(
SolarisProcess
*
)
proc
;
id_t
lwpid_real
;
pid_t
lwpid
;
bool
preExisting
=
false
;
int
SolarisProcessList_walkproc
(
psinfo_t
*
_psinfo
,
lwpsinfo_t
*
_lwpsinfo
,
void
*
listptr
)
{
struct
timeval
tv
;
struct
tm
date
;
bool
preExistingP
=
false
;
bool
preExistingL
=
false
;
bool
preExisting
;
Process
*
cproc
;
SolarisProcess
*
csproc
;
// With 10 bits to spare, we can only list up to 1023 unique LWPs per process
lwpid_real
=
_lwpsinfo
->
pr_lwpid
;
if
(
lwpid_real
>
1023
)
return
;
lwpid
=
proc
->
pid
+
lwpid_real
;
lwp
=
ProcessList_getProcess
(
pl
,
lwpid
,
&
preExisting
,
(
Process_New
)
SolarisProcess_new
);
slwp
=
(
SolarisProcess
*
)
lwp
;
// Common items set for both new and refreshed LWPs
slwp
->
zoneid
=
sproc
->
zoneid
;
lwp
->
percent_cpu
=
((
uint16_t
)
_lwpsinfo
->
pr_pctcpu
/
(
double
)
32768
)
*
(
double
)
100
.
0
;
lwp
->
pgrp
=
proc
->
pgrp
;
lwp
->
st_uid
=
proc
->
st_uid
;
lwp
->
user
=
UsersTable_getRef
(
pl
->
usersTable
,
lwp
->
st_uid
);
lwp
->
session
=
proc
->
session
;
lwp
->
comm
=
xStrdup
(
proc
->
comm
);
lwp
->
commLen
=
strnlen
(
proc
->
comm
,
PRFNSZ
);
slwp
->
zname
=
sproc
->
zname
;
lwp
->
tty_nr
=
proc
->
tty_nr
;
lwp
->
priority
=
_lwpsinfo
->
pr_pri
;
lwp
->
nice
=
_lwpsinfo
->
pr_nice
;
lwp
->
processor
=
_lwpsinfo
->
pr_onpro
;
lwp
->
state
=
_lwpsinfo
->
pr_sname
;
lwp
->
time
=
_lwpsinfo
->
pr_time
.
tv_sec
;
slwp
->
taskid
=
sproc
->
taskid
;
slwp
->
projid
=
sproc
->
projid
;
slwp
->
poolid
=
sproc
->
poolid
;
slwp
->
contid
=
sproc
->
contid
;
lwp
->
show
=
false
;
// Tasks done only for NEW LWPs
if
(
!
preExisting
)
{
slwp
->
is_lwp
=
true
;
lwp
->
basenameOffset
=
-
1
;
slwp
->
kernel
=
sproc
->
kernel
;
// Fake values used for sorting
// Only set once because threads don't generally
// move... between... processes.
lwp
->
pid
=
lwpid
;
lwp
->
ppid
=
proc
->
pid
;
lwp
->
tgid
=
proc
->
pid
;
// Corresponding real values used for display
slwp
->
realpid
=
sproc
->
realpid
;
slwp
->
realppid
=
sproc
->
realpid
;
slwp
->
lwpid
=
lwpid_real
;
// Not tracked per thread
lwp
->
percent_mem
=
(
double
)
0
.
0
;
lwp
->
nlwp
=
0
;
lwp
->
m_resident
=
0
;
lwp
->
m_size
=
0
;
lwp
->
starttime_ctime
=
_lwpsinfo
->
pr_start
.
tv_sec
;
(
void
)
localtime_r
((
time_t
*
)
&
lwp
->
starttime_ctime
,
&
date
);
strftime
(
lwp
->
starttime_show
,
7
,
((
lwp
->
starttime_ctime
>
tv
.
tv_sec
-
86400
)
?
"%R "
:
"%b%d "
),
&
date
);
ProcessList_add
(
pl
,
lwp
);
// Setup process list
ProcessList
*
pl
=
(
ProcessList
*
)
listptr
;
SolarisProcessList
*
spl
=
(
SolarisProcessList
*
)
listptr
;
// Setup Process entry
Process
*
proc
=
ProcessList_getProcess
(
pl
,
_psinfo
->
pr_pid
*
1024
,
&
preExistingP
,
(
Process_New
)
SolarisProcess_new
);
SolarisProcess
*
sproc
=
(
SolarisProcess
*
)
proc
;
// Setup LWP entry
id_t
lwpid_real
=
_lwpsinfo
->
pr_lwpid
;
if
(
lwpid_real
>
1023
)
return
0
;
pid_t
lwpid
=
proc
->
pid
+
lwpid_real
;
Process
*
lwp
=
ProcessList_getProcess
(
pl
,
lwpid
,
&
preExistingL
,
(
Process_New
)
SolarisProcess_new
);
SolarisProcess
*
slwp
=
(
SolarisProcess
*
)
lwp
;
bool
onMasterLWP
=
(
_lwpsinfo
->
pr_lwpid
==
_psinfo
->
pr_lwp
.
pr_lwpid
);
// Determine whether we're updating proc info or LWP info
// based on whether or not we're on the representative LWP
// for a given proc
if
(
onMasterLWP
)
{
cproc
=
proc
;
csproc
=
sproc
;
preExisting
=
preExistingP
;
}
else
{
cproc
=
lwp
;
csproc
=
slwp
;
preExisting
=
preExistingL
;
}
// Top-level process only gets this for the representative LWP
if
(
lwp
->
state
==
'O'
)
proc
->
state
=
'O'
;
if
(
slwp
->
kernel
&&
!
pl
->
settings
->
hideKernelThreads
)
lwp
->
show
=
true
;
if
(
!
slwp
->
kernel
&&
!
pl
->
settings
->
hideUserlandThreads
)
lwp
->
show
=
true
;
lwp
->
updated
=
true
;
gettimeofday
(
&
tv
,
NULL
);
// Common code pass 1
cproc
->
show
=
false
;
csproc
->
zoneid
=
_psinfo
->
pr_zoneid
;
csproc
->
zname
=
SolarisProcessList_readZoneName
(
spl
->
kd
,
sproc
);
csproc
->
taskid
=
_psinfo
->
pr_taskid
;
csproc
->
projid
=
_psinfo
->
pr_projid
;
csproc
->
poolid
=
_psinfo
->
pr_poolid
;
csproc
->
contid
=
_psinfo
->
pr_contract
;
cproc
->
priority
=
_lwpsinfo
->
pr_pri
;
cproc
->
nice
=
_lwpsinfo
->
pr_nice
;
cproc
->
processor
=
_lwpsinfo
->
pr_onpro
;
cproc
->
state
=
_lwpsinfo
->
pr_sname
;
// This could potentially get bungled if the master LWP is not the first
// one enumerated. Unaware of any workaround right now.
if
((
cproc
->
state
==
'O'
)
&&
!
onMasterLWP
)
proc
->
state
=
'O'
;
// 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)
cproc
->
percent_mem
=
((
uint16_t
)
_psinfo
->
pr_pctmem
/
(
double
)
32768
)
*
(
double
)
100
.
0
;
cproc
->
st_uid
=
_psinfo
->
pr_euid
;
cproc
->
user
=
UsersTable_getRef
(
pl
->
usersTable
,
proc
->
st_uid
);
cproc
->
pgrp
=
_psinfo
->
pr_pgid
;
cproc
->
nlwp
=
_psinfo
->
pr_nlwp
;
cproc
->
comm
=
xStrdup
(
_psinfo
->
pr_fname
);
cproc
->
commLen
=
strnlen
(
_psinfo
->
pr_fname
,
PRFNSZ
);
cproc
->
tty_nr
=
_psinfo
->
pr_ttydev
;
cproc
->
m_resident
=
_psinfo
->
pr_rssize
/
PAGE_SIZE_KB
;
cproc
->
m_size
=
_psinfo
->
pr_size
/
PAGE_SIZE_KB
;
return
;
}
if
(
!
preExisting
)
{
csproc
->
realpid
=
_psinfo
->
pr_pid
;
csproc
->
lwpid
=
lwpid_real
;
}
int
SolarisProcessList_walkproc
(
psinfo_t
*
_psinfo
,
lwpsinfo_t
*
_lwpsinfo
,
void
*
listptr
)
{
ProcessList
*
pl
=
(
ProcessList
*
)
listptr
;
SolarisProcessList
*
spl
=
(
SolarisProcessList
*
)
listptr
;
bool
preExisting
=
false
;
Process
*
proc
=
ProcessList_getProcess
(
pl
,
_psinfo
->
pr_pid
*
1024
,
&
preExisting
,
(
Process_New
)
SolarisProcess_new
);
SolarisProcess
*
sproc
=
(
SolarisProcess
*
)
proc
;
struct
timeval
tv
;
struct
tm
date
;
// End common code pass 1
// Are we on the representative LWP?
if
(
_lwpsinfo
->
pr_lwpid
==
_psinfo
->
pr_lwp
.
pr_lwpid
)
{
// Common items set for both new and refreshed processes
if
(
onMasterLWP
)
{
// Are we on the representative LWP?
proc
->
ppid
=
(
_psinfo
->
pr_ppid
*
1024
);
proc
->
tgid
=
(
_psinfo
->
pr_ppid
*
1024
);
sproc
->
realppid
=
_psinfo
->
pr_ppid
;
sproc
->
zoneid
=
_psinfo
->
pr_zoneid
;
sproc
->
zname
=
SolarisProcessList_readZoneName
(
spl
->
kd
,
sproc
);
// NOTE: These 'percentages' are 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)
// 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_mem
=
((
uint16_t
)
_psinfo
->
pr_pctmem
/
(
double
)
32768
)
*
(
double
)
100
.
0
;
proc
->
st_uid
=
_psinfo
->
pr_euid
;
proc
->
user
=
UsersTable_getRef
(
pl
->
usersTable
,
proc
->
st_uid
);
proc
->
pgrp
=
_psinfo
->
pr_pgid
;
proc
->
nlwp
=
_psinfo
->
pr_nlwp
;
proc
->
comm
=
xStrdup
(
_psinfo
->
pr_fname
);
proc
->
commLen
=
strnlen
(
_psinfo
->
pr_fname
,
PRFNSZ
);
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
->
priority
=
_psinfo
->
pr_lwp
.
pr_pri
;
proc
->
nice
=
_psinfo
->
pr_lwp
.
pr_nice
;
proc
->
processor
=
_psinfo
->
pr_lwp
.
pr_onpro
;
proc
->
state
=
_psinfo
->
pr_lwp
.
pr_sname
;
proc
->
time
=
_psinfo
->
pr_time
.
tv_sec
;
sproc
->
taskid
=
_psinfo
->
pr_taskid
;
sproc
->
projid
=
_psinfo
->
pr_projid
;
sproc
->
poolid
=
_psinfo
->
pr_poolid
;
sproc
->
contid
=
_psinfo
->
pr_contract
;
// Tasks done only for NEW processes
if
(
!
preExisting
)
{
if
(
!
preExisting
)
{
// Tasks done only for NEW processes
sproc
->
is_lwp
=
false
;
// Fake PID values used for sorting, since Solaris LWPs lack unique PIDs
proc
->
pid
=
(
_psinfo
->
pr_pid
*
1024
);
// Corresponding real values used for display
sproc
->
realpid
=
_psinfo
->
pr_pid
;
sproc
->
lwpid
=
1
;
proc
->
starttime_ctime
=
_psinfo
->
pr_start
.
tv_sec
;
if
((
sproc
->
realppid
<=
0
)
&&
!
(
sproc
->
realpid
<=
1
))
{
sproc
->
kernel
=
true
;
}
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
);
ProcessList_add
(
pl
,
proc
);
}
// Update proc and thread counts based on settings
if
(
sproc
->
kernel
&&
!
pl
->
settings
->
hideKernelThreads
)
{
pl
->
kernelThreads
+=
proc
->
nlwp
;
pl
->
totalTasks
+=
proc
->
nlwp
+
1
;
...
...
@@ -385,11 +340,39 @@ int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void *
}
}
proc
->
show
=
!
(
pl
->
settings
->
hideKernelThreads
&&
sproc
->
kernel
);
proc
->
updated
=
true
;
}
else
{
// We are not in the rep. LWP, so jump to the LWP handling code
ProcessList_enumerateLWPs
(
proc
,
pl
,
_lwpsinfo
,
tv
);
}
else
{
// We are not in the master LWP, so jump to the LWP handling code
lwp
->
percent_cpu
=
((
uint16_t
)
_lwpsinfo
->
pr_pctcpu
/
(
double
)
32768
)
*
(
double
)
100
.
0
;
lwp
->
time
=
_lwpsinfo
->
pr_time
.
tv_sec
;
if
(
!
preExisting
)
{
// Tasks done only for NEW LWPs
slwp
->
is_lwp
=
true
;
lwp
->
basenameOffset
=
-
1
;
lwp
->
ppid
=
proc
->
pid
;
lwp
->
tgid
=
proc
->
pid
;
slwp
->
realppid
=
sproc
->
realpid
;
lwp
->
starttime_ctime
=
_lwpsinfo
->
pr_start
.
tv_sec
;
}
// Top-level process only gets this for the representative LWP
if
(
slwp
->
kernel
&&
!
pl
->
settings
->
hideKernelThreads
)
lwp
->
show
=
true
;
if
(
!
slwp
->
kernel
&&
!
pl
->
settings
->
hideUserlandThreads
)
lwp
->
show
=
true
;
}
// Top-level LWP or subordinate LWP
// Common code pass 2
if
(
!
preExisting
)
{
if
((
sproc
->
realppid
<=
0
)
&&
!
(
sproc
->
realpid
<=
1
))
{
csproc
->
kernel
=
true
;
}
else
{
csproc
->
kernel
=
false
;
}
(
void
)
localtime_r
((
time_t
*
)
&
cproc
->
starttime_ctime
,
&
date
);
strftime
(
cproc
->
starttime_show
,
7
,
((
cproc
->
starttime_ctime
>
tv
.
tv_sec
-
86400
)
?
"%R "
:
"%b%d "
),
&
date
);
ProcessList_add
(
pl
,
cproc
);
}
cproc
->
updated
=
true
;
// End common code pass 2
return
0
;
}
...
...
@@ -397,6 +380,6 @@ void ProcessList_goThroughEntries(ProcessList* this) {
SolarisProcessList_scanCPUTime
(
this
);
SolarisProcessList_scanMemoryInfo
(
this
);
this
->
kernelThreads
=
1
;
proc_walk
(
&
SolarisProcessList_walkproc
,
this
,
PR_WALK_LWP
);
proc_walk
(
&
SolarisProcessList_walkproc
,
this
,
PR_WALK_LWP
);
}
solaris/SolarisProcessList.h
View file @
475798e8
...
...
@@ -50,8 +50,6 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui
void
ProcessList_delete
(
ProcessList
*
this
);
void
ProcessList_enumerateLWPs
(
Process
*
proc
,
ProcessList
*
pl
,
lwpsinfo_t
*
_lwpsinfo
,
struct
timeval
tv
);
int
SolarisProcessList_walkproc
(
psinfo_t
*
_psinfo
,
lwpsinfo_t
*
_lwpsinfo
,
void
*
listptr
);
void
ProcessList_goThroughEntries
(
ProcessList
*
this
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment