Module Name: src Committed By: riz Date: Sun Dec 2 18:47:37 UTC 2012
Modified Files: src/doc [netbsd-6]: CHANGES-6.1 src/lib/libpthread [netbsd-6]: pthread_int.h pthread_specific.c pthread_tsd.c Log Message: Back out ticket #724 (libpthread changes) until they can be better understood, as they broke threaded programs on (at least) i386 and amd64. To generate a diff of this commit: cvs rdiff -u -r1.1.2.51 -r1.1.2.52 src/doc/CHANGES-6.1 cvs rdiff -u -r1.82.2.1 -r1.82.2.2 src/lib/libpthread/pthread_int.h cvs rdiff -u -r1.21.22.1 -r1.21.22.2 src/lib/libpthread/pthread_specific.c cvs rdiff -u -r1.7.24.1 -r1.7.24.2 src/lib/libpthread/pthread_tsd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/doc/CHANGES-6.1 diff -u src/doc/CHANGES-6.1:1.1.2.51 src/doc/CHANGES-6.1:1.1.2.52 --- src/doc/CHANGES-6.1:1.1.2.51 Sun Dec 2 02:06:18 2012 +++ src/doc/CHANGES-6.1 Sun Dec 2 18:47:37 2012 @@ -1,4 +1,4 @@ -# $NetBSD: CHANGES-6.1,v 1.1.2.51 2012/12/02 02:06:18 riz Exp $ +# $NetBSD: CHANGES-6.1,v 1.1.2.52 2012/12/02 18:47:37 riz Exp $ A complete list of changes from the 6.0 release until the 6.1 release: @@ -915,7 +915,7 @@ sys/dev/usb/if_urndis.c 1.4 lib/libc/arch/arm/sys/__aeabi_read_tp.S 1.3 - Add $NetBSD: CHANGES-6.1,v 1.1.2.51 2012/12/02 02:06:18 riz Exp $ tag. Use ip to save r1 instead of the stack. + Add $NetBSD: CHANGES-6.1,v 1.1.2.52 2012/12/02 18:47:37 riz Exp $ tag. Use ip to save r1 instead of the stack. [matt, ticket #701] sys/net/npf/npf.c 1.14 @@ -7063,15 +7063,6 @@ lib/libc/stdio/fopen.3 1.29 Add 'x' to the mode bits of fopen() to specify O_EXCL, like glibc. [christos, ticket #723] -lib/libpthread/pthread_int.h 1.88 -lib/libpthread/pthread_specific.c 1.24 -lib/libpthread/pthread_tsd.c 1.8-1.10 - - Replace the simple implementation of pthread_key_{create,destroy} - and pthread_{g,s}etspecific functions with one that invalidates - values of keys in other threads when pthread_key_delete() is called. - [christos, ticket #724] - sys/fs/smbfs/smbfs_smb.c 1.43 sys/netsmb/smb_smb.c 1.33 Index: src/lib/libpthread/pthread_int.h diff -u src/lib/libpthread/pthread_int.h:1.82.2.1 src/lib/libpthread/pthread_int.h:1.82.2.2 --- src/lib/libpthread/pthread_int.h:1.82.2.1 Wed Nov 28 23:58:35 2012 +++ src/lib/libpthread/pthread_int.h Sun Dec 2 18:47:36 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_int.h,v 1.82.2.1 2012/11/28 23:58:35 riz Exp $ */ +/* $NetBSD: pthread_int.h,v 1.82.2.2 2012/12/02 18:47:36 riz Exp $ */ /*- * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -145,10 +145,7 @@ struct __pthread_st { /* Thread-specific data. Large so it sits close to the end. */ int pt_havespecific; - struct pt_specific { - void *pts_value; - PTQ_ENTRY(pt_specific) pts_next; - } pt_specific[PTHREAD_KEYS_MAX]; + void *pt_specific[PTHREAD_KEYS_MAX]; /* * Context for thread creation. At the end as it's cached @@ -297,7 +294,6 @@ char *pthread__getenv(const char *) PTHR __dead void pthread__cancelled(void) PTHREAD_HIDE; void pthread__mutex_deferwake(pthread_t, pthread_mutex_t *) PTHREAD_HIDE; int pthread__checkpri(int) PTHREAD_HIDE; -int pthread__add_specific(pthread_t, pthread_key_t, const void *) PTHREAD_HIDE; #ifndef pthread__smt_pause #define pthread__smt_pause() /* nothing */ Index: src/lib/libpthread/pthread_specific.c diff -u src/lib/libpthread/pthread_specific.c:1.21.22.1 src/lib/libpthread/pthread_specific.c:1.21.22.2 --- src/lib/libpthread/pthread_specific.c:1.21.22.1 Wed Nov 28 23:58:35 2012 +++ src/lib/libpthread/pthread_specific.c Sun Dec 2 18:47:36 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_specific.c,v 1.21.22.1 2012/11/28 23:58:35 riz Exp $ */ +/* $NetBSD: pthread_specific.c,v 1.21.22.2 2012/12/02 18:47:36 riz Exp $ */ /*- * Copyright (c) 2001, 2007 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_specific.c,v 1.21.22.1 2012/11/28 23:58:35 riz Exp $"); +__RCSID("$NetBSD: pthread_specific.c,v 1.21.22.2 2012/12/02 18:47:36 riz Exp $"); /* Functions and structures dealing with thread-specific data */ @@ -55,14 +55,18 @@ pthread_setspecific(pthread_key_t key, c * and return it from functions that are const void *, without * generating a warning. */ - return pthread__add_specific(self, key, value); + /*LINTED const cast*/ + self->pt_specific[key] = (void *) value; + self->pt_havespecific = 1; + + return 0; } void * pthread_getspecific(pthread_key_t key) { - return pthread__self()->pt_specific[key].pts_value; + return pthread__self()->pt_specific[key]; } unsigned int Index: src/lib/libpthread/pthread_tsd.c diff -u src/lib/libpthread/pthread_tsd.c:1.7.24.1 src/lib/libpthread/pthread_tsd.c:1.7.24.2 --- src/lib/libpthread/pthread_tsd.c:1.7.24.1 Wed Nov 28 23:58:35 2012 +++ src/lib/libpthread/pthread_tsd.c Sun Dec 2 18:47:36 2012 @@ -1,11 +1,11 @@ -/* $NetBSD: pthread_tsd.c,v 1.7.24.1 2012/11/28 23:58:35 riz Exp $ */ +/* $NetBSD: pthread_tsd.c,v 1.7.24.2 2012/12/02 18:47:36 riz Exp $ */ /*- * Copyright (c) 2001, 2007 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation - * by Nathan J. Williams, by Andrew Doran, and by Christos Zoulas. + * by Nathan J. Williams, and by Andrew Doran. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_tsd.c,v 1.7.24.1 2012/11/28 23:58:35 riz Exp $"); +__RCSID("$NetBSD: pthread_tsd.c,v 1.7.24.2 2012/12/02 18:47:36 riz Exp $"); /* Functions and structures dealing with thread-specific data */ #include <errno.h> @@ -38,23 +38,14 @@ __RCSID("$NetBSD: pthread_tsd.c,v 1.7.24 #include "pthread.h" #include "pthread_int.h" - static pthread_mutex_t tsd_mutex = PTHREAD_MUTEX_INITIALIZER; static int nextkey; - -PTQ_HEAD(pthread__tsd_list, pt_specific) - pthread__tsd_list[PTHREAD_KEYS_MAX]; +void *pthread__tsd_alloc[PTHREAD_KEYS_MAX]; void (*pthread__tsd_destructors[PTHREAD_KEYS_MAX])(void *); __strong_alias(__libc_thr_keycreate,pthread_key_create) __strong_alias(__libc_thr_keydelete,pthread_key_delete) -static void -/*ARGSUSED*/ -null_destructor(void *p) -{ -} - int pthread_key_create(pthread_key_t *key, void (*destructor)(void *)) { @@ -63,14 +54,10 @@ pthread_key_create(pthread_key_t *key, v /* Get a lock on the allocation list */ pthread_mutex_lock(&tsd_mutex); - /* Find an available slot: - * The condition for an available slot is one with the destructor - * not being NULL. If the desired destructor is NULL we set it to - * our own internal destructor to satisfy the non NULL condition. - */ + /* Find an available slot */ /* 1. Search from "nextkey" to the end of the list. */ for (i = nextkey; i < PTHREAD_KEYS_MAX; i++) - if (pthread__tsd_destructors[i] == NULL) + if (pthread__tsd_alloc[i] == NULL) break; if (i == PTHREAD_KEYS_MAX) { @@ -78,7 +65,7 @@ pthread_key_create(pthread_key_t *key, v * of the list back to "nextkey". */ for (i = 0; i < nextkey; i++) - if (pthread__tsd_destructors[i] == NULL) + if (pthread__tsd_alloc[i] == NULL) break; if (i == nextkey) { @@ -91,60 +78,15 @@ pthread_key_create(pthread_key_t *key, v } /* Got one. */ - pthread__assert(PTQ_EMPTY(&pthread__tsd_list[i])); - pthread__tsd_destructors[i] = destructor ? destructor : null_destructor; - + pthread__tsd_alloc[i] = (void *)__builtin_return_address(0); nextkey = (i + 1) % PTHREAD_KEYS_MAX; + pthread__tsd_destructors[i] = destructor; pthread_mutex_unlock(&tsd_mutex); *key = i; return 0; } -/* - * Each thread holds an array of PTHREAD_KEYS_MAX pt_specific list - * elements. When an element is used it is inserted into the appropriate - * key bucket of pthread__tsd_list. This means that ptqe_prev == NULL, - * means that the element is not threaded, ptqe_prev != NULL it is - * already part of the list. When we set to a NULL value we delete from the - * list if it was in the list, and when we set to non-NULL value, we insert - * in the list if it was not already there. - * - * We keep this global array of lists of threads that have called - * pthread_set_specific with non-null values, for each key so that - * we don't have to check all threads for non-NULL values in - * pthread_key_destroy - * - * We could keep an accounting of the number of specific used - * entries per thread, so that we can update pt_havespecific when we delete - * the last one, but we don't bother for now - */ -int -pthread__add_specific(pthread_t self, pthread_key_t key, const void *value) -{ - struct pt_specific *pt; - - pthread__assert(key >= 0 && key < PTHREAD_KEYS_MAX); - - pthread_mutex_lock(&tsd_mutex); - pthread__assert(pthread__tsd_destructors[key] != NULL); - pt = &self->pt_specific[key]; - self->pt_havespecific = 1; - if (value) { - if (pt->pts_next.ptqe_prev == NULL) - PTQ_INSERT_HEAD(&pthread__tsd_list[key], pt, pts_next); - } else { - if (pt->pts_next.ptqe_prev != NULL) { - PTQ_REMOVE(&pthread__tsd_list[key], pt, pts_next); - pt->pts_next.ptqe_prev = NULL; - } - } - pt->pts_value = __UNCONST(value); - pthread_mutex_unlock(&tsd_mutex); - - return 0; -} - int pthread_key_delete(pthread_key_t key) { @@ -161,8 +103,7 @@ pthread_key_delete(pthread_key_t key) * Subject: Re: TSD key reusing issue * Message-ID: <u97d8.29$fl6....@news.cpqcorp.net> * Date: Thu, 21 Feb 2002 09:06:17 -0500 - * http://groups.google.com/groups?\ - * hl=en&selm=u97d8.29%24fL6.200%40news.cpqcorp.net + * http://groups.google.com/groups?hl=en&selm=u97d8.29%24fL6.200%40news.cpqcorp.net * * Given: * @@ -216,31 +157,8 @@ pthread_key_delete(pthread_key_t key) * apply in general, just to this implementation. */ - /* - * We do option 3; we find the list of all pt_specific structures - * threaded on the key we are deleting, unthread them, and set the - * pointer to NULL. Finally we unthread the entry, freeing it for - * further use. - * - * We don't call the destructor here, it is the responsibility - * of the application to cleanup the storage: - * http://pubs.opengroup.org/onlinepubs/9699919799/functions/\ - * pthread_key_delete.html - */ - struct pt_specific *pt; - - pthread__assert(key >= 0 && key < PTHREAD_KEYS_MAX); - + /* For the momemt, we're going with option 1. */ pthread_mutex_lock(&tsd_mutex); - - pthread__assert(pthread__tsd_destructors[key] != NULL); - - while ((pt = PTQ_FIRST(&pthread__tsd_list[key])) != NULL) { - PTQ_REMOVE(&pthread__tsd_list[key], pt, pts_next); - pt->pts_value = NULL; - pt->pts_next.ptqe_prev = NULL; - } - pthread__tsd_destructors[key] = NULL; pthread_mutex_unlock(&tsd_mutex); @@ -288,24 +206,17 @@ pthread__destroy_tsd(pthread_t self) do { done = 1; for (i = 0; i < PTHREAD_KEYS_MAX; i++) { - struct pt_specific *pt = &self->pt_specific[i]; - if (pt->pts_next.ptqe_prev == NULL) - continue; - pthread_mutex_lock(&tsd_mutex); - - if (pt->pts_next.ptqe_prev != NULL) { - PTQ_REMOVE(&pthread__tsd_list[i], pt, pts_next); - val = pt->pts_value; - pt->pts_value = NULL; - pt->pts_next.ptqe_prev = NULL; + if (self->pt_specific[i] != NULL) { + pthread_mutex_lock(&tsd_mutex); destructor = pthread__tsd_destructors[i]; - } else - destructor = NULL; - - pthread_mutex_unlock(&tsd_mutex); - if (destructor != NULL) { - done = 0; - (*destructor)(val); + pthread_mutex_unlock(&tsd_mutex); + if (destructor != NULL) { + done = 0; + val = self->pt_specific[i]; + /* See above */ + self->pt_specific[i] = NULL; + (*destructor)(val); + } } } } while (!done && iterations--);