mirror of
https://github.com/xzeldon/htop.git
synced 2025-07-15 13:34:35 +03:00
Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
a516e0852e | |||
556d7c03e8 | |||
0925c54caa | |||
d0f5b61aa5 | |||
284f8c5e0b | |||
11b65a2861 | |||
b85b718e69 | |||
7891cdc552 | |||
b9fdf1c2a1 | |||
2844429f15 | |||
3834f2a68f | |||
343c2e58be | |||
fd2c4f5ddd | |||
7f95ed8528 | |||
9579d9b7aa | |||
0580dbb202 | |||
c0c2bb98a2 | |||
9b30870eec | |||
25c945e2ef | |||
f94934472f | |||
becd33795c | |||
74f99e3693 | |||
e1f4645bd1 | |||
0afd0fe572 | |||
ff336b652c | |||
58a59c11f4 | |||
3f806368e0 | |||
4855d92469 | |||
b81bb9038c | |||
1f2f567ca1 | |||
393330239e | |||
d2c34259b4 | |||
858ad8029d |
@ -9,7 +9,8 @@ os:
|
|||||||
|
|
||||||
script:
|
script:
|
||||||
- ./autogen.sh
|
- ./autogen.sh
|
||||||
# clang might warn about C11 generic selections in isnan()
|
- ./configure --enable-werror
|
||||||
- CFLAGS=-Wno-c11-extensions ./configure --enable-werror
|
|
||||||
- make -k
|
- make -k
|
||||||
- CFLAGS=-Wno-c11-extensions make distcheck DISTCHECK_CONFIGURE_FLAGS=--enable-werror
|
- make distcheck DISTCHECK_CONFIGURE_FLAGS=--enable-werror
|
||||||
|
- sudo make install
|
||||||
|
- make installcheck
|
||||||
|
@ -63,9 +63,9 @@ Affinity* Affinity_get(const Process* proc, ProcessList* pl) {
|
|||||||
Affinity_add(affinity, i);
|
Affinity_add(affinity, i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unsigned int id;
|
int id;
|
||||||
hwloc_bitmap_foreach_begin(id, cpuset);
|
hwloc_bitmap_foreach_begin(id, cpuset)
|
||||||
Affinity_add(affinity, id);
|
Affinity_add(affinity, (unsigned)id);
|
||||||
hwloc_bitmap_foreach_end();
|
hwloc_bitmap_foreach_end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -425,9 +425,9 @@ Affinity* AffinityPanel_getAffinity(Panel* super, ProcessList* pl) {
|
|||||||
Affinity* affinity = Affinity_new(pl);
|
Affinity* affinity = Affinity_new(pl);
|
||||||
|
|
||||||
#ifdef HAVE_LIBHWLOC
|
#ifdef HAVE_LIBHWLOC
|
||||||
unsigned int i;
|
int i;
|
||||||
hwloc_bitmap_foreach_begin(i, this->workCpuset)
|
hwloc_bitmap_foreach_begin(i, this->workCpuset)
|
||||||
Affinity_add(affinity, i);
|
Affinity_add(affinity, (unsigned)i);
|
||||||
hwloc_bitmap_foreach_end();
|
hwloc_bitmap_foreach_end();
|
||||||
#else
|
#else
|
||||||
for (int i = 0; i < Vector_size(this->cpuids); i++) {
|
for (int i = 0; i < Vector_size(this->cpuids); i++) {
|
||||||
|
@ -52,9 +52,9 @@ static void CPUMeter_init(Meter* this) {
|
|||||||
// Custom uiName runtime logic to include the param (processor)
|
// Custom uiName runtime logic to include the param (processor)
|
||||||
static void CPUMeter_getUiName(const Meter* this, char* buffer, size_t length) {
|
static void CPUMeter_getUiName(const Meter* this, char* buffer, size_t length) {
|
||||||
if (this->param > 0)
|
if (this->param > 0)
|
||||||
xSnprintf(buffer, sizeof(length), "%s %u", Meter_uiName(this), this->param);
|
xSnprintf(buffer, length, "%s %u", Meter_uiName(this), this->param);
|
||||||
else
|
else
|
||||||
xSnprintf(buffer, sizeof(length), "%s", Meter_uiName(this));
|
xSnprintf(buffer, length, "%s", Meter_uiName(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CPUMeter_updateValues(Meter* this) {
|
static void CPUMeter_updateValues(Meter* this) {
|
||||||
|
20
CRT.c
20
CRT.c
@ -138,7 +138,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
|||||||
[PROCESS_GIGABYTES] = ColorPair(Green, Black),
|
[PROCESS_GIGABYTES] = ColorPair(Green, Black),
|
||||||
[PROCESS_BASENAME] = A_BOLD | ColorPair(Cyan, Black),
|
[PROCESS_BASENAME] = A_BOLD | ColorPair(Cyan, Black),
|
||||||
[PROCESS_TREE] = ColorPair(Cyan, Black),
|
[PROCESS_TREE] = ColorPair(Cyan, Black),
|
||||||
[PROCESS_R_STATE] = ColorPair(Green, Black),
|
[PROCESS_RUN_STATE] = ColorPair(Green, Black),
|
||||||
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Black),
|
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Black),
|
||||||
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Black),
|
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Black),
|
||||||
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Black),
|
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Black),
|
||||||
@ -240,7 +240,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
|||||||
[PROCESS_GIGABYTES] = A_BOLD,
|
[PROCESS_GIGABYTES] = A_BOLD,
|
||||||
[PROCESS_BASENAME] = A_BOLD,
|
[PROCESS_BASENAME] = A_BOLD,
|
||||||
[PROCESS_TREE] = A_BOLD,
|
[PROCESS_TREE] = A_BOLD,
|
||||||
[PROCESS_R_STATE] = A_BOLD,
|
[PROCESS_RUN_STATE] = A_BOLD,
|
||||||
[PROCESS_D_STATE] = A_BOLD,
|
[PROCESS_D_STATE] = A_BOLD,
|
||||||
[PROCESS_HIGH_PRIORITY] = A_BOLD,
|
[PROCESS_HIGH_PRIORITY] = A_BOLD,
|
||||||
[PROCESS_LOW_PRIORITY] = A_DIM,
|
[PROCESS_LOW_PRIORITY] = A_DIM,
|
||||||
@ -342,7 +342,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
|||||||
[PROCESS_GIGABYTES] = ColorPair(Green, White),
|
[PROCESS_GIGABYTES] = ColorPair(Green, White),
|
||||||
[PROCESS_BASENAME] = ColorPair(Blue, White),
|
[PROCESS_BASENAME] = ColorPair(Blue, White),
|
||||||
[PROCESS_TREE] = ColorPair(Green, White),
|
[PROCESS_TREE] = ColorPair(Green, White),
|
||||||
[PROCESS_R_STATE] = ColorPair(Green, White),
|
[PROCESS_RUN_STATE] = ColorPair(Green, White),
|
||||||
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, White),
|
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, White),
|
||||||
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, White),
|
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, White),
|
||||||
[PROCESS_LOW_PRIORITY] = ColorPair(Green, White),
|
[PROCESS_LOW_PRIORITY] = ColorPair(Green, White),
|
||||||
@ -444,7 +444,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
|||||||
[PROCESS_GIGABYTES] = ColorPair(Green, Black),
|
[PROCESS_GIGABYTES] = ColorPair(Green, Black),
|
||||||
[PROCESS_BASENAME] = ColorPair(Green, Black),
|
[PROCESS_BASENAME] = ColorPair(Green, Black),
|
||||||
[PROCESS_TREE] = ColorPair(Blue, Black),
|
[PROCESS_TREE] = ColorPair(Blue, Black),
|
||||||
[PROCESS_R_STATE] = ColorPair(Green, Black),
|
[PROCESS_RUN_STATE] = ColorPair(Green, Black),
|
||||||
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Black),
|
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Black),
|
||||||
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Black),
|
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Black),
|
||||||
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Black),
|
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Black),
|
||||||
@ -546,7 +546,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
|||||||
[PROCESS_GIGABYTES] = ColorPair(Green, Blue),
|
[PROCESS_GIGABYTES] = ColorPair(Green, Blue),
|
||||||
[PROCESS_BASENAME] = A_BOLD | ColorPair(Cyan, Blue),
|
[PROCESS_BASENAME] = A_BOLD | ColorPair(Cyan, Blue),
|
||||||
[PROCESS_TREE] = ColorPair(Cyan, Blue),
|
[PROCESS_TREE] = ColorPair(Cyan, Blue),
|
||||||
[PROCESS_R_STATE] = ColorPair(Green, Blue),
|
[PROCESS_RUN_STATE] = ColorPair(Green, Blue),
|
||||||
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Blue),
|
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Blue),
|
||||||
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Blue),
|
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Blue),
|
||||||
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Blue),
|
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Blue),
|
||||||
@ -652,7 +652,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
|||||||
[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue, Black),
|
[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue, Black),
|
||||||
[PROCESS_COMM] = ColorPair(Magenta, Black),
|
[PROCESS_COMM] = ColorPair(Magenta, Black),
|
||||||
[PROCESS_THREAD_COMM] = ColorPair(Yellow, Black),
|
[PROCESS_THREAD_COMM] = ColorPair(Yellow, Black),
|
||||||
[PROCESS_R_STATE] = ColorPair(Green, Black),
|
[PROCESS_RUN_STATE] = ColorPair(Green, Black),
|
||||||
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Black),
|
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Black),
|
||||||
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Black),
|
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Black),
|
||||||
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Black),
|
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Black),
|
||||||
@ -886,6 +886,10 @@ void CRT_init(const Settings* settings, bool allowUnicode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (termType && (String_startsWith(termType, "xterm") || String_eq(termType, "vt220"))) {
|
if (termType && (String_startsWith(termType, "xterm") || String_eq(termType, "vt220"))) {
|
||||||
|
#ifdef HTOP_NETBSD
|
||||||
|
#define define_key(s_, k_) define_key((char*)s_, k_)
|
||||||
|
IGNORE_WCASTQUAL_BEGIN
|
||||||
|
#endif
|
||||||
define_key("\033[H", KEY_HOME);
|
define_key("\033[H", KEY_HOME);
|
||||||
define_key("\033[F", KEY_END);
|
define_key("\033[F", KEY_END);
|
||||||
define_key("\033[7~", KEY_HOME);
|
define_key("\033[7~", KEY_HOME);
|
||||||
@ -906,6 +910,10 @@ void CRT_init(const Settings* settings, bool allowUnicode) {
|
|||||||
sequence[1] = c;
|
sequence[1] = c;
|
||||||
define_key(sequence, KEY_ALT('A' + (c - 'a')));
|
define_key(sequence, KEY_ALT('A' + (c - 'a')));
|
||||||
}
|
}
|
||||||
|
#ifdef HTOP_NETBSD
|
||||||
|
IGNORE_WCASTQUAL_END
|
||||||
|
#undef define_key
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CRT_installSignalHandlers();
|
CRT_installSignalHandlers();
|
||||||
|
2
CRT.h
2
CRT.h
@ -74,7 +74,7 @@ typedef enum ColorElements_ {
|
|||||||
PROCESS_MEGABYTES,
|
PROCESS_MEGABYTES,
|
||||||
PROCESS_GIGABYTES,
|
PROCESS_GIGABYTES,
|
||||||
PROCESS_TREE,
|
PROCESS_TREE,
|
||||||
PROCESS_R_STATE,
|
PROCESS_RUN_STATE,
|
||||||
PROCESS_D_STATE,
|
PROCESS_D_STATE,
|
||||||
PROCESS_BASENAME,
|
PROCESS_BASENAME,
|
||||||
PROCESS_HIGH_PRIORITY,
|
PROCESS_HIGH_PRIORITY,
|
||||||
|
@ -40,7 +40,7 @@ static void CategoriesPanel_delete(Object* object) {
|
|||||||
|
|
||||||
static void CategoriesPanel_makeMetersPage(CategoriesPanel* this) {
|
static void CategoriesPanel_makeMetersPage(CategoriesPanel* this) {
|
||||||
size_t columns = HeaderLayout_getColumns(this->scr->header->headerLayout);
|
size_t columns = HeaderLayout_getColumns(this->scr->header->headerLayout);
|
||||||
MetersPanel** meterPanels = xMallocArray(columns, sizeof(MetersPanel));
|
MetersPanel** meterPanels = xMallocArray(columns, sizeof(MetersPanel*));
|
||||||
|
|
||||||
for (size_t i = 0; i < columns; i++) {
|
for (size_t i = 0; i < columns; i++) {
|
||||||
char titleBuffer[32];
|
char titleBuffer[32];
|
||||||
|
18
ChangeLog
18
ChangeLog
@ -1,6 +1,5 @@
|
|||||||
What's new in version 3.1.0
|
What's new in version 3.1.0
|
||||||
|
|
||||||
|
|
||||||
* Updated COPYING file to remove the PLPA exemption (appendix 2)
|
* Updated COPYING file to remove the PLPA exemption (appendix 2)
|
||||||
With this change the license is now GPLv2 without any additional wording.
|
With this change the license is now GPLv2 without any additional wording.
|
||||||
* Improved default sort ordering
|
* Improved default sort ordering
|
||||||
@ -26,10 +25,11 @@ What's new in version 3.1.0
|
|||||||
Moving this column to be handled as a platform-independently available
|
Moving this column to be handled as a platform-independently available
|
||||||
information simplifies the markup of the command line.
|
information simplifies the markup of the command line.
|
||||||
* Introduce configuration file versioning and config_reader_min_version
|
* Introduce configuration file versioning and config_reader_min_version
|
||||||
Starting with this version the configuration file contains an version
|
Starting with this version the configuration file contains a version
|
||||||
identifying the minimum version of the configuration parser needed to
|
identifying the minimum version of the configuration parser needed to
|
||||||
fully understand the configuration file format.
|
fully understand the configuration file format.
|
||||||
Old configuration file formats are automatically upgraded on startup.
|
Old configuration file formats are automatically upgraded when
|
||||||
|
saving the config file (htoprc).
|
||||||
* Make the configuration parser friendlier to users (thanks to Bart Bakker)
|
* Make the configuration parser friendlier to users (thanks to Bart Bakker)
|
||||||
With this change only settings that cannot be parsed properly are
|
With this change only settings that cannot be parsed properly are
|
||||||
reset to their defaults.
|
reset to their defaults.
|
||||||
@ -48,12 +48,12 @@ What's new in version 3.1.0
|
|||||||
* Option and key ("*") to collapse / expand all branches under PID 1
|
* Option and key ("*") to collapse / expand all branches under PID 1
|
||||||
(and PID 2 if kernel threads are shown) (thanks to Krishna Chaitanya)
|
(and PID 2 if kernel threads are shown) (thanks to Krishna Chaitanya)
|
||||||
* Keep following a process when inverting the sort order, displaying
|
* Keep following a process when inverting the sort order, displaying
|
||||||
the help screen or hiding/unhiding userland threads
|
the help screen or hiding/unhiding userland threads.
|
||||||
If a thread is currently selected the selection is updated to point
|
If a thread is currently selected the selection is updated to point
|
||||||
to the thread's parent process. (thanks to Gonzalo, et.al.)
|
to the thread's parent process. (thanks to Gonzalo, et.al.)
|
||||||
* Reorder process scanning to be performed before updating the display
|
* Reorder process scanning to be performed before updating the display
|
||||||
of the meters in the header
|
of the meters in the header
|
||||||
* Always check the user for a process for any changes
|
* Always check the user for a process for any changes.
|
||||||
This affects multiple platforms that previously didn't correctly handle
|
This affects multiple platforms that previously didn't correctly handle
|
||||||
the user field for a process to change at runtime (e.g. due to seteuid
|
the user field for a process to change at runtime (e.g. due to seteuid
|
||||||
or similar syscalls).
|
or similar syscalls).
|
||||||
@ -105,14 +105,14 @@ What's new in version 3.1.0
|
|||||||
* Correctly color the ZFS ARC ratio (thanks to Ross Williams)
|
* Correctly color the ZFS ARC ratio (thanks to Ross Williams)
|
||||||
* Bugfixes related to CPU time display/calculations for darwin on M1 systems
|
* Bugfixes related to CPU time display/calculations for darwin on M1 systems
|
||||||
(thanks to Alexander Momchilov)
|
(thanks to Alexander Momchilov)
|
||||||
* Harmonize the handling of multiple batteries across different platforms
|
* Harmonize the handling of multiple batteries across different platforms.
|
||||||
The system is now considered to run on AC if at least one power supply
|
The system is now considered to run on AC if at least one power supply
|
||||||
marked as AC is found in the system.
|
marked as AC is found in the system.
|
||||||
Battery capacity is summed up over all batteries found.
|
Battery capacity is summed up over all batteries found.
|
||||||
This also changes the old behavior that batteries reported by the
|
This also changes the old behavior that batteries reported by the
|
||||||
system after the first AC adapter where sometimes ignored.
|
system after the first AC adapter where sometimes ignored.
|
||||||
* Correctly handle multiple batteries on Darwin
|
* Correctly handle multiple batteries on Darwin.
|
||||||
Resolves a possible memory leak on systems with multiple batteries
|
Resolves a possible memory leak on systems with multiple batteries.
|
||||||
* Handle Linux Shmem being part of Cached in the MemoryMeter
|
* Handle Linux Shmem being part of Cached in the MemoryMeter
|
||||||
* Add SwapCached to the Linux swap meter (thanks to David Zarzycki)
|
* Add SwapCached to the Linux swap meter (thanks to David Zarzycki)
|
||||||
* Convert process time to days if applicable (thanks to David Zarzycki)
|
* Convert process time to days if applicable (thanks to David Zarzycki)
|
||||||
@ -138,7 +138,7 @@ What's new in version 3.1.0
|
|||||||
* Add command line option to drop Linux capabilities
|
* Add command line option to drop Linux capabilities
|
||||||
* Support scheduler affinity on platforms beyond Linux
|
* Support scheduler affinity on platforms beyond Linux
|
||||||
* Report on any failure to write the configuration file
|
* Report on any failure to write the configuration file
|
||||||
* Cache stderr to be able to print assert messages
|
* Cache stderr to be able to print assert messages.
|
||||||
These messages are shown in case htop terminates unexpectedly.
|
These messages are shown in case htop terminates unexpectedly.
|
||||||
* Print current settings on crash
|
* Print current settings on crash
|
||||||
* Reset signal handlers on program exit
|
* Reset signal handlers on program exit
|
||||||
|
@ -118,12 +118,6 @@ const PanelClass ColumnsPanel_class = {
|
|||||||
.eventHandler = ColumnsPanel_eventHandler
|
.eventHandler = ColumnsPanel_eventHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Panel* super;
|
|
||||||
unsigned int id;
|
|
||||||
unsigned int offset;
|
|
||||||
} DynamicIterator;
|
|
||||||
|
|
||||||
static void ColumnsPanel_add(Panel* super, unsigned int key, Hashtable* columns) {
|
static void ColumnsPanel_add(Panel* super, unsigned int key, Hashtable* columns) {
|
||||||
const char* name;
|
const char* name;
|
||||||
if (key < LAST_PROCESSFIELD) {
|
if (key < LAST_PROCESSFIELD) {
|
||||||
|
@ -393,10 +393,8 @@ int CommandLine_run(const char* name, int argc, char** argv) {
|
|||||||
|
|
||||||
/* Delete these last, since they can get accessed in the crash handler */
|
/* Delete these last, since they can get accessed in the crash handler */
|
||||||
Settings_delete(settings);
|
Settings_delete(settings);
|
||||||
if (dc)
|
DynamicColumns_delete(dc);
|
||||||
Hashtable_delete(dc);
|
DynamicMeters_delete(dm);
|
||||||
if (dm)
|
|
||||||
Hashtable_delete(dm);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,13 @@ Hashtable* DynamicColumns_new(void) {
|
|||||||
return Platform_dynamicColumns();
|
return Platform_dynamicColumns();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DynamicColumns_delete(Hashtable* dynamics) {
|
||||||
|
if (dynamics) {
|
||||||
|
Platform_dynamicColumnsDone(dynamics);
|
||||||
|
Hashtable_delete(dynamics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char* DynamicColumn_init(unsigned int key) {
|
const char* DynamicColumn_init(unsigned int key) {
|
||||||
return Platform_dynamicColumnInit(key);
|
return Platform_dynamicColumnInit(key);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ typedef struct DynamicColumn_ {
|
|||||||
|
|
||||||
Hashtable* DynamicColumns_new(void);
|
Hashtable* DynamicColumns_new(void);
|
||||||
|
|
||||||
|
void DynamicColumns_delete(Hashtable* dynamics);
|
||||||
|
|
||||||
const char* DynamicColumn_init(unsigned int key);
|
const char* DynamicColumn_init(unsigned int key);
|
||||||
|
|
||||||
const DynamicColumn* DynamicColumn_lookup(Hashtable* dynamics, unsigned int key);
|
const DynamicColumn* DynamicColumn_lookup(Hashtable* dynamics, unsigned int key);
|
||||||
|
@ -38,6 +38,13 @@ Hashtable* DynamicMeters_new(void) {
|
|||||||
return Platform_dynamicMeters();
|
return Platform_dynamicMeters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DynamicMeters_delete(Hashtable* dynamics) {
|
||||||
|
if (dynamics) {
|
||||||
|
Platform_dynamicMetersDone(dynamics);
|
||||||
|
Hashtable_delete(dynamics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int key;
|
unsigned int key;
|
||||||
const char* name;
|
const char* name;
|
||||||
|
@ -17,6 +17,8 @@ typedef struct DynamicMeter_ {
|
|||||||
|
|
||||||
Hashtable* DynamicMeters_new(void);
|
Hashtable* DynamicMeters_new(void);
|
||||||
|
|
||||||
|
void DynamicMeters_delete(Hashtable* dynamics);
|
||||||
|
|
||||||
const char* DynamicMeter_lookup(Hashtable* dynamics, unsigned int key);
|
const char* DynamicMeter_lookup(Hashtable* dynamics, unsigned int key);
|
||||||
|
|
||||||
bool DynamicMeter_search(Hashtable* dynamics, const char* name, unsigned int* key);
|
bool DynamicMeter_search(Hashtable* dynamics, const char* name, unsigned int* key);
|
||||||
|
15
Header.c
15
Header.c
@ -86,8 +86,9 @@ static void Header_addMeterByName(Header* this, const char* name, MeterModeId mo
|
|||||||
if (paren) {
|
if (paren) {
|
||||||
int ok = sscanf(paren, "(%10u)", ¶m); // CPUMeter
|
int ok = sscanf(paren, "(%10u)", ¶m); // CPUMeter
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
char* end, dynamic[32] = {0};
|
char dynamic[32] = {0};
|
||||||
if (sscanf(paren, "(%30s)", dynamic)) { // DynamicMeter
|
if (sscanf(paren, "(%30s)", dynamic)) { // DynamicMeter
|
||||||
|
char* end;
|
||||||
if ((end = strrchr(dynamic, ')')) == NULL)
|
if ((end = strrchr(dynamic, ')')) == NULL)
|
||||||
return; // htoprc parse failure
|
return; // htoprc parse failure
|
||||||
*end = '\0';
|
*end = '\0';
|
||||||
@ -195,16 +196,16 @@ void Header_draw(const Header* this) {
|
|||||||
}
|
}
|
||||||
const int width = COLS - pad;
|
const int width = COLS - pad;
|
||||||
int x = pad;
|
int x = pad;
|
||||||
float roundingLoss = 0.0f;
|
float roundingLoss = 0.0F;
|
||||||
|
|
||||||
Header_forEachColumn(this, col) {
|
Header_forEachColumn(this, col) {
|
||||||
Vector* meters = this->columns[col];
|
Vector* meters = this->columns[col];
|
||||||
float colWidth = (float)width * HeaderLayout_layouts[this->headerLayout].widths[col] / 100.0f;
|
float colWidth = (float)width * HeaderLayout_layouts[this->headerLayout].widths[col] / 100.0F;
|
||||||
|
|
||||||
roundingLoss += colWidth - floorf(colWidth);
|
roundingLoss += colWidth - floorf(colWidth);
|
||||||
if (roundingLoss >= 1.0f) {
|
if (roundingLoss >= 1.0F) {
|
||||||
colWidth += 1.0f;
|
colWidth += 1.0F;
|
||||||
roundingLoss -= 1.0f;
|
roundingLoss -= 1.0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int y = (pad / 2), i = 0; i < Vector_size(meters); i++) {
|
for (int y = (pad / 2), i = 0; i < Vector_size(meters); i++) {
|
||||||
@ -213,7 +214,7 @@ void Header_draw(const Header* this) {
|
|||||||
float actualWidth = colWidth;
|
float actualWidth = colWidth;
|
||||||
if (meter->mode == TEXT_METERMODE) {
|
if (meter->mode == TEXT_METERMODE) {
|
||||||
for (int j = 1; j < meter->columnWidthCount; j++) {
|
for (int j = 1; j < meter->columnWidthCount; j++) {
|
||||||
actualWidth += (float)width * HeaderLayout_layouts[this->headerLayout].widths[col + j] / 100.0f;
|
actualWidth += (float)width * HeaderLayout_layouts[this->headerLayout].widths[col + j] / 100.0F;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
53
Process.c
53
Process.c
@ -707,6 +707,24 @@ void Process_printLeftAlignedField(RichString* str, int attr, const char* conten
|
|||||||
RichString_appendChr(str, attr, ' ', width + 1 - columns);
|
RichString_appendChr(str, attr, ' ', width + 1 - columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Process_printPercentage(float val, char* buffer, int n, int* attr) {
|
||||||
|
if (val >= 0) {
|
||||||
|
if (val < 99.9F) {
|
||||||
|
if (val < 0.05F) {
|
||||||
|
*attr = CRT_colors[PROCESS_SHADOW];
|
||||||
|
}
|
||||||
|
xSnprintf(buffer, n, "%4.1f ", val);
|
||||||
|
} else if (val < 999) {
|
||||||
|
xSnprintf(buffer, n, "%3d. ", (int)val);
|
||||||
|
} else {
|
||||||
|
xSnprintf(buffer, n, "%4d ", (int)val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*attr = CRT_colors[PROCESS_SHADOW];
|
||||||
|
xSnprintf(buffer, n, " N/A ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Process_writeField(const Process* this, RichString* str, ProcessField field) {
|
void Process_writeField(const Process* this, RichString* str, ProcessField field) {
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
size_t n = sizeof(buffer);
|
size_t n = sizeof(buffer);
|
||||||
@ -821,34 +839,13 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
|
|||||||
|
|
||||||
xSnprintf(buffer, n, "%4ld ", this->nlwp);
|
xSnprintf(buffer, n, "%4ld ", this->nlwp);
|
||||||
break;
|
break;
|
||||||
case PERCENT_CPU:
|
case PERCENT_CPU: Process_printPercentage(this->percent_cpu, buffer, n, &attr); break;
|
||||||
case PERCENT_NORM_CPU: {
|
case PERCENT_NORM_CPU: {
|
||||||
float cpuPercentage = this->percent_cpu;
|
float cpuPercentage = this->percent_cpu / this->processList->activeCPUs;
|
||||||
if (field == PERCENT_NORM_CPU) {
|
Process_printPercentage(cpuPercentage, buffer, n, &attr);
|
||||||
cpuPercentage /= this->processList->activeCPUs;
|
|
||||||
}
|
|
||||||
if (cpuPercentage > 999.9F) {
|
|
||||||
xSnprintf(buffer, n, "%4u ", (unsigned int)cpuPercentage);
|
|
||||||
} else if (cpuPercentage > 99.9F) {
|
|
||||||
xSnprintf(buffer, n, "%3u. ", (unsigned int)cpuPercentage);
|
|
||||||
} else {
|
|
||||||
if (cpuPercentage < 0.05F)
|
|
||||||
attr = CRT_colors[PROCESS_SHADOW];
|
|
||||||
|
|
||||||
xSnprintf(buffer, n, "%4.1f ", cpuPercentage);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PERCENT_MEM:
|
case PERCENT_MEM: Process_printPercentage(this->percent_mem, buffer, n, &attr); break;
|
||||||
if (this->percent_mem > 99.9F) {
|
|
||||||
xSnprintf(buffer, n, "100. ");
|
|
||||||
} else {
|
|
||||||
if (this->percent_mem < 0.05F)
|
|
||||||
attr = CRT_colors[PROCESS_SHADOW];
|
|
||||||
|
|
||||||
xSnprintf(buffer, n, "%4.1f ", this->percent_mem);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PGRP: xSnprintf(buffer, n, "%*d ", Process_pidDigits, this->pgrp); break;
|
case PGRP: xSnprintf(buffer, n, "%*d ", Process_pidDigits, this->pgrp); break;
|
||||||
case PID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, this->pid); break;
|
case PID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, this->pid); break;
|
||||||
case PPID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, this->ppid); break;
|
case PPID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, this->ppid); break;
|
||||||
@ -864,8 +861,12 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
|
|||||||
case STATE:
|
case STATE:
|
||||||
xSnprintf(buffer, n, "%c ", this->state);
|
xSnprintf(buffer, n, "%c ", this->state);
|
||||||
switch (this->state) {
|
switch (this->state) {
|
||||||
|
#ifdef HTOP_NETBSD
|
||||||
|
case 'P':
|
||||||
|
#else
|
||||||
case 'R':
|
case 'R':
|
||||||
attr = CRT_colors[PROCESS_R_STATE];
|
#endif
|
||||||
|
attr = CRT_colors[PROCESS_RUN_STATE];
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
attr = CRT_colors[PROCESS_D_STATE];
|
attr = CRT_colors[PROCESS_D_STATE];
|
||||||
|
@ -79,8 +79,6 @@ typedef struct ProcessMergedCommand_ {
|
|||||||
char* str; /* merged Command string */
|
char* str; /* merged Command string */
|
||||||
size_t highlightCount; /* how many portions of cmdline to highlight */
|
size_t highlightCount; /* how many portions of cmdline to highlight */
|
||||||
ProcessCmdlineHighlight highlights[8]; /* which portions of cmdline to highlight */
|
ProcessCmdlineHighlight highlights[8]; /* which portions of cmdline to highlight */
|
||||||
bool separateComm : 1; /* whether comm is a separate field */
|
|
||||||
bool unmatchedExe : 1; /* whether exe matched with cmdline */
|
|
||||||
bool cmdlineChanged : 1; /* whether cmdline changed */
|
bool cmdlineChanged : 1; /* whether cmdline changed */
|
||||||
bool exeChanged : 1; /* whether exe changed */
|
bool exeChanged : 1; /* whether exe changed */
|
||||||
bool commChanged : 1; /* whether comm changed */
|
bool commChanged : 1; /* whether comm changed */
|
||||||
@ -358,6 +356,8 @@ void Process_fillStarttimeBuffer(Process* this);
|
|||||||
|
|
||||||
void Process_printLeftAlignedField(RichString* str, int attr, const char* content, unsigned int width);
|
void Process_printLeftAlignedField(RichString* str, int attr, const char* content, unsigned int width);
|
||||||
|
|
||||||
|
void Process_printPercentage(float val, char* buffer, int n, int* attr);
|
||||||
|
|
||||||
void Process_display(const Object* cast, RichString* out);
|
void Process_display(const Object* cast, RichString* out);
|
||||||
|
|
||||||
void Process_done(Process* this);
|
void Process_done(Process* this);
|
||||||
|
12
Settings.c
12
Settings.c
@ -134,8 +134,9 @@ static void Settings_readFields(Settings* settings, const char* line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dynamically-defined columns are always stored by-name.
|
// Dynamically-defined columns are always stored by-name.
|
||||||
char* end, dynamic[32] = {0};
|
char dynamic[32] = {0};
|
||||||
if (sscanf(ids[i], "Dynamic(%30s)", dynamic)) {
|
if (sscanf(ids[i], "Dynamic(%30s)", dynamic)) {
|
||||||
|
char* end;
|
||||||
if ((end = strrchr(dynamic, ')')) == NULL)
|
if ((end = strrchr(dynamic, ')')) == NULL)
|
||||||
continue;
|
continue;
|
||||||
*end = '\0';
|
*end = '\0';
|
||||||
@ -182,6 +183,8 @@ static bool Settings_read(Settings* this, const char* fileName, unsigned int ini
|
|||||||
// the version of the config file on disk is newer than what we can read
|
// the version of the config file on disk is newer than what we can read
|
||||||
fprintf(stderr, "WARNING: %s specifies configuration format version v%d, but this %s binary supports up to v%d.", fileName, this->config_version, PACKAGE, CONFIG_READER_MIN_VERSION);
|
fprintf(stderr, "WARNING: %s specifies configuration format version v%d, but this %s binary supports up to v%d.", fileName, this->config_version, PACKAGE, CONFIG_READER_MIN_VERSION);
|
||||||
fprintf(stderr, " The configuration version will be downgraded to v%d when %s exits.\n", CONFIG_READER_MIN_VERSION, PACKAGE);
|
fprintf(stderr, " The configuration version will be downgraded to v%d when %s exits.\n", CONFIG_READER_MIN_VERSION, PACKAGE);
|
||||||
|
String_freeArray(option);
|
||||||
|
fclose(fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (String_eq(option[0], "fields")) {
|
} else if (String_eq(option[0], "fields")) {
|
||||||
@ -355,9 +358,9 @@ int Settings_write(const Settings* this, bool onCrash) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define printSettingInteger(setting_, value_) \
|
#define printSettingInteger(setting_, value_) \
|
||||||
fprintf(fd, setting_ "=%d%c", (int) value_, separator);
|
fprintf(fd, setting_ "=%d%c", (int) (value_), separator)
|
||||||
#define printSettingString(setting_, value_) \
|
#define printSettingString(setting_, value_) \
|
||||||
fprintf(fd, setting_ "=%s%c", value_, separator);
|
fprintf(fd, setting_ "=%s%c", value_, separator)
|
||||||
|
|
||||||
if (!onCrash) {
|
if (!onCrash) {
|
||||||
fprintf(fd, "# Beware! This file is rewritten by htop when settings are changed in the interface.\n");
|
fprintf(fd, "# Beware! This file is rewritten by htop when settings are changed in the interface.\n");
|
||||||
@ -541,6 +544,9 @@ Settings* Settings_new(unsigned int initialCpuCount, Hashtable* dynamicColumns)
|
|||||||
this->changed = true;
|
this->changed = true;
|
||||||
Settings_read(this, SYSCONFDIR "/htoprc", initialCpuCount);
|
Settings_read(this, SYSCONFDIR "/htoprc", initialCpuCount);
|
||||||
}
|
}
|
||||||
|
if (!ok) {
|
||||||
|
Settings_defaultMeters(this, initialCpuCount);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
AC_PREREQ([2.69])
|
AC_PREREQ([2.69])
|
||||||
AC_INIT([htop], [3.1.0-dev], [htop@groups.io], [], [https://htop.dev/])
|
AC_INIT([htop], [3.1.0-rc2], [htop@groups.io], [], [https://htop.dev/])
|
||||||
|
|
||||||
AC_CONFIG_SRCDIR([htop.c])
|
AC_CONFIG_SRCDIR([htop.c])
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
@ -482,6 +482,9 @@ AC_ARG_ENABLE([ancient_vserver],
|
|||||||
[],
|
[],
|
||||||
[enable_ancient_vserver=no])
|
[enable_ancient_vserver=no])
|
||||||
if test "x$enable_ancient_vserver" = xyes; then
|
if test "x$enable_ancient_vserver" = xyes; then
|
||||||
|
if test "x$enable_vserver" != xyes; then
|
||||||
|
enable_vserver=implied
|
||||||
|
fi
|
||||||
AC_DEFINE([HAVE_VSERVER], [1], [Define if VServer support enabled.])
|
AC_DEFINE([HAVE_VSERVER], [1], [Define if VServer support enabled.])
|
||||||
AC_DEFINE([HAVE_ANCIENT_VSERVER], [1], [Define if ancient vserver support enabled.])
|
AC_DEFINE([HAVE_ANCIENT_VSERVER], [1], [Define if ancient vserver support enabled.])
|
||||||
fi
|
fi
|
||||||
|
@ -99,6 +99,8 @@ void Platform_gettime_monotonic(uint64_t* msec);
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
||||||
@ -107,6 +109,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
||||||
|
|
||||||
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
||||||
|
@ -92,6 +92,8 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) {
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
||||||
@ -100,6 +102,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
||||||
|
|
||||||
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
||||||
|
@ -92,6 +92,8 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) {
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
||||||
@ -102,6 +104,8 @@ static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
|||||||
|
|
||||||
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -392,9 +392,6 @@ except the process's executable instructions).
|
|||||||
.B M_LRS (LIB)
|
.B M_LRS (LIB)
|
||||||
The library size of the process.
|
The library size of the process.
|
||||||
.TP
|
.TP
|
||||||
.B M_DT (DIRTY)
|
|
||||||
The size of the dirty pages of the process.
|
|
||||||
.TP
|
|
||||||
.B M_SWAP (SWAP)
|
.B M_SWAP (SWAP)
|
||||||
The size of the process's swapped pages.
|
The size of the process's swapped pages.
|
||||||
.TP
|
.TP
|
||||||
|
@ -30,8 +30,6 @@ typedef int IOPriority;
|
|||||||
|
|
||||||
#define IOPriority_tuple(class_, data_) (((class_) << IOPRIO_CLASS_SHIFT) | (data_))
|
#define IOPriority_tuple(class_, data_) (((class_) << IOPRIO_CLASS_SHIFT) | (data_))
|
||||||
|
|
||||||
#define IOPriority_error 0xffffffff
|
|
||||||
|
|
||||||
#define IOPriority_None IOPriority_tuple(IOPRIO_CLASS_NONE, 0)
|
#define IOPriority_None IOPriority_tuple(IOPRIO_CLASS_NONE, 0)
|
||||||
#define IOPriority_Idle IOPriority_tuple(IOPRIO_CLASS_IDLE, 7)
|
#define IOPriority_Idle IOPriority_tuple(IOPRIO_CLASS_IDLE, 7)
|
||||||
|
|
||||||
|
@ -56,7 +56,6 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = {
|
|||||||
[M_TRS] = { .name = "M_TRS", .title = " CODE ", .description = "Size of the text segment of the process", .flags = 0, .defaultSortDesc = true, },
|
[M_TRS] = { .name = "M_TRS", .title = " CODE ", .description = "Size of the text segment of the process", .flags = 0, .defaultSortDesc = true, },
|
||||||
[M_DRS] = { .name = "M_DRS", .title = " DATA ", .description = "Size of the data segment plus stack usage of the process", .flags = 0, .defaultSortDesc = true, },
|
[M_DRS] = { .name = "M_DRS", .title = " DATA ", .description = "Size of the data segment plus stack usage of the process", .flags = 0, .defaultSortDesc = true, },
|
||||||
[M_LRS] = { .name = "M_LRS", .title = " LIB ", .description = "The library size of the process (calculated from memory maps)", .flags = PROCESS_FLAG_LINUX_LRS_FIX, .defaultSortDesc = true, },
|
[M_LRS] = { .name = "M_LRS", .title = " LIB ", .description = "The library size of the process (calculated from memory maps)", .flags = PROCESS_FLAG_LINUX_LRS_FIX, .defaultSortDesc = true, },
|
||||||
[M_DT] = { .name = "M_DT", .title = " DIRTY ", .description = "Size of the dirty pages of the process (unused since Linux 2.6; always 0)", .flags = 0, .defaultSortDesc = true, },
|
|
||||||
[ST_UID] = { .name = "ST_UID", .title = " UID ", .description = "User ID of the process owner", .flags = 0, },
|
[ST_UID] = { .name = "ST_UID", .title = " UID ", .description = "User ID of the process owner", .flags = 0, },
|
||||||
[PERCENT_CPU] = { .name = "PERCENT_CPU", .title = "CPU% ", .description = "Percentage of the CPU time the process used in the last sampling", .flags = 0, .defaultSortDesc = true, },
|
[PERCENT_CPU] = { .name = "PERCENT_CPU", .title = "CPU% ", .description = "Percentage of the CPU time the process used in the last sampling", .flags = 0, .defaultSortDesc = true, },
|
||||||
[PERCENT_NORM_CPU] = { .name = "PERCENT_NORM_CPU", .title = "NCPU%", .description = "Normalized percentage of the CPU time the process used in the last sampling (normalized by cpu count)", .flags = 0, .defaultSortDesc = true, },
|
[PERCENT_NORM_CPU] = { .name = "PERCENT_NORM_CPU", .title = "NCPU%", .description = "Normalized percentage of the CPU time the process used in the last sampling (normalized by cpu count)", .flags = 0, .defaultSortDesc = true, },
|
||||||
@ -88,7 +87,7 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = {
|
|||||||
#ifdef HAVE_DELAYACCT
|
#ifdef HAVE_DELAYACCT
|
||||||
[PERCENT_CPU_DELAY] = { .name = "PERCENT_CPU_DELAY", .title = "CPUD%", .description = "CPU delay %", .flags = PROCESS_FLAG_LINUX_DELAYACCT, .defaultSortDesc = true, },
|
[PERCENT_CPU_DELAY] = { .name = "PERCENT_CPU_DELAY", .title = "CPUD%", .description = "CPU delay %", .flags = PROCESS_FLAG_LINUX_DELAYACCT, .defaultSortDesc = true, },
|
||||||
[PERCENT_IO_DELAY] = { .name = "PERCENT_IO_DELAY", .title = "IOD% ", .description = "Block I/O delay %", .flags = PROCESS_FLAG_LINUX_DELAYACCT, .defaultSortDesc = true, },
|
[PERCENT_IO_DELAY] = { .name = "PERCENT_IO_DELAY", .title = "IOD% ", .description = "Block I/O delay %", .flags = PROCESS_FLAG_LINUX_DELAYACCT, .defaultSortDesc = true, },
|
||||||
[PERCENT_SWAP_DELAY] = { .name = "PERCENT_SWAP_DELAY", .title = "SWAPD% ", .description = "Swapin delay %", .flags = PROCESS_FLAG_LINUX_DELAYACCT, .defaultSortDesc = true, },
|
[PERCENT_SWAP_DELAY] = { .name = "PERCENT_SWAP_DELAY", .title = "SWPD%", .description = "Swapin delay %", .flags = PROCESS_FLAG_LINUX_DELAYACCT, .defaultSortDesc = true, },
|
||||||
#endif
|
#endif
|
||||||
[M_PSS] = { .name = "M_PSS", .title = " PSS ", .description = "proportional set size, same as M_RESIDENT but each page is divided by the number of processes sharing it", .flags = PROCESS_FLAG_LINUX_SMAPS, .defaultSortDesc = true, },
|
[M_PSS] = { .name = "M_PSS", .title = " PSS ", .description = "proportional set size, same as M_RESIDENT but each page is divided by the number of processes sharing it", .flags = PROCESS_FLAG_LINUX_SMAPS, .defaultSortDesc = true, },
|
||||||
[M_SWAP] = { .name = "M_SWAP", .title = " SWAP ", .description = "Size of the process's swapped pages", .flags = PROCESS_FLAG_LINUX_SMAPS, .defaultSortDesc = true, },
|
[M_SWAP] = { .name = "M_SWAP", .title = " SWAP ", .description = "Size of the process's swapped pages", .flags = PROCESS_FLAG_LINUX_SMAPS, .defaultSortDesc = true, },
|
||||||
@ -190,16 +189,6 @@ bool LinuxProcess_changeAutogroupPriorityBy(Process* this, Arg delta) {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DELAYACCT
|
|
||||||
static void LinuxProcess_printDelay(float delay_percent, char* buffer, int n) {
|
|
||||||
if (isnan(delay_percent)) {
|
|
||||||
xSnprintf(buffer, n, " N/A ");
|
|
||||||
} else {
|
|
||||||
xSnprintf(buffer, n, "%4.1f ", delay_percent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void LinuxProcess_writeField(const Process* this, RichString* str, ProcessField field) {
|
static void LinuxProcess_writeField(const Process* this, RichString* str, ProcessField field) {
|
||||||
const LinuxProcess* lp = (const LinuxProcess*) this;
|
const LinuxProcess* lp = (const LinuxProcess*) this;
|
||||||
bool coloring = this->settings->highlightMegabytes;
|
bool coloring = this->settings->highlightMegabytes;
|
||||||
@ -210,7 +199,6 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
|
|||||||
case CMINFLT: Process_printCount(str, lp->cminflt, coloring); return;
|
case CMINFLT: Process_printCount(str, lp->cminflt, coloring); return;
|
||||||
case CMAJFLT: Process_printCount(str, lp->cmajflt, coloring); return;
|
case CMAJFLT: Process_printCount(str, lp->cmajflt, coloring); return;
|
||||||
case M_DRS: Process_printBytes(str, lp->m_drs * pageSize, coloring); return;
|
case M_DRS: Process_printBytes(str, lp->m_drs * pageSize, coloring); return;
|
||||||
case M_DT: Process_printBytes(str, lp->m_dt * pageSize, coloring); return;
|
|
||||||
case M_LRS:
|
case M_LRS:
|
||||||
if (lp->m_lrs) {
|
if (lp->m_lrs) {
|
||||||
Process_printBytes(str, lp->m_lrs * pageSize, coloring);
|
Process_printBytes(str, lp->m_lrs * pageSize, coloring);
|
||||||
@ -279,9 +267,9 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_DELAYACCT
|
#ifdef HAVE_DELAYACCT
|
||||||
case PERCENT_CPU_DELAY: LinuxProcess_printDelay(lp->cpu_delay_percent, buffer, n); break;
|
case PERCENT_CPU_DELAY: Process_printPercentage(lp->cpu_delay_percent, buffer, n, &attr); break;
|
||||||
case PERCENT_IO_DELAY: LinuxProcess_printDelay(lp->blkio_delay_percent, buffer, n); break;
|
case PERCENT_IO_DELAY: Process_printPercentage(lp->blkio_delay_percent, buffer, n, &attr); break;
|
||||||
case PERCENT_SWAP_DELAY: LinuxProcess_printDelay(lp->swapin_delay_percent, buffer, n); break;
|
case PERCENT_SWAP_DELAY: Process_printPercentage(lp->swapin_delay_percent, buffer, n, &attr); break;
|
||||||
#endif
|
#endif
|
||||||
case CTXT:
|
case CTXT:
|
||||||
if (lp->ctxt_diff > 1000) {
|
if (lp->ctxt_diff > 1000) {
|
||||||
@ -330,8 +318,6 @@ static int LinuxProcess_compareByKey(const Process* v1, const Process* v2, Proce
|
|||||||
switch (key) {
|
switch (key) {
|
||||||
case M_DRS:
|
case M_DRS:
|
||||||
return SPACESHIP_NUMBER(p1->m_drs, p2->m_drs);
|
return SPACESHIP_NUMBER(p1->m_drs, p2->m_drs);
|
||||||
case M_DT:
|
|
||||||
return SPACESHIP_NUMBER(p1->m_dt, p2->m_dt);
|
|
||||||
case M_LRS:
|
case M_LRS:
|
||||||
return SPACESHIP_NUMBER(p1->m_lrs, p2->m_lrs);
|
return SPACESHIP_NUMBER(p1->m_lrs, p2->m_lrs);
|
||||||
case M_TRS:
|
case M_TRS:
|
||||||
|
@ -47,7 +47,6 @@ typedef struct LinuxProcess_ {
|
|||||||
long m_trs;
|
long m_trs;
|
||||||
long m_drs;
|
long m_drs;
|
||||||
long m_lrs;
|
long m_lrs;
|
||||||
long m_dt;
|
|
||||||
|
|
||||||
/* Data read (in bytes) */
|
/* Data read (in bytes) */
|
||||||
unsigned long long io_rchar;
|
unsigned long long io_rchar;
|
||||||
|
@ -678,7 +678,7 @@ static bool LinuxProcessList_readStatmFile(LinuxProcess* process, openat_arg_t p
|
|||||||
if (!statmfile)
|
if (!statmfile)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
long int dummy;
|
long int dummy, dummy2;
|
||||||
|
|
||||||
int r = fscanf(statmfile, "%ld %ld %ld %ld %ld %ld %ld",
|
int r = fscanf(statmfile, "%ld %ld %ld %ld %ld %ld %ld",
|
||||||
&process->super.m_virt,
|
&process->super.m_virt,
|
||||||
@ -687,7 +687,7 @@ static bool LinuxProcessList_readStatmFile(LinuxProcess* process, openat_arg_t p
|
|||||||
&process->m_trs,
|
&process->m_trs,
|
||||||
&dummy, /* unused since Linux 2.6; always 0 */
|
&dummy, /* unused since Linux 2.6; always 0 */
|
||||||
&process->m_drs,
|
&process->m_drs,
|
||||||
&process->m_dt);
|
&dummy2); /* unused since Linux 2.6; always 0 */
|
||||||
fclose(statmfile);
|
fclose(statmfile);
|
||||||
|
|
||||||
if (r == 7) {
|
if (r == 7) {
|
||||||
@ -1433,7 +1433,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
|||||||
|
|
||||||
uint64_t recheck = ((uint64_t)rand()) % 2048;
|
uint64_t recheck = ((uint64_t)rand()) % 2048;
|
||||||
|
|
||||||
if (passedTimeInMs > 2000 || passedTimeInMs > recheck) {
|
if (passedTimeInMs > recheck) {
|
||||||
lp->last_mlrs_calctime = pl->realtimeMs;
|
lp->last_mlrs_calctime = pl->realtimeMs;
|
||||||
LinuxProcessList_readMaps(lp, procFd, settings->flags & PROCESS_FLAG_LINUX_LRS_FIX, settings->highlightDeletedExe);
|
LinuxProcessList_readMaps(lp, procFd, settings->flags & PROCESS_FLAG_LINUX_LRS_FIX, settings->highlightDeletedExe);
|
||||||
}
|
}
|
||||||
|
@ -543,6 +543,8 @@ bool Platform_getDiskIO(DiskIOData* data) {
|
|||||||
if (!fd)
|
if (!fd)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
char lastTopDisk[32] = { '\0' };
|
||||||
|
|
||||||
unsigned long long int read_sum = 0, write_sum = 0, timeSpend_sum = 0;
|
unsigned long long int read_sum = 0, write_sum = 0, timeSpend_sum = 0;
|
||||||
char lineBuffer[256];
|
char lineBuffer[256];
|
||||||
while (fgets(lineBuffer, sizeof(lineBuffer), fd)) {
|
while (fgets(lineBuffer, sizeof(lineBuffer), fd)) {
|
||||||
@ -556,22 +558,11 @@ bool Platform_getDiskIO(DiskIOData* data) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* only count root disks, e.g. do not count IO from sda and sda1 twice */
|
/* only count root disks, e.g. do not count IO from sda and sda1 twice */
|
||||||
if ((diskname[0] == 's' || diskname[0] == 'h')
|
if (lastTopDisk[0] && String_startsWith(diskname, lastTopDisk))
|
||||||
&& diskname[1] == 'd'
|
|
||||||
&& isalpha((unsigned char)diskname[2])
|
|
||||||
&& isdigit((unsigned char)diskname[3]))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* only count root disks, e.g. do not count IO from mmcblk0 and mmcblk0p1 twice */
|
/* This assumes disks are listed directly before any of their partitions */
|
||||||
if (diskname[0] == 'm'
|
String_safeStrncpy(lastTopDisk, diskname, sizeof(lastTopDisk));
|
||||||
&& diskname[1] == 'm'
|
|
||||||
&& diskname[2] == 'c'
|
|
||||||
&& diskname[3] == 'b'
|
|
||||||
&& diskname[4] == 'l'
|
|
||||||
&& diskname[5] == 'k'
|
|
||||||
&& isdigit((unsigned char)diskname[6])
|
|
||||||
&& diskname[7] == 'p')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
read_sum += read_tmp;
|
read_sum += read_tmp;
|
||||||
write_sum += write_tmp;
|
write_sum += write_tmp;
|
||||||
|
@ -112,6 +112,8 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) {
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
||||||
@ -120,6 +122,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
||||||
|
|
||||||
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
||||||
|
@ -19,7 +19,6 @@ in the source distribution for its full text.
|
|||||||
M_TRS = 42, \
|
M_TRS = 42, \
|
||||||
M_DRS = 43, \
|
M_DRS = 43, \
|
||||||
M_LRS = 44, \
|
M_LRS = 44, \
|
||||||
M_DT = 45, \
|
|
||||||
CTID = 100, \
|
CTID = 100, \
|
||||||
VPID = 101, \
|
VPID = 101, \
|
||||||
VXID = 102, \
|
VXID = 102, \
|
||||||
|
@ -39,14 +39,17 @@ static long fscale;
|
|||||||
static int pageSize;
|
static int pageSize;
|
||||||
static int pageSizeKB;
|
static int pageSizeKB;
|
||||||
|
|
||||||
static char const *freqSysctls[] = {
|
static const struct {
|
||||||
"machdep.est.frequency.current",
|
const char* name;
|
||||||
"machdep.powernow.frequency.current",
|
long int scale;
|
||||||
"machdep.intrepid.frequency.current",
|
} freqSysctls[] = {
|
||||||
"machdep.loongson.frequency.current",
|
{ "machdep.est.frequency.current", 1 },
|
||||||
"machdep.cpu.frequency.current",
|
{ "machdep.powernow.frequency.current", 1 },
|
||||||
"machdep.frequency.current",
|
{ "machdep.intrepid.frequency.current", 1 },
|
||||||
NULL
|
{ "machdep.loongson.frequency.current", 1 },
|
||||||
|
{ "machdep.cpu.frequency.current", 1 },
|
||||||
|
{ "machdep.frequency.current", 1 },
|
||||||
|
{ "machdep.tsc_freq", 1000000 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void NetBSDProcessList_updateCPUcount(ProcessList* super) {
|
static void NetBSDProcessList_updateCPUcount(ProcessList* super) {
|
||||||
@ -261,7 +264,6 @@ static void NetBSDProcessList_scanProcs(NetBSDProcessList* this) {
|
|||||||
bool hideKernelThreads = settings->hideKernelThreads;
|
bool hideKernelThreads = settings->hideKernelThreads;
|
||||||
bool hideUserlandThreads = settings->hideUserlandThreads;
|
bool hideUserlandThreads = settings->hideUserlandThreads;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int nlwps = 0;
|
|
||||||
|
|
||||||
const struct kinfo_proc2* kprocs = kvm_getproc2(this->kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &count);
|
const struct kinfo_proc2* kprocs = kvm_getproc2(this->kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &count);
|
||||||
|
|
||||||
@ -279,7 +281,6 @@ static void NetBSDProcessList_scanProcs(NetBSDProcessList* this) {
|
|||||||
proc->tpgid = kproc->p_tpgid;
|
proc->tpgid = kproc->p_tpgid;
|
||||||
proc->tgid = kproc->p_pid;
|
proc->tgid = kproc->p_pid;
|
||||||
proc->session = kproc->p_sid;
|
proc->session = kproc->p_sid;
|
||||||
proc->tty_nr = kproc->p_tdev;
|
|
||||||
proc->pgrp = kproc->p__pgid;
|
proc->pgrp = kproc->p__pgid;
|
||||||
proc->isKernelThread = !!(kproc->p_flag & P_SYSTEM);
|
proc->isKernelThread = !!(kproc->p_flag & P_SYSTEM);
|
||||||
proc->isUserlandThread = proc->pid != proc->tgid;
|
proc->isUserlandThread = proc->pid != proc->tgid;
|
||||||
@ -287,6 +288,15 @@ static void NetBSDProcessList_scanProcs(NetBSDProcessList* this) {
|
|||||||
Process_fillStarttimeBuffer(proc);
|
Process_fillStarttimeBuffer(proc);
|
||||||
ProcessList_add(&this->super, proc);
|
ProcessList_add(&this->super, proc);
|
||||||
|
|
||||||
|
proc->tty_nr = kproc->p_tdev;
|
||||||
|
const char* name = ((dev_t)kproc->p_tdev != KERN_PROC_TTY_NODEV) ? devname(kproc->p_tdev, S_IFCHR) : NULL;
|
||||||
|
if (!name) {
|
||||||
|
free(proc->tty_name);
|
||||||
|
proc->tty_name = NULL;
|
||||||
|
} else {
|
||||||
|
free_and_xStrdup(&proc->tty_name, name);
|
||||||
|
}
|
||||||
|
|
||||||
NetBSDProcessList_updateExe(kproc, proc);
|
NetBSDProcessList_updateExe(kproc, proc);
|
||||||
NetBSDProcessList_updateProcessName(this->kd, kproc, proc);
|
NetBSDProcessList_updateProcessName(this->kd, kproc, proc);
|
||||||
} else {
|
} else {
|
||||||
@ -312,8 +322,12 @@ static void NetBSDProcessList_scanProcs(NetBSDProcessList* this) {
|
|||||||
proc->nice = kproc->p_nice - 20;
|
proc->nice = kproc->p_nice - 20;
|
||||||
proc->time = 100 * (kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 1000000));
|
proc->time = 100 * (kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 1000000));
|
||||||
proc->priority = kproc->p_priority - PZERO;
|
proc->priority = kproc->p_priority - PZERO;
|
||||||
|
proc->processor = kproc->p_cpuid;
|
||||||
|
proc->minflt = kproc->p_uru_minflt;
|
||||||
|
proc->majflt = kproc->p_uru_majflt;
|
||||||
|
|
||||||
struct kinfo_lwp* klwps = kvm_getlwps(this->kd, kproc->p_pid, kproc->p_paddr, sizeof(struct kinfo_lwp), &nlwps);
|
int nlwps = 0;
|
||||||
|
const struct kinfo_lwp* klwps = kvm_getlwps(this->kd, kproc->p_pid, kproc->p_paddr, sizeof(struct kinfo_lwp), &nlwps);
|
||||||
|
|
||||||
switch (kproc->p_realstat) {
|
switch (kproc->p_realstat) {
|
||||||
case SIDL: proc->state = 'I'; break;
|
case SIDL: proc->state = 'I'; break;
|
||||||
@ -417,7 +431,7 @@ static void NetBSDProcessList_scanCPUFrequency(NetBSDProcessList* this) {
|
|||||||
unsigned int cpus = this->super.existingCPUs;
|
unsigned int cpus = this->super.existingCPUs;
|
||||||
bool match = false;
|
bool match = false;
|
||||||
char name[64];
|
char name[64];
|
||||||
int freq = 0;
|
long int freq = 0;
|
||||||
size_t freqSize;
|
size_t freqSize;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < cpus; i++) {
|
for (unsigned int i = 0; i < cpus; i++) {
|
||||||
@ -429,7 +443,7 @@ static void NetBSDProcessList_scanCPUFrequency(NetBSDProcessList* this) {
|
|||||||
xSnprintf(name, sizeof(name), "machdep.cpufreq.cpu%u.current", i);
|
xSnprintf(name, sizeof(name), "machdep.cpufreq.cpu%u.current", i);
|
||||||
freqSize = sizeof(freq);
|
freqSize = sizeof(freq);
|
||||||
if (sysctlbyname(name, &freq, &freqSize, NULL, 0) != -1) {
|
if (sysctlbyname(name, &freq, &freqSize, NULL, 0) != -1) {
|
||||||
this->cpuData[i + 1].frequency = freq;
|
this->cpuData[i + 1].frequency = freq; /* already in MHz */
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -442,9 +456,10 @@ static void NetBSDProcessList_scanCPUFrequency(NetBSDProcessList* this) {
|
|||||||
* Iterate through legacy sysctl nodes for single-core frequency until
|
* Iterate through legacy sysctl nodes for single-core frequency until
|
||||||
* we find a match...
|
* we find a match...
|
||||||
*/
|
*/
|
||||||
for (const char** s = freqSysctls; *s != NULL; ++s) {
|
for (size_t i = 0; i < ARRAYSIZE(freqSysctls); i++) {
|
||||||
freqSize = sizeof(freq);
|
freqSize = sizeof(freq);
|
||||||
if (sysctlbyname(*s, &freq, &freqSize, NULL, 0) != -1) {
|
if (sysctlbyname(freqSysctls[i].name, &freq, &freqSize, NULL, 0) != -1) {
|
||||||
|
freq /= freqSysctls[i].scale; /* scale to MHz */
|
||||||
match = true;
|
match = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -260,14 +260,11 @@ double Platform_setCPUValues(Meter* this, int cpu) {
|
|||||||
|
|
||||||
void Platform_setMemoryValues(Meter* this) {
|
void Platform_setMemoryValues(Meter* this) {
|
||||||
const ProcessList* pl = this->pl;
|
const ProcessList* pl = this->pl;
|
||||||
long int usedMem = pl->usedMem;
|
|
||||||
long int buffersMem = pl->buffersMem;
|
|
||||||
long int cachedMem = pl->cachedMem;
|
|
||||||
this->total = pl->totalMem;
|
this->total = pl->totalMem;
|
||||||
this->values[0] = usedMem;
|
this->values[0] = pl->usedMem;
|
||||||
this->values[1] = buffersMem;
|
this->values[1] = pl->buffersMem;
|
||||||
// this->values[2] = "shared memory, like tmpfs and shm"
|
// this->values[2] = "shared memory, like tmpfs and shm"
|
||||||
this->values[3] = cachedMem;
|
this->values[3] = pl->cachedMem;
|
||||||
// this->values[4] = "available memory"
|
// this->values[4] = "available memory"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,19 +281,19 @@ char* Platform_getProcessEnv(pid_t pid) {
|
|||||||
char** ptr;
|
char** ptr;
|
||||||
int count;
|
int count;
|
||||||
kvm_t* kt;
|
kvm_t* kt;
|
||||||
struct kinfo_proc* kproc;
|
const struct kinfo_proc2* kproc;
|
||||||
size_t capacity = 4096, size = 0;
|
size_t capacity = 4096, size = 0;
|
||||||
|
|
||||||
if ((kt = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf)) == NULL) {
|
if ((kt = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf)) == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((kproc = kvm_getprocs(kt, KERN_PROC_PID, pid, &count)) == NULL) {
|
if ((kproc = kvm_getproc2(kt, KERN_PROC_PID, pid, sizeof(struct kinfo_proc2), &count)) == NULL) {
|
||||||
(void) kvm_close(kt);
|
(void) kvm_close(kt);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ptr = kvm_getenvv(kt, kproc, 0)) == NULL) {
|
if ((ptr = kvm_getenvv2(kt, kproc, 0)) == NULL) {
|
||||||
(void) kvm_close(kt);
|
(void) kvm_close(kt);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -393,7 +390,7 @@ bool Platform_getNetworkIO(NetworkIOData* data) {
|
|||||||
if (getifaddrs(&ifaddrs) != 0)
|
if (getifaddrs(&ifaddrs) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (struct ifaddrs* ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
|
for (const struct ifaddrs* ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
|
||||||
if (!ifa->ifa_addr)
|
if (!ifa->ifa_addr)
|
||||||
continue;
|
continue;
|
||||||
if (ifa->ifa_addr->sa_family != AF_LINK)
|
if (ifa->ifa_addr->sa_family != AF_LINK)
|
||||||
@ -401,7 +398,7 @@ bool Platform_getNetworkIO(NetworkIOData* data) {
|
|||||||
if (ifa->ifa_flags & IFF_LOOPBACK)
|
if (ifa->ifa_flags & IFF_LOOPBACK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
struct if_data* ifd = (struct if_data *)ifa->ifa_data;
|
const struct if_data* ifd = (const struct if_data *)ifa->ifa_data;
|
||||||
|
|
||||||
data->bytesReceived += ifd->ifi_ibytes;
|
data->bytesReceived += ifd->ifi_ibytes;
|
||||||
data->packetsReceived += ifd->ifi_ipackets;
|
data->packetsReceived += ifd->ifi_ipackets;
|
||||||
|
@ -96,6 +96,8 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) {
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
||||||
@ -104,6 +106,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
||||||
|
|
||||||
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
||||||
|
@ -90,6 +90,8 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) {
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
||||||
@ -98,6 +100,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
||||||
|
|
||||||
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
||||||
|
@ -226,6 +226,18 @@ void PCPDynamicColumns_init(PCPDynamicColumns* columns) {
|
|||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void PCPDynamicColumns_free(ATTR_UNUSED ht_key_t key, void* value, ATTR_UNUSED void* data) {
|
||||||
|
PCPDynamicColumn* column = (PCPDynamicColumn*) value;
|
||||||
|
free(column->metricName);
|
||||||
|
free(column->super.heading);
|
||||||
|
free(column->super.caption);
|
||||||
|
free(column->super.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCPDynamicColumns_done(Hashtable* table) {
|
||||||
|
Hashtable_foreach(table, PCPDynamicColumns_free, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void PCPDynamicColumn_writeField(PCPDynamicColumn* this, const Process* proc, RichString* str) {
|
void PCPDynamicColumn_writeField(PCPDynamicColumn* this, const Process* proc, RichString* str) {
|
||||||
const PCPProcess* pp = (const PCPProcess*) proc;
|
const PCPProcess* pp = (const PCPProcess*) proc;
|
||||||
unsigned int type = PCPMetric_type(this->id);
|
unsigned int type = PCPMetric_type(this->id);
|
||||||
|
@ -26,6 +26,8 @@ typedef struct PCPDynamicColumns_ {
|
|||||||
|
|
||||||
void PCPDynamicColumns_init(PCPDynamicColumns* columns);
|
void PCPDynamicColumns_init(PCPDynamicColumns* columns);
|
||||||
|
|
||||||
|
void PCPDynamicColumns_done(Hashtable* table);
|
||||||
|
|
||||||
void PCPDynamicColumn_writeField(PCPDynamicColumn* this, const Process* proc, RichString* str);
|
void PCPDynamicColumn_writeField(PCPDynamicColumn* this, const Process* proc, RichString* str);
|
||||||
|
|
||||||
int PCPDynamicColumn_compareByKey(const PCPProcess* p1, const PCPProcess* p2, ProcessField key);
|
int PCPDynamicColumn_compareByKey(const PCPProcess* p1, const PCPProcess* p2, ProcessField key);
|
||||||
|
@ -283,6 +283,22 @@ void PCPDynamicMeters_init(PCPDynamicMeters* meters) {
|
|||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void PCPDynamicMeter_free(ATTR_UNUSED ht_key_t key, void* value, ATTR_UNUSED void* data) {
|
||||||
|
PCPDynamicMeter* meter = (PCPDynamicMeter*) value;
|
||||||
|
for (size_t i = 0; i < meter->totalMetrics; i++) {
|
||||||
|
free(meter->metrics[i].name);
|
||||||
|
free(meter->metrics[i].label);
|
||||||
|
free(meter->metrics[i].suffix);
|
||||||
|
}
|
||||||
|
free(meter->metrics);
|
||||||
|
free(meter->super.caption);
|
||||||
|
free(meter->super.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCPDynamicMeters_done(Hashtable* table) {
|
||||||
|
Hashtable_foreach(table, PCPDynamicMeter_free, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void PCPDynamicMeter_enable(PCPDynamicMeter* this) {
|
void PCPDynamicMeter_enable(PCPDynamicMeter* this) {
|
||||||
for (size_t i = 0; i < this->totalMetrics; i++)
|
for (size_t i = 0; i < this->totalMetrics; i++)
|
||||||
PCPMetric_enable(this->metrics[i].id, true);
|
PCPMetric_enable(this->metrics[i].id, true);
|
||||||
|
@ -33,6 +33,8 @@ typedef struct PCPDynamicMeters_ {
|
|||||||
|
|
||||||
void PCPDynamicMeters_init(PCPDynamicMeters* meters);
|
void PCPDynamicMeters_init(PCPDynamicMeters* meters);
|
||||||
|
|
||||||
|
void PCPDynamicMeters_done(Hashtable* table);
|
||||||
|
|
||||||
void PCPDynamicMeter_enable(PCPDynamicMeter* this);
|
void PCPDynamicMeter_enable(PCPDynamicMeter* this);
|
||||||
|
|
||||||
void PCPDynamicMeter_updateValues(PCPDynamicMeter* this, Meter* meter);
|
void PCPDynamicMeter_updateValues(PCPDynamicMeter* this, Meter* meter);
|
||||||
|
@ -317,7 +317,7 @@ static void PCPProcessList_updateCmdline(Process* process, int pid, int offset,
|
|||||||
Process_updateComm(process, comm);
|
Process_updateComm(process, comm);
|
||||||
|
|
||||||
if (PCPMetric_instance(PCP_PROC_EXE, pid, offset, &value, PM_TYPE_STRING)) {
|
if (PCPMetric_instance(PCP_PROC_EXE, pid, offset, &value, PM_TYPE_STRING)) {
|
||||||
Process_updateExe(process, value.cp);
|
Process_updateExe(process, value.cp[0] ? value.cp : NULL);
|
||||||
free(value.cp);
|
free(value.cp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,6 +363,14 @@ void Platform_init(void) {
|
|||||||
Platform_getMaxPid();
|
Platform_getMaxPid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Platform_dynamicColumnsDone(Hashtable* columns) {
|
||||||
|
PCPDynamicColumns_done(columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_dynamicMetersDone(Hashtable* meters) {
|
||||||
|
PCPDynamicMeters_done(meters);
|
||||||
|
}
|
||||||
|
|
||||||
void Platform_done(void) {
|
void Platform_done(void) {
|
||||||
pmDestroyContext(pcp->context);
|
pmDestroyContext(pcp->context);
|
||||||
if (pcp->result)
|
if (pcp->result)
|
||||||
|
@ -138,6 +138,8 @@ void Platform_gettime_monotonic(uint64_t* msec);
|
|||||||
|
|
||||||
Hashtable* Platform_dynamicMeters(void);
|
Hashtable* Platform_dynamicMeters(void);
|
||||||
|
|
||||||
|
void Platform_dynamicMetersDone(Hashtable* meters);
|
||||||
|
|
||||||
void Platform_dynamicMeterInit(Meter* meter);
|
void Platform_dynamicMeterInit(Meter* meter);
|
||||||
|
|
||||||
void Platform_dynamicMeterUpdateValues(Meter* meter);
|
void Platform_dynamicMeterUpdateValues(Meter* meter);
|
||||||
@ -146,6 +148,8 @@ void Platform_dynamicMeterDisplay(const Meter* meter, RichString* out);
|
|||||||
|
|
||||||
Hashtable* Platform_dynamicColumns(void);
|
Hashtable* Platform_dynamicColumns(void);
|
||||||
|
|
||||||
|
void Platform_dynamicColumnsDone(Hashtable* columns);
|
||||||
|
|
||||||
const char* Platform_dynamicColumnInit(unsigned int key);
|
const char* Platform_dynamicColumnInit(unsigned int key);
|
||||||
|
|
||||||
bool Platform_dynamicColumnWriteField(const Process* proc, RichString* str, unsigned int key);
|
bool Platform_dynamicColumnWriteField(const Process* proc, RichString* str, unsigned int key);
|
||||||
|
@ -131,6 +131,8 @@ IGNORE_WCASTQUAL_END
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
||||||
@ -139,6 +141,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
||||||
|
|
||||||
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
||||||
|
@ -79,6 +79,8 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) {
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
|
||||||
|
|
||||||
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
|
||||||
@ -87,6 +89,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
|
|||||||
|
|
||||||
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
|
||||||
|
|
||||||
|
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
|
||||||
|
|
||||||
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
|
||||||
|
|
||||||
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
|
||||||
|
Reference in New Issue
Block a user