diff options
author | Richard Braun <rbraun@sceen.net> | 2012-09-23 00:06:53 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2012-09-23 00:09:27 +0200 |
commit | 27f7e15e4e048cc13a97f514fb7c9ff0c97b9ee5 (patch) | |
tree | ac4ee1b32a5ec293920ca6a44c823e19dddde451 /libports | |
parent | 901c61a1d25e7c8963e51012760a82730eda1910 (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.
Diffstat (limited to 'libports')
-rw-r--r-- | libports/manage-multithread.c | 56 |
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) (); |