From: Diego Nieto Cid <[email protected]>
task_priority_override, which requires a host privileged
port right, sets the task priority, its procesor set max
priotrity and its threads priorite and max priority if
required.
---
include/mach/mach_host.defs | 11 +++++
kern/task.c | 94 +++++++++++++++++++++++++++++++++++++
2 files changed, 105 insertions(+)
diff --git a/include/mach/mach_host.defs b/include/mach/mach_host.defs
index 70a2e866..ce1f89cb 100644
--- a/include/mach/mach_host.defs
+++ b/include/mach/mach_host.defs
@@ -400,3 +400,14 @@ routine host_get_uptime64(
routine processor_set_processors(
set_name : processor_set_name_t;
out processors_list : processor_name_array_t);
+
+/*
+ * Override the priority of a task, its threads
+ * and processor set, increasing the max priority
+ * if required.
+ * Only available to privileged users.
+ */
+routine task_priority_override(
+ host_priv : host_priv_t;
+ task : task_t;
+ priority : int);
diff --git a/kern/task.c b/kern/task.c
index 061a8fa4..2cfd0dc5 100644
--- a/kern/task.c
+++ b/kern/task.c
@@ -1375,3 +1375,97 @@ register_new_task_notification(
new_task_notification = notification;
return KERN_SUCCESS;
}
+
+/*
+ * thread_set_priority:
+ *
+ * Sets the priority of the given threead.
+ * Will adjust max_priority if necessary.
+ */
+static kern_return_t
+thread_set_priority(
+ thread_t thread,
+ int priority)
+{
+ spl_t s;
+
+ s = splsched();
+ thread_lock(thread);
+
+ if (priority < thread->max_priority)
+ thread->max_priority = priority;
+ thread->priority = priority;
+ compute_priority(thread, TRUE);
+
+ thread_unlock(thread);
+ (void) splx(s);
+
+ return KERN_SUCCESS;
+}
+
+/*
+ * Override the priority of a task, its threads
+ * and processor set, increasing the max priority
+ * if required.
+ * Only available to privileged users.
+ */
+kern_return_t
+task_priority_override(
+ const host_t host,
+ const task_t task,
+ int priority)
+{
+ kern_return_t ret = KERN_SUCCESS;
+ processor_set_t pset;
+
+ if ((host == HOST_NULL) ||(task == TASK_NULL) ||
+ invalid_pri(priority))
+ return KERN_INVALID_ARGUMENT;
+
+
+ /*
+ * FIXME? thread_create says that processor set must
+ * be locked first. So we lock the task, get the pset
+ * then unlock the task to accuire the locks in the right order.
+ *
+ * My concerns are:
+ *
+ * 1. What happens if a thread is created and we are holding
+ * the task lock? May it deadlock if we don't accuire them
+ * in the right order?
+ *
+ * 2. Should we call pset_reference just to adjust it's max priority?
+ *
+ * 3. Do all threads run on the same processsor set as the task?
+ * If not, shall we care?
+ *
+ * 4. Should we try to catch up with changed processor sets, like
+ * thread_create does?
+ */
+ task_lock(task);
+ pset = task->processor_set;
+ task_unlock(task);
+
+ pset_lock(pset);
+ task_lock(task);
+
+ task->priority = priority;
+ pset->max_priority = priority;
+
+ {
+ thread_t thread;
+ queue_head_t *list;
+
+ list = &task->thread_list;
+ queue_iterate(list, thread, thread_t, thread_list) {
+ if (thread_set_priority(thread, priority)
+ != KERN_SUCCESS)
+ ret = KERN_FAILURE;
+ }
+ }
+
+ task_unlock(task);
+ pset_unlock(pset);
+
+ return ret;
+}
--
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.