1 1.33 christos /* $NetBSD: thread-stub.c,v 1.33 2024/09/23 22:38:59 christos Exp $ */ 2 1.2 thorpej 3 1.2 thorpej /*- 4 1.21 ad * Copyright (c) 2003, 2009 The NetBSD Foundation, Inc. 5 1.2 thorpej * All rights reserved. 6 1.2 thorpej * 7 1.2 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.2 thorpej * by Jason R. Thorpe. 9 1.2 thorpej * 10 1.2 thorpej * Redistribution and use in source and binary forms, with or without 11 1.2 thorpej * modification, are permitted provided that the following conditions 12 1.2 thorpej * are met: 13 1.2 thorpej * 1. Redistributions of source code must retain the above copyright 14 1.2 thorpej * notice, this list of conditions and the following disclaimer. 15 1.2 thorpej * 2. Redistributions in binary form must reproduce the above copyright 16 1.2 thorpej * notice, this list of conditions and the following disclaimer in the 17 1.2 thorpej * documentation and/or other materials provided with the distribution. 18 1.2 thorpej * 19 1.2 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.2 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.2 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.2 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.2 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.2 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.2 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.2 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.2 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.2 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.2 thorpej * POSSIBILITY OF SUCH DAMAGE. 30 1.2 thorpej */ 31 1.2 thorpej 32 1.13 lukem #include <sys/cdefs.h> 33 1.13 lukem #if defined(LIBC_SCCS) && !defined(lint) 34 1.33 christos __RCSID("$NetBSD: thread-stub.c,v 1.33 2024/09/23 22:38:59 christos Exp $"); 35 1.13 lukem #endif /* LIBC_SCCS and not lint */ 36 1.13 lukem 37 1.2 thorpej /* 38 1.2 thorpej * Stubs for thread operations, for use when threads are not used by 39 1.2 thorpej * the application. See "reentrant.h" for details. 40 1.2 thorpej */ 41 1.2 thorpej 42 1.2 thorpej #ifdef _REENTRANT 43 1.2 thorpej 44 1.2 thorpej #define __LIBC_THREAD_STUBS 45 1.2 thorpej 46 1.26 joerg #define pthread_join __libc_pthread_join 47 1.26 joerg #define pthread_detach __libc_pthread_detach 48 1.2 thorpej #include "namespace.h" 49 1.2 thorpej #include "reentrant.h" 50 1.29 christos #include "tsd.h" 51 1.2 thorpej 52 1.5 thorpej #include <errno.h> 53 1.2 thorpej #include <signal.h> 54 1.8 matt #include <stdlib.h> 55 1.2 thorpej #include <unistd.h> 56 1.2 thorpej 57 1.2 thorpej extern int __isthreaded; 58 1.2 thorpej 59 1.21 ad #define DIE() (void)raise(SIGABRT) 60 1.2 thorpej 61 1.2 thorpej #define CHECK_NOT_THREADED_ALWAYS() \ 62 1.2 thorpej do { \ 63 1.2 thorpej if (__isthreaded) \ 64 1.2 thorpej DIE(); \ 65 1.32 rillig } while (0) 66 1.2 thorpej 67 1.2 thorpej #if 1 68 1.2 thorpej #define CHECK_NOT_THREADED() CHECK_NOT_THREADED_ALWAYS() 69 1.2 thorpej #else 70 1.2 thorpej #define CHECK_NOT_THREADED() /* nothing */ 71 1.2 thorpej #endif 72 1.2 thorpej 73 1.26 joerg __weak_alias(pthread_join, __libc_pthread_join) 74 1.26 joerg __weak_alias(pthread_detach, __libc_pthread_detach) 75 1.26 joerg 76 1.26 joerg int 77 1.26 joerg pthread_join(pthread_t thread, void **valptr) 78 1.26 joerg { 79 1.26 joerg 80 1.26 joerg if (thread == pthread_self()) 81 1.26 joerg return EDEADLK; 82 1.26 joerg return ESRCH; 83 1.26 joerg } 84 1.26 joerg 85 1.26 joerg int 86 1.26 joerg pthread_detach(pthread_t thread) 87 1.26 joerg { 88 1.26 joerg 89 1.26 joerg if (thread == pthread_self()) 90 1.26 joerg return 0; 91 1.26 joerg return ESRCH; 92 1.26 joerg } 93 1.26 joerg 94 1.33 christos __weak_alias(pthread_setname_np, __libc_mutex_catchall_stub) 95 1.33 christos __weak_alias(pthread_setaffinity_np, __libc_mutex_catchall_stub) 96 1.33 christos 97 1.2 thorpej /* mutexes */ 98 1.2 thorpej 99 1.23 christos int __libc_mutex_catchall_stub(mutex_t *); 100 1.2 thorpej 101 1.2 thorpej __weak_alias(__libc_mutex_init,__libc_mutex_init_stub) 102 1.2 thorpej __weak_alias(__libc_mutex_lock,__libc_mutex_catchall_stub) 103 1.2 thorpej __weak_alias(__libc_mutex_trylock,__libc_mutex_catchall_stub) 104 1.2 thorpej __weak_alias(__libc_mutex_unlock,__libc_mutex_catchall_stub) 105 1.2 thorpej __weak_alias(__libc_mutex_destroy,__libc_mutex_catchall_stub) 106 1.2 thorpej 107 1.23 christos __strong_alias(__libc_mutex_lock_stub,__libc_mutex_catchall_stub) 108 1.23 christos __strong_alias(__libc_mutex_trylock_stub,__libc_mutex_catchall_stub) 109 1.23 christos __strong_alias(__libc_mutex_unlock_stub,__libc_mutex_catchall_stub) 110 1.23 christos __strong_alias(__libc_mutex_destroy_stub,__libc_mutex_catchall_stub) 111 1.23 christos 112 1.23 christos int __libc_mutexattr_catchall_stub(mutexattr_t *); 113 1.4 thorpej 114 1.4 thorpej __weak_alias(__libc_mutexattr_init,__libc_mutexattr_catchall_stub) 115 1.4 thorpej __weak_alias(__libc_mutexattr_destroy,__libc_mutexattr_catchall_stub) 116 1.4 thorpej __weak_alias(__libc_mutexattr_settype,__libc_mutexattr_settype_stub) 117 1.4 thorpej 118 1.23 christos __strong_alias(__libc_mutexattr_init_stub,__libc_mutexattr_catchall_stub) 119 1.23 christos __strong_alias(__libc_mutexattr_destroy_stub,__libc_mutexattr_catchall_stub) 120 1.23 christos 121 1.2 thorpej int 122 1.2 thorpej __libc_mutex_init_stub(mutex_t *m, const mutexattr_t *a) 123 1.2 thorpej { 124 1.2 thorpej /* LINTED deliberate lack of effect */ 125 1.2 thorpej (void)m; 126 1.2 thorpej /* LINTED deliberate lack of effect */ 127 1.2 thorpej (void)a; 128 1.2 thorpej 129 1.2 thorpej CHECK_NOT_THREADED(); 130 1.2 thorpej 131 1.2 thorpej return (0); 132 1.2 thorpej } 133 1.2 thorpej 134 1.2 thorpej int 135 1.2 thorpej __libc_mutex_catchall_stub(mutex_t *m) 136 1.2 thorpej { 137 1.2 thorpej /* LINTED deliberate lack of effect */ 138 1.2 thorpej (void)m; 139 1.2 thorpej 140 1.2 thorpej CHECK_NOT_THREADED(); 141 1.2 thorpej 142 1.2 thorpej return (0); 143 1.2 thorpej } 144 1.2 thorpej 145 1.4 thorpej int 146 1.4 thorpej __libc_mutexattr_settype_stub(mutexattr_t *ma, int type) 147 1.4 thorpej { 148 1.4 thorpej /* LINTED deliberate lack of effect */ 149 1.4 thorpej (void)ma; 150 1.4 thorpej /* LINTED deliberate lack of effect */ 151 1.4 thorpej (void)type; 152 1.4 thorpej 153 1.28 kamil CHECK_NOT_THREADED(); 154 1.28 kamil 155 1.4 thorpej return (0); 156 1.4 thorpej } 157 1.4 thorpej 158 1.4 thorpej int 159 1.4 thorpej __libc_mutexattr_catchall_stub(mutexattr_t *ma) 160 1.4 thorpej { 161 1.4 thorpej /* LINTED deliberate lack of effect */ 162 1.4 thorpej (void)ma; 163 1.4 thorpej 164 1.4 thorpej CHECK_NOT_THREADED(); 165 1.4 thorpej 166 1.4 thorpej return (0); 167 1.4 thorpej } 168 1.2 thorpej 169 1.2 thorpej /* condition variables */ 170 1.2 thorpej 171 1.23 christos int __libc_cond_catchall_stub(cond_t *); 172 1.2 thorpej 173 1.2 thorpej __weak_alias(__libc_cond_init,__libc_cond_init_stub) 174 1.2 thorpej __weak_alias(__libc_cond_signal,__libc_cond_catchall_stub) 175 1.2 thorpej __weak_alias(__libc_cond_broadcast,__libc_cond_catchall_stub) 176 1.25 joerg __weak_alias(__libc_cond_wait,__libc_cond_catchall_stub) 177 1.2 thorpej __weak_alias(__libc_cond_timedwait,__libc_cond_timedwait_stub) 178 1.2 thorpej __weak_alias(__libc_cond_destroy,__libc_cond_catchall_stub) 179 1.2 thorpej 180 1.23 christos __strong_alias(__libc_cond_signal_stub,__libc_cond_catchall_stub) 181 1.23 christos __strong_alias(__libc_cond_broadcast_stub,__libc_cond_catchall_stub) 182 1.23 christos __strong_alias(__libc_cond_destroy_stub,__libc_cond_catchall_stub) 183 1.23 christos 184 1.2 thorpej int 185 1.2 thorpej __libc_cond_init_stub(cond_t *c, const condattr_t *a) 186 1.2 thorpej { 187 1.2 thorpej /* LINTED deliberate lack of effect */ 188 1.2 thorpej (void)c; 189 1.2 thorpej /* LINTED deliberate lack of effect */ 190 1.2 thorpej (void)a; 191 1.2 thorpej 192 1.2 thorpej CHECK_NOT_THREADED(); 193 1.2 thorpej 194 1.2 thorpej return (0); 195 1.2 thorpej } 196 1.2 thorpej 197 1.2 thorpej int 198 1.2 thorpej __libc_cond_wait_stub(cond_t *c, mutex_t *m) 199 1.2 thorpej { 200 1.2 thorpej /* LINTED deliberate lack of effect */ 201 1.2 thorpej (void)c; 202 1.2 thorpej /* LINTED deliberate lack of effect */ 203 1.2 thorpej (void)m; 204 1.2 thorpej 205 1.2 thorpej CHECK_NOT_THREADED(); 206 1.2 thorpej 207 1.2 thorpej return (0); 208 1.2 thorpej } 209 1.2 thorpej 210 1.2 thorpej int 211 1.2 thorpej __libc_cond_timedwait_stub(cond_t *c, mutex_t *m, const struct timespec *t) 212 1.2 thorpej { 213 1.2 thorpej /* LINTED deliberate lack of effect */ 214 1.2 thorpej (void)c; 215 1.2 thorpej /* LINTED deliberate lack of effect */ 216 1.2 thorpej (void)m; 217 1.2 thorpej /* LINTED deliberate lack of effect */ 218 1.2 thorpej (void)t; 219 1.2 thorpej 220 1.2 thorpej CHECK_NOT_THREADED(); 221 1.2 thorpej 222 1.2 thorpej return (0); 223 1.2 thorpej } 224 1.2 thorpej 225 1.2 thorpej int 226 1.2 thorpej __libc_cond_catchall_stub(cond_t *c) 227 1.2 thorpej { 228 1.2 thorpej /* LINTED deliberate lack of effect */ 229 1.2 thorpej (void)c; 230 1.2 thorpej 231 1.2 thorpej CHECK_NOT_THREADED(); 232 1.2 thorpej 233 1.2 thorpej return (0); 234 1.2 thorpej } 235 1.2 thorpej 236 1.2 thorpej 237 1.2 thorpej /* read-write locks */ 238 1.2 thorpej 239 1.23 christos int __libc_rwlock_catchall_stub(rwlock_t *); 240 1.2 thorpej 241 1.2 thorpej __weak_alias(__libc_rwlock_init,__libc_rwlock_init_stub) 242 1.2 thorpej __weak_alias(__libc_rwlock_rdlock,__libc_rwlock_catchall_stub) 243 1.2 thorpej __weak_alias(__libc_rwlock_wrlock,__libc_rwlock_catchall_stub) 244 1.2 thorpej __weak_alias(__libc_rwlock_tryrdlock,__libc_rwlock_catchall_stub) 245 1.2 thorpej __weak_alias(__libc_rwlock_trywrlock,__libc_rwlock_catchall_stub) 246 1.2 thorpej __weak_alias(__libc_rwlock_unlock,__libc_rwlock_catchall_stub) 247 1.2 thorpej __weak_alias(__libc_rwlock_destroy,__libc_rwlock_catchall_stub) 248 1.2 thorpej 249 1.23 christos __strong_alias(__libc_rwlock_rdlock_stub,__libc_rwlock_catchall_stub) 250 1.23 christos __strong_alias(__libc_rwlock_wrlock_stub,__libc_rwlock_catchall_stub) 251 1.23 christos __strong_alias(__libc_rwlock_tryrdlock_stub,__libc_rwlock_catchall_stub) 252 1.23 christos __strong_alias(__libc_rwlock_trywrlock_stub,__libc_rwlock_catchall_stub) 253 1.23 christos __strong_alias(__libc_rwlock_unlock_stub,__libc_rwlock_catchall_stub) 254 1.23 christos __strong_alias(__libc_rwlock_destroy_stub,__libc_rwlock_catchall_stub) 255 1.23 christos 256 1.23 christos 257 1.2 thorpej int 258 1.23 christos __libc_rwlock_init_stub(rwlock_t *l, const rwlockattr_t *a) 259 1.2 thorpej { 260 1.2 thorpej /* LINTED deliberate lack of effect */ 261 1.2 thorpej (void)l; 262 1.2 thorpej /* LINTED deliberate lack of effect */ 263 1.2 thorpej (void)a; 264 1.2 thorpej 265 1.2 thorpej CHECK_NOT_THREADED(); 266 1.2 thorpej 267 1.2 thorpej return (0); 268 1.2 thorpej } 269 1.2 thorpej 270 1.2 thorpej int 271 1.2 thorpej __libc_rwlock_catchall_stub(rwlock_t *l) 272 1.2 thorpej { 273 1.2 thorpej /* LINTED deliberate lack of effect */ 274 1.2 thorpej (void)l; 275 1.2 thorpej 276 1.2 thorpej CHECK_NOT_THREADED(); 277 1.2 thorpej 278 1.2 thorpej return (0); 279 1.2 thorpej } 280 1.2 thorpej 281 1.2 thorpej 282 1.7 thorpej /* 283 1.7 thorpej * thread-specific data; we need to actually provide a simple TSD 284 1.7 thorpej * implementation, since some thread-safe libraries want to use it. 285 1.7 thorpej */ 286 1.7 thorpej 287 1.29 christos struct __libc_tsd __libc_tsd[TSD_KEYS_MAX]; 288 1.7 thorpej static int __libc_tsd_nextkey; 289 1.2 thorpej 290 1.2 thorpej __weak_alias(__libc_thr_keycreate,__libc_thr_keycreate_stub) 291 1.2 thorpej __weak_alias(__libc_thr_setspecific,__libc_thr_setspecific_stub) 292 1.2 thorpej __weak_alias(__libc_thr_getspecific,__libc_thr_getspecific_stub) 293 1.2 thorpej __weak_alias(__libc_thr_keydelete,__libc_thr_keydelete_stub) 294 1.2 thorpej 295 1.2 thorpej int 296 1.2 thorpej __libc_thr_keycreate_stub(thread_key_t *k, void (*d)(void *)) 297 1.2 thorpej { 298 1.7 thorpej int i; 299 1.2 thorpej 300 1.7 thorpej for (i = __libc_tsd_nextkey; i < TSD_KEYS_MAX; i++) { 301 1.7 thorpej if (__libc_tsd[i].tsd_inuse == 0) 302 1.7 thorpej goto out; 303 1.7 thorpej } 304 1.7 thorpej 305 1.7 thorpej for (i = 0; i < __libc_tsd_nextkey; i++) { 306 1.7 thorpej if (__libc_tsd[i].tsd_inuse == 0) 307 1.7 thorpej goto out; 308 1.7 thorpej } 309 1.7 thorpej 310 1.7 thorpej return (EAGAIN); 311 1.7 thorpej 312 1.7 thorpej out: 313 1.7 thorpej /* 314 1.7 thorpej * XXX We don't actually do anything with the destructor. We 315 1.7 thorpej * XXX probably should. 316 1.7 thorpej */ 317 1.7 thorpej __libc_tsd[i].tsd_inuse = 1; 318 1.7 thorpej __libc_tsd_nextkey = (i + i) % TSD_KEYS_MAX; 319 1.7 thorpej __libc_tsd[i].tsd_dtor = d; 320 1.7 thorpej *k = i; 321 1.2 thorpej 322 1.2 thorpej return (0); 323 1.2 thorpej } 324 1.2 thorpej 325 1.2 thorpej int 326 1.2 thorpej __libc_thr_setspecific_stub(thread_key_t k, const void *v) 327 1.2 thorpej { 328 1.2 thorpej 329 1.14 christos __libc_tsd[k].tsd_val = __UNCONST(v); 330 1.2 thorpej 331 1.2 thorpej return (0); 332 1.2 thorpej } 333 1.2 thorpej 334 1.2 thorpej void * 335 1.2 thorpej __libc_thr_getspecific_stub(thread_key_t k) 336 1.2 thorpej { 337 1.2 thorpej 338 1.7 thorpej return (__libc_tsd[k].tsd_val); 339 1.2 thorpej } 340 1.2 thorpej 341 1.2 thorpej int 342 1.2 thorpej __libc_thr_keydelete_stub(thread_key_t k) 343 1.2 thorpej { 344 1.2 thorpej 345 1.7 thorpej /* 346 1.7 thorpej * XXX Do not recycle key; see big comment in libpthread. 347 1.7 thorpej */ 348 1.7 thorpej 349 1.7 thorpej __libc_tsd[k].tsd_dtor = NULL; 350 1.2 thorpej 351 1.2 thorpej return (0); 352 1.2 thorpej } 353 1.2 thorpej 354 1.2 thorpej 355 1.2 thorpej /* misc. */ 356 1.2 thorpej 357 1.2 thorpej __weak_alias(__libc_thr_once,__libc_thr_once_stub) 358 1.2 thorpej __weak_alias(__libc_thr_sigsetmask,__libc_thr_sigsetmask_stub) 359 1.2 thorpej __weak_alias(__libc_thr_self,__libc_thr_self_stub) 360 1.5 thorpej __weak_alias(__libc_thr_yield,__libc_thr_yield_stub) 361 1.5 thorpej __weak_alias(__libc_thr_create,__libc_thr_create_stub) 362 1.5 thorpej __weak_alias(__libc_thr_exit,__libc_thr_exit_stub) 363 1.9 nathanw __weak_alias(__libc_thr_setcancelstate,__libc_thr_setcancelstate_stub) 364 1.16 drochner __weak_alias(__libc_thr_equal,__libc_thr_equal_stub) 365 1.18 christos __weak_alias(__libc_thr_curcpu,__libc_thr_curcpu_stub) 366 1.2 thorpej 367 1.5 thorpej 368 1.2 thorpej int 369 1.2 thorpej __libc_thr_once_stub(once_t *o, void (*r)(void)) 370 1.2 thorpej { 371 1.2 thorpej 372 1.3 thorpej /* XXX Knowledge of libpthread types. */ 373 1.3 thorpej 374 1.3 thorpej if (o->pto_done == 0) { 375 1.3 thorpej (*r)(); 376 1.3 thorpej o->pto_done = 1; 377 1.3 thorpej } 378 1.2 thorpej 379 1.2 thorpej return (0); 380 1.2 thorpej } 381 1.2 thorpej 382 1.2 thorpej int 383 1.2 thorpej __libc_thr_sigsetmask_stub(int h, const sigset_t *s, sigset_t *o) 384 1.2 thorpej { 385 1.2 thorpej 386 1.2 thorpej CHECK_NOT_THREADED(); 387 1.2 thorpej 388 1.30 kamil if (sigprocmask(h, s, o)) 389 1.30 kamil return errno; 390 1.30 kamil return 0; 391 1.2 thorpej } 392 1.2 thorpej 393 1.2 thorpej thr_t 394 1.2 thorpej __libc_thr_self_stub(void) 395 1.2 thorpej { 396 1.2 thorpej 397 1.6 thorpej return ((thr_t) -1); 398 1.5 thorpej } 399 1.5 thorpej 400 1.31 jdolecek /* This is the strong symbol generated for sched_yield(2) via WSYSCALL() */ 401 1.31 jdolecek int _sys_sched_yield(void); 402 1.31 jdolecek 403 1.11 nathanw int 404 1.5 thorpej __libc_thr_yield_stub(void) 405 1.5 thorpej { 406 1.31 jdolecek return _sys_sched_yield(); 407 1.5 thorpej } 408 1.5 thorpej 409 1.5 thorpej int 410 1.5 thorpej __libc_thr_create_stub(thr_t *tp, const thrattr_t *ta, 411 1.5 thorpej void *(*f)(void *), void *a) 412 1.5 thorpej { 413 1.5 thorpej /* LINTED deliberate lack of effect */ 414 1.5 thorpej (void)tp; 415 1.5 thorpej /* LINTED deliberate lack of effect */ 416 1.5 thorpej (void)ta; 417 1.5 thorpej /* LINTED deliberate lack of effect */ 418 1.5 thorpej (void)f; 419 1.5 thorpej /* LINTED deliberate lack of effect */ 420 1.5 thorpej (void)a; 421 1.5 thorpej 422 1.2 thorpej DIE(); 423 1.2 thorpej 424 1.5 thorpej return (EOPNOTSUPP); 425 1.5 thorpej } 426 1.5 thorpej 427 1.27 christos __dead void 428 1.5 thorpej __libc_thr_exit_stub(void *v) 429 1.5 thorpej { 430 1.5 thorpej /* LINTED deliberate lack of effect */ 431 1.5 thorpej (void)v; 432 1.5 thorpej exit(0); 433 1.9 nathanw } 434 1.9 nathanw 435 1.9 nathanw int 436 1.9 nathanw __libc_thr_setcancelstate_stub(int new, int *old) 437 1.9 nathanw { 438 1.9 nathanw /* LINTED deliberate lack of effect */ 439 1.9 nathanw (void)new; 440 1.9 nathanw 441 1.9 nathanw /* LINTED deliberate lack of effect */ 442 1.9 nathanw (void)old; 443 1.9 nathanw 444 1.9 nathanw CHECK_NOT_THREADED(); 445 1.9 nathanw 446 1.9 nathanw return (0); 447 1.2 thorpej } 448 1.2 thorpej 449 1.16 drochner int 450 1.16 drochner __libc_thr_equal_stub(pthread_t t1, pthread_t t2) 451 1.16 drochner { 452 1.16 drochner 453 1.16 drochner /* assert that t1=t2=pthread_self() */ 454 1.16 drochner return (t1 == t2); 455 1.16 drochner } 456 1.16 drochner 457 1.17 ad unsigned int 458 1.18 christos __libc_thr_curcpu_stub(void) 459 1.17 ad { 460 1.17 ad 461 1.17 ad return (0); 462 1.17 ad } 463 1.17 ad 464 1.2 thorpej #endif /* _REENTRANT */ 465