Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
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
0cbdf8ba
Commit
0cbdf8ba
authored
7 years ago
by
Hisham Muhammad
Browse files
Options
Download
Email Patches
Plain Diff
Implemented various performance counters
parent
cf0c074c
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
Process.c
+19
-19
Process.c
Process.h
+3
-1
Process.h
ScreensPanel.c
+6
-2
ScreensPanel.c
Settings.h
+0
-1
Settings.h
linux/LinuxProcess.c
+113
-37
linux/LinuxProcess.c
linux/LinuxProcess.h
+44
-10
linux/LinuxProcess.h
linux/LinuxProcessList.c
+66
-21
linux/LinuxProcessList.c
linux/LinuxProcessList.h
+44
-0
linux/LinuxProcessList.h
linux/Platform.c
+1
-0
linux/Platform.c
scripts/MakeHeader.py
+12
-2
scripts/MakeHeader.py
with
308 additions
and
93 deletions
+308
-93
Process.c
View file @
0cbdf8ba
...
...
@@ -28,6 +28,7 @@ in the source distribution for its full text.
#include <time.h>
#include <assert.h>
#include <math.h>
#include <inttypes.h>
#ifdef __ANDROID__
#define SYS_ioprio_get __NR_ioprio_get
...
...
@@ -150,7 +151,7 @@ typedef struct ProcessFieldData_ {
const char* name;
const char* title;
const char* description;
int flags;
u
int
64_t
flags;
} ProcessFieldData;
// Implemented in platform-specific code:
...
...
@@ -362,6 +363,21 @@ void Process_outputRate(RichString* str, char* buffer, int n, double rate, int c
}
}
void
Process_printPercentage
(
float
val
,
char
*
buffer
,
int
n
,
int
*
attr
)
{
if
(
val
>=
0
)
{
if
(
val
<
100
)
{
xSnprintf
(
buffer
,
n
,
"%4.1f "
,
val
);
}
else
if
(
val
<
1000
)
{
xSnprintf
(
buffer
,
n
,
"%3d. "
,
(
unsigned
int
)
val
);
}
else
{
xSnprintf
(
buffer
,
n
,
"%4d "
,
(
unsigned
int
)
val
);
}
}
else
{
*
attr
=
CRT_colors
[
PROCESS_SHADOW
];
xSnprintf
(
buffer
,
n
,
" N/A "
);
}
}
void
Process_writeField
(
Process
*
this
,
RichString
*
str
,
ProcessField
field
)
{
char
buffer
[
256
];
buffer
[
255
]
=
'\0'
;
int
attr
=
CRT_colors
[
DEFAULT_COLOR
];
...
...
@@ -370,24 +386,8 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
bool
coloring
=
this
->
settings
->
highlightMegabytes
;
switch
(
field
)
{
case
PERCENT_CPU
:
{
if
(
this
->
percent_cpu
>
999
.
9
)
{
xSnprintf
(
buffer
,
n
,
"%4d "
,
(
unsigned
int
)
this
->
percent_cpu
);
}
else
if
(
this
->
percent_cpu
>
99
.
9
)
{
xSnprintf
(
buffer
,
n
,
"%3d. "
,
(
unsigned
int
)
this
->
percent_cpu
);
}
else
{
xSnprintf
(
buffer
,
n
,
"%4.1f "
,
this
->
percent_cpu
);
}
break
;
}
case
PERCENT_MEM
:
{
if
(
this
->
percent_mem
>
99
.
9
)
{
xSnprintf
(
buffer
,
n
,
"100. "
);
}
else
{
xSnprintf
(
buffer
,
n
,
"%4.1f "
,
this
->
percent_mem
);
}
break
;
}
case
PERCENT_CPU
:
Process_printPercentage
(
this
->
percent_cpu
,
buffer
,
n
,
&
attr
);
break
;
case
PERCENT_MEM
:
Process_printPercentage
(
this
->
percent_mem
,
buffer
,
n
,
&
attr
);
break
;
case
COMM
:
{
if
(
this
->
settings
->
highlightThreads
&&
Process_isThread
(
this
))
{
attr
=
CRT_colors
[
PROCESS_THREAD
];
...
...
This diff is collapsed.
Click to expand it.
Process.h
View file @
0cbdf8ba
...
...
@@ -129,7 +129,7 @@ typedef struct ProcessFieldData_ {
const
char
*
name
;
const
char
*
title
;
const
char
*
description
;
int
flags
;
u
int
64_t
flags
;
}
ProcessFieldData
;
// Implemented in platform-specific code:
...
...
@@ -176,6 +176,8 @@ void Process_printTime(RichString* str, unsigned long long totalHundredths);
void
Process_outputRate
(
RichString
*
str
,
char
*
buffer
,
int
n
,
double
rate
,
int
coloring
);
void
Process_printPercentage
(
float
val
,
char
*
buffer
,
int
n
,
int
*
attr
);
void
Process_writeField
(
Process
*
this
,
RichString
*
str
,
ProcessField
field
);
void
Process_display
(
Object
*
cast
,
RichString
*
out
);
...
...
This diff is collapsed.
Click to expand it.
ScreensPanel.c
View file @
0cbdf8ba
...
...
@@ -48,6 +48,7 @@ typedef struct ScreenListItem_ {
}*/
ObjectClass
ScreenListItem_class
=
{
.
extends
=
Class
(
ListItem
),
.
display
=
ListItem_display
,
.
delete
=
ListItem_delete
,
.
compare
=
ListItem_compare
...
...
@@ -319,8 +320,11 @@ void ScreensPanel_update(Panel* super) {
this
->
settings
->
changed
=
true
;
this
->
settings
->
screens
=
xRealloc
(
this
->
settings
->
screens
,
sizeof
(
char
*
)
*
(
size
+
1
));
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
char
*
name
=
((
ListItem
*
)
Panel_get
(
super
,
i
))
->
value
;
this
->
settings
->
screens
[
i
]
->
name
=
xStrdup
(
name
);
ScreenListItem
*
item
=
(
ScreenListItem
*
)
Panel_get
(
super
,
i
);
ScreenSettings
*
ss
=
item
->
ss
;
free
(
ss
->
name
);
this
->
settings
->
screens
[
i
]
=
ss
;
ss
->
name
=
xStrdup
(((
ListItem
*
)
item
)
->
value
);
}
this
->
settings
->
screens
[
size
]
=
NULL
;
}
This diff is collapsed.
Click to expand it.
Settings.h
View file @
0cbdf8ba
...
...
@@ -9,7 +9,6 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#define DEFAULT_DELAY 15
#include "Process.h"
#include <stdbool.h>
...
...
This diff is collapsed.
Click to expand it.
linux/LinuxProcess.c
View file @
0cbdf8ba
...
...
@@ -20,12 +20,22 @@ 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
#define PROCESS_FLAG_LINUX_IOPRIO 0x0100L
#define PROCESS_FLAG_LINUX_OPENVZ 0x0200L
#define PROCESS_FLAG_LINUX_VSERVER 0x0400L
#define PROCESS_FLAG_LINUX_CGROUP 0x0800L
#define PROCESS_FLAG_LINUX_OOM 0x1000L
#define PROCESS_FLAG_LINUX_HPC 0xff0000L
#define PROCESS_FLAG_LINUX_HPC_CYCLE 0x10000L
#define PROCESS_FLAG_LINUX_HPC_INSN 0x20000L
#define PROCESS_FLAG_LINUX_HPC_MISS 0x40000L
#define PROCESS_FLAG_LINUX_HPC_BMISS 0x80000L
#define PROCESS_FLAG_LINUX_HPC_L1DR 0x100000L
#define PROCESS_FLAG_LINUX_HPC_L1DW 0x200000L
#define PROCESS_FLAG_LINUX_HPC_L1DRM 0x400000L
#define PROCESS_FLAG_LINUX_HPC_L1DWM 0x800000L
typedef enum UnsupportedProcessFields {
FLAGS = 9,
...
...
@@ -91,8 +101,16 @@ typedef enum LinuxProcessFields {
#endif
#ifdef HAVE_PERFCOUNTERS
IPC = 119,
MCYCLE = 120,
MINSTR = 121,
PERCENT_MISS = 122,
PERCENT_BMISS = 123,
L1DREADS = 124,
L1DRMISSES = 125,
L1DWRITES = 126,
L1DWMISSES = 127,
#endif
LAST_PROCESSFIELD = 12
0
,
LAST_PROCESSFIELD = 12
8
,
} LinuxProcessField;
#include "IOPriority.h"
...
...
@@ -148,7 +166,21 @@ typedef struct LinuxProcess_ {
#ifdef HAVE_PERFCOUNTERS
PerfCounter* cycleCounter;
PerfCounter* insnCounter;
double ipc;
PerfCounter* missCounter;
PerfCounter* brCounter;
PerfCounter* l1drCounter;
PerfCounter* l1drmCounter;
PerfCounter* l1dwCounter;
PerfCounter* l1dwmCounter;
float ipc;
float mcycle;
float minstr;
float pMiss;
float pBMiss;
float l1dr;
float l1drm;
float l1dw;
float l1dwm;
#endif
} LinuxProcess;
...
...
@@ -241,12 +273,20 @@ ProcessFieldData Process_fields[] = {
[
OOM
]
=
{
.
name
=
"OOM"
,
.
title
=
" OOM "
,
.
description
=
"OOM (Out-of-Memory) killer score"
,
.
flags
=
PROCESS_FLAG_LINUX_OOM
,
},
[
IO_PRIORITY
]
=
{
.
name
=
"IO_PRIORITY"
,
.
title
=
"IO "
,
.
description
=
"I/O priority"
,
.
flags
=
PROCESS_FLAG_LINUX_IOPRIO
,
},
#ifdef HAVE_DELAYACCT
[
PERCENT_CPU_DELAY
]
=
{
.
name
=
"PERCENT_CPU_DELAY"
,
.
title
=
"CP
U
D% "
,
.
description
=
"CPU delay %"
,
.
flags
=
0
,
},
[
PERCENT_CPU_DELAY
]
=
{
.
name
=
"PERCENT_CPU_DELAY"
,
.
title
=
"CPD% "
,
.
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
=
"SW
AP
D% "
,
.
description
=
"Swapin delay %"
,
.
flags
=
0
,
},
[
PERCENT_SWAP_DELAY
]
=
{
.
name
=
"PERCENT_SWAP_DELAY"
,
.
title
=
"SWD% "
,
.
description
=
"Swapin delay %"
,
.
flags
=
0
,
},
#endif
#ifdef HAVE_PERFCOUNTERS
[
IPC
]
=
{
.
name
=
"IPC"
,
.
title
=
" IPC "
,
.
description
=
"Executed instructions per cycle"
,
.
flags
=
PROCESS_FLAG_LINUX_HPC
,
},
[
IPC
]
=
{
.
name
=
"IPC"
,
.
title
=
" IPC "
,
.
description
=
"Executed instructions per cycle"
,
.
flags
=
PROCESS_FLAG_LINUX_HPC_CYCLE
|
PROCESS_FLAG_LINUX_HPC_INSN
,
},
[
MCYCLE
]
=
{
.
name
=
"MCYCLE"
,
.
title
=
" Mcycle "
,
.
description
=
"Cycles (millions)"
,
.
flags
=
PROCESS_FLAG_LINUX_HPC_CYCLE
,
},
[
MINSTR
]
=
{
.
name
=
"MINSTR"
,
.
title
=
" Minstr "
,
.
description
=
"Instructions (millions)"
,
.
flags
=
PROCESS_FLAG_LINUX_HPC_INSN
,
},
[
PERCENT_MISS
]
=
{
.
name
=
"PERCENT_MISS"
,
.
title
=
"MIS% "
,
.
description
=
"Cache misses per 100 instructions"
,
.
flags
=
PROCESS_FLAG_LINUX_HPC_MISS
|
PROCESS_FLAG_LINUX_HPC_INSN
,
},
[
PERCENT_BMISS
]
=
{
.
name
=
"PERCENT_BMISS"
,
.
title
=
"BrM% "
,
.
description
=
"Branch misprediction per 100 instructions"
,
.
flags
=
PROCESS_FLAG_LINUX_HPC_BMISS
|
PROCESS_FLAG_LINUX_HPC_INSN
,
},
[
L1DREADS
]
=
{
.
name
=
"L1DREADS"
,
.
title
=
" L1Dread "
,
.
description
=
"L1 data cache: reads (thousands)"
,
.
flags
=
PROCESS_FLAG_LINUX_HPC_L1DR
,
},
[
L1DRMISSES
]
=
{
.
name
=
"L1DRMISSES"
,
.
title
=
" R miss "
,
.
description
=
"L1 data cache: reads misses (thousands)"
,
.
flags
=
PROCESS_FLAG_LINUX_HPC_L1DRM
,
},
[
L1DWRITES
]
=
{
.
name
=
"L1DWRITES"
,
.
title
=
" L1Dwrite "
,
.
description
=
"L1D data cache: writes (thousands)"
,
.
flags
=
PROCESS_FLAG_LINUX_HPC_L1DW
,
},
[
L1DWMISSES
]
=
{
.
name
=
"L1DWMISSES"
,
.
title
=
" W miss "
,
.
description
=
"L1D data cache: write misses (thousands)"
,
.
flags
=
PROCESS_FLAG_LINUX_HPC_L1DWM
,
},
#endif
[
LAST_PROCESSFIELD
]
=
{
.
name
=
"*** report bug! ***"
,
.
title
=
NULL
,
.
description
=
NULL
,
.
flags
=
0
,
},
};
...
...
@@ -324,14 +364,43 @@ bool LinuxProcess_setIOPriority(LinuxProcess* this, IOPriority ioprio) {
return
(
LinuxProcess_updateIOPriority
(
this
)
==
ioprio
);
}
#ifdef HAVE_DELAYACCT
void
LinuxProcess_printDelay
(
float
delay_percent
,
char
*
buffer
,
int
n
)
{
if
(
delay_percent
==
-
1LL
)
{
xSnprintf
(
buffer
,
n
,
" N/A "
);
}
else
{
xSnprintf
(
buffer
,
n
,
"%4.1f "
,
delay_percent
);
}
#if HAVE_DELAYACCT || HAVE_PERFCOUNTERS
static
char
*
perfFmt
[]
=
{
"%6.2f "
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
"%6.1f "
,
"%7.1f "
,
"%8.2f "
,
"%9.1f "
,
};
static
char
*
perfNA
[]
=
{
" N/A "
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
" N/A "
,
" N/A "
,
" N/A "
,
" N/A "
,
};
static
inline
void
LinuxProcess_printPerfCounter
(
float
val
,
int
len
,
char
*
buffer
,
int
n
,
int
*
attr
)
{
if
(
val
!=
-
1
)
{
xSnprintf
(
buffer
,
n
,
perfFmt
[
len
],
val
);
}
else
{
xSnprintf
(
buffer
,
n
,
perfNA
[
len
]);
*
attr
=
CRT_colors
[
PROCESS_SHADOW
];
}
}
#endif
void
LinuxProcess_writeField
(
Process
*
this
,
RichString
*
str
,
ProcessField
field
)
{
...
...
@@ -408,19 +477,20 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
break
;
}
#ifdef HAVE_DELAYACCT
case
PERCENT_CPU_DELAY
:
Linux
Process_print
Delay
(
lp
->
cpu_delay_percent
,
buffer
,
n
);
break
;
case
PERCENT_IO_DELAY
:
Linux
Process_print
Delay
(
lp
->
blkio_delay_percent
,
buffer
,
n
);
break
;
case
PERCENT_SWAP_DELAY
:
Linux
Process_print
Delay
(
lp
->
swapin_delay_percent
,
buffer
,
n
);
break
;
case
PERCENT_CPU_DELAY
:
Process_print
Percentage
(
lp
->
cpu_delay_percent
,
buffer
,
n
,
&
attr
);
break
;
case
PERCENT_IO_DELAY
:
Process_print
Percentage
(
lp
->
blkio_delay_percent
,
buffer
,
n
,
&
attr
);
break
;
case
PERCENT_SWAP_DELAY
:
Process_print
Percentage
(
lp
->
swapin_delay_percent
,
buffer
,
n
,
&
attr
);
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
;
}
}
case
PERCENT_MISS
:
Process_printPercentage
(
lp
->
pMiss
,
buffer
,
n
,
&
attr
);
break
;
case
PERCENT_BMISS
:
Process_printPercentage
(
lp
->
pBMiss
,
buffer
,
n
,
&
attr
);
break
;
case
IPC
:
LinuxProcess_printPerfCounter
(
lp
->
ipc
,
0
,
buffer
,
n
,
&
attr
);
break
;
case
MCYCLE
:
LinuxProcess_printPerfCounter
(
lp
->
mcycle
,
8
,
buffer
,
n
,
&
attr
);
break
;
case
MINSTR
:
LinuxProcess_printPerfCounter
(
lp
->
minstr
,
8
,
buffer
,
n
,
&
attr
);
break
;
case
L1DREADS
:
LinuxProcess_printPerfCounter
(
lp
->
l1dr
,
9
,
buffer
,
n
,
&
attr
);
break
;
case
L1DRMISSES
:
LinuxProcess_printPerfCounter
(
lp
->
l1drm
,
9
,
buffer
,
n
,
&
attr
);
break
;
case
L1DWRITES
:
LinuxProcess_printPerfCounter
(
lp
->
l1dw
,
9
,
buffer
,
n
,
&
attr
);
break
;
case
L1DWMISSES
:
LinuxProcess_printPerfCounter
(
lp
->
l1dwm
,
9
,
buffer
,
n
,
&
attr
);
break
;
#endif
default:
Process_writeField
((
Process
*
)
this
,
str
,
field
);
...
...
@@ -429,6 +499,8 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
RichString_append
(
str
,
attr
,
buffer
);
}
#define COMPARE_FIELD(_f) return (p2->_f > p1->_f ? 1 : -1)
long
LinuxProcess_compare
(
const
void
*
v1
,
const
void
*
v2
)
{
LinuxProcess
*
p1
,
*
p2
;
Settings
*
settings
=
((
Process
*
)
v1
)
->
settings
;
...
...
@@ -484,16 +556,20 @@ long LinuxProcess_compare(const void* v1, const void* v2) {
case
OOM
:
return
(
p2
->
oom
-
p1
->
oom
);
#ifdef HAVE_DELAYACCT
case
PERCENT_CPU_DELAY
:
return
(
p2
->
cpu_delay_percent
>
p1
->
cpu_delay_percent
?
1
:
-
1
);
case
PERCENT_IO_DELAY
:
return
(
p2
->
blkio_delay_percent
>
p1
->
blkio_delay_percent
?
1
:
-
1
);
case
PERCENT_SWAP_DELAY
:
return
(
p2
->
swapin_delay_percent
>
p1
->
swapin_delay_percent
?
1
:
-
1
);
case
PERCENT_CPU_DELAY
:
COMPARE_FIELD
(
cpu_delay_percent
);
case
PERCENT_IO_DELAY
:
COMPARE_FIELD
(
blkio_delay_percent
);
case
PERCENT_SWAP_DELAY
:
COMPARE_FIELD
(
swapin_delay_percent
);
#endif
#ifdef HAVE_PERFCOUNTERS
case
IPC
:
return
(
p2
->
ipc
>
p1
->
ipc
?
1
:
-
1
);
case
PERCENT_MISS
:
COMPARE_FIELD
(
pMiss
);
case
PERCENT_BMISS
:
COMPARE_FIELD
(
pBMiss
);
case
IPC
:
COMPARE_FIELD
(
ipc
);
case
MCYCLE
:
COMPARE_FIELD
(
mcycle
);
case
MINSTR
:
COMPARE_FIELD
(
minstr
);
case
L1DREADS
:
COMPARE_FIELD
(
l1dr
);
case
L1DRMISSES
:
COMPARE_FIELD
(
l1drm
);
case
L1DWRITES
:
COMPARE_FIELD
(
l1dw
);
case
L1DWMISSES
:
COMPARE_FIELD
(
l1dwm
);
#endif
case
IO_PRIORITY
:
return
LinuxProcess_effectiveIOPriority
(
p1
)
-
LinuxProcess_effectiveIOPriority
(
p2
);
...
...
This diff is collapsed.
Click to expand it.
linux/LinuxProcess.h
View file @
0cbdf8ba
...
...
@@ -12,12 +12,22 @@ 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
#define PROCESS_FLAG_LINUX_IOPRIO 0x0100L
#define PROCESS_FLAG_LINUX_OPENVZ 0x0200L
#define PROCESS_FLAG_LINUX_VSERVER 0x0400L
#define PROCESS_FLAG_LINUX_CGROUP 0x0800L
#define PROCESS_FLAG_LINUX_OOM 0x1000L
#define PROCESS_FLAG_LINUX_HPC 0xff0000L
#define PROCESS_FLAG_LINUX_HPC_CYCLE 0x10000L
#define PROCESS_FLAG_LINUX_HPC_INSN 0x20000L
#define PROCESS_FLAG_LINUX_HPC_MISS 0x40000L
#define PROCESS_FLAG_LINUX_HPC_BMISS 0x80000L
#define PROCESS_FLAG_LINUX_HPC_L1DR 0x100000L
#define PROCESS_FLAG_LINUX_HPC_L1DW 0x200000L
#define PROCESS_FLAG_LINUX_HPC_L1DRM 0x400000L
#define PROCESS_FLAG_LINUX_HPC_L1DWM 0x800000L
typedef
enum
UnsupportedProcessFields
{
FLAGS
=
9
,
...
...
@@ -83,8 +93,16 @@ typedef enum LinuxProcessFields {
#endif
#ifdef HAVE_PERFCOUNTERS
IPC
=
119
,
MCYCLE
=
120
,
MINSTR
=
121
,
PERCENT_MISS
=
122
,
PERCENT_BMISS
=
123
,
L1DREADS
=
124
,
L1DRMISSES
=
125
,
L1DWRITES
=
126
,
L1DWMISSES
=
127
,
#endif
LAST_PROCESSFIELD
=
12
0
,
LAST_PROCESSFIELD
=
12
8
,
}
LinuxProcessField
;
#include "IOPriority.h"
...
...
@@ -140,7 +158,21 @@ typedef struct LinuxProcess_ {
#ifdef HAVE_PERFCOUNTERS
PerfCounter
*
cycleCounter
;
PerfCounter
*
insnCounter
;
double
ipc
;
PerfCounter
*
missCounter
;
PerfCounter
*
brCounter
;
PerfCounter
*
l1drCounter
;
PerfCounter
*
l1drmCounter
;
PerfCounter
*
l1dwCounter
;
PerfCounter
*
l1dwmCounter
;
float
ipc
;
float
mcycle
;
float
minstr
;
float
pMiss
;
float
pBMiss
;
float
l1dr
;
float
l1drm
;
float
l1dw
;
float
l1dwm
;
#endif
}
LinuxProcess
;
...
...
@@ -177,12 +209,14 @@ IOPriority LinuxProcess_updateIOPriority(LinuxProcess* this);
bool
LinuxProcess_setIOPriority
(
LinuxProcess
*
this
,
IOPriority
ioprio
);
#if
def
HAVE_DELAYACCT
void
LinuxProcess_printDelay
(
float
delay_percent
,
char
*
buffer
,
int
n
);
#if HAVE_DELAYACCT
|| HAVE_PERFCOUNTERS
#endif
void
LinuxProcess_writeField
(
Process
*
this
,
RichString
*
str
,
ProcessField
field
);
#define COMPARE_FIELD(_f) return (p2->_f > p1->_f ? 1 : -1)
long
LinuxProcess_compare
(
const
void
*
v1
,
const
void
*
v2
);
bool
Process_isThread
(
Process
*
this
);
...
...
This diff is collapsed.
Click to expand it.
linux/LinuxProcessList.c
View file @
0cbdf8ba
...
...
@@ -647,9 +647,9 @@ static void LinuxProcessList_readDelayAcctData(LinuxProcessList* this, LinuxProc
}
if
(
nl_send_sync
(
this
->
netlink_socket
,
msg
)
<
0
)
{
process
->
swapin_delay_percent
=
-
1
LL
;
process
->
blkio_delay_percent
=
-
1
LL
;
process
->
cpu_delay_percent
=
-
1
LL
;
process
->
swapin_delay_percent
=
-
1
;
process
->
blkio_delay_percent
=
-
1
;
process
->
cpu_delay_percent
=
-
1
;
return
;
}
...
...
@@ -662,26 +662,71 @@ static void LinuxProcessList_readDelayAcctData(LinuxProcessList* this, LinuxProc
#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
);
#define READ_COUNTER(_b, _var, _flag, _type, _config) \
bool _b ## Ok = false; \
uint64_t _b ## Delta = 0; \
if (flags & _flag) { \
if (!_var) { \
_var = PerfCounter_new(lp->super.pid, _type, _config); \
_b ## Ok = PerfCounter_read(_var); \
_b ## Delta = 0; \
} else { \
_b ## Ok = PerfCounter_read(_var); \
_b ## Delta = PerfCounter_delta(_var); \
} \
if (_b ## Ok) { \
} \
} else { \
if (_var) { \
PerfCounter_delete(_var); \
_var = NULL; \
} \
}
if
(
!
lp
->
insnCounter
)
{
lp
->
insnCounter
=
PerfCounter_new
(
lp
->
super
.
pid
,
PERF_TYPE_HARDWARE
,
PERF_COUNT_HW_INSTRUCTIONS
);
#define SET_IF(_ok, _var, _exp) \
if (_ok) { \
_var = _exp; \
} else { \
_var = -1; \
}
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
;
#define SET_IFNZ(_ok, _z, _var, _exp) \
if (_ok) { \
if (_z > 0) { \
_var = _exp; \
} else { \
_var = 0; \
} \
} else { \
_var = -1; \
}
#define L1DR (PERF_COUNT_HW_CACHE_L1D | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16))
#define L1DRM (PERF_COUNT_HW_CACHE_L1D | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16))
#define L1DW (PERF_COUNT_HW_CACHE_L1D | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16))
#define L1DWM (PERF_COUNT_HW_CACHE_L1D | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16))
static
void
LinuxProcessList_readPerfCounters
(
LinuxProcess
*
lp
,
uint64_t
flags
)
{
READ_COUNTER
(
c
,
lp
->
cycleCounter
,
PROCESS_FLAG_LINUX_HPC_CYCLE
,
PERF_TYPE_HARDWARE
,
PERF_COUNT_HW_CPU_CYCLES
);
READ_COUNTER
(
i
,
lp
->
insnCounter
,
PROCESS_FLAG_LINUX_HPC_INSN
,
PERF_TYPE_HARDWARE
,
PERF_COUNT_HW_INSTRUCTIONS
);
READ_COUNTER
(
m
,
lp
->
missCounter
,
PROCESS_FLAG_LINUX_HPC_MISS
,
PERF_TYPE_HARDWARE
,
PERF_COUNT_HW_CACHE_MISSES
);
READ_COUNTER
(
b
,
lp
->
brCounter
,
PROCESS_FLAG_LINUX_HPC_BMISS
,
PERF_TYPE_HARDWARE
,
PERF_COUNT_HW_BRANCH_MISSES
);
READ_COUNTER
(
r
,
lp
->
l1drCounter
,
PROCESS_FLAG_LINUX_HPC_L1DR
,
PERF_TYPE_HW_CACHE
,
L1DR
);
READ_COUNTER
(
R
,
lp
->
l1drmCounter
,
PROCESS_FLAG_LINUX_HPC_L1DRM
,
PERF_TYPE_HW_CACHE
,
L1DRM
);
READ_COUNTER
(
w
,
lp
->
l1dwCounter
,
PROCESS_FLAG_LINUX_HPC_L1DW
,
PERF_TYPE_HW_CACHE
,
L1DW
);
READ_COUNTER
(
W
,
lp
->
l1dwmCounter
,
PROCESS_FLAG_LINUX_HPC_L1DWM
,
PERF_TYPE_HW_CACHE
,
L1DWM
);
SET_IF
(
cOk
,
lp
->
mcycle
,
(
double
)
cDelta
/
1000000
);
SET_IF
(
iOk
,
lp
->
minstr
,
(
double
)
iDelta
/
1000000
);
SET_IFNZ
(
cOk
&&
iOk
,
cDelta
,
lp
->
ipc
,
(
double
)
iDelta
/
cDelta
);
SET_IFNZ
(
mOk
&&
iOk
,
iDelta
,
lp
->
pMiss
,
100
*
((
double
)
mDelta
/
iDelta
));
SET_IFNZ
(
bOk
&&
iOk
,
iDelta
,
lp
->
pBMiss
,
100
*
((
double
)
bDelta
/
iDelta
));
SET_IF
(
rOk
,
lp
->
l1dr
,
(
double
)
rDelta
/
1000
);
SET_IF
(
ROk
,
lp
->
l1drm
,
(
double
)
RDelta
/
1000
);
SET_IF
(
wOk
,
lp
->
l1dw
,
(
double
)
wDelta
/
1000
);
SET_IF
(
WOk
,
lp
->
l1dwm
,
(
double
)
WDelta
/
1000
);
}
#endif
...
...
@@ -899,7 +944,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
#ifdef HAVE_PERFCOUNTERS
if
(
ss
->
flags
&
PROCESS_FLAG_LINUX_HPC
)
LinuxProcessList_readPerfCounters
(
lp
);
LinuxProcessList_readPerfCounters
(
lp
,
ss
->
flags
);
#endif
if
(
proc
->
state
==
'Z'
&&
(
proc
->
basenameOffset
==
0
))
{
...
...
This diff is collapsed.
Click to expand it.
linux/LinuxProcessList.h
View file @
0cbdf8ba
...
...
@@ -118,6 +118,50 @@ void ProcessList_delete(ProcessList* pl);
#ifdef HAVE_PERFCOUNTERS
#define READ_COUNTER(_b, _var, _flag, _type, _config) \
bool _b ## Ok = false; \
uint64_t _b ## Delta = 0; \
if (flags & _flag) { \
if (!_var) { \
_var = PerfCounter_new(lp->super.pid, _type, _config); \
_b ## Ok = PerfCounter_read(_var); \
_b ## Delta = 0; \
} else { \
_b ## Ok = PerfCounter_read(_var); \
_b ## Delta = PerfCounter_delta(_var); \
} \
if (_b ## Ok) { \
} \
} else { \
if (_var) { \
PerfCounter_delete(_var); \
_var = NULL; \
} \
}
#define SET_IF(_ok, _var, _exp) \
if (_ok) { \
_var = _exp; \
} else { \
_var = -1; \
}
#define SET_IFNZ(_ok, _z, _var, _exp) \
if (_ok) { \
if (_z > 0) { \
_var = _exp; \
} else { \
_var = 0; \
} \
} else { \
_var = -1; \
}
#define L1DR (PERF_COUNT_HW_CACHE_L1D | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16))
#define L1DRM (PERF_COUNT_HW_CACHE_L1D | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16))
#define L1DW (PERF_COUNT_HW_CACHE_L1D | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16))
#define L1DWM (PERF_COUNT_HW_CACHE_L1D | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16))
#endif
void
ProcessList_goThroughEntries
(
ProcessList
*
super
);
...
...
This diff is collapsed.
Click to expand it.
linux/Platform.c
View file @
0cbdf8ba
...
...
@@ -22,6 +22,7 @@ in the source distribution for its full text.
#include "ClockMeter.h"
#include "HostnameMeter.h"
#include "LinuxProcess.h"
#include "CRT.h"
#include <math.h>
#include <assert.h>
...
...
This diff is collapsed.
Click to expand it.
scripts/MakeHeader.py
View file @
0cbdf8ba
...
...
@@ -12,6 +12,7 @@ ANY=1
COPY
=
2
SKIP
=
3
SKIPONE
=
4
COPYDEFINE
=
5
state
=
ANY
static
=
0
...
...
@@ -49,7 +50,11 @@ for line in file.readlines():
elif
len
(
line
)
>
1
:
static
=
0
equals
=
line
.
find
(
" = "
)
if
line
[
-
3
:]
==
"= {"
:
if
line
[:
7
]
==
"#define"
:
if
line
[
-
1
:]
==
"
\\
"
:
state
=
COPYDEFINE
out
.
write
(
line
+
"
\n
"
)
elif
line
[
-
3
:]
==
"= {"
:
out
.
write
(
"extern "
+
line
[:
-
4
]
+
";
\n
"
)
state
=
SKIP
elif
equals
!=
-
1
:
...
...
@@ -60,7 +65,7 @@ for line in file.readlines():
out
.
write
(
line
[:
-
2
].
replace
(
"inline"
,
"extern"
)
+
";
\n
"
)
state
=
SKIP
else
:
out
.
write
(
line
+
"
\n
"
)
out
.
write
(
line
+
"
\n
"
)
is_blank
=
False
elif
line
==
""
:
if
not
is_blank
:
...
...
@@ -69,6 +74,11 @@ for line in file.readlines():
else
:
out
.
write
(
line
+
"
\n
"
)
is_blank
=
False
elif
state
==
COPYDEFINE
:
is_blank
=
False
out
.
write
(
line
+
"
\n
"
)
if
line
[
-
1
:]
!=
"
\\
"
:
state
=
ANY
elif
state
==
COPY
:
is_blank
=
False
if
line
==
"}*/"
:
...
...
This diff is collapsed.
Click to expand it.
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
Menu
Projects
Groups
Snippets
Help