171b3fa15SDavid Xu /* 271b3fa15SDavid Xu * Copyright (c) 2001 Alexander Kabaev 371b3fa15SDavid Xu * All rights reserved. 471b3fa15SDavid Xu * 571b3fa15SDavid Xu * Redistribution and use in source and binary forms, with or without 671b3fa15SDavid Xu * modification, are permitted provided that the following conditions 771b3fa15SDavid Xu * are met: 871b3fa15SDavid Xu * 1. Redistributions of source code must retain the above copyright 971b3fa15SDavid Xu * notice, this list of conditions and the following disclaimer 1071b3fa15SDavid Xu * in this position and unchanged. 1171b3fa15SDavid Xu * 2. Redistributions in binary form must reproduce the above copyright 1271b3fa15SDavid Xu * notice, this list of conditions and the following disclaimer in the 1371b3fa15SDavid Xu * documentation and/or other materials provided with the distribution. 1471b3fa15SDavid Xu * 3. The name of the author may not be used to endorse or promote products 1571b3fa15SDavid Xu * derived from this software without specific prior written permission. 1671b3fa15SDavid Xu * 1771b3fa15SDavid Xu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1871b3fa15SDavid Xu * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1971b3fa15SDavid Xu * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2071b3fa15SDavid Xu * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2171b3fa15SDavid Xu * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2271b3fa15SDavid Xu * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2371b3fa15SDavid Xu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2471b3fa15SDavid Xu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2571b3fa15SDavid Xu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2671b3fa15SDavid Xu * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2771b3fa15SDavid Xu * 2871b3fa15SDavid Xu * $FreeBSD: src/lib/libpthread/thread/thr_rtld.c,v 1.5 2003/11/05 18:19:24 deischen Exp $ 29*9e2ee207SJoerg Sonnenberger * $DragonFly: src/lib/libthread_xu/thread/thr_rtld.c,v 1.2 2005/03/29 19:26:20 joerg Exp $ 3071b3fa15SDavid Xu */ 31*9e2ee207SJoerg Sonnenberger #include <machine/tls.h> 32*9e2ee207SJoerg Sonnenberger 3371b3fa15SDavid Xu #include <stdlib.h> 3471b3fa15SDavid Xu #include <pthread.h> 3571b3fa15SDavid Xu 3671b3fa15SDavid Xu #include "rtld_lock.h" 3771b3fa15SDavid Xu #include "thr_private.h" 3871b3fa15SDavid Xu 3971b3fa15SDavid Xu static int _thr_rtld_clr_flag(int); 4071b3fa15SDavid Xu static void *_thr_rtld_lock_create(void); 4171b3fa15SDavid Xu static void _thr_rtld_lock_destroy(void *); 4271b3fa15SDavid Xu static void _thr_rtld_lock_release(void *); 4371b3fa15SDavid Xu static void _thr_rtld_rlock_acquire(void *); 4471b3fa15SDavid Xu static int _thr_rtld_set_flag(int); 4571b3fa15SDavid Xu static void _thr_rtld_wlock_acquire(void *); 4671b3fa15SDavid Xu 4771b3fa15SDavid Xu static void * 4871b3fa15SDavid Xu _thr_rtld_lock_create(void) 4971b3fa15SDavid Xu { 5071b3fa15SDavid Xu pthread_rwlock_t prwlock; 5171b3fa15SDavid Xu if (_pthread_rwlock_init(&prwlock, NULL)) 5271b3fa15SDavid Xu return (NULL); 5371b3fa15SDavid Xu return (prwlock); 5471b3fa15SDavid Xu } 5571b3fa15SDavid Xu 5671b3fa15SDavid Xu static void 5771b3fa15SDavid Xu _thr_rtld_lock_destroy(void *lock) 5871b3fa15SDavid Xu { 5971b3fa15SDavid Xu pthread_rwlock_t prwlock; 6071b3fa15SDavid Xu 6171b3fa15SDavid Xu prwlock = (pthread_rwlock_t)lock; 6271b3fa15SDavid Xu if (prwlock != NULL) 6371b3fa15SDavid Xu _pthread_rwlock_destroy(&prwlock); 6471b3fa15SDavid Xu } 6571b3fa15SDavid Xu 6671b3fa15SDavid Xu static void 6771b3fa15SDavid Xu _thr_rtld_rlock_acquire(void *lock) 6871b3fa15SDavid Xu { 6971b3fa15SDavid Xu pthread_rwlock_t prwlock; 7071b3fa15SDavid Xu 7171b3fa15SDavid Xu prwlock = (pthread_rwlock_t)lock; 7271b3fa15SDavid Xu _thr_rwlock_rdlock(&prwlock); 7371b3fa15SDavid Xu } 7471b3fa15SDavid Xu 7571b3fa15SDavid Xu static void 7671b3fa15SDavid Xu _thr_rtld_wlock_acquire(void *lock) 7771b3fa15SDavid Xu { 7871b3fa15SDavid Xu pthread_rwlock_t prwlock; 7971b3fa15SDavid Xu 8071b3fa15SDavid Xu prwlock = (pthread_rwlock_t)lock; 8171b3fa15SDavid Xu _thr_rwlock_wrlock(&prwlock); 8271b3fa15SDavid Xu } 8371b3fa15SDavid Xu 8471b3fa15SDavid Xu static void 8571b3fa15SDavid Xu _thr_rtld_lock_release(void *lock) 8671b3fa15SDavid Xu { 8771b3fa15SDavid Xu pthread_rwlock_t prwlock; 8871b3fa15SDavid Xu 8971b3fa15SDavid Xu prwlock = (pthread_rwlock_t)lock; 9071b3fa15SDavid Xu _thr_rwlock_unlock(&prwlock); 9171b3fa15SDavid Xu } 9271b3fa15SDavid Xu 9371b3fa15SDavid Xu 9471b3fa15SDavid Xu static int 9571b3fa15SDavid Xu _thr_rtld_set_flag(int mask) 9671b3fa15SDavid Xu { 9771b3fa15SDavid Xu struct pthread *curthread; 9871b3fa15SDavid Xu int bits; 9971b3fa15SDavid Xu 100*9e2ee207SJoerg Sonnenberger curthread = tls_get_curthread(); 10171b3fa15SDavid Xu if (curthread != NULL) { 10271b3fa15SDavid Xu bits = curthread->rtld_bits; 10371b3fa15SDavid Xu curthread->rtld_bits |= mask; 10471b3fa15SDavid Xu } else { 10571b3fa15SDavid Xu bits = 0; 10671b3fa15SDavid Xu PANIC("No current thread in rtld call"); 10771b3fa15SDavid Xu } 10871b3fa15SDavid Xu 10971b3fa15SDavid Xu return (bits); 11071b3fa15SDavid Xu } 11171b3fa15SDavid Xu 11271b3fa15SDavid Xu static int 11371b3fa15SDavid Xu _thr_rtld_clr_flag(int mask) 11471b3fa15SDavid Xu { 11571b3fa15SDavid Xu struct pthread *curthread; 11671b3fa15SDavid Xu int bits; 11771b3fa15SDavid Xu 118*9e2ee207SJoerg Sonnenberger curthread = tls_get_curthread(); 11971b3fa15SDavid Xu if (curthread != NULL) { 12071b3fa15SDavid Xu bits = curthread->rtld_bits; 12171b3fa15SDavid Xu curthread->rtld_bits &= ~mask; 12271b3fa15SDavid Xu } else { 12371b3fa15SDavid Xu bits = 0; 12471b3fa15SDavid Xu PANIC("No current thread in rtld call"); 12571b3fa15SDavid Xu } 12671b3fa15SDavid Xu return (bits); 12771b3fa15SDavid Xu } 12871b3fa15SDavid Xu 12971b3fa15SDavid Xu void 13071b3fa15SDavid Xu _thr_rtld_init(void) 13171b3fa15SDavid Xu { 13271b3fa15SDavid Xu struct RtldLockInfo li; 13371b3fa15SDavid Xu 13471b3fa15SDavid Xu li.lock_create = _thr_rtld_lock_create; 13571b3fa15SDavid Xu li.lock_destroy = _thr_rtld_lock_destroy; 13671b3fa15SDavid Xu li.rlock_acquire = _thr_rtld_rlock_acquire; 13771b3fa15SDavid Xu li.wlock_acquire = _thr_rtld_wlock_acquire; 13871b3fa15SDavid Xu li.lock_release = _thr_rtld_lock_release; 13971b3fa15SDavid Xu li.thread_set_flag = _thr_rtld_set_flag; 14071b3fa15SDavid Xu li.thread_clr_flag = _thr_rtld_clr_flag; 14171b3fa15SDavid Xu li.at_fork = NULL; 14271b3fa15SDavid Xu _rtld_thread_init(&li); 14371b3fa15SDavid Xu } 14471b3fa15SDavid Xu 14571b3fa15SDavid Xu void 14671b3fa15SDavid Xu _thr_rtld_fini(void) 14771b3fa15SDavid Xu { 14871b3fa15SDavid Xu _rtld_thread_init(NULL); 14971b3fa15SDavid Xu } 150