summaryrefslogtreecommitdiff
path: root/libthreads
diff options
context:
space:
mode:
Diffstat (limited to 'libthreads')
-rw-r--r--libthreads/cprocs.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/libthreads/cprocs.c b/libthreads/cprocs.c
index e721abd2..929461c1 100644
--- a/libthreads/cprocs.c
+++ b/libthreads/cprocs.c
@@ -373,7 +373,10 @@ cproc_alloc()
register cproc_t p = (cproc_t) malloc(sizeof(struct cproc));
p->incarnation = NO_CTHREAD;
+#if 0
+ /* This member is not used in GNU. */
p->reply_port = MACH_PORT_NULL;
+#endif
spin_lock_init(&p->lock);
p->wired = MACH_PORT_NULL;
@@ -595,6 +598,7 @@ cproc_waiter()
cproc_block()
{
+ extern unsigned int __hurd_threadvar_max; /* GNU */
register cproc_t waiter, new, p = cproc_self();
register int extra;
@@ -663,9 +667,15 @@ cproc_block()
p->state = CPROC_BLOCKED;
spin_lock(&waiter->lock); /* in case still switching */
spin_unlock(&waiter->lock);
- cproc_start_wait(&p->context, waiter,
- cproc_stack_base(waiter, sizeof(ur_cthread_t *)),
- &p->lock);
+ cproc_start_wait
+ (&p->context, waiter,
+ cproc_stack_base(waiter,
+ sizeof(ur_cthread_t *) +
+ /* Account for GNU per-thread
+ variables. */
+ __hurd_threadvar_max *
+ sizeof (long int)),
+ &p->lock);
}
}
}
@@ -698,10 +708,26 @@ cproc_create()
spin_unlock(&ready_lock);
#endif STATISTICS
} else {
+ vm_offset_t stack;
spin_unlock(&n_kern_lock);
child->state = CPROC_BLOCKED;
- cproc_prepare(child, &child->context,
- cproc_stack_base(child, 0));
+ /* The original CMU code does the excessively clever
+ optimization of putting CHILD at the base of the stack
+ and setting up to be the argument to cthread_body in the
+ same place (by passing zero as the second arg to
+ cproc_stack_base here).. This doesn't fly for GNU,
+ because we need some more space allocated at the base of
+ the stack, after the cproc_self pointer (where CHILD is
+ stored). */
+ stack = cproc_stack_base(child,
+ sizeof(ur_cthread_t *) +
+ /* Account for GNU per-thread
+ variables. */
+ __hurd_threadvar_max *
+ sizeof (long int));
+ cproc_prepare(child, &child->context, stack);
+ /* Set up the cproc_self ptr at the base of CHILD's stack. */
+ ur_cthread_ptr(stack) = child;
cproc_ready(child,0);
}
return child;