1 /* 2 * Copyright (c) 2006, David Xu <davidxu@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * $FreeBSD: src/lib/libpthread/thread/thr_rtld.c,v 1.5 2003/11/05 18:19:24 deischen Exp $ 27 */ 28 29 #include <machine/tls.h> 30 #include <stdlib.h> 31 #include <pthread.h> 32 33 #include "rtld_lock.h" 34 #include "thr_private.h" 35 36 static int _thr_rtld_clr_flag(int); 37 static void *_thr_rtld_lock_create(void); 38 static void _thr_rtld_lock_destroy(void *); 39 static void _thr_rtld_lock_release(void *); 40 static void _thr_rtld_rlock_acquire(void *); 41 static int _thr_rtld_set_flag(int); 42 static void _thr_rtld_wlock_acquire(void *); 43 44 static void * 45 _thr_rtld_lock_create(void) 46 { 47 pthread_rwlock_t prwlock; 48 if (_pthread_rwlock_init(&prwlock, NULL)) 49 return (NULL); 50 return (prwlock); 51 } 52 53 static void 54 _thr_rtld_lock_destroy(void *lock) 55 { 56 pthread_rwlock_t prwlock; 57 58 prwlock = (pthread_rwlock_t)lock; 59 if (prwlock != NULL) 60 _pthread_rwlock_destroy(&prwlock); 61 } 62 63 static void 64 _thr_rtld_rlock_acquire(void *lock) 65 { 66 pthread_rwlock_t prwlock; 67 68 prwlock = (pthread_rwlock_t)lock; 69 _thr_rwlock_rdlock(&prwlock); 70 } 71 72 static void 73 _thr_rtld_wlock_acquire(void *lock) 74 { 75 pthread_rwlock_t prwlock; 76 77 prwlock = (pthread_rwlock_t)lock; 78 _thr_rwlock_wrlock(&prwlock); 79 } 80 81 static void 82 _thr_rtld_lock_release(void *lock) 83 { 84 pthread_rwlock_t prwlock; 85 86 prwlock = (pthread_rwlock_t)lock; 87 _thr_rwlock_unlock(&prwlock); 88 } 89 90 91 static int 92 _thr_rtld_set_flag(int mask) 93 { 94 struct pthread *curthread; 95 int bits; 96 97 curthread = tls_get_curthread(); 98 if (curthread != NULL) { 99 bits = curthread->rtld_bits; 100 curthread->rtld_bits |= mask; 101 } else { 102 bits = 0; 103 PANIC("No current thread in rtld call"); 104 } 105 106 return (bits); 107 } 108 109 static int 110 _thr_rtld_clr_flag(int mask) 111 { 112 struct pthread *curthread; 113 int bits; 114 115 curthread = tls_get_curthread(); 116 if (curthread != NULL) { 117 bits = curthread->rtld_bits; 118 curthread->rtld_bits &= ~mask; 119 } else { 120 bits = 0; 121 PANIC("No current thread in rtld call"); 122 } 123 return (bits); 124 } 125 126 void 127 _thr_rtld_init(void) 128 { 129 struct RtldLockInfo li; 130 131 li.lock_create = _thr_rtld_lock_create; 132 li.lock_destroy = _thr_rtld_lock_destroy; 133 li.rlock_acquire = _thr_rtld_rlock_acquire; 134 li.wlock_acquire = _thr_rtld_wlock_acquire; 135 li.lock_release = _thr_rtld_lock_release; 136 li.thread_set_flag = _thr_rtld_set_flag; 137 li.thread_clr_flag = _thr_rtld_clr_flag; 138 li.at_fork = NULL; 139 _rtld_thread_init(&li); 140 } 141 142 void 143 _thr_rtld_fini(void) 144 { 145 _rtld_thread_init(NULL); 146 } 147