summaryrefslogtreecommitdiffstats
path: root/lib/libpthread/thread/thr_spec.c
diff options
context:
space:
mode:
authorjb <jb@FreeBSD.org>1998-06-06 07:24:24 +0000
committerjb <jb@FreeBSD.org>1998-06-06 07:24:24 +0000
commitfa1af3c55b714cb0c83c88b0136e3b5038e4496c (patch)
treee5ea3ec41087592538b3a1ea07c8a68b3a3ef617 /lib/libpthread/thread/thr_spec.c
parent0e04174c22864c80cfad6e467beaeef0503b40ca (diff)
downloadFreeBSD-src-fa1af3c55b714cb0c83c88b0136e3b5038e4496c.zip
FreeBSD-src-fa1af3c55b714cb0c83c88b0136e3b5038e4496c.tar.gz
Simplify the handling of thread specific data. Only track if a key
is allocated or not, rather than keeping a count and attempting to know it it is in-use. POSIX says that once a key is deleted, using the key again results in undefined behaviour.
Diffstat (limited to 'lib/libpthread/thread/thr_spec.c')
-rw-r--r--lib/libpthread/thread/thr_spec.c78
1 files changed, 33 insertions, 45 deletions
diff --git a/lib/libpthread/thread/thr_spec.c b/lib/libpthread/thread/thr_spec.c
index cf60f38..eaad36d 100644
--- a/lib/libpthread/thread/thr_spec.c
+++ b/lib/libpthread/thread/thr_spec.c
@@ -40,54 +40,47 @@
/* Static variables: */
static struct pthread_key key_table[PTHREAD_KEYS_MAX];
-static long key_table_lock = 0;
int
pthread_key_create(pthread_key_t * key, void (*destructor) (void *))
{
- /* Lock the key table: */
- _spinlock(&key_table_lock);
-
for ((*key) = 0; (*key) < PTHREAD_KEYS_MAX; (*key)++) {
- if (key_table[(*key)].count == 0) {
- key_table[(*key)].count++;
+ /* Lock the key table entry: */
+ _spinlock(&key_table[*key].access_lock);
+
+ if (key_table[(*key)].allocated == 0) {
+ key_table[(*key)].allocated = 1;
key_table[(*key)].destructor = destructor;
- /* Unlock the key table: */
- _atomic_unlock(&key_table_lock);
+ /* Unlock the key table entry: */
+ _atomic_unlock(&key_table[*key].access_lock);
return (0);
}
- }
- /* Unlock the key table: */
- _atomic_unlock(&key_table_lock);
+ /* Unlock the key table entry: */
+ _atomic_unlock(&key_table[*key].access_lock);
+ }
return (EAGAIN);
}
int
pthread_key_delete(pthread_key_t key)
{
- int ret;
-
- /* Lock the key table: */
- _spinlock(&key_table_lock);
+ int ret = 0;
if (key < PTHREAD_KEYS_MAX) {
- switch (key_table[key].count) {
- case 1:
- key_table[key].destructor = NULL;
- key_table[key].count = 0;
- case 0:
- ret = 0;
- break;
- default:
- ret = EBUSY;
- }
+ /* Lock the key table entry: */
+ _spinlock(&key_table[key].access_lock);
+
+ if (key_table[key].allocated)
+ key_table[key].allocated = 0;
+ else
+ ret = EINVAL;
+
+ /* Unlock the key table entry: */
+ _atomic_unlock(&key_table[key].access_lock);
} else
ret = EINVAL;
-
- /* Unlock the key table: */
- _atomic_unlock(&key_table_lock);
return (ret);
}
@@ -104,14 +97,14 @@ _thread_cleanupspecific(void)
/* Lock the key table entry: */
_spinlock(&key_table[key].access_lock);
- if (_thread_run->specific_data[key]) {
- data = (void *) _thread_run->specific_data[key];
- _thread_run->specific_data[key] = NULL;
- _thread_run->specific_data_count--;
- if (key_table[key].destructor) {
- key_table[key].destructor(data);
+ if (key_table[key].allocated) {
+ if (_thread_run->specific_data[key]) {
+ data = (void *) _thread_run->specific_data[key];
+ _thread_run->specific_data[key] = NULL;
+ _thread_run->specific_data_count--;
+ if (key_table[key].destructor)
+ key_table[key].destructor(data);
}
- key_table[key].count--;
}
/* Unlock the key table entry: */
@@ -150,17 +143,13 @@ pthread_setspecific(pthread_key_t key, const void *value)
/* Lock the key table entry: */
_spinlock(&key_table[key].access_lock);
- if (key_table[key].count) {
+ if (key_table[key].allocated) {
if (pthread->specific_data[key] == NULL) {
- if (value != NULL) {
+ if (value != NULL)
pthread->specific_data_count++;
- key_table[key].count++;
- }
} else {
- if (value == NULL) {
+ if (value == NULL)
pthread->specific_data_count--;
- key_table[key].count--;
- }
}
pthread->specific_data[key] = value;
ret = 0;
@@ -187,13 +176,12 @@ pthread_getspecific(pthread_key_t key)
pthread = _thread_run;
/* Check if there is specific data: */
- if (pthread->specific_data != NULL &&
- (key < PTHREAD_KEYS_MAX) && (key_table)) {
+ if (pthread->specific_data != NULL && key < PTHREAD_KEYS_MAX) {
/* Lock the key table entry: */
_spinlock(&key_table[key].access_lock);
/* Check if this key has been used before: */
- if (key_table[key].count) {
+ if (key_table[key].allocated) {
/* Return the value: */
data = (void *) pthread->specific_data[key];
} else {
OpenPOWER on IntegriCloud