-
-
Notifications
You must be signed in to change notification settings - Fork 404
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
Showing
11 changed files
with
297 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
/* | ||
htop - Scheduling.c | ||
(C) 2023 htop dev team | ||
Released under the GNU GPLv2+, see the COPYING file | ||
in the source distribution for its full text. | ||
*/ | ||
|
||
#include "Scheduling.h" | ||
#include "EnvScreen.h" | ||
|
||
#ifdef SCHEDULER_SUPPORT | ||
|
||
#include <errno.h> | ||
|
||
#include "FunctionBar.h" | ||
#include "ListItem.h" | ||
#include "Macros.h" | ||
#include "Object.h" | ||
#include "Panel.h" | ||
#include "XUtils.h" | ||
|
||
|
||
static const SchedulingPolicy policies[] = { | ||
[SCHED_OTHER] = { "Other", SCHED_OTHER, false }, | ||
#ifdef SCHED_BATCH | ||
[SCHED_BATCH] = { "Batch", SCHED_BATCH, false }, | ||
#endif | ||
#ifdef SCHED_IDLE | ||
[SCHED_IDLE] = { "Idle", SCHED_IDLE, false }, | ||
#endif | ||
[SCHED_FIFO] = { "FiFo", SCHED_FIFO, true }, | ||
[SCHED_RR] = { "RoundRobin", SCHED_RR, true }, | ||
}; | ||
|
||
#ifdef SCHED_RESET_ON_FORK | ||
static bool reset_on_fork = false; | ||
#endif | ||
|
||
|
||
Panel* Scheduling_newPolicyPanel(int preSelectedPolicy) { | ||
Panel* this = Panel_new(0, 0, 0, 0, Class(ListItem), true, FunctionBar_newEnterEsc("Select ", "Cancel ")); | ||
Panel_setHeader(this, "New policy:"); | ||
|
||
#ifdef SCHED_RESET_ON_FORK | ||
Panel_add(this, (Object*) ListItem_new(reset_on_fork ? "Reset on fork: on" : "Reset on fork: off", -1)); | ||
#endif | ||
|
||
for (unsigned i = 0; i < ARRAYSIZE(policies); i++) { | ||
if (!policies[i].name) | ||
continue; | ||
|
||
Panel_add(this, (Object*) ListItem_new(policies[i].name, policies[i].id)); | ||
if (policies[i].id == preSelectedPolicy) | ||
Panel_setSelected(this, i); | ||
} | ||
|
||
return this; | ||
} | ||
|
||
void Scheduling_togglePolicyPanelResetOnFork(Panel* schedPanel) { | ||
#ifdef SCHED_RESET_ON_FORK | ||
reset_on_fork = !reset_on_fork; | ||
|
||
ListItem* item = (ListItem*) Panel_get(schedPanel, 0); | ||
|
||
free_and_xStrdup(&item->value, reset_on_fork ? "Reset on fork: on" : "Reset on fork: off"); | ||
#else | ||
(void)schedPanel; | ||
#endif | ||
} | ||
|
||
Panel* Scheduling_newPriorityPanel(int policy, int preSelectedPriority) { | ||
if (policy < 0 || (unsigned)policy >= ARRAYSIZE(policies) || policies[policy].name == NULL) | ||
return NULL; | ||
|
||
if (!policies[policy].prioritySupport) | ||
return NULL; | ||
|
||
int min = sched_get_priority_min(policy); | ||
if (min < 0) | ||
return NULL; | ||
int max = sched_get_priority_max(policy); | ||
if (max < 0 ) | ||
return NULL; | ||
|
||
Panel* this = Panel_new(0, 0, 0, 0, Class(ListItem), true, FunctionBar_newEnterEsc("Select ", "Cancel ")); | ||
Panel_setHeader(this, "Priority:"); | ||
|
||
for (int i = min; i <= max; i++) { | ||
char buf[16]; | ||
xSnprintf(buf, sizeof(buf), "%d", i); | ||
Panel_add(this, (Object*) ListItem_new(buf, i)); | ||
if (i == preSelectedPriority) | ||
Panel_setSelected(this, i); | ||
} | ||
|
||
return this; | ||
} | ||
|
||
bool Scheduling_setPolicy(Process* proc, Arg arg) { | ||
const SchedulingArg* sarg = arg.v; | ||
int policy = sarg->policy; | ||
|
||
assert(policy >= 0); | ||
assert((unsigned)policy < ARRAYSIZE(policies)); | ||
assert(policies[policy].name); | ||
|
||
const struct sched_param param = { .sched_priority = policies[policy].prioritySupport ? sarg->priority : 0 }; | ||
|
||
#ifdef SCHED_RESET_ON_FORK | ||
if (reset_on_fork) | ||
policy &= SCHED_RESET_ON_FORK; | ||
#endif | ||
|
||
int r = sched_setscheduler(proc->pid, policy, ¶m); | ||
|
||
/* POSIX says on success the previous scheduling policy should be returned, | ||
* but Linux always returns 0. */ | ||
return r != -1; | ||
} | ||
|
||
const char* Scheduling_formatPolicy(int policy) { | ||
#ifdef SCHED_RESET_ON_FORK | ||
policy = policy & ~SCHED_RESET_ON_FORK; | ||
#endif | ||
|
||
switch (policy) { | ||
case SCHED_OTHER: | ||
return "OTHER"; | ||
case SCHED_FIFO: | ||
return "FIFO"; | ||
case SCHED_RR: | ||
return "RR"; | ||
#ifdef SCHED_BATCH | ||
case SCHED_BATCH: | ||
return "BATCH"; | ||
#endif | ||
#ifdef SCHED_IDLE | ||
case SCHED_IDLE: | ||
return "IDLE"; | ||
#endif | ||
#ifdef SCHED_DEADLINE | ||
case SCHED_DEADLINE: | ||
return "EDF"; | ||
#endif | ||
default: | ||
return "???"; | ||
} | ||
} | ||
|
||
void Scheduling_readProcessPolicy(Process* proc) { | ||
proc->scheduling_policy = sched_getscheduler(proc->pid); | ||
} | ||
#endif /* SCHEDULER_SUPPORT */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#ifndef HEADER_Scheduling | ||
#define HEADER_Scheduling | ||
/* | ||
htop - Scheduling.h | ||
(C) 2023 htop dev team | ||
Released under the GNU GPLv2+, see the COPYING file | ||
in the source distribution for its full text. | ||
*/ | ||
|
||
#include "config.h" // IWYU pragma: keep | ||
|
||
#include <sched.h> | ||
#include <stdbool.h> | ||
|
||
#include "Panel.h" | ||
|
||
|
||
#if defined(HAVE_SCHED_SETSCHEDULER) && defined(HAVE_SCHED_GETSCHEDULER) | ||
#define SCHEDULER_SUPPORT | ||
|
||
typedef struct { | ||
const char* name; | ||
int id; | ||
bool prioritySupport; | ||
} SchedulingPolicy; | ||
|
||
#define SCHEDULINGPANEL_INITSELECTEDPOLICY SCHED_OTHER | ||
#define SCHEDULINGPANEL_INITSELECTEDPRIORITY 50 | ||
|
||
Panel* Scheduling_newPolicyPanel(int preSelectedPolicy); | ||
void Scheduling_togglePolicyPanelResetOnFork(Panel* schedPanel); | ||
|
||
Panel* Scheduling_newPriorityPanel(int policy, int preSelectedPriority); | ||
|
||
|
||
typedef struct { | ||
int policy; | ||
int priority; | ||
} SchedulingArg; | ||
|
||
bool Scheduling_setPolicy(Process* proc, Arg arg); | ||
|
||
const char* Scheduling_formatPolicy(int policy); | ||
|
||
void Scheduling_readProcessPolicy(Process* proc); | ||
|
||
#endif | ||
|
||
#endif /* HEADER_Scheduling */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.