2 * Copyright (c) 2001 Daniel Eischen <deischen@FreeBSD.org>.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
33 #include "libc_private.h"
36 * Weak symbols: All libc internal usage of these functions should
37 * use the weak symbol versions (_pthread_XXX). If libpthread is
38 * linked, it will override these functions with (non-weak) routines.
39 * The _pthread_XXX functions are provided solely for internal libc
40 * usage to avoid unwanted cancellation points and to differentiate
41 * between application locks and libc locks (threads holding the
42 * latter can't be allowed to exit/terminate).
45 /* Define a null pthread structure just to satisfy _pthread_self. */
49 static struct pthread main_thread;
51 static int stub_main(void);
52 static void *stub_null(void);
53 static struct pthread *stub_self(void);
54 static int stub_zero(void);
56 #define PJT_DUAL_ENTRY(entry) \
57 (pthread_func_t)entry, (pthread_func_t)entry
59 pthread_func_entry_t __thr_jtable[PJT_MAX] = {
60 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_COND_BROADCAST */
61 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_COND_DESTROY */
62 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_COND_INIT */
63 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_COND_SIGNAL */
64 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_COND_WAIT */
65 {PJT_DUAL_ENTRY(stub_null)}, /* PJT_GETSPECIFIC */
66 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_KEY_CREATE */
67 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_KEY_DELETE */
68 {PJT_DUAL_ENTRY(stub_main)}, /* PJT_MAIN_NP */
69 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_MUTEX_DESTROY */
70 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_MUTEX_INIT */
71 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_MUTEX_LOCK */
72 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_MUTEX_TRYLOCK */
73 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_MUTEX_UNLOCK */
74 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_MUTEXATTR_DESTROY */
75 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_MUTEXATTR_INIT */
76 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_MUTEXATTR_SETTYPE */
77 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_ONCE */
78 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_RWLOCK_DESTROY */
79 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_RWLOCK_INIT */
80 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_RWLOCK_RDLOCK */
81 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_RWLOCK_TRYRDLOCK */
82 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_RWLOCK_TRYWRLOCK */
83 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_RWLOCK_UNLOCK */
84 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_RWLOCK_WRLOCK */
85 {PJT_DUAL_ENTRY(stub_self)}, /* PJT_SELF */
86 {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_SETSPECIFIC */
87 {PJT_DUAL_ENTRY(stub_zero)} /* PJT_SIGMASK */
91 * Weak aliases for exported (pthread_*) and internal (_pthread_*) routines.
93 #define WEAK_REF(sym, alias) __weak_reference(sym, alias)
95 #define FUNC_TYPE(name) __CONCAT(name, _func_t)
96 #define FUNC_INT(name) __CONCAT(name, _int)
97 #define FUNC_EXP(name) __CONCAT(name, _exp)
99 #define STUB_FUNC(name, idx, ret) \
100 static ret FUNC_EXP(name)(void) __used; \
101 static ret FUNC_INT(name)(void) __used; \
102 WEAK_REF(FUNC_EXP(name), name); \
103 WEAK_REF(FUNC_INT(name), __CONCAT(_, name)); \
104 typedef ret (*FUNC_TYPE(name))(void); \
105 static ret FUNC_EXP(name)(void) \
107 FUNC_TYPE(name) func; \
108 func = (FUNC_TYPE(name))__thr_jtable[idx][0]; \
111 static ret FUNC_INT(name)(void) \
113 FUNC_TYPE(name) func; \
114 func = (FUNC_TYPE(name))__thr_jtable[idx][1]; \
118 #define STUB_FUNC1(name, idx, ret, p0_type) \
119 static ret FUNC_EXP(name)(p0_type) __used; \
120 static ret FUNC_INT(name)(p0_type) __used; \
121 WEAK_REF(FUNC_EXP(name), name); \
122 WEAK_REF(FUNC_INT(name), __CONCAT(_, name)); \
123 typedef ret (*FUNC_TYPE(name))(p0_type); \
124 static ret FUNC_EXP(name)(p0_type p0) \
126 FUNC_TYPE(name) func; \
127 func = (FUNC_TYPE(name))__thr_jtable[idx][0]; \
130 static ret FUNC_INT(name)(p0_type p0) \
132 FUNC_TYPE(name) func; \
133 func = (FUNC_TYPE(name))__thr_jtable[idx][1]; \
137 #define STUB_FUNC2(name, idx, ret, p0_type, p1_type) \
138 static ret FUNC_EXP(name)(p0_type, p1_type) __used; \
139 static ret FUNC_INT(name)(p0_type, p1_type) __used; \
140 WEAK_REF(FUNC_EXP(name), name); \
141 WEAK_REF(FUNC_INT(name), __CONCAT(_, name)); \
142 typedef ret (*FUNC_TYPE(name))(p0_type, p1_type); \
143 static ret FUNC_EXP(name)(p0_type p0, p1_type p1) \
145 FUNC_TYPE(name) func; \
146 func = (FUNC_TYPE(name))__thr_jtable[idx][0]; \
147 return (func(p0, p1)); \
149 static ret FUNC_INT(name)(p0_type p0, p1_type p1) \
151 FUNC_TYPE(name) func; \
152 func = (FUNC_TYPE(name))__thr_jtable[idx][1]; \
153 return (func(p0, p1)); \
156 #define STUB_FUNC3(name, idx, ret, p0_type, p1_type, p2_type) \
157 static ret FUNC_EXP(name)(p0_type, p1_type, p2_type) __used; \
158 static ret FUNC_INT(name)(p0_type, p1_type, p2_type) __used; \
159 WEAK_REF(FUNC_EXP(name), name); \
160 WEAK_REF(FUNC_INT(name), __CONCAT(_, name)); \
161 typedef ret (*FUNC_TYPE(name))(p0_type, p1_type, p2_type); \
162 static ret FUNC_EXP(name)(p0_type p0, p1_type p1, p2_type p2) \
164 FUNC_TYPE(name) func; \
165 func = (FUNC_TYPE(name))__thr_jtable[idx][0]; \
166 return (func(p0, p1, p2)); \
168 static ret FUNC_INT(name)(p0_type p0, p1_type p1, p2_type p2) \
170 FUNC_TYPE(name) func; \
171 func = (FUNC_TYPE(name))__thr_jtable[idx][1]; \
172 return (func(p0, p1, p2)); \
175 STUB_FUNC1(pthread_cond_broadcast, PJT_COND_BROADCAST, int, void *)
176 STUB_FUNC1(pthread_cond_destroy, PJT_COND_DESTROY, int, void *)
177 STUB_FUNC2(pthread_cond_init, PJT_COND_INIT, int, void *, void *)
178 STUB_FUNC1(pthread_cond_signal, PJT_COND_SIGNAL, int, void *)
179 STUB_FUNC2(pthread_cond_wait, PJT_COND_WAIT, int, void *, void *)
180 STUB_FUNC1(pthread_getspecific, PJT_GETSPECIFIC, void *, pthread_key_t)
181 STUB_FUNC2(pthread_key_create, PJT_KEY_CREATE, int, void *, void *)
182 STUB_FUNC1(pthread_key_delete, PJT_KEY_DELETE, int, pthread_key_t)
183 STUB_FUNC(pthread_main_np, PJT_MAIN_NP, int)
184 STUB_FUNC1(pthread_mutex_destroy, PJT_MUTEX_DESTROY, int, void *)
185 STUB_FUNC2(pthread_mutex_init, PJT_MUTEX_INIT, int, void *, void *)
186 STUB_FUNC1(pthread_mutex_lock, PJT_MUTEX_LOCK, int, void *)
187 STUB_FUNC1(pthread_mutex_trylock, PJT_MUTEX_TRYLOCK, int, void *)
188 STUB_FUNC1(pthread_mutex_unlock, PJT_MUTEX_UNLOCK, int, void *)
189 STUB_FUNC1(pthread_mutexattr_destroy, PJT_MUTEXATTR_DESTROY, int, void *)
190 STUB_FUNC1(pthread_mutexattr_init, PJT_MUTEXATTR_INIT, int, void *)
191 STUB_FUNC1(pthread_mutexattr_settype, PJT_MUTEXATTR_SETTYPE, int, void *)
192 STUB_FUNC2(pthread_once, PJT_ONCE, int, void *, void *)
193 STUB_FUNC1(pthread_rwlock_destroy, PJT_RWLOCK_DESTROY, int, void *)
194 STUB_FUNC2(pthread_rwlock_init, PJT_RWLOCK_INIT, int, void *, void *)
195 STUB_FUNC1(pthread_rwlock_rdlock, PJT_RWLOCK_RDLOCK, int, void *)
196 STUB_FUNC1(pthread_rwlock_tryrdlock, PJT_RWLOCK_TRYRDLOCK, int, void *)
197 STUB_FUNC1(pthread_rwlock_trywrlock, PJT_RWLOCK_TRYWRLOCK, int, void *)
198 STUB_FUNC1(pthread_rwlock_unlock, PJT_RWLOCK_UNLOCK, int, void *)
199 STUB_FUNC1(pthread_rwlock_wrlock, PJT_RWLOCK_WRLOCK, int, void *)
200 STUB_FUNC(pthread_self, PJT_SELF, pthread_t)
201 STUB_FUNC2(pthread_setspecific, PJT_SETSPECIFIC, int, pthread_key_t, void *)
202 STUB_FUNC3(pthread_sigmask, PJT_SIGMASK, int, int, void *, void *)
216 static struct pthread *
219 return (&main_thread);