diff options
-rw-r--r-- | lib/librthread/rthread.c | 22 | ||||
-rw-r--r-- | lib/librthread/rthread.h | 5 | ||||
-rw-r--r-- | lib/librthread/rthread_attr.c | 10 | ||||
-rw-r--r-- | lib/librthread/rthread_sched.c | 58 |
4 files changed, 86 insertions, 9 deletions
diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c index d29e1277a89..71bff294202 100644 --- a/lib/librthread/rthread.c +++ b/lib/librthread/rthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.c,v 1.24 2005/12/30 21:51:27 otto Exp $ */ +/* $OpenBSD: rthread.c,v 1.25 2005/12/31 08:51:20 otto Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -38,10 +38,10 @@ #include "rthread.h" -static int threads_ready; static int concurrency_level; /* not used */ -struct listhead _thread_list = LIST_HEAD_INITIALIZER(thread_list); +int _threads_ready; +struct listhead _thread_list = LIST_HEAD_INITIALIZER(_thread_list); _spinlock_lock_t _thread_lock = _SPINLOCK_UNLOCKED; struct pthread _initial_thread; @@ -105,7 +105,7 @@ _rthread_init(void) thread->flags |= THREAD_CANCEL_ENABLE|THREAD_CANCEL_DEFERRED; strlcpy(thread->name, "Main process", sizeof(thread->name)); LIST_INSERT_HEAD(&_thread_list, thread, threads); - threads_ready = 1; + _threads_ready = 1; __isthreaded = 1; return (0); @@ -153,7 +153,7 @@ pthread_self(void) { pthread_t thread; - if (!threads_ready) + if (!_threads_ready) if (_rthread_init()) return (NULL); @@ -225,7 +225,7 @@ pthread_create(pthread_t *threadp, const pthread_attr_t *attr, pid_t tid; int rc = 0; - if (!threads_ready) + if (!_threads_ready) if ((rc = _rthread_init())) return (rc); @@ -236,6 +236,8 @@ pthread_create(pthread_t *threadp, const pthread_attr_t *attr, thread->donesem.lock = _SPINLOCK_UNLOCKED; thread->fn = start_routine; thread->arg = arg; + if (attr) + thread->attr = *(*attr); _spinlock(&_thread_lock); @@ -256,6 +258,14 @@ pthread_create(pthread_t *threadp, const pthread_attr_t *attr, thread->tid = tid; thread->flags |= THREAD_CANCEL_ENABLE|THREAD_CANCEL_DEFERRED; *threadp = thread; + + /* + * Since _rthread_start() aquires the thread lock and due to the way + * signal delivery is implemented, this is not a race. + */ + if (thread->attr.create_suspended) + kill(thread->tid, SIGSTOP); + _spinunlock(&_thread_lock); return (0); diff --git a/lib/librthread/rthread.h b/lib/librthread/rthread.h index 50e4f77d37c..7bf10dacf6c 100644 --- a/lib/librthread/rthread.h +++ b/lib/librthread/rthread.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.h,v 1.12 2005/12/30 20:35:11 otto Exp $ */ +/* $OpenBSD: rthread.h,v 1.13 2005/12/31 08:51:20 otto Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -78,6 +78,7 @@ struct pthread_attr { int sched_policy; struct sched_param sched_param; int sched_inherit; + int create_suspended; }; struct rthread_key { @@ -108,6 +109,7 @@ struct pthread { struct stack *stack; LIST_ENTRY(pthread) threads; int sched_policy; + struct pthread_attr attr; struct sched_param sched_param; struct rthread_storage *local_storage; int sigpend; @@ -119,6 +121,7 @@ struct pthread { #define THREAD_CANCEL_ENABLE 0x008 #define THREAD_CANCEL_DEFERRED 0x010 +extern int _threads_ready; extern LIST_HEAD(listhead, pthread) _thread_list; extern struct pthread _initial_thread; extern _spinlock_lock_t _thread_lock; diff --git a/lib/librthread/rthread_attr.c b/lib/librthread/rthread_attr.c index 2f01f17de50..93a18346079 100644 --- a/lib/librthread/rthread_attr.c +++ b/lib/librthread/rthread_attr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread_attr.c,v 1.3 2005/12/19 06:47:40 tedu Exp $ */ +/* $OpenBSD: rthread_attr.c,v 1.4 2005/12/31 08:51:20 otto Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -141,3 +141,11 @@ pthread_attr_setscope(pthread_attr_t *attrp, int contentionscope) return (0); } + +int +pthread_attr_setcreatesuspend_np(pthread_attr_t *attr) +{ + (*attr)->create_suspended = 1; + return (0); +} + diff --git a/lib/librthread/rthread_sched.c b/lib/librthread/rthread_sched.c index d1dae0867b6..a1919c467d8 100644 --- a/lib/librthread/rthread_sched.c +++ b/lib/librthread/rthread_sched.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread_sched.c,v 1.4 2005/12/30 04:05:55 tedu Exp $ */ +/* $OpenBSD: rthread_sched.c,v 1.5 2005/12/31 08:51:20 otto Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -33,6 +33,7 @@ #include <errno.h> #include <pthread.h> +#include <pthread_np.h> #include "rthread.h" @@ -125,3 +126,58 @@ pthread_yield(void) { sched_yield(); } + +int +pthread_suspend_np(pthread_t thread) +{ + int errn = 0; + + if (thread->tid == pthread_self()->tid) + return (EDEADLK); + /* + * XXX Avoid a bug in current signal handling by refusing to + * suspend the main thread. + */ + if (pthread_main_np() == 0) + if (kill(thread->tid, SIGSTOP) == -1) + errn = errno; + return (errn); +} + +void +pthread_suspend_all_np(void) +{ + pthread_t t; + pid_t me = getthrid(); + + _spinlock(&_thread_lock); + LIST_FOREACH(t, &_thread_list, threads) + if (t->tid != me) + pthread_suspend_np(t); + _spinunlock(&_thread_lock); +} + +int +pthread_resume_np(pthread_t thread) +{ + int errn = 0; + + /* XXX check if really suspended? */ + if (kill(thread->tid, SIGCONT) == -1) + errn = errno; + return (errn); +} + +void +pthread_resume_all_np(void) +{ + pthread_t t; + pid_t me = getthrid(); + + _spinlock(&_thread_lock); + LIST_FOREACH(t, &_thread_list, threads) + if (t->tid != me) + pthread_resume_np(t); + _spinunlock(&_thread_lock); +} + |