diff options
Diffstat (limited to 'usr/src/lib/libc')
-rw-r--r-- | usr/src/lib/libc/inc/libc.h | 1 | ||||
-rw-r--r-- | usr/src/lib/libc/inc/mtlib.h | 3 | ||||
-rw-r--r-- | usr/src/lib/libc/inc/priv_private.h | 7 | ||||
-rw-r--r-- | usr/src/lib/libc/inc/synonyms.h | 2 | ||||
-rw-r--r-- | usr/src/lib/libc/inc/thr_uberdata.h | 6 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/crypt.c | 9 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/getauxv.c | 33 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/getenv.c | 44 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/nss_common.c | 38 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/nss_dbdefs.c | 6 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/privlib.c | 85 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/tsdalloc.c | 26 | ||||
-rw-r--r-- | usr/src/lib/libc/port/mapfile-vers | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/pthread.c | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/rtsched.c | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/tdb_agent.c | 12 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/tsd.c | 49 |
17 files changed, 207 insertions, 126 deletions
diff --git a/usr/src/lib/libc/inc/libc.h b/usr/src/lib/libc/inc/libc.h index 65f68f7e2c..020c311eab 100644 --- a/usr/src/lib/libc/inc/libc.h +++ b/usr/src/lib/libc/inc/libc.h @@ -80,6 +80,7 @@ extern int _sigwait(sigset_t *); extern int _thr_getspecific(thread_key_t key, void **valuep); extern int _thr_setspecific(unsigned int key, void *value); extern int _thr_keycreate(thread_key_t *pkey, void (*destructor)(void *)); +extern int _thr_keycreate_once(thread_key_t *pkey, void (*destructor)(void *)); extern void *_pthread_getspecific(thread_key_t); extern int _pollsys(struct pollfd *, nfds_t, const timespec_t *, const sigset_t *); diff --git a/usr/src/lib/libc/inc/mtlib.h b/usr/src/lib/libc/inc/mtlib.h index 629b61ee9b..5d3fbf1451 100644 --- a/usr/src/lib/libc/inc/mtlib.h +++ b/usr/src/lib/libc/inc/mtlib.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -104,6 +104,7 @@ extern int _thr_kill(thread_t, int); extern int _thr_create(void *, size_t, void *(*)(void *), void *, long, thread_t *); extern int _thr_keycreate(thread_key_t *, void (*)(void *)); +extern int _thr_keycreate_once(thread_key_t *, void (*)(void *)); extern int _thr_setspecific(thread_key_t, void *); extern int _thr_getspecific(thread_key_t, void **); extern void *_pthread_getspecific(thread_key_t); diff --git a/usr/src/lib/libc/inc/priv_private.h b/usr/src/lib/libc/inc/priv_private.h index 573a3272c8..e33d22dc03 100644 --- a/usr/src/lib/libc/inc/priv_private.h +++ b/usr/src/lib/libc/inc/priv_private.h @@ -18,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -40,8 +41,8 @@ extern "C" { #endif -#define LOADPRIVDATA(d) if ((d = privdata) == NULL) d = __priv_getdata() -#define GETPRIVDATA() (privdata == NULL ? __priv_getdata() : privdata) +#define LOADPRIVDATA(d) d = __priv_getdata() +#define GETPRIVDATA() __priv_getdata() #define LOCKPRIVDATA() { \ /* Data already allocated */ \ (void) lock_data(); \ diff --git a/usr/src/lib/libc/inc/synonyms.h b/usr/src/lib/libc/inc/synonyms.h index 209d7f6063..b6782b3a59 100644 --- a/usr/src/lib/libc/inc/synonyms.h +++ b/usr/src/lib/libc/inc/synonyms.h @@ -762,6 +762,7 @@ extern "C" { #define pthread_getspecific _pthread_getspecific #define pthread_join _pthread_join #define pthread_key_create _pthread_key_create +#define pthread_key_create_once_np _pthread_key_create_once_np #define pthread_key_delete _pthread_key_delete #define pthread_kill _pthread_kill #define pthread_mutexattr_destroy _pthread_mutexattr_destroy @@ -1038,6 +1039,7 @@ extern "C" { #define thr_getstate _thr_getstate #define thr_join _thr_join #define thr_keycreate _thr_keycreate +#define thr_keycreate_once _thr_keycreate_once #define thr_kill _thr_kill #define thr_main _thr_main #define thr_min_stack _thr_min_stack diff --git a/usr/src/lib/libc/inc/thr_uberdata.h b/usr/src/lib/libc/inc/thr_uberdata.h index c03fb3fdcc..4b00040fcf 100644 --- a/usr/src/lib/libc/inc/thr_uberdata.h +++ b/usr/src/lib/libc/inc/thr_uberdata.h @@ -1289,6 +1289,11 @@ extern int __rwlock_init(rwlock_t *, int, void *); extern int rw_read_is_held(rwlock_t *); extern int rw_write_is_held(rwlock_t *); +extern void _membar_enter(void); +extern void _membar_exit(void); +extern void _membar_producer(void); +extern void _membar_consumer(void); + extern int _thr_continue(thread_t); extern int _thr_create(void *, size_t, void *(*)(void *), void *, long, thread_t *); @@ -1298,6 +1303,7 @@ extern int _thr_getprio(thread_t, int *); extern int _thr_getspecific(thread_key_t, void **); extern int _thr_join(thread_t, thread_t *, void **); extern int _thr_keycreate(thread_key_t *, PFrV); +extern int _thr_keycreate_once(thread_key_t *, PFrV); extern int _thr_key_delete(thread_key_t); extern int _thr_main(void); extern thread_t _thr_self(void); diff --git a/usr/src/lib/libc/port/gen/crypt.c b/usr/src/lib/libc/port/gen/crypt.c index 52286d4822..ee77dea287 100644 --- a/usr/src/lib/libc/port/gen/crypt.c +++ b/usr/src/lib/libc/port/gen/crypt.c @@ -18,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -46,6 +47,7 @@ #include <fcntl.h> #include <syslog.h> #include <unistd.h> +#include <atomic.h> #include <crypt.h> #include <libc.h> @@ -903,8 +905,10 @@ allocate_KS(void) int failed; int assigned; - if (KS != NULL) /* already allocated */ + if (KS != NULL) { /* already allocated */ + membar_consumer(); return (0); + } ks = calloc(16, 48 * sizeof (char)); failed = 0; @@ -913,6 +917,7 @@ allocate_KS(void) assigned = 0; } else { assigned = 1; + membar_producer(); if ((KS = ks) == NULL) /* calloc() failed */ failed = 1; } diff --git a/usr/src/lib/libc/port/gen/getauxv.c b/usr/src/lib/libc/port/gen/getauxv.c index c32fefdfb6..270c21f955 100644 --- a/usr/src/lib/libc/port/gen/getauxv.c +++ b/usr/src/lib/libc/port/gen/getauxv.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,6 +37,7 @@ #include <mtlib.h> #include <thread.h> #include <synch.h> +#include <atomic.h> static mutex_t auxlock = DEFAULTMUTEX; @@ -57,34 +57,37 @@ _getaux(int type) * passed to the process at exec(2). Only do this once. */ if (auxb == NULL) { - struct stat statb; - int fd; - lmutex_lock(&auxlock); - if (auxb == NULL) { + struct stat statb; + auxv_t *buf = NULL; + int fd; + if ((fd = open("/proc/self/auxv", O_RDONLY)) != -1 && fstat(fd, &statb) != -1) - auxb = libc_malloc( + buf = libc_malloc( statb.st_size + sizeof (auxv_t)); - if (auxb != NULL) { - i = read(fd, auxb, statb.st_size); + if (buf != NULL) { + i = read(fd, buf, statb.st_size); if (i != -1) { nauxv = i / sizeof (auxv_t); - auxb[nauxv].a_type = AT_NULL; + buf[nauxv].a_type = AT_NULL; } else { - libc_free(auxb); - auxb = NULL; + libc_free(buf); + buf = NULL; } } if (fd != -1) (void) close(fd); - } + membar_producer(); + auxb = buf; + } lmutex_unlock(&auxlock); } + membar_consumer(); /* * Scan the auxiliary entries looking for the required type. diff --git a/usr/src/lib/libc/port/gen/getenv.c b/usr/src/lib/libc/port/gen/getenv.c index f5bc6d7290..6329a048d8 100644 --- a/usr/src/lib/libc/port/gen/getenv.c +++ b/usr/src/lib/libc/port/gen/getenv.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -131,26 +131,29 @@ envsize(const char **e) static void initenv() { - lmutex_lock(&update_lock); if ((my_environ != environ) || !initenv_done) { - if (!initenv_done) { - /* Call the NLSPATH janitor in. */ - clean_env(); + lmutex_lock(&update_lock); + if ((my_environ != environ) || !initenv_done) { + if (!initenv_done) { + /* Call the NLSPATH janitor in. */ + clean_env(); - /* Pacify leak detectors in normal operation. */ - orig_environ = environ; + /* Pacify leak detectors in normal operation. */ + orig_environ = environ; #ifdef __lint - my_environ = orig_environ; + my_environ = orig_environ; #endif + } + my_environ = environ; + environ_base = my_environ; + environ_size = envsize(environ_base); + membar_producer(); initenv_done = 1; } - - my_environ = environ; - environ_base = my_environ; - environ_size = envsize(environ_base); + lmutex_unlock(&update_lock); } - lmutex_unlock(&update_lock); + membar_consumer(); } /* @@ -220,8 +223,7 @@ addtoenv(char *string, int overwrite) int new_size; int old_gen; - if ((my_environ != environ) || !initenv_done) - initenv(); + initenv(); lmutex_lock(&update_lock); @@ -419,8 +421,7 @@ unsetenv(const char *name) return (-1); } - if ((my_environ != environ) || !initenv_done) - initenv(); + initenv(); lmutex_lock(&update_lock); @@ -455,8 +456,7 @@ getenv(const char *name) { char *value; - if (!initenv_done) - initenv(); + initenv(); if (findenv(environ, name, 1, &value) != NULL) return (value); diff --git a/usr/src/lib/libc/port/gen/nss_common.c b/usr/src/lib/libc/port/gen/nss_common.c index 2f4349770f..d21f635d42 100644 --- a/usr/src/lib/libc/port/gen/nss_common.c +++ b/usr/src/lib/libc/port/gen/nss_common.c @@ -18,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,6 +39,7 @@ #include "synonyms.h" #include <mtlib.h> #include <dlfcn.h> +#include <atomic.h> #define __NSS_PRIVATE_INTERFACE #include "nsswitch_priv.h" @@ -252,7 +254,7 @@ typedef struct nss_cfglist { #define NSS_CFG_INCR 16 -static nss_cfglist_t *nss_cfg = (nss_cfglist_t *)NULL; +static nss_cfglist_t *nss_cfg = NULL; static int nss_cfgcount = 0; static int nss_cfgmax = 0; static mutex_t nss_cfglock = DEFAULTMUTEX; @@ -303,39 +305,47 @@ nss_cfgcn_cmp(const char *cfgname, const char *compname) static int nss_cfg_init() { + nss_cfglist_t *cfg; int i; /* First time caller? */ - if (nss_cfg != NULL) + if (nss_cfg != NULL) { + membar_consumer(); return (0); + } /* Initialize internal tables */ lmutex_lock(&nss_cfglock); if (nss_cfg != NULL) { lmutex_unlock(&nss_cfglock); + membar_consumer(); return (0); } - nss_cfg = (nss_cfglist_t *)libc_malloc(NSS_CFG_INCR * - sizeof (nss_cfglist_t)); - if (nss_cfg == (nss_cfglist_t *)NULL) { + cfg = libc_malloc(NSS_CFG_INCR * sizeof (nss_cfglist_t)); + if (cfg == NULL) { errno = ENOMEM; lmutex_unlock(&nss_cfglock); return (-1); } - nss_cfgmax = NSS_CFG_INCR; - for (i = 0; i < nss_cfgmax; i++) { - nss_cfg[i].list = (nss_cfgparam_t *)libc_malloc(NSS_CFG_INCR * - sizeof (nss_cfgparam_t)); - if (nss_cfg[i].list == (nss_cfgparam_t *)NULL) { + for (i = 0; i < NSS_CFG_INCR; i++) { + cfg[i].list = libc_malloc( + NSS_CFG_INCR * sizeof (nss_cfgparam_t)); + if (cfg[i].list == NULL) { + while (--i >= 0) + libc_free(cfg[i].list); + libc_free(cfg); errno = ENOMEM; lmutex_unlock(&nss_cfglock); return (-1); } - nss_cfg[i].max = NSS_CFG_INCR; + cfg[i].max = NSS_CFG_INCR; } + nss_cfgmax = NSS_CFG_INCR; + membar_producer(); + nss_cfg = cfg; + lmutex_unlock(&nss_cfglock); /* Initialize Policy Engine values */ - lmutex_unlock(&nss_cfglock); if (nss_cfg_policy_init() < 0) { return (-1); } @@ -352,7 +362,7 @@ nss_cfgcomp_get(char *name, int add) size_t nsize; /* Make sure system is init'd */ - if (nss_cfg == NULL && nss_cfg_init() < 0) + if (nss_cfg_init() < 0) return ((nss_cfglist_t *)NULL); /* and check component:name validity */ diff --git a/usr/src/lib/libc/port/gen/nss_dbdefs.c b/usr/src/lib/libc/port/gen/nss_dbdefs.c index 61a2bbf6dd..f22276c769 100644 --- a/usr/src/lib/libc/port/gen/nss_dbdefs.c +++ b/usr/src/lib/libc/port/gen/nss_dbdefs.c @@ -18,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,6 +37,7 @@ #include <dlfcn.h> #include <link.h> #include <thread.h> +#include <atomic.h> /* headers for key2str/str2key routines */ #include <sys/ethernet.h> #include <exec_attr.h> @@ -319,10 +321,12 @@ nss_dbop_search(const char *name, uint32_t dbop) } getXbyYdbopHASH[hval] = i | DBOP_HASH_TAG; } + membar_producer(); getXbyYdbop_hashed = 1; } lmutex_unlock(&getXbydbop_hash_lock); } + membar_consumer(); cp = name; hval = 0; while (*cp) { diff --git a/usr/src/lib/libc/port/gen/privlib.c b/usr/src/lib/libc/port/gen/privlib.c index 76586f514e..f7d289aa25 100644 --- a/usr/src/lib/libc/port/gen/privlib.c +++ b/usr/src/lib/libc/port/gen/privlib.c @@ -18,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -62,6 +63,7 @@ #include <strings.h> #include <synch.h> #include <alloca.h> +#include <atomic.h> #include <sys/ucred.h> #include <sys/procfs.h> #include <sys/param.h> @@ -233,7 +235,7 @@ __priv_free_info(priv_data_t *d) int lock_data(void) { - if (privdata == NULL && __priv_getdata() == NULL) + if (__priv_getdata() == NULL) return (-1); lmutex_lock(&pd_lock); @@ -310,54 +312,59 @@ static priv_set_t *__priv_allocset(priv_data_t *); priv_data_t * __priv_getdata(void) { - lmutex_lock(&pd_lock); if (privdata == NULL) { - priv_data_t *tmp; - priv_impl_info_t *ip; - size_t size = sizeof (priv_impl_info_t) + 2048; - size_t realsize; - priv_impl_info_t *aip = alloca(size); - - if (getprivinfo(aip, size) != 0) - goto out; + lmutex_lock(&pd_lock); + if (privdata == NULL) { + priv_data_t *tmp; + priv_impl_info_t *ip; + size_t size = sizeof (priv_impl_info_t) + 2048; + size_t realsize; + priv_impl_info_t *aip = alloca(size); + + if (getprivinfo(aip, size) != 0) + goto out; - realsize = PRIV_IMPL_INFO_SIZE(aip); + realsize = PRIV_IMPL_INFO_SIZE(aip); - ip = libc_malloc(realsize); + ip = libc_malloc(realsize); - if (ip == NULL) - goto out; + if (ip == NULL) + goto out; - if (realsize <= size) { - (void) memcpy(ip, aip, realsize); - } else if (getprivinfo(ip, realsize) != 0) { - libc_free(ip); - goto out; - } + if (realsize <= size) { + (void) memcpy(ip, aip, realsize); + } else if (getprivinfo(ip, realsize) != 0) { + libc_free(ip); + goto out; + } - if ((tmp = __priv_parse_info(ip)) == NULL) { - libc_free(ip); - goto out; - } + if ((tmp = __priv_parse_info(ip)) == NULL) { + libc_free(ip); + goto out; + } - /* Allocate the zoneset just once, here */ - tmp->pd_zoneset = __priv_allocset(tmp); - if (tmp->pd_zoneset == NULL) - goto clean; + /* Allocate the zoneset just once, here */ + tmp->pd_zoneset = __priv_allocset(tmp); + if (tmp->pd_zoneset == NULL) + goto clean; - if (zone_getattr(getzoneid(), ZONE_ATTR_PRIVSET, - tmp->pd_zoneset, tmp->pd_setsize) == tmp->pd_setsize) { - privdata = tmp; - goto out; - } + if (zone_getattr(getzoneid(), ZONE_ATTR_PRIVSET, + tmp->pd_zoneset, tmp->pd_setsize) + == tmp->pd_setsize) { + membar_producer(); + privdata = tmp; + goto out; + } - priv_freeset(tmp->pd_zoneset); + priv_freeset(tmp->pd_zoneset); clean: - __priv_free_info(tmp); - libc_free(ip); - } + __priv_free_info(tmp); + libc_free(ip); + } out: - lmutex_unlock(&pd_lock); + lmutex_unlock(&pd_lock); + } + membar_consumer(); return (privdata); } diff --git a/usr/src/lib/libc/port/gen/tsdalloc.c b/usr/src/lib/libc/port/gen/tsdalloc.c index c6549402b5..1da9dc01e2 100644 --- a/usr/src/lib/libc/port/gen/tsdalloc.c +++ b/usr/src/lib/libc/port/gen/tsdalloc.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -65,9 +65,7 @@ _free_tsdbuf(void *ptr) void * tsdalloc(__tsd_item_t n, size_t size, pfrv_t destructor) { - static int once_key = 0; - static mutex_t key_lock = DEFAULTMUTEX; - static thread_key_t key; + static thread_key_t key = THR_ONCE_KEY; tsdent_t *loc; void *p; int error; @@ -77,17 +75,9 @@ tsdalloc(__tsd_item_t n, size_t size, pfrv_t destructor) return (NULL); } - if (once_key == 0) { - lmutex_lock(&key_lock); - if (once_key == 0) { - if ((error = _thr_keycreate(&key, _free_tsdbuf)) != 0) { - lmutex_unlock(&key_lock); - errno = error; - return (NULL); - } - once_key = 1; - } - lmutex_unlock(&key_lock); + if ((error = _thr_keycreate_once(&key, _free_tsdbuf)) != 0) { + errno = error; + return (NULL); } if ((loc = _pthread_getspecific(key)) != NULL) { diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index 0475f99826..7168e3d575 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -78,6 +78,7 @@ SUNW_1.23 { # SunOS 5.11 (Solaris 11) mq_unlink; nanosleep; posix_fallocate; + pthread_key_create_once_np; _renameat; sched_getparam; sched_get_priority_max; @@ -104,6 +105,7 @@ SUNW_1.23 { # SunOS 5.11 (Solaris 11) sigtimedwait; sigwaitinfo; strnlen; + thr_keycreate_once; timer_create; timer_delete; timer_getoverrun; @@ -1857,6 +1859,7 @@ SUNWprivate_1.1 { _pthread_getspecific; _pthread_join; _pthread_key_create; + _pthread_key_create_once_np; _pthread_key_delete; _pthread_kill; __pthread_min_stack; @@ -2087,6 +2090,7 @@ SUNWprivate_1.1 { _thr_getstate; _thr_join; _thr_keycreate; + _thr_keycreate_once; _thr_key_delete; _thr_kill; _thr_main; diff --git a/usr/src/lib/libc/port/threads/pthread.c b/usr/src/lib/libc/port/threads/pthread.c index d8c324a7d9..baaadae7bd 100644 --- a/usr/src/lib/libc/port/threads/pthread.c +++ b/usr/src/lib/libc/port/threads/pthread.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -145,10 +145,12 @@ _pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) &once->mlock); (*init_routine)(); pthread_cleanup_pop(0); + _membar_producer(); once->once_flag = PTHREAD_ONCE_DONE; } (void) _private_mutex_unlock(&once->mlock); } + _membar_consumer(); return (0); } diff --git a/usr/src/lib/libc/port/threads/rtsched.c b/usr/src/lib/libc/port/threads/rtsched.c index a85118dc5c..c76e0b722a 100644 --- a/usr/src/lib/libc/port/threads/rtsched.c +++ b/usr/src/lib/libc/port/threads/rtsched.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -112,10 +112,12 @@ _validate_rt_prio(int policy, int pri) lmutex_lock(&prio_lock); if (!initialized) { /* do this only once */ _init_rt_prio_ranges(); + _membar_producer(); initialized = 1; } lmutex_unlock(&prio_lock); } + _membar_consumer(); switch (policy) { case SCHED_FIFO: diff --git a/usr/src/lib/libc/port/threads/tdb_agent.c b/usr/src/lib/libc/port/threads/tdb_agent.c index 938766fa32..bd9d7cf187 100644 --- a/usr/src/lib/libc/port/threads/tdb_agent.c +++ b/usr/src/lib/libc/port/threads/tdb_agent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -217,9 +217,10 @@ initialize_sync_hash() addr_hash[tdb_addr_hash(&udp->tdb_hash_lock)] = (uintptr_t)&udp->tdb_hash_lock_stats; + tdbp->tdb_register_count = 1; /* assign to tdb_sync_addr_hash only after fully initialized */ + _membar_producer(); tdbp->tdb_sync_addr_hash = addr_hash; - tdbp->tdb_register_count = 1; lmutex_unlock(&udp->tdb_hash_lock); } @@ -269,6 +270,7 @@ tdb_sync_obj_register(void *addr, int *new) goto out; } } + _membar_consumer(); sapp = &tdbp->tdb_sync_addr_hash[tdb_addr_hash(addr)]; if (udp->uberflags.uf_tdb_register_sync == REGISTER_SYNC_ON) { diff --git a/usr/src/lib/libc/port/threads/tsd.c b/usr/src/lib/libc/port/threads/tsd.c index 11484f6763..ac89be862d 100644 --- a/usr/src/lib/libc/port/threads/tsd.c +++ b/usr/src/lib/libc/port/threads/tsd.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -128,6 +128,47 @@ _thr_keycreate(thread_key_t *pkey, void (*destructor)(void *)) return (0); } +/* + * Same as _thr_keycreate(), above, except that the key creation + * is performed only once. This relies upon the fact that a key + * value of THR_ONCE_KEY is invalid, and requires that the key be + * allocated with a value of THR_ONCE_KEY before calling here. + * THR_ONCE_KEY and PTHREAD_ONCE_KEY_NP, defined in <thread.h> + * and <pthread.h> respectively, must have the same value. + * Example: + * + * static pthread_key_t key = PTHREAD_ONCE_KEY_NP; + * ... + * pthread_key_create_once_np(&key, destructor); + */ +#pragma weak pthread_key_create_once_np = _thr_keycreate_once +#pragma weak _pthread_key_create_once_np = _thr_keycreate_once +#pragma weak thr_keycreate_once = _thr_keycreate_once +int +_thr_keycreate_once(thread_key_t *keyp, void (*destructor)(void *)) +{ + static mutex_t key_lock = DEFAULTMUTEX; + thread_key_t key; + int error; + + if (*keyp == THR_ONCE_KEY) { + lmutex_lock(&key_lock); + if (*keyp == THR_ONCE_KEY) { + error = _thr_keycreate(&key, destructor); + if (error) { + lmutex_unlock(&key_lock); + return (error); + } + _membar_producer(); + *keyp = key; + } + lmutex_unlock(&key_lock); + } + _membar_consumer(); + + return (0); +} + #pragma weak pthread_key_delete = _thr_key_delete #pragma weak _pthread_key_delete = _thr_key_delete int |