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
cf0c074c
Commit
cf0c074c
authored
Jan 29, 2018
by
Hisham Muhammad
Browse files
Add IPC performance counter for Linux
parent
9c40c9a0
Changes
6
Hide whitespace changes
Inline
Side-by-side
Makefile.am
View file @
cf0c074c
...
...
@@ -39,10 +39,12 @@ EnvScreen.h InfoScreen.h XAlloc.h
if
HTOP_LINUX
htop_CFLAGS
+=
-rdynamic
myhtopplatsources
=
linux/Platform.c linux/IOPriorityPanel.c linux/IOPriority.c
\
linux/LinuxProcess.c linux/LinuxProcessList.c linux/LinuxCRT.c linux/Battery.c
linux/LinuxProcess.c linux/LinuxProcessList.c linux/LinuxCRT.c linux/Battery.c
\
linux/PerfCounter.c
myhtopplatheaders
=
linux/Platform.h linux/IOPriorityPanel.h linux/IOPriority.h
\
linux/LinuxProcess.h linux/LinuxProcessList.h linux/LinuxCRT.h linux/Battery.h
linux/LinuxProcess.h linux/LinuxProcessList.h linux/LinuxCRT.h linux/Battery.h
\
linux/PerfCounter.h
endif
if
HTOP_FREEBSD
...
...
configure.ac
View file @
cf0c074c
...
...
@@ -257,8 +257,10 @@ then
fi
AC_ARG_ENABLE(perfcounters, [AS_HELP_STRING([--enable-perfcounters], [enable hardware performance counters])],, enable_perfcounters="yes")
if test "x$enable_perfcounters
_
$my_htop_platform" =
xyes_
linux
if test "x$enable_perfcounters
" = "xyes" -a "
$my_htop_platform" =
"
linux
"
then
AC_DEFINE(HAVE_PERFCOUNTERS, 1, [Define if hardware performance counter support should be enabled.])
AC_CHECK_HEADERS([linux/perf_counter.h], [have_perf_counter=yes],
[have_perf_counter=no])
...
...
linux/LinuxProcess.c
View file @
cf0c074c
...
...
@@ -18,11 +18,14 @@ in the source distribution for its full text.
/*{
#include "PerfCounter.h"
#define PROCESS_FLAG_LINUX_IOPRIO 0x0100
#define PROCESS_FLAG_LINUX_OPENVZ 0x0200
#define PROCESS_FLAG_LINUX_VSERVER 0x0400
#define PROCESS_FLAG_LINUX_CGROUP 0x0800
#define PROCESS_FLAG_LINUX_OOM 0x1000
#define PROCESS_FLAG_LINUX_HPC 0x2000
typedef enum UnsupportedProcessFields {
FLAGS = 9,
...
...
@@ -86,7 +89,10 @@ typedef enum LinuxProcessFields {
PERCENT_IO_DELAY = 117,
PERCENT_SWAP_DELAY = 118,
#endif
LAST_PROCESSFIELD = 119,
#ifdef HAVE_PERFCOUNTERS
IPC = 119,
#endif
LAST_PROCESSFIELD = 120,
} LinuxProcessField;
#include "IOPriority.h"
...
...
@@ -139,6 +145,11 @@ typedef struct LinuxProcess_ {
float blkio_delay_percent;
float swapin_delay_percent;
#endif
#ifdef HAVE_PERFCOUNTERS
PerfCounter* cycleCounter;
PerfCounter* insnCounter;
double ipc;
#endif
} LinuxProcess;
#ifndef Process_isKernelThread
...
...
@@ -233,6 +244,9 @@ ProcessFieldData Process_fields[] = {
[
PERCENT_CPU_DELAY
]
=
{
.
name
=
"PERCENT_CPU_DELAY"
,
.
title
=
"CPUD% "
,
.
description
=
"CPU delay %"
,
.
flags
=
0
,
},
[
PERCENT_IO_DELAY
]
=
{
.
name
=
"PERCENT_IO_DELAY"
,
.
title
=
"IOD% "
,
.
description
=
"Block I/O delay %"
,
.
flags
=
0
,
},
[
PERCENT_SWAP_DELAY
]
=
{
.
name
=
"PERCENT_SWAP_DELAY"
,
.
title
=
"SWAPD% "
,
.
description
=
"Swapin delay %"
,
.
flags
=
0
,
},
#endif
#ifdef HAVE_PERFCOUNTERS
[
IPC
]
=
{
.
name
=
"IPC"
,
.
title
=
" IPC "
,
.
description
=
"Executed instructions per cycle"
,
.
flags
=
PROCESS_FLAG_LINUX_HPC
,
},
#endif
[
LAST_PROCESSFIELD
]
=
{
.
name
=
"*** report bug! ***"
,
.
title
=
NULL
,
.
description
=
NULL
,
.
flags
=
0
,
},
};
...
...
@@ -273,6 +287,10 @@ void Process_delete(Object* cast) {
Process_done
((
Process
*
)
cast
);
#ifdef HAVE_CGROUP
free
(
this
->
cgroup
);
#endif
#ifdef HAVE_PERFCOUNTERS
PerfCounter_delete
(
this
->
cycleCounter
);
PerfCounter_delete
(
this
->
insnCounter
);
#endif
free
(
this
->
ttyDevice
);
free
(
this
);
...
...
@@ -394,6 +412,16 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
case
PERCENT_IO_DELAY
:
LinuxProcess_printDelay
(
lp
->
blkio_delay_percent
,
buffer
,
n
);
break
;
case
PERCENT_SWAP_DELAY
:
LinuxProcess_printDelay
(
lp
->
swapin_delay_percent
,
buffer
,
n
);
break
;
#endif
#ifdef HAVE_PERFCOUNTERS
case
IPC
:
{
if
(
lp
->
ipc
==
-
1
)
{
attr
=
CRT_colors
[
PROCESS_SHADOW
];
xSnprintf
(
buffer
,
n
,
" N/A "
);
break
;
}
else
{
xSnprintf
(
buffer
,
n
,
"%5.2f "
,
lp
->
ipc
);
break
;
}
}
#endif
default:
Process_writeField
((
Process
*
)
this
,
str
,
field
);
return
;
...
...
@@ -463,6 +491,10 @@ long LinuxProcess_compare(const void* v1, const void* v2) {
case
PERCENT_SWAP_DELAY
:
return
(
p2
->
swapin_delay_percent
>
p1
->
swapin_delay_percent
?
1
:
-
1
);
#endif
#ifdef HAVE_PERFCOUNTERS
case
IPC
:
return
(
p2
->
ipc
>
p1
->
ipc
?
1
:
-
1
);
#endif
case
IO_PRIORITY
:
return
LinuxProcess_effectiveIOPriority
(
p1
)
-
LinuxProcess_effectiveIOPriority
(
p2
);
default:
...
...
linux/LinuxProcess.h
View file @
cf0c074c
...
...
@@ -10,11 +10,14 @@ in the source distribution for its full text.
*/
#include "PerfCounter.h"
#define PROCESS_FLAG_LINUX_IOPRIO 0x0100
#define PROCESS_FLAG_LINUX_OPENVZ 0x0200
#define PROCESS_FLAG_LINUX_VSERVER 0x0400
#define PROCESS_FLAG_LINUX_CGROUP 0x0800
#define PROCESS_FLAG_LINUX_OOM 0x1000
#define PROCESS_FLAG_LINUX_HPC 0x2000
typedef
enum
UnsupportedProcessFields
{
FLAGS
=
9
,
...
...
@@ -78,7 +81,10 @@ typedef enum LinuxProcessFields {
PERCENT_IO_DELAY
=
117
,
PERCENT_SWAP_DELAY
=
118
,
#endif
LAST_PROCESSFIELD
=
119
,
#ifdef HAVE_PERFCOUNTERS
IPC
=
119
,
#endif
LAST_PROCESSFIELD
=
120
,
}
LinuxProcessField
;
#include "IOPriority.h"
...
...
@@ -131,6 +137,11 @@ typedef struct LinuxProcess_ {
float
blkio_delay_percent
;
float
swapin_delay_percent
;
#endif
#ifdef HAVE_PERFCOUNTERS
PerfCounter
*
cycleCounter
;
PerfCounter
*
insnCounter
;
double
ipc
;
#endif
}
LinuxProcess
;
#ifndef Process_isKernelThread
...
...
linux/LinuxProcessList.c
View file @
cf0c074c
...
...
@@ -660,6 +660,32 @@ static void LinuxProcessList_readDelayAcctData(LinuxProcessList* this, LinuxProc
#endif
#ifdef HAVE_PERFCOUNTERS
static
void
LinuxProcessList_readPerfCounters
(
LinuxProcess
*
lp
)
{
if
(
!
lp
->
cycleCounter
)
{
lp
->
cycleCounter
=
PerfCounter_new
(
lp
->
super
.
pid
,
PERF_TYPE_HARDWARE
,
PERF_COUNT_HW_CPU_CYCLES
);
}
if
(
!
lp
->
insnCounter
)
{
lp
->
insnCounter
=
PerfCounter_new
(
lp
->
super
.
pid
,
PERF_TYPE_HARDWARE
,
PERF_COUNT_HW_INSTRUCTIONS
);
}
bool
cOk
=
PerfCounter_read
(
lp
->
cycleCounter
);
bool
iOk
=
PerfCounter_read
(
lp
->
insnCounter
);
if
(
cOk
&&
iOk
)
{
uint64_t
i
=
PerfCounter_delta
(
lp
->
insnCounter
);
uint64_t
c
=
PerfCounter_delta
(
lp
->
cycleCounter
);
if
(
c
>
0
)
{
lp
->
ipc
=
(
double
)
i
/
c
;
}
else
{
lp
->
ipc
=
0
;
}
}
else
{
lp
->
ipc
=
-
1
;
}
}
#endif
static
void
setCommand
(
Process
*
process
,
const
char
*
command
,
int
len
)
{
if
(
process
->
comm
&&
process
->
commLen
>=
len
)
{
strncpy
(
process
->
comm
,
command
,
len
+
1
);
...
...
@@ -871,6 +897,11 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
if
(
ss
->
flags
&
PROCESS_FLAG_LINUX_OOM
)
LinuxProcessList_readOomData
(
lp
,
dirname
,
name
);
#ifdef HAVE_PERFCOUNTERS
if
(
ss
->
flags
&
PROCESS_FLAG_LINUX_HPC
)
LinuxProcessList_readPerfCounters
(
lp
);
#endif
if
(
proc
->
state
==
'Z'
&&
(
proc
->
basenameOffset
==
0
))
{
proc
->
basenameOffset
=
-
1
;
setCommand
(
proc
,
command
,
commLen
);
...
...
linux/LinuxProcessList.h
View file @
cf0c074c
...
...
@@ -116,6 +116,10 @@ void ProcessList_delete(ProcessList* pl);
#endif
#ifdef HAVE_PERFCOUNTERS
#endif
void
ProcessList_goThroughEntries
(
ProcessList
*
super
);
#endif
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