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