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
0cbdf8ba
Commit
0cbdf8ba
authored
Jan 31, 2018
by
Hisham Muhammad
Browse files
Implemented various performance counters
parent
cf0c074c
Changes
10
Show whitespace changes
Inline
Side-by-side
Process.c
View file @
0cbdf8ba
...
@@ -28,6 +28,7 @@ in the source distribution for its full text.
...
@@ -28,6 +28,7 @@ in the source distribution for its full text.
#include <time.h>
#include <time.h>
#include <assert.h>
#include <assert.h>
#include <math.h>
#include <math.h>
#include <inttypes.h>
#ifdef __ANDROID__
#ifdef __ANDROID__
#define SYS_ioprio_get __NR_ioprio_get
#define SYS_ioprio_get __NR_ioprio_get
...
@@ -150,7 +151,7 @@ typedef struct ProcessFieldData_ {
...
@@ -150,7 +151,7 @@ typedef struct ProcessFieldData_ {
const char* name;
const char* name;
const char* title;
const char* title;
const char* description;
const char* description;
int flags;
u
int
64_t
flags;
} ProcessFieldData;
} ProcessFieldData;
// Implemented in platform-specific code:
// Implemented in platform-specific code:
...
@@ -362,6 +363,21 @@ void Process_outputRate(RichString* str, char* buffer, int n, double rate, int c
...
@@ -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
)
{
void
Process_writeField
(
Process
*
this
,
RichString
*
str
,
ProcessField
field
)
{
char
buffer
[
256
];
buffer
[
255
]
=
'\0'
;
char
buffer
[
256
];
buffer
[
255
]
=
'\0'
;
int
attr
=
CRT_colors
[
DEFAULT_COLOR
];
int
attr
=
CRT_colors
[
DEFAULT_COLOR
];
...
@@ -370,24 +386,8 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
...
@@ -370,24 +386,8 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
bool
coloring
=
this
->
settings
->
highlightMegabytes
;
bool
coloring
=
this
->
settings
->
highlightMegabytes
;
switch
(
field
)
{
switch
(
field
)
{
case
PERCENT_CPU
:
{
case
PERCENT_CPU
:
Process_printPercentage
(
this
->
percent_cpu
,
buffer
,
n
,
&
attr
);
break
;
if
(
this
->
percent_cpu
>
999
.
9
)
{
case
PERCENT_MEM
:
Process_printPercentage
(
this
->
percent_mem
,
buffer
,
n
,
&
attr
);
break
;
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
COMM
:
{
case
COMM
:
{
if
(
this
->
settings
->
highlightThreads
&&
Process_isThread
(
this
))
{
if
(
this
->
settings
->
highlightThreads
&&
Process_isThread
(
this
))
{
attr
=
CRT_colors
[
PROCESS_THREAD
];
attr
=
CRT_colors
[
PROCESS_THREAD
];
...
...
Process.h
View file @
0cbdf8ba
...
@@ -129,7 +129,7 @@ typedef struct ProcessFieldData_ {
...
@@ -129,7 +129,7 @@ typedef struct ProcessFieldData_ {
const
char
*
name
;
const
char
*
name
;
const
char
*
title
;
const
char
*
title
;
const
char
*
description
;
const
char
*
description
;
int
flags
;
u
int
64_t
flags
;
}
ProcessFieldData
;
}
ProcessFieldData
;
// Implemented in platform-specific code:
// Implemented in platform-specific code:
...
@@ -176,6 +176,8 @@ void Process_printTime(RichString* str, unsigned long long totalHundredths);
...
@@ -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_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_writeField
(
Process
*
this
,
RichString
*
str
,
ProcessField
field
);
void
Process_display
(
Object
*
cast
,
RichString
*
out
);
void
Process_display
(
Object
*
cast
,
RichString
*
out
);
...
...
ScreensPanel.c
View file @
0cbdf8ba
...
@@ -48,6 +48,7 @@ typedef struct ScreenListItem_ {
...
@@ -48,6 +48,7 @@ typedef struct ScreenListItem_ {
}*/
}*/
ObjectClass
ScreenListItem_class
=
{
ObjectClass
ScreenListItem_class
=
{
.
extends
=
Class
(
ListItem
),
.
display
=
ListItem_display
,
.
display
=
ListItem_display
,
.
delete
=
ListItem_delete
,
.
delete
=
ListItem_delete
,
.
compare
=
ListItem_compare
.
compare
=
ListItem_compare
...
@@ -319,8 +320,11 @@ void ScreensPanel_update(Panel* super) {
...
@@ -319,8 +320,11 @@ void ScreensPanel_update(Panel* super) {
this
->
settings
->
changed
=
true
;
this
->
settings
->
changed
=
true
;
this
->
settings
->
screens
=
xRealloc
(
this
->
settings
->
screens
,
sizeof
(
char
*
)
*
(
size
+
1
));
this
->
settings
->
screens
=
xRealloc
(
this
->
settings
->
screens
,
sizeof
(
char
*
)
*
(
size
+
1
));
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
char
*
name
=
((
ListItem
*
)
Panel_get
(
super
,
i
))
->
value
;
ScreenListItem
*
item
=
(
ScreenListItem
*
)
Panel_get
(
super
,
i
);
this
->
settings
->
screens
[
i
]
->
name
=
xStrdup
(
name
);
ScreenSettings
*
ss
=
item
->
ss
;
free
(
ss
->
name
);
this
->
settings
->
screens
[
i
]
=
ss
;
ss
->
name
=
xStrdup
(((
ListItem
*
)
item
)
->
value
);
}
}
this
->
settings
->
screens
[
size
]
=
NULL
;
this
->
settings
->
screens
[
size
]
=
NULL
;
}
}
Settings.h
View file @
0cbdf8ba
...
@@ -9,7 +9,6 @@ Released under the GNU GPL, see the COPYING file
...
@@ -9,7 +9,6 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
in the source distribution for its full text.
*/
*/
#define DEFAULT_DELAY 15
#include "Process.h"
#include "Process.h"
#include <stdbool.h>
#include <stdbool.h>
...
...
linux/LinuxProcess.c
View file @
0cbdf8ba
...
@@ -20,12 +20,22 @@ in the source distribution for its full text.
...
@@ -20,12 +20,22 @@ in the source distribution for its full text.
#include "PerfCounter.h"
#include "PerfCounter.h"
#define PROCESS_FLAG_LINUX_IOPRIO 0x0100
#define PROCESS_FLAG_LINUX_IOPRIO 0x0100L
#define PROCESS_FLAG_LINUX_OPENVZ 0x0200
#define PROCESS_FLAG_LINUX_OPENVZ 0x0200L
#define PROCESS_FLAG_LINUX_VSERVER 0x0400
#define PROCESS_FLAG_LINUX_VSERVER 0x0400L
#define PROCESS_FLAG_LINUX_CGROUP 0x0800
#define PROCESS_FLAG_LINUX_CGROUP 0x0800L
#define PROCESS_FLAG_LINUX_OOM 0x1000
#define PROCESS_FLAG_LINUX_OOM 0x1000L
#define PROCESS_FLAG_LINUX_HPC 0x2000
#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 {
typedef enum UnsupportedProcessFields {
FLAGS = 9,
FLAGS = 9,
...
@@ -91,8 +101,16 @@ typedef enum LinuxProcessFields {
...
@@ -91,8 +101,16 @@ typedef enum LinuxProcessFields {
#endif
#endif
#ifdef HAVE_PERFCOUNTERS
#ifdef HAVE_PERFCOUNTERS
IPC = 119,
IPC = 119,
MCYCLE = 120,
MINSTR = 121,
PERCENT_MISS = 122,
PERCENT_BMISS = 123,
L1DREADS = 124,
L1DRMISSES = 125,
L1DWRITES = 126,
L1DWMISSES = 127,
#endif
#endif
LAST_PROCESSFIELD = 12
0
,
LAST_PROCESSFIELD = 12
8
,
} LinuxProcessField;
} LinuxProcessField;
#include "IOPriority.h"
#include "IOPriority.h"
...
@@ -148,7 +166,21 @@ typedef struct LinuxProcess_ {
...
@@ -148,7 +166,21 @@ typedef struct LinuxProcess_ {
#ifdef HAVE_PERFCOUNTERS
#ifdef HAVE_PERFCOUNTERS
PerfCounter* cycleCounter;
PerfCounter* cycleCounter;
PerfCounter* insnCounter;
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
#endif
} LinuxProcess;
} LinuxProcess;
...
@@ -241,12 +273,20 @@ ProcessFieldData Process_fields[] = {
...
@@ -241,12 +273,20 @@ ProcessFieldData Process_fields[] = {
[
OOM
]
=
{
.
name
=
"OOM"
,
.
title
=
" OOM "
,
.
description
=
"OOM (Out-of-Memory) killer score"
,
.
flags
=
PROCESS_FLAG_LINUX_OOM
,
},
[
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
,
},
[
IO_PRIORITY
]
=
{
.
name
=
"IO_PRIORITY"
,
.
title
=
"IO "
,
.
description
=
"I/O priority"
,
.
flags
=
PROCESS_FLAG_LINUX_IOPRIO
,
},
#ifdef HAVE_DELAYACCT
#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_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
#endif
#ifdef HAVE_PERFCOUNTERS
#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
#endif
[
LAST_PROCESSFIELD
]
=
{
.
name
=
"*** report bug! ***"
,
.
title
=
NULL
,
.
description
=
NULL
,
.
flags
=
0
,
},
[
LAST_PROCESSFIELD
]
=
{
.
name
=
"*** report bug! ***"
,
.
title
=
NULL
,
.
description
=
NULL
,
.
flags
=
0
,
},
};
};
...
@@ -324,14 +364,43 @@ bool LinuxProcess_setIOPriority(LinuxProcess* this, IOPriority ioprio) {
...
@@ -324,14 +364,43 @@ bool LinuxProcess_setIOPriority(LinuxProcess* this, IOPriority ioprio) {
return
(
LinuxProcess_updateIOPriority
(
this
)
==
ioprio
);
return
(
LinuxProcess_updateIOPriority
(
this
)
==
ioprio
);
}
}
#ifdef HAVE_DELAYACCT
#if HAVE_DELAYACCT || HAVE_PERFCOUNTERS
void
LinuxProcess_printDelay
(
float
delay_percent
,
char
*
buffer
,
int
n
)
{
if
(
delay_percent
==
-
1LL
)
{
static
char
*
perfFmt
[]
=
{
xSnprintf
(
buffer
,
n
,
" N/A "
);
"%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
{
}
else
{
xSnprintf
(
buffer
,
n
,
"%4.1f "
,
delay_percent
);
xSnprintf
(
buffer
,
n
,
perfNA
[
len
]);
*
attr
=
CRT_colors
[
PROCESS_SHADOW
];
}
}
}
}
#endif
#endif
void
LinuxProcess_writeField
(
Process
*
this
,
RichString
*
str
,
ProcessField
field
)
{
void
LinuxProcess_writeField
(
Process
*
this
,
RichString
*
str
,
ProcessField
field
)
{
...
@@ -408,19 +477,20 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
...
@@ -408,19 +477,20 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
break
;
break
;
}
}
#ifdef HAVE_DELAYACCT
#ifdef HAVE_DELAYACCT
case
PERCENT_CPU_DELAY
:
Linux
Process_print
Delay
(
lp
->
cpu_delay_percent
,
buffer
,
n
);
break
;
case
PERCENT_CPU_DELAY
:
Process_print
Percentage
(
lp
->
cpu_delay_percent
,
buffer
,
n
,
&
attr
);
break
;
case
PERCENT_IO_DELAY
:
Linux
Process_print
Delay
(
lp
->
blkio_delay_percent
,
buffer
,
n
);
break
;
case
PERCENT_IO_DELAY
:
Process_print
Percentage
(
lp
->
blkio_delay_percent
,
buffer
,
n
,
&
attr
);
break
;
case
PERCENT_SWAP_DELAY
:
Linux
Process_print
Delay
(
lp
->
swapin_delay_percent
,
buffer
,
n
);
break
;
case
PERCENT_SWAP_DELAY
:
Process_print
Percentage
(
lp
->
swapin_delay_percent
,
buffer
,
n
,
&
attr
);
break
;
#endif
#endif
#ifdef HAVE_PERFCOUNTERS
#ifdef HAVE_PERFCOUNTERS
case
IPC
:
{
case
PERCENT_MISS
:
Process_printPercentage
(
lp
->
pMiss
,
buffer
,
n
,
&
attr
);
break
;
if
(
lp
->
ipc
==
-
1
)
{
case
PERCENT_BMISS
:
Process_printPercentage
(
lp
->
pBMiss
,
buffer
,
n
,
&
attr
);
break
;
attr
=
CRT_colors
[
PROCESS_SHADOW
];
case
IPC
:
LinuxProcess_printPerfCounter
(
lp
->
ipc
,
0
,
buffer
,
n
,
&
attr
);
break
;
xSnprintf
(
buffer
,
n
,
" N/A "
);
break
;
case
MCYCLE
:
LinuxProcess_printPerfCounter
(
lp
->
mcycle
,
8
,
buffer
,
n
,
&
attr
);
break
;
}
else
{
case
MINSTR
:
LinuxProcess_printPerfCounter
(
lp
->
minstr
,
8
,
buffer
,
n
,
&
attr
);
break
;
xSnprintf
(
buffer
,
n
,
"%5.2f "
,
lp
->
ipc
);
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
#endif
default:
default:
Process_writeField
((
Process
*
)
this
,
str
,
field
);
Process_writeField
((
Process
*
)
this
,
str
,
field
);
...
@@ -429,6 +499,8 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
...
@@ -429,6 +499,8 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
RichString_append
(
str
,
attr
,
buffer
);
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
)
{
long
LinuxProcess_compare
(
const
void
*
v1
,
const
void
*
v2
)
{
LinuxProcess
*
p1
,
*
p2
;
LinuxProcess
*
p1
,
*
p2
;
Settings
*
settings
=
((
Process
*
)
v1
)
->
settings
;
Settings
*
settings
=
((
Process
*
)
v1
)
->
settings
;
...
@@ -484,16 +556,20 @@ long LinuxProcess_compare(const void* v1, const void* v2) {
...
@@ -484,16 +556,20 @@ long LinuxProcess_compare(const void* v1, const void* v2) {
case
OOM
:
case
OOM
:
return
(
p2
->
oom
-
p1
->
oom
);
return
(
p2
->
oom
-
p1
->
oom
);
#ifdef HAVE_DELAYACCT
#ifdef HAVE_DELAYACCT
case
PERCENT_CPU_DELAY
:
case
PERCENT_CPU_DELAY
:
COMPARE_FIELD
(
cpu_delay_percent
);
return
(
p2
->
cpu_delay_percent
>
p1
->
cpu_delay_percent
?
1
:
-
1
);
case
PERCENT_IO_DELAY
:
COMPARE_FIELD
(
blkio_delay_percent
);
case
PERCENT_IO_DELAY
:
case
PERCENT_SWAP_DELAY
:
COMPARE_FIELD
(
swapin_delay_percent
);
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
);
#endif
#endif
#ifdef HAVE_PERFCOUNTERS
#ifdef HAVE_PERFCOUNTERS
case
IPC
:
case
PERCENT_MISS
:
COMPARE_FIELD
(
pMiss
);
return
(
p2
->
ipc
>
p1
->
ipc
?
1
:
-
1
);
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
#endif
case
IO_PRIORITY
:
case
IO_PRIORITY
:
return
LinuxProcess_effectiveIOPriority
(
p1
)
-
LinuxProcess_effectiveIOPriority
(
p2
);
return
LinuxProcess_effectiveIOPriority
(
p1
)
-
LinuxProcess_effectiveIOPriority
(
p2
);
...
...
linux/LinuxProcess.h
View file @
0cbdf8ba
...
@@ -12,12 +12,22 @@ in the source distribution for its full text.
...
@@ -12,12 +12,22 @@ in the source distribution for its full text.
#include "PerfCounter.h"
#include "PerfCounter.h"
#define PROCESS_FLAG_LINUX_IOPRIO 0x0100
#define PROCESS_FLAG_LINUX_IOPRIO 0x0100L
#define PROCESS_FLAG_LINUX_OPENVZ 0x0200
#define PROCESS_FLAG_LINUX_OPENVZ 0x0200L
#define PROCESS_FLAG_LINUX_VSERVER 0x0400
#define PROCESS_FLAG_LINUX_VSERVER 0x0400L
#define PROCESS_FLAG_LINUX_CGROUP 0x0800
#define PROCESS_FLAG_LINUX_CGROUP 0x0800L
#define PROCESS_FLAG_LINUX_OOM 0x1000
#define PROCESS_FLAG_LINUX_OOM 0x1000L
#define PROCESS_FLAG_LINUX_HPC 0x2000
#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
{
typedef
enum
UnsupportedProcessFields
{
FLAGS
=
9
,
FLAGS
=
9
,
...
@@ -83,8 +93,16 @@ typedef enum LinuxProcessFields {
...
@@ -83,8 +93,16 @@ typedef enum LinuxProcessFields {
#endif
#endif
#ifdef HAVE_PERFCOUNTERS
#ifdef HAVE_PERFCOUNTERS
IPC
=
119
,
IPC
=
119
,
MCYCLE
=
120
,
MINSTR
=
121
,
PERCENT_MISS
=
122
,
PERCENT_BMISS
=
123
,
L1DREADS
=
124
,
L1DRMISSES
=
125
,
L1DWRITES
=
126
,
L1DWMISSES
=
127
,
#endif
#endif
LAST_PROCESSFIELD
=
12
0
,
LAST_PROCESSFIELD
=
12
8
,
}
LinuxProcessField
;
}
LinuxProcessField
;
#include "IOPriority.h"
#include "IOPriority.h"
...
@@ -140,7 +158,21 @@ typedef struct LinuxProcess_ {
...
@@ -140,7 +158,21 @@ typedef struct LinuxProcess_ {
#ifdef HAVE_PERFCOUNTERS
#ifdef HAVE_PERFCOUNTERS
PerfCounter
*
cycleCounter
;
PerfCounter
*
cycleCounter
;
PerfCounter
*
insnCounter
;
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
#endif
}
LinuxProcess
;
}
LinuxProcess
;
...
@@ -177,12 +209,14 @@ IOPriority LinuxProcess_updateIOPriority(LinuxProcess* this);
...
@@ -177,12 +209,14 @@ IOPriority LinuxProcess_updateIOPriority(LinuxProcess* this);
bool
LinuxProcess_setIOPriority
(
LinuxProcess
*
this
,
IOPriority
ioprio
);
bool
LinuxProcess_setIOPriority
(
LinuxProcess
*
this
,
IOPriority
ioprio
);
#if
def
HAVE_DELAYACCT
#if HAVE_DELAYACCT
|| HAVE_PERFCOUNTERS
void
LinuxProcess_printDelay
(
float
delay_percent
,
char
*
buffer
,
int
n
);
#endif
#endif
void
LinuxProcess_writeField
(
Process
*
this
,
RichString
*
str
,
ProcessField
field
);
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
);
long
LinuxProcess_compare
(
const
void
*
v1
,
const
void
*
v2
);
bool
Process_isThread
(
Process
*
this
);
bool
Process_isThread
(
Process
*
this
);
...
...
linux/LinuxProcessList.c
View file @
0cbdf8ba
...
@@ -647,9 +647,9 @@ static void LinuxProcessList_readDelayAcctData(LinuxProcessList* this, LinuxProc
...
@@ -647,9 +647,9 @@ static void LinuxProcessList_readDelayAcctData(LinuxProcessList* this, LinuxProc
}
}
if
(
nl_send_sync
(
this
->
netlink_socket
,
msg
)
<
0
)
{
if
(
nl_send_sync
(
this
->
netlink_socket
,
msg
)
<
0
)
{
process
->
swapin_delay_percent
=
-
1
LL
;
process
->
swapin_delay_percent
=
-
1
;
process
->
blkio_delay_percent
=
-
1
LL
;
process
->
blkio_delay_percent
=
-
1
;
process
->
cpu_delay_percent
=
-
1
LL
;
process
->
cpu_delay_percent
=
-
1
;
return
;
return
;
}
}
...
@@ -662,26 +662,71 @@ static void LinuxProcessList_readDelayAcctData(LinuxProcessList* this, LinuxProc
...
@@ -662,26 +662,71 @@ static void LinuxProcessList_readDelayAcctData(LinuxProcessList* this, LinuxProc
#ifdef HAVE_PERFCOUNTERS
#ifdef HAVE_PERFCOUNTERS
static
void
LinuxProcessList_readPerfCounters
(
LinuxProcess
*
lp
)
{
#define READ_COUNTER(_b, _var, _flag, _type, _config) \
if
(
!
lp
->
cycleCounter
)
{
bool _b ## Ok = false; \
lp
->
cycleCounter
=
PerfCounter_new
(
lp
->
super
.
pid
,
PERF_TYPE_HARDWARE
,
PERF_COUNT_HW_CPU_CYCLES
);
uint64_t _b ## Delta = 0; \
}
if (flags & _flag) { \
if
(
!
lp
->
insnCounter
)
{
if (!_var) { \
lp
->
insnCounter
=
PerfCounter_new
(
lp
->
super
.
pid
,
PERF_TYPE_HARDWARE
,
PERF_COUNT_HW_INSTRUCTIONS
);
_var = PerfCounter_new(lp->super.pid, _type, _config); \
}
_b ## Ok = PerfCounter_read(_var); \
bool
cOk
=
PerfCounter_read
(
lp
->
cycleCounter
);
_b ## Delta = 0; \
bool
iOk
=
PerfCounter_read
(
lp
->
insnCounter
);
} else { \
if
(
cOk
&&
iOk
)
{
_b ## Ok = PerfCounter_read(_var); \
uint64_t
i
=
PerfCounter_delta
(
lp
->
insnCounter
);
_b ## Delta = PerfCounter_delta(_var); \
uint64_t
c
=
PerfCounter_delta
(
lp
->
cycleCounter
);
} \
if
(
c
>
0
)
{
if (_b ## Ok) { \
lp
->
ipc
=
(
double
)
i
/
c
;
} \
}
else
{
} else { \
lp
->
ipc
=
0
;
if (_var) { \
}
PerfCounter_delete(_var); \
}
else
{
_var = NULL; \
lp
->
ipc
=
-
1
;
} \
}
}
#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))
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
#endif
...
@@ -899,7 +944,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
...
@@ -899,7 +944,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
#ifdef HAVE_PERFCOUNTERS
#ifdef HAVE_PERFCOUNTERS
if
(
ss
->
flags
&
PROCESS_FLAG_LINUX_HPC
)
if
(
ss
->
flags
&
PROCESS_FLAG_LINUX_HPC
)
LinuxProcessList_readPerfCounters
(
lp
);
LinuxProcessList_readPerfCounters
(
lp
,
ss
->
flags
);
#endif
#endif
if
(
proc
->
state
==
'Z'
&&
(
proc
->
basenameOffset
==
0
))
{
if
(
proc
->
state
==
'Z'
&&
(
proc
->
basenameOffset
==
0
))
{
...
...
linux/LinuxProcessList.h
View file @
0cbdf8ba
...
@@ -118,6 +118,50 @@ void ProcessList_delete(ProcessList* pl);
...
@@ -118,6 +118,50 @@ void ProcessList_delete(ProcessList* pl);
#ifdef HAVE_PERFCOUNTERS
#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
#endif
void
ProcessList_goThroughEntries
(
ProcessList
*
super
);
void
ProcessList_goThroughEntries
(
ProcessList
*
super
);
...
...
linux/Platform.c
View file @
0cbdf8ba
...
@@ -22,6 +22,7 @@ in the source distribution for its full text.
...
@@ -22,6 +22,7 @@ in the source distribution for its full text.
#include "ClockMeter.h"
#include "ClockMeter.h"
#include "HostnameMeter.h"
#include "HostnameMeter.h"
#include "LinuxProcess.h"
#include "LinuxProcess.h"
#include "CRT.h"
#include <math.h>
#include <math.h>
#include <assert.h>
#include <assert.h>
...
...
scripts/MakeHeader.py
View file @
0cbdf8ba
...
@@ -12,6 +12,7 @@ ANY=1
...
@@ -12,6 +12,7 @@ ANY=1
COPY
=
2
COPY
=
2
SKIP
=
3
SKIP
=
3
SKIPONE
=
4
SKIPONE
=
4
COPYDEFINE
=
5
state
=
ANY
state
=
ANY
static
=
0
static
=
0
...
@@ -49,7 +50,11 @@ for line in file.readlines():
...
@@ -49,7 +50,11 @@ for line in file.readlines():
elif
len
(
line
)
>
1
:
elif
len
(
line
)
>
1
:
static
=
0
static
=
0
equals
=
line
.
find
(
" = "
)
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
"
)
out
.
write
(
"extern "
+
line
[:
-
4
]
+
";
\n
"
)
state
=
SKIP
state
=
SKIP
elif
equals
!=
-
1
:
elif
equals
!=
-
1
:
...
@@ -60,7 +65,7 @@ for line in file.readlines():
...
@@ -60,7 +65,7 @@ for line in file.readlines():
out
.
write
(
line
[:
-
2
].
replace
(
"inline"
,
"extern"
)
+
";
\n
"
)
out
.
write
(
line
[:
-
2
].
replace
(
"inline"
,
"extern"
)
+
";
\n
"
)
state
=
SKIP
state
=
SKIP
else
:
else
:
out
.
write
(
line
+
"
\n
"
)
out
.
write
(
line
+
"
\n
"
)
is_blank
=
False
is_blank
=
False
elif
line
==
""
:
elif
line
==
""
:
if
not
is_blank
:
if
not
is_blank
:
...
@@ -69,6 +74,11 @@ for line in file.readlines():
...
@@ -69,6 +74,11 @@ for line in file.readlines():
else
:
else
:
out
.
write
(
line
+
"
\n
"
)
out
.
write
(
line
+
"
\n
"
)
is_blank
=
False
is_blank
=
False
elif
state
==
COPYDEFINE
:
is_blank
=
False
out
.
write
(
line
+
"
\n
"
)
if
line
[
-
1
:]
!=
"
\\
"
:
state
=
ANY
elif
state
==
COPY
:
elif
state
==
COPY
:
is_blank
=
False
is_blank
=
False
if
line
==
"}*/"
:
if
line
==
"}*/"
:
...
...
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