1 /* 2 * Copyright (c) 2001 Daniel Eischen <deischen@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, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: src/lib/libc/gen/_pthread_stubs.c,v 1.5 2001/06/11 23:18:22 iedowse Exp $ 27 */ 28 29 #include <sys/cdefs.h> 30 #include "namespace.h" 31 /* following should not be included in namespace here */ 32 #undef pthread_kill 33 #undef pthread_sigmask 34 #include <errno.h> 35 #include <stdlib.h> 36 #include <signal.h> 37 #include "un-namespace.h" 38 #include <pthread.h> 39 40 /* 41 * Weak symbols: All libc internal usage of these functions should 42 * use the weak symbol versions (_pthread_XXX). If libpthread is 43 * linked, it will override these functions with (non-weak) routines. 44 * The _pthread_XXX functions are provided solely for internal libc 45 * usage to avoid unwanted cancellation points and to differentiate 46 * between application locks and libc locks (threads holding the 47 * latter can't be allowed to exit/terminate). 48 */ 49 50 #define WRlc(f, n) \ 51 __weak_reference_asm(f, _ ## n); 52 #define WR(f, n) \ 53 __weak_reference_asm(f, _ ## n); \ 54 __weak_reference_asm(f, n) 55 56 /* XXX this needs something more clever, should not some of these return errors? */ 57 WR(__atfork, pthread_atfork); 58 WR(stub_zero, pthread_attr_destroy); 59 WR(stub_zero, pthread_attr_get_np); 60 WR(stub_zero, pthread_attr_getaffinity_np); 61 WR(stub_zero, pthread_attr_getdetachstate); 62 WR(stub_zero, pthread_attr_getguardsize); 63 WR(stub_zero, pthread_attr_getinheritsched); 64 WR(stub_zero, pthread_attr_getschedparam); 65 WR(stub_zero, pthread_attr_getschedpolicy); 66 WR(stub_zero, pthread_attr_getscope); 67 WR(stub_zero, pthread_attr_getstack); 68 WR(stub_zero, pthread_attr_getstackaddr); 69 WR(stub_zero, pthread_attr_getstacksize); 70 WR(stub_zero, pthread_attr_init); 71 WR(stub_zero, pthread_attr_setaffinity_np); 72 WR(stub_zero, pthread_attr_setcreatesuspend_np); 73 WR(stub_zero, pthread_attr_setdetachstate); 74 WR(stub_zero, pthread_attr_setguardsize); 75 WR(stub_zero, pthread_attr_setinheritsched); 76 WR(stub_zero, pthread_attr_setschedparam); 77 WR(stub_zero, pthread_attr_setschedpolicy); 78 WR(stub_zero, pthread_attr_setscope); 79 WR(stub_zero, pthread_attr_setstack); 80 WR(stub_zero, pthread_attr_setstackaddr); 81 WR(stub_zero, pthread_attr_setstacksize); 82 WR(stub_zero, pthread_barrier_destroy); 83 WR(stub_zero, pthread_barrier_init); 84 WR(stub_zero, pthread_barrier_wait); 85 WR(stub_zero, pthread_barrierattr_destroy); 86 WR(stub_zero, pthread_barrierattr_getpshared); 87 WR(stub_zero, pthread_barrierattr_init); 88 WR(stub_zero, pthread_barrierattr_setpshared); 89 WRlc(stub_zero, pthread_cancel); 90 WR(stub_zero, pthread_cleanup_pop); 91 WR(stub_zero, pthread_cleanup_push); 92 WR(stub_zero, pthread_cond_broadcast); 93 WR(stub_zero, pthread_cond_destroy); 94 WR(stub_zero, pthread_cond_init); 95 WR(stub_zero, pthread_cond_signal); 96 WR(stub_zero, pthread_cond_timedwait); 97 WR(stub_zero, pthread_cond_wait); 98 WR(stub_zero, pthread_condattr_destroy); 99 WR(stub_zero, pthread_condattr_getclock); 100 WR(stub_zero, pthread_condattr_getpshared); 101 WR(stub_zero, pthread_condattr_init); 102 WR(stub_zero, pthread_condattr_setclock); 103 WR(stub_zero, pthread_condattr_setpshared); 104 WR(stub_zero, pthread_detach); 105 WR(stub_equal, pthread_equal); 106 WR(stub_exit, pthread_exit); 107 WR(stub_zero, pthread_getaffinity_np); 108 WR(stub_zero, pthread_getattr_np); 109 WR(stub_zero, pthread_getconcurrency); 110 WR(stub_zero, pthread_getcpuclockid); 111 WR(stub_zero, pthread_getprio); 112 WR(stub_zero, pthread_getschedparam); 113 WR(stub_null, pthread_getspecific); 114 WR(stub_zero, pthread_getthreadid_np); 115 WR(stub_empty, pthread_init_early); 116 WR(stub_isthreaded, pthread_is_threaded_np); 117 WR(stub_zero, pthread_join); 118 WR(stub_zero, pthread_key_create); 119 WR(stub_zero, pthread_key_delete); 120 WR(stub_zero, pthread_kill); 121 WR(stub_main, pthread_main_np); 122 WR(stub_zero, pthread_multi_np); 123 WR(stub_zero, pthread_mutex_destroy); 124 WR(stub_zero, pthread_mutex_getprioceiling); 125 WR(stub_zero, pthread_mutex_init); 126 WR(stub_zero, pthread_mutex_lock); 127 WR(stub_zero, pthread_mutex_setprioceiling); 128 WR(stub_zero, pthread_mutex_timedlock); 129 WR(stub_zero, pthread_mutex_trylock); 130 WR(stub_zero, pthread_mutex_unlock); 131 WR(stub_zero, pthread_mutexattr_destroy); 132 WR(stub_zero, pthread_mutexattr_getkind_np); 133 WR(stub_zero, pthread_mutexattr_getprioceiling); 134 WR(stub_zero, pthread_mutexattr_getprotocol); 135 WR(stub_zero, pthread_mutexattr_getpshared); 136 WR(stub_zero, pthread_mutexattr_gettype); 137 WR(stub_zero, pthread_mutexattr_init); 138 WR(stub_zero, pthread_mutexattr_setkind_np); 139 WR(stub_zero, pthread_mutexattr_setprioceiling); 140 WR(stub_zero, pthread_mutexattr_setprotocol); 141 WR(stub_zero, pthread_mutexattr_setpshared); 142 WR(stub_zero, pthread_mutexattr_settype); 143 WR(stub_once, pthread_once); 144 WR(stub_zero, pthread_resume_all_np); 145 WR(stub_zero, pthread_resume_np); 146 WR(stub_zero, pthread_rwlock_destroy); 147 WR(stub_zero, pthread_rwlock_init); 148 WR(stub_zero, pthread_rwlock_rdlock); 149 WR(stub_zero, pthread_rwlock_timedrdlock); 150 WR(stub_zero, pthread_rwlock_timedwrlock); 151 WR(stub_zero, pthread_rwlock_tryrdlock); 152 WR(stub_zero, pthread_rwlock_trywrlock); 153 WR(stub_zero, pthread_rwlock_unlock); 154 WR(stub_zero, pthread_rwlock_wrlock); 155 WR(stub_zero, pthread_rwlockattr_destroy); 156 WR(stub_zero, pthread_rwlockattr_getpshared); 157 WR(stub_zero, pthread_rwlockattr_init); 158 WR(stub_zero, pthread_rwlockattr_setpshared); 159 WR(stub_self, pthread_self); 160 WR(stub_pthread_get_name_np, pthread_get_name_np); 161 WR(stub_zero, pthread_set_name_np); 162 WR(stub_zero, pthread_setaffinity_np); 163 WR(stub_zero, pthread_setcancelstate); 164 WR(stub_zero, pthread_setcanceltype); 165 WR(stub_zero, pthread_setconcurrency); 166 WR(stub_zero, pthread_setprio); 167 WR(stub_zero, pthread_setschedparam); 168 WR(stub_zero, pthread_setspecific); 169 WR(stub_sigmask, pthread_sigmask); 170 WR(stub_zero, pthread_single_np); 171 WR(stub_zero, pthread_spin_destroy); 172 WR(stub_zero, pthread_spin_init); 173 WR(stub_zero, pthread_spin_lock); 174 WR(stub_zero, pthread_spin_trylock); 175 WR(stub_zero, pthread_spin_unlock); 176 WR(stub_zero, pthread_suspend_all_np); 177 WR(stub_zero, pthread_suspend_np); 178 WR(stub_zero, pthread_switch_add_np); 179 WR(stub_zero, pthread_switch_delete_np); 180 WR(stub_zero, pthread_testcancel); 181 WR(stub_zero, pthread_timedjoin_np); 182 WR(stub_zero, pthread_yield); 183 WR(stub_zero, sem_close); 184 WR(stub_zero, sem_destroy); 185 WR(stub_zero, sem_getvalue); 186 WR(stub_zero, sem_init); 187 WR(stub_zero, sem_open); 188 WR(stub_zero, sem_post); 189 WR(stub_zero, sem_trywait); 190 WR(stub_zero, sem_timedwait); 191 WR(stub_zero, sem_unlink); 192 WR(stub_zero, sem_wait); 193 194 195 static int __used 196 stub_zero(void) 197 { 198 return (0); 199 } 200 201 static int __used 202 stub_once(pthread_once_t *o, void (*r)(void)) 203 { 204 if (o->__state != PTHREAD_DONE_INIT) { 205 (*r)(); 206 o->__state = PTHREAD_DONE_INIT; 207 } 208 209 return (0); 210 } 211 212 static void * __used 213 stub_null(void) 214 { 215 return (NULL); 216 } 217 218 static void * __used 219 stub_self(void) 220 { 221 static struct {} main_thread; 222 223 return (&main_thread); 224 } 225 226 static int __used 227 stub_main(void) 228 { 229 return (-1); 230 } 231 232 static int __used 233 stub_equal(pthread_t a, pthread_t b) 234 { 235 return (a == b); 236 } 237 238 static void __used 239 stub_empty(void) 240 { 241 } 242 243 static void __used 244 stub_exit(void) 245 { 246 exit(0); 247 } 248 249 static int __used 250 stub_sigmask(int how, const sigset_t *set, sigset_t *oset) 251 { 252 if (_sigprocmask(how, set, oset)) 253 return (errno); 254 return (0); 255 } 256 257 static void __used 258 stub_pthread_get_name_np(pthread_t a, char *name, size_t len) 259 { 260 if (len) 261 name[0] = 0; 262 } 263 264 /* 265 * If libpthread is loaded, make sure it is initialised before 266 * other libraries call pthread functions 267 */ 268 void _pthread_init(void) __constructor(101); 269 void _pthread_init_early(void); 270 void 271 _pthread_init(void) 272 { 273 _pthread_init_early(); 274 } 275 276 extern void (*cb_prepare)(void); 277 extern void (*cb_parent)(void); 278 extern void (*cb_child)(void); 279 extern int __isthreaded; 280 281 static int __used 282 __atfork(void (*prepare)(void), void (*parent)(void), 283 void (*child)(void)) 284 { 285 if (__isthreaded) 286 return (-1); 287 cb_prepare = prepare; 288 cb_parent = parent; 289 cb_child = child; 290 return (0); 291 } 292 293 static int __used 294 stub_isthreaded(void) 295 { 296 return (__isthreaded != 0); 297 } 298