aboutsummaryrefslogtreecommitdiff
path: root/libports/manage-multithread.c
diff options
context:
space:
mode:
Diffstat (limited to 'libports/manage-multithread.c')
-rw-r--r--libports/manage-multithread.c67
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);
}