summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libc')
-rw-r--r--usr/src/lib/libc/inc/libc.h1
-rw-r--r--usr/src/lib/libc/inc/mtlib.h3
-rw-r--r--usr/src/lib/libc/inc/priv_private.h7
-rw-r--r--usr/src/lib/libc/inc/synonyms.h2
-rw-r--r--usr/src/lib/libc/inc/thr_uberdata.h6
-rw-r--r--usr/src/lib/libc/port/gen/crypt.c9
-rw-r--r--usr/src/lib/libc/port/gen/getauxv.c33
-rw-r--r--usr/src/lib/libc/port/gen/getenv.c44
-rw-r--r--usr/src/lib/libc/port/gen/nss_common.c38
-rw-r--r--usr/src/lib/libc/port/gen/nss_dbdefs.c6
-rw-r--r--usr/src/lib/libc/port/gen/privlib.c85
-rw-r--r--usr/src/lib/libc/port/gen/tsdalloc.c26
-rw-r--r--usr/src/lib/libc/port/mapfile-vers4
-rw-r--r--usr/src/lib/libc/port/threads/pthread.c4
-rw-r--r--usr/src/lib/libc/port/threads/rtsched.c4
-rw-r--r--usr/src/lib/libc/port/threads/tdb_agent.c12
-rw-r--r--usr/src/lib/libc/port/threads/tsd.c49
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