summaryrefslogtreecommitdiff
path: root/libports/manage-multithread.c
diff options
context:
space:
mode:
Diffstat (limited to 'libports/manage-multithread.c')
-rw-r--r--libports/manage-multithread.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/libports/manage-multithread.c b/libports/manage-multithread.c
index 82fa2ac6..c25bfd38 100644
--- a/libports/manage-multithread.c
+++ b/libports/manage-multithread.c
@@ -23,6 +23,49 @@
#include <assert.h>
#include <cthreads.h>
#include <mach/message.h>
+#include <mach/thread_info.h>
+#include <mach/thread_switch.h>
+
+/* A very high priority is assigned to reduce thread storms in core servers. */
+#define THREAD_PRI 2
+
+static void
+adjust_priority (void)
+{
+ mach_port_t host_priv, self, pset, pset_priv;
+ error_t err;
+
+ self = MACH_PORT_NULL;
+
+ err = get_privileged_ports (&host_priv, NULL);
+ if (err)
+ goto out;
+
+ self = mach_thread_self ();
+ err = thread_get_assignment (self, &pset);
+ if (err)
+ goto out;
+
+ err = host_processor_set_priv (host_priv, pset, &pset_priv);
+ if (err)
+ goto out;
+
+ err = thread_max_priority (self, pset_priv, 0);
+ if (err)
+ goto out;
+
+ err = thread_priority (self, THREAD_PRI, 0);
+
+out:
+ if (self != MACH_PORT_NULL)
+ mach_port_deallocate (mach_task_self (), self);
+
+ if (err)
+ {
+ errno = err;
+ perror ("unable to adjust libports thread priority");
+ }
+}
void
ports_manage_port_operations_multithread (struct port_bucket *bucket,
@@ -123,6 +166,19 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket,
int timeout;
error_t err;
+ /* XXX To reduce starvation, the priority of new threads is initially
+ depressed. This helps already existing threads complete their job
+ and be recycled to handle new messages. The duration of this
+ depression is made a function of the total number of threads because
+ more threads implies more contention, and the priority of threads
+ blocking on a contented spin lock is also implicitely depressed.
+ The lock isn't needed, since an approximation is sufficient. */
+ timeout = (((totalthreads - 1) / 100) + 1) * 10;
+ thread_switch (MACH_PORT_NULL, SWITCH_OPTION_DEPRESS, timeout);
+
+ /* XXX Give servers a greater priority when possible. */
+ adjust_priority ();
+
if (hook)
(*hook) ();