summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/librthread/rthread.c22
-rw-r--r--lib/librthread/rthread.h5
-rw-r--r--lib/librthread/rthread_attr.c10
-rw-r--r--lib/librthread/rthread_sched.c58
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);
+}
+