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
47e881f4
Commit
47e881f4
authored
Oct 04, 2012
by
Hisham Muhammad
Browse files
Add IO priority support ('i' key)
parent
e6c6d7fb
Changes
14
Hide whitespace changes
Inline
Side-by-side
AffinityPanel.c
View file @
47e881f4
...
@@ -50,7 +50,7 @@ Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity) {
...
@@ -50,7 +50,7 @@ Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity) {
}
else
{
}
else
{
mode
=
false
;
mode
=
false
;
}
}
Panel_add
(
this
,
(
Object
*
)
CheckItem_new
(
strdup
(
number
),
NULL
,
mode
));
Panel_add
(
this
,
(
Object
*
)
CheckItem_new
(
strdup
(
number
),
NULL
,
mode
));
}
}
return
this
;
return
this
;
}
}
...
...
CRT.c
View file @
47e881f4
...
@@ -129,7 +129,7 @@ static void CRT_handleSIGSEGV(int sgn) {
...
@@ -129,7 +129,7 @@ static void CRT_handleSIGSEGV(int sgn) {
fprintf
(
stderr
,
"
\n\n
htop "
VERSION
" aborting. Please report bug at http://htop.sf.net
\n
"
);
fprintf
(
stderr
,
"
\n\n
htop "
VERSION
" aborting. Please report bug at http://htop.sf.net
\n
"
);
#ifdef HAVE_EXECINFO_H
#ifdef HAVE_EXECINFO_H
size_t
size
=
backtrace
(
backtraceArray
,
sizeof
(
backtraceArray
)
/
sizeof
(
void
*
));
size_t
size
=
backtrace
(
backtraceArray
,
sizeof
(
backtraceArray
)
/
sizeof
(
void
*
));
fprintf
(
stderr
,
"
B
acktrace:
\n
"
);
fprintf
(
stderr
,
"
\n
Please include in your report the following b
acktrace:
\n
"
);
backtrace_symbols_fd
(
backtraceArray
,
size
,
2
);
backtrace_symbols_fd
(
backtraceArray
,
size
,
2
);
fprintf
(
stderr
,
"
\n
Additionally, in order to make the above backtrace useful,"
);
fprintf
(
stderr
,
"
\n
Additionally, in order to make the above backtrace useful,"
);
fprintf
(
stderr
,
"
\n
please also run the following command to generate a disassembly of your binary:"
);
fprintf
(
stderr
,
"
\n
please also run the following command to generate a disassembly of your binary:"
);
...
...
ChangeLog
View file @
47e881f4
What's new in version 1.0.2
What's new in version 1.0.2
* Add IO priority support ('i' key)
* Avoid deleting .htoprc if it is a symlink
* Avoid deleting .htoprc if it is a symlink
* BUGFIX: Fix crashes when process list is empty
* BUGFIX: Fix crashes when process list is empty
...
...
IOPriority.c
0 → 100644
View file @
47e881f4
/*
htop - IOPriority.c
(C) 2004-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
Based on ionice,
Copyright (C) 2005 Jens Axboe <jens@axboe.dk>
Released under the terms of the GNU General Public License version 2
*/
#include "IOPriority.h"
/*{
enum {
IOPRIO_CLASS_NONE,
IOPRIO_CLASS_RT,
IOPRIO_CLASS_BE,
IOPRIO_CLASS_IDLE,
};
#define IOPRIO_WHO_PROCESS 1
#define IOPRIO_CLASS_SHIFT (13)
#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
#define IOPriority_class(ioprio_) ((int) ((ioprio_) >> IOPRIO_CLASS_SHIFT) )
#define IOPriority_data(ioprio_) ((int) ((ioprio_) & IOPRIO_PRIO_MASK) )
typedef int IOPriority;
#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_Idle IOPriority_tuple(IOPRIO_CLASS_IDLE, 0)
}*/
IOPriority.h
0 → 100644
View file @
47e881f4
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_IOPriority
#define HEADER_IOPriority
/*
htop - IOPriority.h
(C) 2004-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
Based on ionice,
Copyright (C) 2005 Jens Axboe <jens@axboe.dk>
Released under the terms of the GNU General Public License version 2
*/
enum
{
IOPRIO_CLASS_NONE
,
IOPRIO_CLASS_RT
,
IOPRIO_CLASS_BE
,
IOPRIO_CLASS_IDLE
,
};
#define IOPRIO_WHO_PROCESS 1
#define IOPRIO_CLASS_SHIFT (13)
#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
#define IOPriority_class(ioprio_) ((int) ((ioprio_) >> IOPRIO_CLASS_SHIFT) )
#define IOPriority_data(ioprio_) ((int) ((ioprio_) & IOPRIO_PRIO_MASK) )
typedef
int
IOPriority
;
#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_Idle IOPriority_tuple(IOPRIO_CLASS_IDLE, 0)
#endif
IOPriorityPanel.c
0 → 100644
View file @
47e881f4
/*
htop - IOPriorityPanel.c
(C) 2004-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "IOPriorityPanel.h"
/*{
#include "Panel.h"
#include "IOPriority.h"
#include "ListItem.h"
}*/
Panel
*
IOPriorityPanel_new
(
IOPriority
currPrio
)
{
Panel
*
this
=
Panel_new
(
1
,
1
,
1
,
1
,
LISTITEM_CLASS
,
true
,
ListItem_compare
);
Panel_setHeader
(
this
,
"IO Priority:"
);
Panel_add
(
this
,
(
Object
*
)
ListItem_new
(
"None (based on nice)"
,
IOPriority_None
));
if
(
currPrio
==
IOPriority_None
)
Panel_setSelected
(
this
,
0
);
struct
{
int
klass
;
const
char
*
name
;
}
classes
[]
=
{
{
.
klass
=
IOPRIO_CLASS_RT
,
.
name
=
"Realtime"
},
{
.
klass
=
IOPRIO_CLASS_BE
,
.
name
=
"Best-effort"
},
{
.
klass
=
0
,
.
name
=
NULL
}
};
for
(
int
c
=
0
;
classes
[
c
].
name
;
c
++
)
{
for
(
int
i
=
0
;
i
<
8
;
i
++
)
{
char
name
[
50
];
snprintf
(
name
,
sizeof
(
name
)
-
1
,
"%s %d %s"
,
classes
[
c
].
name
,
i
,
i
==
0
?
"(High)"
:
(
i
==
7
?
"(Low)"
:
""
));
IOPriority
ioprio
=
IOPriority_tuple
(
classes
[
c
].
klass
,
i
);
Panel_add
(
this
,
(
Object
*
)
ListItem_new
(
name
,
ioprio
));
if
(
currPrio
==
ioprio
)
Panel_setSelected
(
this
,
Panel_size
(
this
)
-
1
);
}
}
Panel_add
(
this
,
(
Object
*
)
ListItem_new
(
"Idle"
,
IOPriority_Idle
));
if
(
currPrio
==
IOPriority_Idle
)
Panel_setSelected
(
this
,
Panel_size
(
this
)
-
1
);
return
this
;
}
IOPriority
IOPriorityPanel_getIOPriority
(
Panel
*
this
)
{
return
(
IOPriority
)
(
((
ListItem
*
)
Panel_getSelected
(
this
))
->
key
);
}
IOPriorityPanel.h
0 → 100644
View file @
47e881f4
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_IOPriorityPanel
#define HEADER_IOPriorityPanel
/*
htop - IOPriorityPanel.h
(C) 2004-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Panel.h"
#include "IOPriority.h"
#include "ListItem.h"
Panel
*
IOPriorityPanel_new
(
IOPriority
currPrio
);
IOPriority
IOPriorityPanel_getIOPriority
(
Panel
*
this
);
#endif
Makefile.am
View file @
47e881f4
...
@@ -18,18 +18,18 @@ ClockMeter.c ColorsPanel.c ColumnsPanel.c CPUMeter.c CRT.c \
...
@@ -18,18 +18,18 @@ ClockMeter.c ColorsPanel.c ColumnsPanel.c CPUMeter.c CRT.c \
DisplayOptionsPanel.c FunctionBar.c Hashtable.c Header.c htop.c ListItem.c
\
DisplayOptionsPanel.c FunctionBar.c Hashtable.c Header.c htop.c ListItem.c
\
LoadAverageMeter.c MemoryMeter.c Meter.c MetersPanel.c Object.c Panel.c
\
LoadAverageMeter.c MemoryMeter.c Meter.c MetersPanel.c Object.c Panel.c
\
BatteryMeter.c Process.c ProcessList.c RichString.c ScreenManager.c Settings.c
\
BatteryMeter.c Process.c ProcessList.c RichString.c ScreenManager.c Settings.c
\
SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c
\
IOPriorityPanel.c
SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c
\
UptimeMeter.c UsersTable.c Vector.c AvailableColumnsPanel.c AffinityPanel.c
\
UptimeMeter.c UsersTable.c Vector.c AvailableColumnsPanel.c AffinityPanel.c
\
HostnameMeter.c OpenFilesScreen.c Affinity.c
HostnameMeter.c OpenFilesScreen.c Affinity.c
IOPriority.c
myhtopheaders
=
AvailableColumnsPanel.h AvailableMetersPanel.h
\
myhtopheaders
=
AvailableColumnsPanel.h AvailableMetersPanel.h
\
CategoriesPanel.h CheckItem.h ClockMeter.h ColorsPanel.h ColumnsPanel.h
\
CategoriesPanel.h CheckItem.h ClockMeter.h ColorsPanel.h ColumnsPanel.h
\
CPUMeter.h CRT.h DisplayOptionsPanel.h FunctionBar.h
\
IOPriorityPanel.h
CPUMeter.h CRT.h DisplayOptionsPanel.h FunctionBar.h
\
Hashtable.h Header.h htop.h ListItem.h LoadAverageMeter.h MemoryMeter.h
\
Hashtable.h Header.h htop.h ListItem.h LoadAverageMeter.h MemoryMeter.h
\
BatteryMeter.h Meter.h MetersPanel.h Object.h Panel.h ProcessList.h RichString.h
\
BatteryMeter.h Meter.h MetersPanel.h Object.h Panel.h ProcessList.h RichString.h
\
ScreenManager.h Settings.h SignalsPanel.h String.h
\
ScreenManager.h Settings.h SignalsPanel.h String.h
\
SwapMeter.h TasksMeter.h TraceScreen.h UptimeMeter.h UsersTable.h Vector.h
\
SwapMeter.h TasksMeter.h TraceScreen.h UptimeMeter.h UsersTable.h Vector.h
\
Process.h AffinityPanel.h HostnameMeter.h OpenFilesScreen.h Affinity.h
Process.h AffinityPanel.h HostnameMeter.h OpenFilesScreen.h Affinity.h
IOPriority.h
SUFFIXES
=
.h
SUFFIXES
=
.h
...
...
Process.c
View file @
47e881f4
...
@@ -26,6 +26,7 @@ in the source distribution for its full text.
...
@@ -26,6 +26,7 @@ in the source distribution for its full text.
#include <sched.h>
#include <sched.h>
#include <time.h>
#include <time.h>
#include <assert.h>
#include <assert.h>
#include <sys/syscall.h>
#ifdef HAVE_LIBHWLOC
#ifdef HAVE_LIBHWLOC
#include <hwloc/linux.h>
#include <hwloc/linux.h>
...
@@ -41,6 +42,7 @@ in the source distribution for its full text.
...
@@ -41,6 +42,7 @@ in the source distribution for its full text.
/*{
/*{
#include "Object.h"
#include "Object.h"
#include "Affinity.h"
#include "Affinity.h"
#include "IOPriority.h"
#include <sys/types.h>
#include <sys/types.h>
#ifndef Process_isKernelThread
#ifndef Process_isKernelThread
...
@@ -73,6 +75,7 @@ typedef enum ProcessField_ {
...
@@ -73,6 +75,7 @@ typedef enum ProcessField_ {
#ifdef HAVE_CGROUP
#ifdef HAVE_CGROUP
CGROUP,
CGROUP,
#endif
#endif
IO_PRIORITY,
LAST_PROCESSFIELD
LAST_PROCESSFIELD
} ProcessField;
} ProcessField;
...
@@ -111,6 +114,7 @@ typedef struct Process_ {
...
@@ -111,6 +114,7 @@ typedef struct Process_ {
long int priority;
long int priority;
long int nice;
long int nice;
long int nlwp;
long int nlwp;
IOPriority ioPriority;
char starttime_show[8];
char starttime_show[8];
time_t starttime_ctime;
time_t starttime_ctime;
#ifdef DEBUG
#ifdef DEBUG
...
@@ -199,6 +203,7 @@ const char *Process_fieldNames[] = {
...
@@ -199,6 +203,7 @@ const char *Process_fieldNames[] = {
#ifdef HAVE_CGROUP
#ifdef HAVE_CGROUP
"CGROUP"
,
"CGROUP"
,
#endif
#endif
"IO_PRIORITY"
,
"*** report bug! ***"
"*** report bug! ***"
};
};
...
@@ -224,6 +229,7 @@ const char *Process_fieldTitles[] = {
...
@@ -224,6 +229,7 @@ const char *Process_fieldTitles[] = {
#ifdef HAVE_CGROUP
#ifdef HAVE_CGROUP
" CGROUP "
,
" CGROUP "
,
#endif
#endif
"IO "
,
"*** report bug! ***"
"*** report bug! ***"
};
};
...
@@ -507,7 +513,24 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
...
@@ -507,7 +513,24 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
#ifdef HAVE_CGROUP
#ifdef HAVE_CGROUP
case
CGROUP
:
snprintf
(
buffer
,
n
,
"%-10s "
,
this
->
cgroup
);
break
;
case
CGROUP
:
snprintf
(
buffer
,
n
,
"%-10s "
,
this
->
cgroup
);
break
;
#endif
#endif
case
IO_PRIORITY
:
{
int
klass
=
IOPriority_class
(
this
->
ioPriority
);
if
(
klass
==
IOPRIO_CLASS_NONE
)
{
// see note [1] above
snprintf
(
buffer
,
n
,
"B%1d "
,
(
int
)
(
this
->
nice
+
20
)
/
5
);
}
else
if
(
klass
==
IOPRIO_CLASS_BE
)
{
snprintf
(
buffer
,
n
,
"B%1d "
,
IOPriority_data
(
this
->
ioPriority
));
}
else
if
(
klass
==
IOPRIO_CLASS_RT
)
{
attr
=
CRT_colors
[
PROCESS_HIGH_PRIORITY
];
snprintf
(
buffer
,
n
,
"R%1d "
,
IOPriority_data
(
this
->
ioPriority
));
}
else
if
(
this
->
ioPriority
==
IOPriority_Idle
)
{
attr
=
CRT_colors
[
PROCESS_LOW_PRIORITY
];
snprintf
(
buffer
,
n
,
"id "
);
}
else
{
snprintf
(
buffer
,
n
,
"?? "
);
}
break
;
}
default:
default:
snprintf
(
buffer
,
n
,
"- "
);
snprintf
(
buffer
,
n
,
"- "
);
}
}
...
@@ -572,6 +595,31 @@ bool Process_setPriority(Process* this, int priority) {
...
@@ -572,6 +595,31 @@ bool Process_setPriority(Process* this, int priority) {
return
(
err
==
0
);
return
(
err
==
0
);
}
}
bool
Process_changePriorityBy
(
Process
*
this
,
size_t
delta
)
{
return
Process_setPriority
(
this
,
this
->
nice
+
delta
);
}
IOPriority
Process_updateIOPriority
(
Process
*
this
)
{
IOPriority
ioprio
=
syscall
(
SYS_ioprio_get
,
IOPRIO_WHO_PROCESS
,
this
->
pid
);
this
->
ioPriority
=
ioprio
;
return
ioprio
;
}
bool
Process_setIOPriority
(
Process
*
this
,
IOPriority
ioprio
)
{
syscall
(
SYS_ioprio_set
,
IOPRIO_WHO_PROCESS
,
this
->
pid
,
ioprio
);
return
(
Process_updateIOPriority
(
this
)
==
ioprio
);
}
/*
[1] Note that before kernel 2.6.26 a process that has not asked for
an io priority formally uses "none" as scheduling class, but the
io scheduler will treat such processes as if it were in the best
effort class. The priority within the best effort class will be
dynamically derived from the cpu nice level of the process:
io_priority = (cpu_nice + 20) / 5. -- From ionice(1) man page
*/
#define Process_effectiveIOPriority(p_) (IOPriority_class(p_->ioPriority) == IOPRIO_CLASS_NONE ? IOPriority_tuple(IOPRIO_CLASS_BE, (p_->nice + 20) / 5) : p_->ioPriority)
#ifdef HAVE_LIBHWLOC
#ifdef HAVE_LIBHWLOC
Affinity
*
Process_getAffinity
(
Process
*
this
)
{
Affinity
*
Process_getAffinity
(
Process
*
this
)
{
...
@@ -631,8 +679,8 @@ bool Process_setAffinity(Process* this, Affinity* affinity) {
...
@@ -631,8 +679,8 @@ bool Process_setAffinity(Process* this, Affinity* affinity) {
#endif
#endif
void
Process_sendSignal
(
Process
*
this
,
in
t
sgn
)
{
void
Process_sendSignal
(
Process
*
this
,
size_
t
sgn
)
{
kill
(
this
->
pid
,
sgn
);
kill
(
this
->
pid
,
(
int
)
sgn
);
}
}
int
Process_pidCompare
(
const
void
*
v1
,
const
void
*
v2
)
{
int
Process_pidCompare
(
const
void
*
v1
,
const
void
*
v2
)
{
...
@@ -729,7 +777,8 @@ int Process_compare(const void* v1, const void* v2) {
...
@@ -729,7 +777,8 @@ int Process_compare(const void* v1, const void* v2) {
case
CGROUP
:
case
CGROUP
:
return
strcmp
(
p1
->
cgroup
?
p1
->
cgroup
:
""
,
p2
->
cgroup
?
p2
->
cgroup
:
""
);
return
strcmp
(
p1
->
cgroup
?
p1
->
cgroup
:
""
,
p2
->
cgroup
?
p2
->
cgroup
:
""
);
#endif
#endif
case
IO_PRIORITY
:
return
Process_effectiveIOPriority
(
p1
)
-
Process_effectiveIOPriority
(
p2
);
default:
default:
return
(
p1
->
pid
-
p2
->
pid
);
return
(
p1
->
pid
-
p2
->
pid
);
}
}
...
...
Process.h
View file @
47e881f4
...
@@ -21,6 +21,7 @@ in the source distribution for its full text.
...
@@ -21,6 +21,7 @@ in the source distribution for its full text.
#include "Object.h"
#include "Object.h"
#include "Affinity.h"
#include "Affinity.h"
#include "IOPriority.h"
#include <sys/types.h>
#include <sys/types.h>
#ifndef Process_isKernelThread
#ifndef Process_isKernelThread
...
@@ -53,6 +54,7 @@ typedef enum ProcessField_ {
...
@@ -53,6 +54,7 @@ typedef enum ProcessField_ {
#ifdef HAVE_CGROUP
#ifdef HAVE_CGROUP
CGROUP
,
CGROUP
,
#endif
#endif
IO_PRIORITY
,
LAST_PROCESSFIELD
LAST_PROCESSFIELD
}
ProcessField
;
}
ProcessField
;
...
@@ -91,6 +93,7 @@ typedef struct Process_ {
...
@@ -91,6 +93,7 @@ typedef struct Process_ {
long
int
priority
;
long
int
priority
;
long
int
nice
;
long
int
nice
;
long
int
nlwp
;
long
int
nlwp
;
IOPriority
ioPriority
;
char
starttime_show
[
8
];
char
starttime_show
[
8
];
time_t
starttime_ctime
;
time_t
starttime_ctime
;
#ifdef DEBUG
#ifdef DEBUG
...
@@ -175,6 +178,22 @@ void Process_toggleTag(Process* this);
...
@@ -175,6 +178,22 @@ void Process_toggleTag(Process* this);
bool
Process_setPriority
(
Process
*
this
,
int
priority
);
bool
Process_setPriority
(
Process
*
this
,
int
priority
);
bool
Process_changePriorityBy
(
Process
*
this
,
size_t
delta
);
IOPriority
Process_updateIOPriority
(
Process
*
this
);
bool
Process_setIOPriority
(
Process
*
this
,
IOPriority
ioprio
);
/*
[1] Note that before kernel 2.6.26 a process that has not asked for
an io priority formally uses "none" as scheduling class, but the
io scheduler will treat such processes as if it were in the best
effort class. The priority within the best effort class will be
dynamically derived from the cpu nice level of the process:
extern io_priority;
*/
#define Process_effectiveIOPriority(p_) (IOPriority_class(p_->ioPriority) == IOPRIO_CLASS_NONE ? IOPriority_tuple(IOPRIO_CLASS_BE, (p_->nice + 20) / 5) : p_->ioPriority)
#ifdef HAVE_LIBHWLOC
#ifdef HAVE_LIBHWLOC
Affinity
*
Process_getAffinity
(
Process
*
this
);
Affinity
*
Process_getAffinity
(
Process
*
this
);
...
@@ -189,7 +208,7 @@ bool Process_setAffinity(Process* this, Affinity* affinity);
...
@@ -189,7 +208,7 @@ bool Process_setAffinity(Process* this, Affinity* affinity);
#endif
#endif
void
Process_sendSignal
(
Process
*
this
,
in
t
sgn
);
void
Process_sendSignal
(
Process
*
this
,
size_
t
sgn
);
int
Process_pidCompare
(
const
void
*
v1
,
const
void
*
v2
);
int
Process_pidCompare
(
const
void
*
v1
,
const
void
*
v2
);
...
...
ProcessList.c
View file @
47e881f4
...
@@ -268,7 +268,7 @@ void ProcessList_printHeader(ProcessList* this, RichString* header) {
...
@@ -268,7 +268,7 @@ void ProcessList_printHeader(ProcessList* this, RichString* header) {
ProcessField
*
fields
=
this
->
fields
;
ProcessField
*
fields
=
this
->
fields
;
for
(
int
i
=
0
;
fields
[
i
];
i
++
)
{
for
(
int
i
=
0
;
fields
[
i
];
i
++
)
{
const
char
*
field
=
Process_fieldTitles
[
fields
[
i
]];
const
char
*
field
=
Process_fieldTitles
[
fields
[
i
]];
if
(
this
->
sortKey
==
fields
[
i
])
if
(
!
this
->
treeView
&&
this
->
sortKey
==
fields
[
i
])
RichString_append
(
header
,
CRT_colors
[
PANEL_HIGHLIGHT_FOCUS
],
field
);
RichString_append
(
header
,
CRT_colors
[
PANEL_HIGHLIGHT_FOCUS
],
field
);
else
else
RichString_append
(
header
,
CRT_colors
[
PANEL_HEADER_FOCUS
],
field
);
RichString_append
(
header
,
CRT_colors
[
PANEL_HEADER_FOCUS
],
field
);
...
@@ -681,6 +681,7 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P
...
@@ -681,6 +681,7 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P
unsigned
long
long
int
lasttimes
=
(
process
->
utime
+
process
->
stime
);
unsigned
long
long
int
lasttimes
=
(
process
->
utime
+
process
->
stime
);
if
(
!
ProcessList_readStatFile
(
process
,
dirname
,
name
,
command
))
if
(
!
ProcessList_readStatFile
(
process
,
dirname
,
name
,
command
))
goto
errorReadingProcess
;
goto
errorReadingProcess
;
Process_updateIOPriority
(
process
);
float
percent_cpu
=
(
process
->
utime
+
process
->
stime
-
lasttimes
)
/
period
*
100
.
0
;
float
percent_cpu
=
(
process
->
utime
+
process
->
stime
-
lasttimes
)
/
period
*
100
.
0
;
process
->
percent_cpu
=
MAX
(
MIN
(
percent_cpu
,
cpus
*
100
.
0
),
0
.
0
);
process
->
percent_cpu
=
MAX
(
MIN
(
percent_cpu
,
cpus
*
100
.
0
),
0
.
0
);
if
(
isnan
(
process
->
percent_cpu
))
process
->
percent_cpu
=
0
.
0
;
if
(
isnan
(
process
->
percent_cpu
))
process
->
percent_cpu
=
0
.
0
;
...
...
configure.ac
View file @
47e881f4
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.65)
AC_PREREQ(2.65)
AC_INIT([htop],[1.0.
1
],[loderunner@users.sourceforge.net])
AC_INIT([htop],[1.0.
2
],[loderunner@users.sourceforge.net])
# The following two lines are required by hwloc scripts
# The following two lines are required by hwloc scripts
AC_USE_SYSTEM_EXTENSIONS
AC_USE_SYSTEM_EXTENSIONS
...
...
htop.c
View file @
47e881f4
...
@@ -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 "TraceScreen.h"
#include "TraceScreen.h"
#include "OpenFilesScreen.h"
#include "OpenFilesScreen.h"
#include "AffinityPanel.h"
#include "AffinityPanel.h"
#include "IOPriorityPanel.h"
#include <unistd.h>
#include <unistd.h>
#include <math.h>
#include <math.h>
...
@@ -124,18 +125,18 @@ static void showHelp(ProcessList* pl) {
...
@@ -124,18 +125,18 @@ static void showHelp(ProcessList* pl) {
mvaddstr
(
12
,
0
,
" F4
\\
: incremental name filtering K: hide/show kernel threads"
);
mvaddstr
(
12
,
0
,
" F4
\\
: incremental name filtering K: hide/show kernel threads"
);
mvaddstr
(
13
,
0
,
" Space: tag processes F: cursor follows process"
);
mvaddstr
(
13
,
0
,
" Space: tag processes F: cursor follows process"
);
mvaddstr
(
14
,
0
,
" U: untag all processes + -: expand/collapse tree"
);
mvaddstr
(
14
,
0
,
" U: untag all processes + -: expand/collapse tree"
);
mvaddstr
(
15
,
0
,
" F9 k: kill process/tagged processes
P
: sort by CPU%"
);
mvaddstr
(
15
,
0
,
" F9 k: kill process/tagged processes
P M T
: sort by CPU%
, MEM% or TIME
"
);
mvaddstr
(
16
,
0
,
" ] F7: higher priority (root only)
M
: s
ort by MEM%
"
);
mvaddstr
(
16
,
0
,
" ] F7: higher priority (root only)
i
: s
et IO priority
"
);
mvaddstr
(
17
,
0
,
" [ F8: lower priority (+ nice)
T
:
sort by TIME
"
);
mvaddstr
(
17
,
0
,
" [ F8: lower priority (+ nice)
I
:
invert sort order
"
);
#if (HAVE_LIBHWLOC || HAVE_NATIVE_AFFINITY)
#if (HAVE_LIBHWLOC || HAVE_NATIVE_AFFINITY)
if
(
pl
->
cpuCount
>
1
)
if
(
pl
->
cpuCount
>
1
)
mvaddstr
(
18
,
0
,
" a: set CPU affinity
I: inver
t sort
order
"
);
mvaddstr
(
18
,
0
,
" a: set CPU affinity
F6 >: selec
t sort
column
"
);
else
else
#endif
#endif
mvaddstr
(
18
,
0
,
"
I: inver
t sort
order
"
);
mvaddstr
(
18
,
0
,
"
F6 >: selec
t sort
column
"
);
mvaddstr
(
19
,
0
,
" F2 S: setup
F6 >: select sort column
"
);
mvaddstr
(
19
,
0
,
" F2 S: setup
l: list open files with lsof
"
);
mvaddstr
(
20
,
0
,
" F1 h: show this help screen
l
:
list open file
s with
lsof
"
);
mvaddstr
(
20
,
0
,
" F1 h: show this help screen
s
:
trace syscall
s with
strace
"
);
mvaddstr
(
21
,
0
,
" F10 q: quit
s: trace syscalls with strace
"
);
mvaddstr
(
21
,
0
,
" F10 q: quit"
);
attrset
(
CRT_colors
[
HELP_BOLD
]);
attrset
(
CRT_colors
[
HELP_BOLD
]);
mvaddstr
(
9
,
0
,
" Arrows"
);
mvaddstr
(
9
,
40
,
" F5 t"
);
mvaddstr
(
9
,
0
,
" Arrows"
);
mvaddstr
(
9
,
40
,
" F5 t"
);
...
@@ -144,17 +145,17 @@ static void showHelp(ProcessList* pl) {
...
@@ -144,17 +145,17 @@ static void showHelp(ProcessList* pl) {
mvaddstr
(
12
,
0
,
" F4
\\
"
);
mvaddstr
(
12
,
40
,
" K"
);
mvaddstr
(
12
,
0
,
" F4
\\
"
);
mvaddstr
(
12
,
40
,
" K"
);
mvaddstr
(
13
,
0
,
" Space"
);
mvaddstr
(
13
,
40
,
" F"
);
mvaddstr
(
13
,
0
,
" Space"
);
mvaddstr
(
13
,
40
,
" F"
);
mvaddstr
(
14
,
0
,
" U"
);
mvaddstr
(
14
,
40
,
" + -"
);
mvaddstr
(
14
,
0
,
" U"
);
mvaddstr
(
14
,
40
,
" + -"
);
mvaddstr
(
15
,
0
,
" F9 k"
);
mvaddstr
(
15
,
40
,
"
P
"
);
mvaddstr
(
15
,
0
,
" F9 k"
);
mvaddstr
(
15
,
40
,
"
P M T
"
);
mvaddstr
(
16
,
0
,
" ] F7"
);
mvaddstr
(
16
,
40
,
"
M
"
);
mvaddstr
(
16
,
0
,
" ] F7"
);
mvaddstr
(
16
,
40
,
"
i
"
);
mvaddstr
(
17
,
0
,
" [ F8"
);
mvaddstr
(
17
,
40
,
"
T
"
);
mvaddstr
(
17
,
0
,
" [ F8"
);
mvaddstr
(
17
,
40
,
"
I
"
);
mvaddstr
(
18
,
40
,
"
I
"
);
mvaddstr
(
18
,
40
,
"
F6 >
"
);
#if (HAVE_LIBHWLOC || HAVE_NATIVE_AFFINITY)
#if (HAVE_LIBHWLOC || HAVE_NATIVE_AFFINITY)
if
(
pl
->
cpuCount
>
1
)
if
(
pl
->
cpuCount
>
1
)
mvaddstr
(
18
,
0
,
" a:"
);
mvaddstr
(
18
,
0
,
" a:"
);
#endif
#endif
mvaddstr
(
19
,
0
,
" F2 S"
);
mvaddstr
(
19
,
40
,
"
F6 >
"
);
mvaddstr
(
19
,
0
,
" F2 S"
);
mvaddstr
(
19
,
40
,
"
l
"
);
mvaddstr
(
20
,
0
,
" ? F1 h"
);
mvaddstr
(
20
,
40
,
"
l
"
);
mvaddstr
(
20
,
0
,
" ? F1 h"
);
mvaddstr
(
20
,
40
,
"
s
"
);
mvaddstr
(
21
,
0
,
" F10 q"
);
mvaddstr
(
21
,
40
,
" s"
);
mvaddstr
(
21
,
0
,
" F10 q"
);
attrset
(
CRT_colors
[
DEFAULT_COLOR
]);
attrset
(
CRT_colors
[
DEFAULT_COLOR
]);
attrset
(
CRT_colors
[
HELP_BOLD
]);
attrset
(
CRT_colors
[
HELP_BOLD
]);
...
@@ -178,20 +179,30 @@ static void Setup_run(Settings* settings, const Header* header) {
...
@@ -178,20 +179,30 @@ static void Setup_run(Settings* settings, const Header* header) {
ScreenManager_delete
(
scr
);
ScreenManager_delete
(
scr
);
}
}
static
bool
changePriority
(
Panel
*
panel
,
int
delta
)
{
typedef
bool
(
*
ForeachProcessFn
)(
Process
*
,
size_t
);
static
bool
foreachProcess
(
Panel
*
panel
,
ForeachProcessFn
fn
,
int
arg
,
bool
*
wasAnyTagged
)
{
bool
ok
=
true
;
bool
ok
=
true
;
bool
anyTagged
=
false
;
bool
anyTagged
=
false
;
for
(
int
i
=
0
;
i
<
Panel_size
(
panel
);
i
++
)
{
for
(
int
i
=
0
;
i
<
Panel_size
(
panel
);
i
++
)
{
Process
*
p
=
(
Process
*
)
Panel_get
(
panel
,
i
);
Process
*
p
=
(
Process
*
)
Panel_get
(
panel
,
i
);
if
(
p
->
tag
)
{
if
(
p
->
tag
)
{
ok
=
Process_setPriority
(
p
,
p
->
nice
+
delta
)
&&
ok
;
ok
=
fn
(
p
,
arg
)
&&
ok
;
anyTagged
=
true
;
anyTagged
=
true
;
}
}
}
}
if
(
!
anyTagged
)
{
if
(
!
anyTagged
)
{
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
panel
);
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
panel
);
if
(
p
)
ok
=
Process_setPriority
(
p
,
p
->
nice
+
delta
)
&&
ok
;
if
(
p
)
ok
=
fn
(
p
,
arg
)
&&
ok
;
}
}
if
(
wasAnyTagged
)
*
wasAnyTagged
=
anyTagged
;
return
ok
;
}
static
bool
changePriority
(
Panel
*
panel
,
int
delta
)
{
bool
anyTagged
;
bool
ok
=
foreachProcess
(
panel
,
(
ForeachProcessFn
)
Process_changePriorityBy
,
delta
,
&
anyTagged
);
if
(
!
ok
)
if
(
!
ok
)
beep
();
beep
();
return
anyTagged
;
return
anyTagged
;
...
@@ -764,20 +775,6 @@ int main(int argc, char** argv) {
...
@@ -764,20 +775,6 @@ int main(int argc, char** argv) {
if
(
!
killPanel
)
{
if
(
!
killPanel
)
{
killPanel
=
(
Panel
*
)
SignalsPanel_new
(
0
,
0
,
0
,
0
);
killPanel
=
(
Panel
*
)
SignalsPanel_new
(
0
,
0
,
0
,
0
);
}
}
bool
anyTagged
=
false
;
pid_t
selectedPid
=
0
;
for
(
int
i
=
0
;
i
<
Panel_size
(
panel
);
i
++
)
{
Process
*
p
=
(
Process
*
)
Panel_get
(
panel
,
i
);
if
(
p
->
tag
)
{
anyTagged
=
true
;
break
;
}
}
if
(
!
anyTagged
)
{
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
panel
);
if
(
p
)
selectedPid
=
p
->
pid
;
if
(
selectedPid
==
0
)
break
;
}
SignalsPanel_reset
((
SignalsPanel
*
)
killPanel
);
SignalsPanel_reset
((
SignalsPanel
*
)
killPanel
);
const
char
*
fuFunctions
[]
=
{
"Send "
,
"Cancel "
,
NULL
};
const
char
*
fuFunctions
[]
=
{
"Send "
,
"Cancel "
,
NULL
};
ListItem
*
sgn
=
(
ListItem
*
)
pickFromVector
(
panel
,
killPanel
,
15
,
headerHeight
,
fuFunctions
,
defaultBar
,
header
);
ListItem
*
sgn
=
(
ListItem
*
)
pickFromVector
(
panel
,
killPanel
,
15
,
headerHeight
,
fuFunctions
,
defaultBar
,
header
);
...
@@ -786,18 +783,7 @@ int main(int argc, char** argv) {
...
@@ -786,18 +783,7 @@ int main(int argc, char** argv) {
Panel_setHeader
(
panel
,
"Sending..."
);
Panel_setHeader
(
panel
,
"Sending..."
);
Panel_draw
(
panel
,
true
);
Panel_draw
(
panel
,
true
);
refresh
();
refresh
();
if
(
anyTagged
)
{
foreachProcess
(
panel
,
(
ForeachProcessFn
)
Process_sendSignal
,
(
size_t
)
sgn
->
key
,
NULL
);
for
(
int
i
=
0
;
i
<
Panel_size
(
panel
);
i
++
)
{
Process
*
p
=
(
Process
*
)
Panel_get
(
panel
,
i
);
if
(
p
->
tag
)
{
Process_sendSignal
(
p
,
sgn
->
key
);
}
}
}
else
{
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
panel
);
if
(
p
->
pid
==
selectedPid
)
Process_sendSignal
(
p
,
sgn
->
key
);
}
napms
(
500
);
napms
(
500
);
}
}
}
}
...
@@ -822,21 +808,8 @@ int main(int argc, char** argv) {
...
@@ -822,21 +808,8 @@ int main(int argc, char** argv) {
void
*
set
=
pickFromVector
(
panel
,
affinityPanel
,
15
,
headerHeight
,
fuFunctions
,
defaultBar
,
header
);
void
*
set
=
pickFromVector
(
panel
,
affinityPanel
,
15
,
headerHeight
,
fuFunctions
,
defaultBar
,
header
);
if
(
set
)
{
if
(
set
)
{
Affinity
*
affinity
=
AffinityPanel_getAffinity
(
affinityPanel
);
Affinity
*
affinity
=
AffinityPanel_getAffinity
(
affinityPanel
);
bool
anyTagged
=
false
;
bool
ok
=
foreachProcess
(
panel
,
(
ForeachProcessFn
)
Process_setAffinity
,
(
size_t
)
affinity
,
NULL
);
bool
ok
=
true
;
if
(
!
ok
)
beep
();
for
(
int
i
=
0
;
i
<
Panel_size
(
panel
);
i
++
)
{
Process
*
p
=
(
Process
*
)
Panel_get
(
panel
,
i
);
if
(
p
->
tag
)
{
ok
=
Process_setAffinity
(
p
,
affinity
)
&&
ok
;
anyTagged
=
true
;
}
}
if
(
!
anyTagged
)
{
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
panel
);
if
(
p
)
ok
=
Process_setAffinity
(
p
,
affinity
)
&&
ok
;
}
if
(
!
ok
)
beep
();
Affinity_delete
(
affinity
);
Affinity_delete
(
affinity
);
}
}
Panel_delete
((
Object
*
)
affinityPanel
);
Panel_delete
((
Object
*
)
affinityPanel
);
...
@@ -878,6 +851,25 @@ int main(int argc, char** argv) {
...
@@ -878,6 +851,25 @@ int main(int argc, char** argv) {
refreshTimeout
=
0
;
refreshTimeout
=
0
;
break
;
break
;
}
}
case
'i'
:
{
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
panel
);
if
(
!
p
)
break
;
IOPriority
ioprio
=
p
->
ioPriority
;
Panel
*
ioprioPanel
=
IOPriorityPanel_new
(
ioprio
);
const
char
*
fuFunctions
[]
=
{
"Set "
,
"Cancel "
,
NULL
};
void
*
set
=
pickFromVector
(
panel
,
ioprioPanel
,
21
,
headerHeight
,
fuFunctions
,
defaultBar
,
header
);
if
(
set
)
{
IOPriority
ioprio
=
IOPriorityPanel_getIOPriority
(
ioprioPanel
);
bool
ok
=
foreachProcess
(
panel
,
(
ForeachProcessFn
)
Process_setIOPriority
,
(
size_t
)
ioprio
,
NULL
);
if
(
!
ok
)
beep
();
}
Panel_delete
((
Object
*
)
ioprioPanel
);
ProcessList_printHeader
(
pl
,
Panel_getHeader
(
panel
));
refreshTimeout
=
0
;
break
;
}
case
'I'
:
case
'I'
:
{
{
refreshTimeout
=
0
;
refreshTimeout
=
0
;
...
@@ -914,6 +906,8 @@ int main(int argc, char** argv) {
...
@@ -914,6 +906,8 @@ int main(int argc, char** argv) {
case
KEY_F
(
5
):
case
KEY_F
(
5
):
refreshTimeout
=
0
;
refreshTimeout
=
0
;
pl
->
treeView
=
!
pl
->
treeView
;
pl
->
treeView
=
!
pl
->
treeView
;
if
(
pl
->
treeView
)
pl
->
direction
=
1
;
ProcessList_printHeader
(
pl
,
Panel_getHeader
(
panel
));
ProcessList_expandTree
(
pl
);
ProcessList_expandTree
(
pl
);
settings
->
changed
=
true
;
settings
->
changed
=
true
;
if
(
following
!=
-
1
)
continue
;
if
(
following
!=
-
1
)
continue
;
...
...
htop.h
View file @
47e881f4
...
@@ -15,6 +15,8 @@ in the source distribution for its full text.
...
@@ -15,6 +15,8 @@ in the source distribution for its full text.
#define COPYRIGHT "(C) 2004-2011 Hisham Muhammad"
#define COPYRIGHT "(C) 2004-2011 Hisham Muhammad"
typedef
bool
(
*
ForeachProcessFn
)(
Process
*
,
size_t
);
typedef
struct
IncBuffer_
;
typedef
struct
IncBuffer_
;
int
main
(
int
argc
,
char
**
argv
);
int
main
(
int
argc
,
char
**
argv
);
...
...
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