diff options
Diffstat (limited to 'libports/manage-multithread.c')
-rw-r--r-- | libports/manage-multithread.c | 67 |
1 files changed, 46 insertions, 21 deletions
diff --git a/libports/manage-multithread.c b/libports/manage-multithread.c index 035cd38d..c46a09fc 100644 --- a/libports/manage-multithread.c +++ b/libports/manage-multithread.c @@ -19,13 +19,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ports.h" -#include <spin-lock.h> #include <assert.h> -#include <cthreads.h> +#include <stdio.h> #include <mach/message.h> #include <mach/thread_info.h> #include <mach/thread_switch.h> +#define STACK_SIZE (64 * 1024) + +/* FIXME Until threadvars are completely replaced with correct TLS, use this + hack to set the stack size. */ +size_t __pthread_stack_default_size = STACK_SIZE; + #define THREAD_PRI 2 /* XXX To reduce starvation, the priority of new threads is initially @@ -88,9 +93,14 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, { volatile unsigned int nreqthreads; volatile unsigned int totalthreads; - spin_lock_t lock = SPIN_LOCK_INITIALIZER; + pthread_spinlock_t lock = PTHREAD_SPINLOCK_INITIALIZER; + pthread_attr_t attr; + + auto void * thread_function (void *); - auto int thread_function (int); + /* FIXME This is currently a no-op. */ + pthread_attr_init (&attr); + pthread_attr_setstacksize (&attr, STACK_SIZE); int internal_demuxer (mach_msg_header_t *inp, @@ -110,18 +120,32 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, /* msgt_unused = */ 0 }; - spin_lock (&lock); + pthread_spin_lock (&lock); assert (nreqthreads); nreqthreads--; if (nreqthreads != 0) - spin_unlock (&lock); + pthread_spin_unlock (&lock); else /* No thread would be listening for requests, spawn one. */ { + pthread_t pthread_id; + error_t err; + totalthreads++; nreqthreads++; - spin_unlock (&lock); - cthread_detach (cthread_fork ((cthread_fn_t) thread_function, 0)); + pthread_spin_unlock (&lock); + + err = pthread_create (&pthread_id, &attr, thread_function, NULL); + if (!err) + pthread_detach (pthread_id); + else + { + /* XXX The number of threads should be adjusted but the code + and design of the Hurd servers just don't handle thread + creation failure. */ + errno = err; + perror ("pthread_create"); + } } /* Fill in default response. */ @@ -146,10 +170,10 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, } else { - mutex_lock (&_ports_lock); + pthread_mutex_lock (&_ports_lock); if (inp->msgh_seqno < pi->cancel_threshold) hurd_thread_cancel (link.thread); - mutex_unlock (&_ports_lock); + pthread_mutex_unlock (&_ports_lock); status = demuxer (inp, outheadp); ports_end_rpc (pi, &link); } @@ -161,16 +185,17 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, status = 1; } - spin_lock (&lock); + pthread_spin_lock (&lock); nreqthreads++; - spin_unlock (&lock); + pthread_spin_unlock (&lock); return status; } - int - thread_function (int master) + void * + thread_function (void *arg) { + int master = (int) arg; int timeout; error_t err; @@ -195,32 +220,32 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, if (master) { - spin_lock (&lock); + pthread_spin_lock (&lock); if (totalthreads != 1) { - spin_unlock (&lock); + pthread_spin_unlock (&lock); goto startover; } } else { - spin_lock (&lock); + pthread_spin_lock (&lock); if (nreqthreads == 1) { /* No other thread is listening for requests, continue. */ - spin_unlock (&lock); + pthread_spin_unlock (&lock); goto startover; } nreqthreads--; totalthreads--; - spin_unlock (&lock); + pthread_spin_unlock (&lock); } - return 0; + return NULL; } nreqthreads = 1; totalthreads = 1; - thread_function (1); + thread_function ((void *) 1); } |