summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2012-10-04 23:59:45 +0000
committerHisham Muhammad <hisham@gobolinux.org>2012-10-04 23:59:45 +0000
commit47e881f460cfb441be64a1ff17295357fb02d0ad (patch)
treea0e48ec820c059d71be2abb0573393ef76052ea7
parente6c6d7fbf7c463c7e8c877b60059c47f1841e9c0 (diff)
Add IO priority support ('i' key)
-rw-r--r--AffinityPanel.c2
-rw-r--r--CRT.c2
-rw-r--r--ChangeLog1
-rw-r--r--IOPriority.c41
-rw-r--r--IOPriority.h43
-rw-r--r--IOPriorityPanel.c43
-rw-r--r--IOPriorityPanel.h20
-rw-r--r--Makefile.am8
-rw-r--r--Process.c57
-rw-r--r--Process.h21
-rw-r--r--ProcessList.c3
-rw-r--r--configure.ac2
-rw-r--r--htop.c112
-rw-r--r--htop.h2
14 files changed, 285 insertions, 72 deletions
diff --git a/AffinityPanel.c b/AffinityPanel.c
index 729eec42..8c406fb3 100644
--- a/AffinityPanel.c
+++ b/AffinityPanel.c
@@ -50,7 +50,7 @@ Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity) {
} else {
mode = false;
}
- Panel_add(this, (Object*) CheckItem_new(strdup(number), NULL, mode));
+ Panel_add(this, (Object*) CheckItem_new(strdup(number), NULL, mode));
}
return this;
}
diff --git a/CRT.c b/CRT.c
index 880f4dd1..97f2144e 100644
--- a/CRT.c
+++ b/CRT.c
@@ -129,7 +129,7 @@ static void CRT_handleSIGSEGV(int sgn) {
fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at http://htop.sf.net\n");
#ifdef HAVE_EXECINFO_H
size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *));
- fprintf(stderr, "Backtrace: \n");
+ fprintf(stderr, "\n Please include in your report the following backtrace: \n");
backtrace_symbols_fd(backtraceArray, size, 2);
fprintf(stderr, "\nAdditionally, in order to make the above backtrace useful,");
fprintf(stderr, "\nplease also run the following command to generate a disassembly of your binary:");
diff --git a/ChangeLog b/ChangeLog
index 5185f7ad..45b4edbb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
What's new in version 1.0.2
+* Add IO priority support ('i' key)
* Avoid deleting .htoprc if it is a symlink
* BUGFIX: Fix crashes when process list is empty
diff --git a/IOPriority.c b/IOPriority.c
new file mode 100644
index 00000000..7b197436
--- /dev/null
+++ b/IOPriority.c
@@ -0,0 +1,41 @@
+/*
+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)
+
+}*/
+
diff --git a/IOPriority.h b/IOPriority.h
new file mode 100644
index 00000000..d69e30d5
--- /dev/null
+++ b/IOPriority.h
@@ -0,0 +1,43 @@
+/* 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
diff --git a/IOPriorityPanel.c b/IOPriorityPanel.c
new file mode 100644
index 00000000..bc80b7dc
--- /dev/null
+++ b/IOPriorityPanel.c
@@ -0,0 +1,43 @@
+/*
+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 );
+}
diff --git a/IOPriorityPanel.h b/IOPriorityPanel.h
new file mode 100644
index 00000000..f87af4e4
--- /dev/null
+++ b/IOPriorityPanel.h
@@ -0,0 +1,20 @@
+/* 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
diff --git a/Makefile.am b/Makefile.am
index a1ff7d65..05a72e7e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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 \
LoadAverageMeter.c MemoryMeter.c Meter.c MetersPanel.c Object.c Panel.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 \
-HostnameMeter.c OpenFilesScreen.c Affinity.c
+HostnameMeter.c OpenFilesScreen.c Affinity.c IOPriority.c
myhtopheaders = AvailableColumnsPanel.h AvailableMetersPanel.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 \
BatteryMeter.h Meter.h MetersPanel.h Object.h Panel.h ProcessList.h RichString.h \
ScreenManager.h Settings.h SignalsPanel.h String.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
diff --git a/Process.c b/Process.c
index 68edd70e..9cc5c001 100644
--- a/Process.c
+++ b/Process.c
@@ -26,6 +26,7 @@ in the source distribution for its full text.
#include <sched.h>
#include <time.h>
#include <assert.h>
+#include <sys/syscall.h>
#ifdef HAVE_LIBHWLOC
#include <hwloc/linux.h>
@@ -41,6 +42,7 @@ in the source distribution for its full text.
/*{
#include "Object.h"
#include "Affinity.h"
+#include "IOPriority.h"
#include <sys/types.h>
#ifndef Process_isKernelThread
@@ -73,6 +75,7 @@ typedef enum ProcessField_ {
#ifdef HAVE_CGROUP
CGROUP,
#endif
+ IO_PRIORITY,
LAST_PROCESSFIELD
} ProcessField;
@@ -111,6 +114,7 @@ typedef struct Process_ {
long int priority;
long int nice;
long int nlwp;
+ IOPriority ioPriority;
char starttime_show[8];
time_t starttime_ctime;
#ifdef DEBUG
@@ -199,6 +203,7 @@ const char *Process_fieldNames[] = {
#ifdef HAVE_CGROUP
"CGROUP",
#endif
+ "IO_PRIORITY",
"*** report bug! ***"
};
@@ -224,6 +229,7 @@ const char *Process_fieldTitles[] = {
#ifdef HAVE_CGROUP
" CGROUP ",
#endif
+ "IO ",
"*** report bug! ***"
};
@@ -507,7 +513,24 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
#ifdef HAVE_CGROUP
case CGROUP: snprintf(buffer, n, "%-10s ", this->cgroup); break;
#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:
snprintf(buffer, n, "- ");
}
@@ -572,6 +595,31 @@ bool Process_setPriority(Process* this, int priority) {
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
Affinity* Process_getAffinity(Process* this) {
@@ -631,8 +679,8 @@ bool Process_setAffinity(Process* this, Affinity* affinity) {
#endif
-void Process_sendSignal(Process* this, int sgn) {
- kill(this->pid, sgn);
+void Process_sendSignal(Process* this, size_t sgn) {
+ kill(this->pid, (int) sgn);
}
int Process_pidCompare(const void* v1, const void* v2) {
@@ -729,7 +777,8 @@ int Process_compare(const void* v1, const void* v2) {
case CGROUP:
return strcmp(p1->cgroup ? p1->cgroup : "", p2->cgroup ? p2->cgroup : "");
#endif
-
+ case IO_PRIORITY:
+ return Process_effectiveIOPriority(p1) - Process_effectiveIOPriority(p2);
default:
return (p1->pid - p2->pid);
}
diff --git a/Process.h b/Process.h
index 2c3e0c33..c5f59346 100644
--- a/Process.h
+++ b/Process.h
@@ -21,6 +21,7 @@ in the source distribution for its full text.
#include "Object.h"
#include "Affinity.h"
+#include "IOPriority.h"
#include <sys/types.h>
#ifndef Process_isKernelThread
@@ -53,6 +54,7 @@ typedef enum ProcessField_ {
#ifdef HAVE_CGROUP
CGROUP,
#endif
+ IO_PRIORITY,
LAST_PROCESSFIELD
} ProcessField;
@@ -91,6 +93,7 @@ typedef struct Process_ {
long int priority;
long int nice;
long int nlwp;
+ IOPriority ioPriority;
char starttime_show[8];
time_t starttime_ctime;
#ifdef DEBUG
@@ -175,6 +178,22 @@ void Process_toggleTag(Process* this);
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
Affinity* Process_getAffinity(Process* this);
@@ -189,7 +208,7 @@ bool Process_setAffinity(Process* this, Affinity* affinity);
#endif
-void Process_sendSignal(Process* this, int sgn);
+void Process_sendSignal(Process* this, size_t sgn);
int Process_pidCompare(const void* v1, const void* v2);
diff --git a/ProcessList.c b/ProcessList.c
index 14a8b29c..268793f2 100644
--- a/ProcessList.c
+++ b/ProcessList.c
@@ -268,7 +268,7 @@ void ProcessList_printHeader(ProcessList* this, RichString* header) {
ProcessField* fields = this->fields;
for (int i = 0; fields[i]; 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);
else
RichString_append(header, CRT_colors[PANEL_HEADER_FOCUS], field);
@@ -681,6 +681,7 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P
unsigned long long int lasttimes = (process->utime + process->stime);
if (! ProcessList_readStatFile(process, dirname, name, command))
goto errorReadingProcess;
+ Process_updateIOPriority(process);
float percent_cpu = (process->utime + process->stime - lasttimes) / period * 100.0;
process->percent_cpu = MAX(MIN(percent_cpu, cpus*100.0), 0.0);
if (isnan(process->percent_cpu)) process->percent_cpu = 0.0;
diff --git a/configure.ac b/configure.ac
index 639d048d..ff6901b1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
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
AC_USE_SYSTEM_EXTENSIONS
diff --git a/htop.c b/htop.c
index c8f42e11..44aa8579 100644
--- a/htop.c
+++ b/htop.c
@@ -22,6 +22,7 @@ in the source distribution for its full text.
#include "TraceScreen.h"
#include "OpenFilesScreen.h"
#include "AffinityPanel.h"
+#include "IOPriorityPanel.h"
#include <unistd.h>
#include <math.h>
@@ -124,18 +125,18 @@ static void showHelp(ProcessList* pl) {
mvaddstr(12, 0, " F4 \\: incremental name filtering K: hide/show kernel threads");
mvaddstr(13, 0, " Space: tag processes F: cursor follows process");
mvaddstr(14, 0, " U: untag all processes + -: expand/collapse tree");
- mvaddstr(15, 0, " F9 k: kill process/tagged processes P: sort by CPU%");
- mvaddstr(16, 0, " ] F7: higher priority (root only) M: sort by MEM%");
- mvaddstr(17, 0, " [ F8: lower priority (+ nice) T: sort by TIME");
+ 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) i: set IO priority");
+ mvaddstr(17, 0, " [ F8: lower priority (+ nice) I: invert sort order");
#if (HAVE_LIBHWLOC || HAVE_NATIVE_AFFINITY)
if (pl->cpuCount > 1)
- mvaddstr(18, 0, " a: set CPU affinity I: invert sort order");
+ mvaddstr(18, 0, " a: set CPU affinity F6 >: select sort column");
else
#endif
- mvaddstr(18, 0, " I: invert sort order");
- mvaddstr(19, 0, " F2 S: setup F6 >: select sort column");
- mvaddstr(20, 0, " F1 h: show this help screen l: list open files with lsof");
- mvaddstr(21, 0, " F10 q: quit s: trace syscalls with strace");
+ mvaddstr(18, 0, " 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 s: trace syscalls with strace");
+ mvaddstr(21, 0, " F10 q: quit");
attrset(CRT_colors[HELP_BOLD]);
mvaddstr( 9, 0, " Arrows"); mvaddstr( 9,40, " F5 t");
@@ -144,17 +145,17 @@ static void showHelp(ProcessList* pl) {
mvaddstr(12, 0, " F4 \\"); mvaddstr(12,40, " K");
mvaddstr(13, 0, " Space"); mvaddstr(13,40, " F");
mvaddstr(14, 0, " U"); mvaddstr(14,40, " + -");
- mvaddstr(15, 0, " F9 k"); mvaddstr(15,40, " P");
- mvaddstr(16, 0, " ] F7"); mvaddstr(16,40, " M");
- mvaddstr(17, 0, " [ F8"); mvaddstr(17,40, " T");
- mvaddstr(18,40, " I");
+ mvaddstr(15, 0, " F9 k"); mvaddstr(15,40, "P M T");
+ mvaddstr(16, 0, " ] F7"); mvaddstr(16,40, " i");
+ mvaddstr(17, 0, " [ F8"); mvaddstr(17,40, " I");
+ mvaddstr(18,40, " F6 >");
#if (HAVE_LIBHWLOC || HAVE_NATIVE_AFFINITY)
if (pl->cpuCount > 1)
mvaddstr(18, 0, " a:");
#endif
- mvaddstr(19, 0, " F2 S"); mvaddstr(19,40, " F6 >");
- mvaddstr(20, 0, " ? F1 h"); mvaddstr(20,40, " l");
- mvaddstr(21, 0, " F10 q"); mvaddstr(21,40, " s");
+ mvaddstr(19, 0, " F2 S"); mvaddstr(19,40, " l");
+ mvaddstr(20, 0, " ? F1 h"); mvaddstr(20,40, " s");
+ mvaddstr(21, 0, " F10 q");
attrset(CRT_colors[DEFAULT_COLOR]);
attrset(CRT_colors[HELP_BOLD]);
@@ -178,20 +179,30 @@ static void Setup_run(Settings* settings, const Header* header) {
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 anyTagged = false;
for (int i = 0; i < Panel_size(panel); i++) {
Process* p = (Process*) Panel_get(panel, i);
if (p->tag) {
- ok = Process_setPriority(p, p->nice + delta) && ok;
+ ok = fn(p, arg) && ok;
anyTagged = true;
}
}
if (!anyTagged) {
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)
beep();
return anyTagged;
@@ -764,20 +775,6 @@ int main(int argc, char** argv) {
if (!killPanel) {
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);
const char* fuFunctions[] = {"Send ", "Cancel ", NULL};
ListItem* sgn = (ListItem*) pickFromVector(panel, killPanel, 15, headerHeight, fuFunctions, defaultBar, header);
@@ -786,18 +783,7 @@ int main(int argc, char** argv) {
Panel_setHeader(panel, "Sending...");
Panel_draw(panel, true);
refresh();
- if (anyTagged) {
- 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);
- }
+ foreachProcess(panel, (ForeachProcessFn) Process_sendSignal, (size_t) sgn->key, NULL);
napms(500);
}
}
@@ -822,21 +808,8 @@ int main(int argc, char** argv) {
void* set = pickFromVector(panel, affinityPanel, 15, headerHeight, fuFunctions, defaultBar, header);
if (set) {
Affinity* affinity = AffinityPanel_getAffinity(affinityPanel);
- bool anyTagged = false;
- bool ok = true;
- 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();
+ bool ok = foreachProcess(panel, (ForeachProcessFn) Process_setAffinity, (size_t) affinity, NULL);
+ if (!ok) beep();
Affinity_delete(affinity);
}
Panel_delete((Object*)affinityPanel);
@@ -878,6 +851,25 @@ int main(int argc, char** argv) {
refreshTimeout = 0;
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':
{
refreshTimeout = 0;
@@ -914,6 +906,8 @@ int main(int argc, char** argv) {
case KEY_F(5):
refreshTimeout = 0;
pl->treeView = !pl->treeView;
+ if (pl->treeView) pl->direction = 1;
+ ProcessList_printHeader(pl, Panel_getHeader(panel));
ProcessList_expandTree(pl);
settings->changed = true;
if (following != -1) continue;
diff --git a/htop.h b/htop.h
index 227f36d3..8d8ed7ed 100644
--- a/htop.h
+++ b/htop.h
@@ -15,6 +15,8 @@ in the source distribution for its full text.
#define COPYRIGHT "(C) 2004-2011 Hisham Muhammad"
+typedef bool(*ForeachProcessFn)(Process*, size_t);
+
typedef struct IncBuffer_;
int main(int argc, char** argv);

© 2014-2024 Faster IT GmbH | imprint | privacy policy