From da494896914a327476ab7e0298619d742a6205d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Tue, 10 Jan 2023 19:40:04 +0100 Subject: Add support for scheduling policies Add a process column for scheduling policy to show the current scheduling policy of the process. Add a the ability to change the scheduling policy of a process via the key 'Y'. Currently implemented on Linux and FreeBSD only but should be portable, since sched_getscheduler(2) is part of POSIX.1-2001. Closes: #1161 --- Action.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'Action.c') diff --git a/Action.c b/Action.c index 81432f5d..5d33f662 100644 --- a/Action.c +++ b/Action.c @@ -29,6 +29,7 @@ in the source distribution for its full text. #include "Process.h" #include "ProcessLocksScreen.h" #include "ProvideCurses.h" +#include "Scheduling.h" #include "ScreenManager.h" #include "SignalsPanel.h" #include "TraceScreen.h" @@ -407,6 +408,51 @@ static Htop_Reaction actionSetAffinity(State* st) { } +#ifdef SCHEDULER_SUPPORT +static Htop_Reaction actionSetSchedPolicy(State* st) { + if (Settings_isReadonly()) + return HTOP_KEEP_FOLLOWING; + + static int preSelectedPolicy = SCHEDULINGPANEL_INITSELECTEDPOLICY; + static int preSelectedPriority = SCHEDULINGPANEL_INITSELECTEDPRIORITY; + + Panel* schedPanel = Scheduling_newPolicyPanel(preSelectedPolicy); + + const ListItem* policy; + for(;;) { + policy = (const ListItem*) Action_pickFromVector(st, schedPanel, 18, true); + + if (!policy || policy->key != -1) + break; + + Scheduling_togglePolicyPanelResetOnFork(schedPanel); + } + + if (policy) { + preSelectedPolicy = policy->key; + + Panel* prioPanel = Scheduling_newPriorityPanel(policy->key, preSelectedPriority); + if (prioPanel) { + const ListItem* prio = (const ListItem*) Action_pickFromVector(st, prioPanel, 14, true); + if (prio) + preSelectedPriority = prio->key; + + Panel_delete((Object*) prioPanel); + } + + SchedulingArg v = { .policy = preSelectedPolicy, .priority = preSelectedPriority }; + + bool ok = MainPanel_foreachProcess(st->mainPanel, Scheduling_setPolicy, (Arg) { .v = &v }, NULL); + if (!ok) + beep(); + } + + Panel_delete((Object*)schedPanel); + + return HTOP_REFRESH | HTOP_REDRAW_BAR | HTOP_KEEP_FOLLOWING; +} +#endif /* SCHEDULER_SUPPORT */ + static Htop_Reaction actionKill(State* st) { if (Settings_isReadonly()) return HTOP_OK; @@ -571,6 +617,9 @@ static const struct { { .key = " x: ", .roInactive = false, .info = "list file locks of process" }, { .key = " s: ", .roInactive = true, .info = "trace syscalls with strace" }, { .key = " w: ", .roInactive = false, .info = "wrap process command in multiple lines" }, +#ifdef SCHEDULER_SUPPORT + { .key = " Y: ", .roInactive = true, .info = "set scheduling policy" }, +#endif { .key = " F2 C S: ", .roInactive = false, .info = "setup" }, { .key = " F1 h ?: ", .roInactive = false, .info = "show this help screen" }, { .key = " F10 q: ", .roInactive = false, .info = "quit" }, @@ -779,6 +828,9 @@ void Action_setBindings(Htop_Action* keys) { keys['S'] = actionSetup; keys['T'] = actionSortByTime; keys['U'] = actionUntagAll; +#ifdef SCHEDULER_SUPPORT + keys['Y'] = actionSetSchedPolicy; +#endif keys['Z'] = actionTogglePauseProcessUpdate; keys['['] = actionLowerPriority; keys['\014'] = actionRedraw; // Ctrl+L -- cgit v1.2.3