18360efbdSAlfred Perlstein /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3d915a14eSPedro F. Giffuni * 48360efbdSAlfred Perlstein * Copyright (c) 1997,98 The NetBSD Foundation, Inc. 58360efbdSAlfred Perlstein * All rights reserved. 68360efbdSAlfred Perlstein * 78360efbdSAlfred Perlstein * This code is derived from software contributed to The NetBSD Foundation 88360efbdSAlfred Perlstein * by J.T. Conklin. 98360efbdSAlfred Perlstein * 108360efbdSAlfred Perlstein * Redistribution and use in source and binary forms, with or without 118360efbdSAlfred Perlstein * modification, are permitted provided that the following conditions 128360efbdSAlfred Perlstein * are met: 138360efbdSAlfred Perlstein * 1. Redistributions of source code must retain the above copyright 148360efbdSAlfred Perlstein * notice, this list of conditions and the following disclaimer. 158360efbdSAlfred Perlstein * 2. Redistributions in binary form must reproduce the above copyright 168360efbdSAlfred Perlstein * notice, this list of conditions and the following disclaimer in the 178360efbdSAlfred Perlstein * documentation and/or other materials provided with the distribution. 188360efbdSAlfred Perlstein * 198360efbdSAlfred Perlstein * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 208360efbdSAlfred Perlstein * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 218360efbdSAlfred Perlstein * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 228360efbdSAlfred Perlstein * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 238360efbdSAlfred Perlstein * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 248360efbdSAlfred Perlstein * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 258360efbdSAlfred Perlstein * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 268360efbdSAlfred Perlstein * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 278360efbdSAlfred Perlstein * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 288360efbdSAlfred Perlstein * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 298360efbdSAlfred Perlstein * POSSIBILITY OF SUCH DAMAGE. 308360efbdSAlfred Perlstein */ 318360efbdSAlfred Perlstein 328360efbdSAlfred Perlstein /* 338360efbdSAlfred Perlstein * Requirements: 348360efbdSAlfred Perlstein * 358360efbdSAlfred Perlstein * 1. The thread safe mechanism should be lightweight so the library can 368360efbdSAlfred Perlstein * be used by non-threaded applications without unreasonable overhead. 378360efbdSAlfred Perlstein * 388360efbdSAlfred Perlstein * 2. There should be no dependency on a thread engine for non-threaded 398360efbdSAlfred Perlstein * applications. 408360efbdSAlfred Perlstein * 418360efbdSAlfred Perlstein * 3. There should be no dependency on any particular thread engine. 428360efbdSAlfred Perlstein * 438360efbdSAlfred Perlstein * 4. The library should be able to be compiled without support for thread 448360efbdSAlfred Perlstein * safety. 458360efbdSAlfred Perlstein * 468360efbdSAlfred Perlstein * 478360efbdSAlfred Perlstein * Rationale: 488360efbdSAlfred Perlstein * 498360efbdSAlfred Perlstein * One approach for thread safety is to provide discrete versions of the 508360efbdSAlfred Perlstein * library: one thread safe, the other not. The disadvantage of this is 518360efbdSAlfred Perlstein * that libc is rather large, and two copies of a library which are 99%+ 5232223c1bSPedro F. Giffuni * identical is not an efficient use of resources. 538360efbdSAlfred Perlstein * 548360efbdSAlfred Perlstein * Another approach is to provide a single thread safe library. However, 558360efbdSAlfred Perlstein * it should not add significant run time or code size overhead to non- 568360efbdSAlfred Perlstein * threaded applications. 578360efbdSAlfred Perlstein * 588360efbdSAlfred Perlstein * Since the NetBSD C library is used in other projects, it should be 598360efbdSAlfred Perlstein * easy to replace the mutual exclusion primitives with ones provided by 608360efbdSAlfred Perlstein * another system. Similarly, it should also be easy to remove all 618360efbdSAlfred Perlstein * support for thread safety completely if the target environment does 628360efbdSAlfred Perlstein * not support threads. 638360efbdSAlfred Perlstein * 648360efbdSAlfred Perlstein * 658360efbdSAlfred Perlstein * Implementation Details: 668360efbdSAlfred Perlstein * 678360efbdSAlfred Perlstein * The mutex primitives used by the library (mutex_t, mutex_lock, etc.) 68d52a982eSEitan Adler * are macros which expand to the corresponding primitives provided by 698360efbdSAlfred Perlstein * the thread engine or to nothing. The latter is used so that code is 708360efbdSAlfred Perlstein * not unreasonably cluttered with #ifdefs when all thread safe support 718360efbdSAlfred Perlstein * is removed. 728360efbdSAlfred Perlstein * 738360efbdSAlfred Perlstein * The mutex macros can be directly mapped to the mutex primitives from 748360efbdSAlfred Perlstein * pthreads, however it should be reasonably easy to wrap another mutex 758360efbdSAlfred Perlstein * implementation so it presents a similar interface. 768360efbdSAlfred Perlstein * 778360efbdSAlfred Perlstein * Stub implementations of the mutex functions are provided with *weak* 788360efbdSAlfred Perlstein * linkage. These functions simply return success. When linked with a 798360efbdSAlfred Perlstein * thread library (i.e. -lpthread), the functions will override the 808360efbdSAlfred Perlstein * stubs. 818360efbdSAlfred Perlstein */ 828360efbdSAlfred Perlstein 838360efbdSAlfred Perlstein #include <pthread.h> 848360efbdSAlfred Perlstein #include <pthread_np.h> 858360efbdSAlfred Perlstein #include "libc_private.h" 868360efbdSAlfred Perlstein 878360efbdSAlfred Perlstein #define mutex_t pthread_mutex_t 888360efbdSAlfred Perlstein #define cond_t pthread_cond_t 898360efbdSAlfred Perlstein #define rwlock_t pthread_rwlock_t 9033dee819SBrian Feldman #define once_t pthread_once_t 918360efbdSAlfred Perlstein 928360efbdSAlfred Perlstein #define thread_key_t pthread_key_t 938360efbdSAlfred Perlstein #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 948360efbdSAlfred Perlstein #define RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER 9533dee819SBrian Feldman #define ONCE_INITIALIZER PTHREAD_ONCE_INIT 968360efbdSAlfred Perlstein 978360efbdSAlfred Perlstein #define mutex_init(m, a) _pthread_mutex_init(m, a) 988360efbdSAlfred Perlstein #define mutex_lock(m) if (__isthreaded) \ 998360efbdSAlfred Perlstein _pthread_mutex_lock(m) 1008360efbdSAlfred Perlstein #define mutex_unlock(m) if (__isthreaded) \ 1018360efbdSAlfred Perlstein _pthread_mutex_unlock(m) 1028360efbdSAlfred Perlstein #define mutex_trylock(m) (__isthreaded ? 0 : _pthread_mutex_trylock(m)) 1038360efbdSAlfred Perlstein 1048360efbdSAlfred Perlstein #define cond_init(c, a, p) _pthread_cond_init(c, a) 1058360efbdSAlfred Perlstein #define cond_signal(m) if (__isthreaded) \ 1068360efbdSAlfred Perlstein _pthread_cond_signal(m) 107ceb33671SDoug Rabson #define cond_broadcast(m) if (__isthreaded) \ 108ceb33671SDoug Rabson _pthread_cond_broadcast(m) 1098360efbdSAlfred Perlstein #define cond_wait(c, m) if (__isthreaded) \ 1108360efbdSAlfred Perlstein _pthread_cond_wait(c, m) 1118360efbdSAlfred Perlstein 1128360efbdSAlfred Perlstein #define rwlock_init(l, a) _pthread_rwlock_init(l, a) 1138360efbdSAlfred Perlstein #define rwlock_rdlock(l) if (__isthreaded) \ 1148360efbdSAlfred Perlstein _pthread_rwlock_rdlock(l) 1158360efbdSAlfred Perlstein #define rwlock_wrlock(l) if (__isthreaded) \ 1168360efbdSAlfred Perlstein _pthread_rwlock_wrlock(l) 1178360efbdSAlfred Perlstein #define rwlock_unlock(l) if (__isthreaded) \ 1188360efbdSAlfred Perlstein _pthread_rwlock_unlock(l) 1198360efbdSAlfred Perlstein 1208360efbdSAlfred Perlstein #define thr_keycreate(k, d) _pthread_key_create(k, d) 1218360efbdSAlfred Perlstein #define thr_setspecific(k, p) _pthread_setspecific(k, p) 1228360efbdSAlfred Perlstein #define thr_getspecific(k) _pthread_getspecific(k) 1238360efbdSAlfred Perlstein #define thr_sigsetmask(f, n, o) _pthread_sigmask(f, n, o) 1248360efbdSAlfred Perlstein 12533dee819SBrian Feldman #define thr_once(o, i) _pthread_once(o, i) 1268360efbdSAlfred Perlstein #define thr_self() _pthread_self() 1278360efbdSAlfred Perlstein #define thr_exit(x) _pthread_exit(x) 1288360efbdSAlfred Perlstein #define thr_main() _pthread_main_np() 129