summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/librthread/rthread.c7
-rw-r--r--lib/librthread/rthread.h7
-rw-r--r--lib/librthread/rthread_tls.c58
3 files changed, 50 insertions, 22 deletions
diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c
index e60ef5f51a1..db6a492b2be 100644
--- a/lib/librthread/rthread.c
+++ b/lib/librthread/rthread.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread.c,v 1.3 2005/12/13 05:56:55 tedu Exp $ */
+/* $OpenBSD: rthread.c,v 1.4 2005/12/14 04:01:44 tedu Exp $ */
/*
* Copyright (c) 2004 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -96,6 +96,8 @@ thread_init(void)
pthread_t thread;
extern int __isthreaded;
+ printf("rthread init\n");
+
__isthreaded = 1;
thread = malloc(sizeof(*thread));
@@ -117,7 +119,6 @@ alloc_stack(size_t len)
return (stack);
}
-
/*
* real pthread functions
*/
@@ -143,7 +144,9 @@ pthread_exit(void *retval)
thread->retval = retval;
thread->flags |= THREAD_DONE;
+
_sem_post(&thread->donesem);
+ rthread_tls_destructors(thread);
#if 0
if (thread->flags & THREAD_DETACHED)
free(thread);
diff --git a/lib/librthread/rthread.h b/lib/librthread/rthread.h
index beceb9b5543..ea5a83ae701 100644
--- a/lib/librthread/rthread.h
+++ b/lib/librthread/rthread.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread.h,v 1.3 2005/12/13 17:22:46 tedu Exp $ */
+/* $OpenBSD: rthread.h,v 1.4 2005/12/14 04:01:44 tedu Exp $ */
/*
* Copyright (c) 2004 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -73,8 +73,7 @@ struct pthread_attr {
};
struct rthread_key {
- int keyid;
- struct rthread_key *next;
+ int used;
void (*destructor)(void *);
};
@@ -110,4 +109,6 @@ int _sem_post(sem_t);
int _sem_wakeup(sem_t);
int _sem_wakeall(sem_t);
+void rthread_tls_destructors(pthread_t);
+
int _atomic_lock(register volatile _spinlock_lock_t *);
diff --git a/lib/librthread/rthread_tls.c b/lib/librthread/rthread_tls.c
index 7f18e148357..a028a04dc50 100644
--- a/lib/librthread/rthread_tls.c
+++ b/lib/librthread/rthread_tls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread_tls.c,v 1.2 2005/12/07 02:56:59 tedu Exp $ */
+/* $OpenBSD: rthread_tls.c,v 1.3 2005/12/14 04:01:44 tedu Exp $ */
/*
* Copyright (c) 2004 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -36,26 +36,29 @@
#include "rthread.h"
-struct rthread_key *rthread_key_list;
+static struct rthread_key rkeys[PTHREAD_KEYS_MAX];
int
pthread_key_create(pthread_key_t *key, void (*destructor)(void*))
{
- static int last_key;
- struct rthread_key *rkey;
-
- last_key++;
-
- rkey = malloc(sizeof(*rkey));
- if (!rkey)
- return (errno);
- memset(rkey, 0, sizeof(*rkey));
- rkey->keyid = last_key;
- rkey->destructor = destructor;
- rkey->next = rthread_key_list;
- rthread_key_list = rkey;
-
- *key = last_key;
+ static int hint;
+ int i;
+
+ if (rkeys[hint].used) {
+ for (i = 0; i < PTHREAD_KEYS_MAX; i++) {
+ if (!rkeys[i].used)
+ break;
+ }
+ if (i == PTHREAD_KEYS_MAX)
+ return (EAGAIN);
+ hint = i;
+ }
+ rkeys[hint].used = 1;
+ rkeys[hint].destructor = destructor;
+
+ *key = hint++;
+ if (hint >= PTHREAD_KEYS_MAX)
+ hint = 0;
return (0);
}
@@ -64,6 +67,9 @@ int
pthread_key_delete(pthread_key_t key)
{
+ rkeys[key].used = 0;
+ rkeys[key].destructor = NULL;
+
return (0);
}
@@ -117,3 +123,21 @@ pthread_setspecific(pthread_key_t key, const void *data)
return (0);
}
+
+void
+rthread_tls_destructors(pthread_t thread)
+{
+ struct rthread_storage *rs;
+ int i;
+
+ for (i = 0; i < PTHREAD_DESTRUCTOR_ITERATIONS; i++) {
+ for (rs = thread->local_storage; rs; rs = rs->next) {
+ if (!rs->data)
+ continue;
+ if (rkeys[rs->keyid].destructor) {
+ rkeys[rs->keyid].destructor(rs->data);
+ rs->data = NULL;
+ }
+ }
+ }
+}