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 * $DragonFly: src/lib/libthread_xu/thread/thr_rtld.c,v 1.2 2005/03/29 19:26:20 joerg Exp $ 28 */ 29 #include <machine/tls.h> 30 31 #include <stdlib.h> 32 #include <pthread.h> 33 34 #include "rtld_lock.h" 35 #include "thr_private.h" 36 37 static int _thr_rtld_clr_flag(int); 38 static void *_thr_rtld_lock_create(void); 39 static void _thr_rtld_lock_destroy(void *); 40 static void _thr_rtld_lock_release(void *); 41 static void _thr_rtld_rlock_acquire(void *); 42 static int _thr_rtld_set_flag(int); 43 static void _thr_rtld_wlock_acquire(void *); 44 45 static void * 46 _thr_rtld_lock_create(void) 47 { 48 pthread_rwlock_t prwlock; 49 if (_pthread_rwlock_init(&prwlock, NULL)) 50 return (NULL); 51 return (prwlock); 52 } 53 54 static void 55 _thr_rtld_lock_destroy(void *lock) 56 { 57 pthread_rwlock_t prwlock; 58 59 prwlock = (pthread_rwlock_t)lock; 60 if (prwlock != NULL) 61 _pthread_rwlock_destroy(&prwlock); 62 } 63 64 static void 65 _thr_rtld_rlock_acquire(void *lock) 66 { 67 pthread_rwlock_t prwlock; 68 69 prwlock = (pthread_rwlock_t)lock; 70 _thr_rwlock_rdlock(&prwlock); 71 } 72 73 static void 74 _thr_rtld_wlock_acquire(void *lock) 75 { 76 pthread_rwlock_t prwlock; 77 78 prwlock = (pthread_rwlock_t)lock; 79 _thr_rwlock_wrlock(&prwlock); 80 } 81 82 static void 83 _thr_rtld_lock_release(void *lock) 84 { 85 pthread_rwlock_t prwlock; 86 87 prwlock = (pthread_rwlock_t)lock; 88 _thr_rwlock_unlock(&prwlock); 89 } 90 91 92 static int 93 _thr_rtld_set_flag(int mask) 94 { 95 struct pthread *curthread; 96 int bits; 97 98 curthread = tls_get_curthread(); 99 if (curthread != NULL) { 100 bits = curthread->rtld_bits; 101 curthread->rtld_bits |= mask; 102 } else { 103 bits = 0; 104 PANIC("No current thread in rtld call"); 105 } 106 107 return (bits); 108 } 109 110 static int 111 _thr_rtld_clr_flag(int mask) 112 { 113 struct pthread *curthread; 114 int bits; 115 116 curthread = tls_get_curthread(); 117 if (curthread != NULL) { 118 bits = curthread->rtld_bits; 119 curthread->rtld_bits &= ~mask; 120 } else { 121 bits = 0; 122 PANIC("No current thread in rtld call"); 123 } 124 return (bits); 125 } 126 127 void 128 _thr_rtld_init(void) 129 { 130 struct RtldLockInfo li; 131 132 li.lock_create = _thr_rtld_lock_create; 133 li.lock_destroy = _thr_rtld_lock_destroy; 134 li.rlock_acquire = _thr_rtld_rlock_acquire; 135 li.wlock_acquire = _thr_rtld_wlock_acquire; 136 li.lock_release = _thr_rtld_lock_release; 137 li.thread_set_flag = _thr_rtld_set_flag; 138 li.thread_clr_flag = _thr_rtld_clr_flag; 139 li.at_fork = NULL; 140 _rtld_thread_init(&li); 141 } 142 143 void 144 _thr_rtld_fini(void) 145 { 146 _rtld_thread_init(NULL); 147 } 148