summaryrefslogtreecommitdiff
path: root/lib/libpthread/uthread/uthread_create.c
diff options
context:
space:
mode:
authorDavid Leonard <d@cvs.openbsd.org>1999-11-25 07:01:48 +0000
committerDavid Leonard <d@cvs.openbsd.org>1999-11-25 07:01:48 +0000
commit0fe78c3128864d128b2b10153b8d533ff8c00375 (patch)
tree5229c3d97eed15f4d71927a5f454180aef2632f6 /lib/libpthread/uthread/uthread_create.c
parented00fa742a6455d22e3b56cf846dc5acd7a51fd7 (diff)
sync with FreeBSD
Diffstat (limited to 'lib/libpthread/uthread/uthread_create.c')
-rw-r--r--lib/libpthread/uthread/uthread_create.c85
1 files changed, 36 insertions, 49 deletions
diff --git a/lib/libpthread/uthread/uthread_create.c b/lib/libpthread/uthread/uthread_create.c
index 002f563d14a..67811b2d583 100644
--- a/lib/libpthread/uthread/uthread_create.c
+++ b/lib/libpthread/uthread/uthread_create.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_create.c,v 1.11 1999/11/25 07:01:33 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_create.c,v 1.10 1999/05/26 00:18:23 d Exp $
+ * $FreeBSD: uthread_create.c,v 1.19 1999/08/28 00:03:28 peter Exp $
*/
#include <errno.h>
#include <stdlib.h>
@@ -37,22 +38,25 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/mman.h>
#ifdef _THREAD_SAFE
#include <machine/reg.h>
#include <pthread.h>
#include "pthread_private.h"
-#include "thread_private.h"
int
pthread_create(pthread_t * thread, const pthread_attr_t * attr,
void *(*start_routine) (void *), void *arg)
{
int f_gc = 0;
+ int i;
int ret = 0;
+ int status;
pthread_t gc_thread;
pthread_t new_thread;
pthread_attr_t pattr;
- void *stack;
+ struct stack *stack;
/*
* Locking functions in libc are required when there are
@@ -72,31 +76,24 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
} else {
pattr = *attr;
}
- /* Check if a stack was specified in the thread attributes: */
- if ((stack = pattr->stackaddr_attr) != NULL) {
- }
- /* Allocate memory for the stack: */
- else if ((stack = (void *) malloc(pattr->stacksize_attr)) == NULL) {
- /* Insufficient memory to create a thread: */
+ /* Create a stack from the specified attributes: */
+ if ((stack = _thread_stack_alloc(pattr->stackaddr_attr,
+ pattr->stacksize_attr)) == NULL) {
ret = EAGAIN;
free(new_thread);
}
+
/* Check for errors: */
if (ret != 0) {
} else {
/* Initialise the thread structure: */
memset(new_thread, 0, sizeof(struct pthread));
+ _SPINLOCK_INIT(&new_thread->lock);
new_thread->slice_usec = -1;
new_thread->sig_saved = 0;
new_thread->stack = stack;
new_thread->start_routine = start_routine;
new_thread->arg = arg;
-#ifdef _THREAD_RUSAGE
- timerclear(&new_thread->ru_utime);
- timerclear(&new_thread->ru_stime);
-#endif
- _SPINUNLOCK(&new_thread->lock);
-
new_thread->cancelstate = PTHREAD_CANCEL_ENABLE;
new_thread->canceltype = PTHREAD_CANCEL_DEFERRED;
@@ -106,12 +103,6 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
*/
new_thread->magic = PTHREAD_MAGIC;
- if (pattr->suspend == PTHREAD_CREATE_SUSPENDED) {
- PTHREAD_NEW_STATE(new_thread,PS_SUSPENDED);
- } else {
- PTHREAD_NEW_STATE(new_thread,PS_RUNNING);
- }
-
/* Initialise the thread for signals: */
new_thread->sigmask = _thread_run->sigmask;
@@ -123,8 +114,8 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
* returned from a longjmp() to the beginning of
* _thread_start().
*/
-
- _thread_machdep_thread_create(new_thread, _thread_start, pattr);
+ _thread_machdep_thread_create(new_thread, _thread_start,
+ pattr);
/* Copy the thread attributes: */
memcpy(&new_thread->attr, pattr, sizeof(struct pthread_attr));
@@ -135,22 +126,26 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
*/
if (new_thread->attr.flags & PTHREAD_INHERIT_SCHED) {
/* Copy the scheduling attributes: */
- new_thread->base_priority = _thread_run->base_priority;
- new_thread->attr.prio = _thread_run->base_priority;
- new_thread->attr.sched_policy = _thread_run->attr.sched_policy;
+ new_thread->base_priority
+ = _thread_run->base_priority;
+ new_thread->attr.prio
+ = _thread_run->base_priority;
+ new_thread->attr.sched_policy
+ = _thread_run->attr.sched_policy;
} else {
/*
* Use just the thread priority, leaving the
* other scheduling attributes as their
* default values:
*/
- new_thread->base_priority = new_thread->attr.prio;
+ new_thread->base_priority
+ = new_thread->attr.prio;
}
new_thread->active_priority = new_thread->base_priority;
new_thread->inherited_priority = 0;
/* Initialise the join queue for the new thread: */
- _thread_queue_init(&(new_thread->join_queue));
+ TAILQ_INIT(&(new_thread->join_queue));
/* Initialize the mutex queue: */
TAILQ_INIT(&new_thread->mutexq);
@@ -158,32 +153,24 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
/* Initialise hooks in the thread structure: */
new_thread->specific_data = NULL;
new_thread->cleanup = NULL;
- new_thread->queue = NULL;
- new_thread->qnxt = NULL;
new_thread->flags = 0;
+ new_thread->poll_data.nfds = 0;
+ new_thread->poll_data.fds = NULL;
- /* Lock the thread list: */
- _lock_thread_list();
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
/*
* Check if the garbage collector thread
* needs to be started.
*/
- f_gc = (_thread_link_list == _thread_initial);
+ f_gc = (TAILQ_FIRST(&_thread_list) == _thread_initial);
/* Add the thread to the linked list of all threads: */
- new_thread->nxt = _thread_link_list;
- _thread_link_list = new_thread;
-
- /* Unlock the thread list: */
- _unlock_thread_list();
-
- /*
- * Guard against preemption by a scheduling signal.
- * A change of thread state modifies the waiting
- * and priority queues.
- */
- _thread_kern_sched_defer();
+ TAILQ_INSERT_HEAD(&_thread_list, new_thread, tle);
if (pattr->suspend == PTHREAD_CREATE_SUSPENDED) {
new_thread->state = PS_SUSPENDED;
@@ -194,10 +181,10 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
}
/*
- * Reenable preemption and yield if a scheduling
- * signal occurred while in the critical region.
+ * Undefer and handle pending signals, yielding
+ * if necessary.
*/
- _thread_kern_sched_undefer();
+ _thread_kern_sig_undefer();
/* Return a pointer to the thread structure: */
if (thread != NULL)