1 /* 2 * Copyright (c) 2001 Alexander Kabaev 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, this list of conditions and the following disclaimer 10 * in this position and unchanged. 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 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $FreeBSD: src/lib/libpthread/thread/thr_rtld.c,v 1.5 2003/11/05 18:19:24 deischen Exp $ 29 * $DragonFly: src/lib/libthread_xu/thread/thr_rtld.c,v 1.2 2005/03/29 19:26:20 joerg Exp $ 30 */ 31 #include <machine/tls.h> 32 33 #include <stdlib.h> 34 #include <pthread.h> 35 36 #include "rtld_lock.h" 37 #include "thr_private.h" 38 39 static int _thr_rtld_clr_flag(int); 40 static void *_thr_rtld_lock_create(void); 41 static void _thr_rtld_lock_destroy(void *); 42 static void _thr_rtld_lock_release(void *); 43 static void _thr_rtld_rlock_acquire(void *); 44 static int _thr_rtld_set_flag(int); 45 static void _thr_rtld_wlock_acquire(void *); 46 47 static void * 48 _thr_rtld_lock_create(void) 49 { 50 pthread_rwlock_t prwlock; 51 if (_pthread_rwlock_init(&prwlock, NULL)) 52 return (NULL); 53 return (prwlock); 54 } 55 56 static void 57 _thr_rtld_lock_destroy(void *lock) 58 { 59 pthread_rwlock_t prwlock; 60 61 prwlock = (pthread_rwlock_t)lock; 62 if (prwlock != NULL) 63 _pthread_rwlock_destroy(&prwlock); 64 } 65 66 static void 67 _thr_rtld_rlock_acquire(void *lock) 68 { 69 pthread_rwlock_t prwlock; 70 71 prwlock = (pthread_rwlock_t)lock; 72 _thr_rwlock_rdlock(&prwlock); 73 } 74 75 static void 76 _thr_rtld_wlock_acquire(void *lock) 77 { 78 pthread_rwlock_t prwlock; 79 80 prwlock = (pthread_rwlock_t)lock; 81 _thr_rwlock_wrlock(&prwlock); 82 } 83 84 static void 85 _thr_rtld_lock_release(void *lock) 86 { 87 pthread_rwlock_t prwlock; 88 89 prwlock = (pthread_rwlock_t)lock; 90 _thr_rwlock_unlock(&prwlock); 91 } 92 93 94 static int 95 _thr_rtld_set_flag(int mask) 96 { 97 struct pthread *curthread; 98 int bits; 99 100 curthread = tls_get_curthread(); 101 if (curthread != NULL) { 102 bits = curthread->rtld_bits; 103 curthread->rtld_bits |= mask; 104 } else { 105 bits = 0; 106 PANIC("No current thread in rtld call"); 107 } 108 109 return (bits); 110 } 111 112 static int 113 _thr_rtld_clr_flag(int mask) 114 { 115 struct pthread *curthread; 116 int bits; 117 118 curthread = tls_get_curthread(); 119 if (curthread != NULL) { 120 bits = curthread->rtld_bits; 121 curthread->rtld_bits &= ~mask; 122 } else { 123 bits = 0; 124 PANIC("No current thread in rtld call"); 125 } 126 return (bits); 127 } 128 129 void 130 _thr_rtld_init(void) 131 { 132 struct RtldLockInfo li; 133 134 li.lock_create = _thr_rtld_lock_create; 135 li.lock_destroy = _thr_rtld_lock_destroy; 136 li.rlock_acquire = _thr_rtld_rlock_acquire; 137 li.wlock_acquire = _thr_rtld_wlock_acquire; 138 li.lock_release = _thr_rtld_lock_release; 139 li.thread_set_flag = _thr_rtld_set_flag; 140 li.thread_clr_flag = _thr_rtld_clr_flag; 141 li.at_fork = NULL; 142 _rtld_thread_init(&li); 143 } 144 145 void 146 _thr_rtld_fini(void) 147 { 148 _rtld_thread_init(NULL); 149 } 150