aboutsummaryrefslogtreecommitdiffstats
path: root/Scheduling.c
diff options
context:
space:
mode:
authorDaniel Lange <DLange@git.local>2024-01-10 12:40:37 +0100
committerDaniel Lange <DLange@git.local>2024-01-10 12:40:37 +0100
commit7271b076b82785ffca73ee9e4ae84cabb77018ee (patch)
treee8270dd60ec096bee8157dbadf029e15ed584592 /Scheduling.c
parentf288666edc9180a2e81e6655951878124f321df6 (diff)
downloaddebian_htop-7271b076b82785ffca73ee9e4ae84cabb77018ee.tar.gz
debian_htop-7271b076b82785ffca73ee9e4ae84cabb77018ee.tar.bz2
debian_htop-7271b076b82785ffca73ee9e4ae84cabb77018ee.zip
New upstream version 3.3.0upstream/3.3.0upstream
Diffstat (limited to 'Scheduling.c')
-rw-r--r--Scheduling.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/Scheduling.c b/Scheduling.c
new file mode 100644
index 0000000..d5c4b8a
--- /dev/null
+++ b/Scheduling.c
@@ -0,0 +1,162 @@
+/*
+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 "config.h" // IWYU pragma: keep
+
+#include "Scheduling.h"
+
+#ifdef SCHEDULER_SUPPORT
+
+#include <assert.h>
+#include <stddef.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;
+}
+
+static bool Scheduling_setPolicy(Process* p, 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(Process_getPid(p), policy, &param);
+
+ /* POSIX says on success the previous scheduling policy should be returned,
+ * but Linux always returns 0. */
+ return r != -1;
+}
+
+bool Scheduling_rowSetPolicy(Row* row, Arg arg) {
+ Process* p = (Process*) row;
+ assert(Object_isA((const Object*) p, (const ObjectClass*) &Process_class));
+ return Scheduling_setPolicy(p, arg);
+}
+
+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(Process_getPid(proc));
+}
+#endif /* SCHEDULER_SUPPORT */

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