summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2012-09-23 00:06:53 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2012-09-23 00:09:27 +0200
commit27f7e15e4e048cc13a97f514fb7c9ff0c97b9ee5 (patch)
treeac4ee1b32a5ec293920ca6a44c823e19dddde451
parent901c61a1d25e7c8963e51012760a82730eda1910 (diff)
Reduce starvation among libports threads
* libports/manage-multithread.c: Include <mach/thread_info.h> and <mach/thread_switch.h> (THREAD_PRI): New macro. (adjust_priority): New function. (ports_manage_port_operations_multithread): Set higher priority to privileged translators's threads. Reduce priority of newly-created threads, to give originators a chance to finish what they were doing.
-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) ();