1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1993-2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "mt.h" 30 #include <stdlib.h> 31 32 void * 33 thr_get_storage(pthread_key_t *keyp, size_t size, void (*destructor)(void *)) 34 { 35 extern mutex_t tsd_lock; 36 pthread_key_t key; 37 void *addr; 38 39 if ((key = *keyp) == 0) { 40 mutex_lock(&tsd_lock); 41 if ((key = *keyp) == 0) { 42 if (pthread_key_create(keyp, destructor) != 0) { 43 mutex_unlock(&tsd_lock); 44 return (NULL); 45 } 46 key = *keyp; 47 } 48 mutex_unlock(&tsd_lock); 49 } 50 51 addr = pthread_getspecific(key); 52 if (addr == NULL && size != 0) { 53 addr = calloc(1, size); 54 if (addr != NULL && pthread_setspecific(key, addr) != 0) { 55 free(addr); 56 return (NULL); 57 } 58 } 59 60 return (addr); 61 } 62 63 /* 64 * sig_mutex_lock() and sig_mutex_unlock() are the same 65 * as mutex_lock() and mutex_unlock() except that all 66 * signals are deferred while the lock is held. Likewise 67 * for sig_rw_rdlock(), sig_rw_wrlock() and sig_rw_unlock(). 68 * 69 * _sigoff() and _sigon() are consolidation-private 70 * interfaces in libc that defer and enable signals. 71 * Calls to these can nest but must be balanced, so 72 * nested calls to these functions work properly. 73 */ 74 75 void 76 sig_mutex_lock(mutex_t *mp) 77 { 78 _sigoff(); 79 (void) mutex_lock(mp); 80 } 81 82 void 83 sig_mutex_unlock(mutex_t *mp) 84 { 85 (void) mutex_unlock(mp); 86 _sigon(); 87 } 88 89 void 90 sig_rw_rdlock(rwlock_t *rwlp) 91 { 92 _sigoff(); 93 (void) rw_rdlock(rwlp); 94 } 95 96 void 97 sig_rw_wrlock(rwlock_t *rwlp) 98 { 99 _sigoff(); 100 (void) rw_wrlock(rwlp); 101 } 102 103 void 104 sig_rw_unlock(rwlock_t *rwlp) 105 { 106 (void) rw_unlock(rwlp); 107 _sigon(); 108 } 109