1 /* $NetBSD: thread-stub.c,v 1.27 2013/05/28 17:29:41 christos Exp $ */
4 * Copyright (c) 2003, 2009 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 #if defined(LIBC_SCCS) && !defined(lint)
34 __RCSID("$NetBSD: thread-stub.c,v 1.27 2013/05/28 17:29:41 christos Exp $");
35 #endif /* LIBC_SCCS and not lint */
38 * Stubs for thread operations, for use when threads are not used by
39 * the application. See "reentrant.h" for details.
44 #define __LIBC_THREAD_STUBS
46 #define pthread_join __libc_pthread_join
47 #define pthread_detach __libc_pthread_detach
48 #include "namespace.h"
49 #include "reentrant.h"
56 extern int __isthreaded
;
58 #define DIE() (void)raise(SIGABRT)
60 #define CHECK_NOT_THREADED_ALWAYS() \
64 } while (/*CONSTCOND*/0)
67 #define CHECK_NOT_THREADED() CHECK_NOT_THREADED_ALWAYS()
69 #define CHECK_NOT_THREADED() /* nothing */
72 __weak_alias(pthread_join
, __libc_pthread_join
)
73 __weak_alias(pthread_detach
, __libc_pthread_detach
)
76 pthread_join(pthread_t thread
, void **valptr
)
79 if (thread
== pthread_self())
85 pthread_detach(pthread_t thread
)
88 if (thread
== pthread_self())
95 int __libc_mutex_catchall_stub(mutex_t
*);
97 __weak_alias(__libc_mutex_init
,__libc_mutex_init_stub
)
98 __weak_alias(__libc_mutex_lock
,__libc_mutex_catchall_stub
)
99 __weak_alias(__libc_mutex_trylock
,__libc_mutex_catchall_stub
)
100 __weak_alias(__libc_mutex_unlock
,__libc_mutex_catchall_stub
)
101 __weak_alias(__libc_mutex_destroy
,__libc_mutex_catchall_stub
)
103 __strong_alias(__libc_mutex_lock_stub
,__libc_mutex_catchall_stub
)
104 __strong_alias(__libc_mutex_trylock_stub
,__libc_mutex_catchall_stub
)
105 __strong_alias(__libc_mutex_unlock_stub
,__libc_mutex_catchall_stub
)
106 __strong_alias(__libc_mutex_destroy_stub
,__libc_mutex_catchall_stub
)
108 int __libc_mutexattr_catchall_stub(mutexattr_t
*);
110 __weak_alias(__libc_mutexattr_init
,__libc_mutexattr_catchall_stub
)
111 __weak_alias(__libc_mutexattr_destroy
,__libc_mutexattr_catchall_stub
)
112 __weak_alias(__libc_mutexattr_settype
,__libc_mutexattr_settype_stub
)
114 __strong_alias(__libc_mutexattr_init_stub
,__libc_mutexattr_catchall_stub
)
115 __strong_alias(__libc_mutexattr_destroy_stub
,__libc_mutexattr_catchall_stub
)
118 __libc_mutex_init_stub(mutex_t
*m
, const mutexattr_t
*a
)
120 /* LINTED deliberate lack of effect */
122 /* LINTED deliberate lack of effect */
125 CHECK_NOT_THREADED();
131 __libc_mutex_catchall_stub(mutex_t
*m
)
133 /* LINTED deliberate lack of effect */
136 CHECK_NOT_THREADED();
142 __libc_mutexattr_settype_stub(mutexattr_t
*ma
, int type
)
144 /* LINTED deliberate lack of effect */
146 /* LINTED deliberate lack of effect */
153 __libc_mutexattr_catchall_stub(mutexattr_t
*ma
)
155 /* LINTED deliberate lack of effect */
158 CHECK_NOT_THREADED();
163 /* condition variables */
165 int __libc_cond_catchall_stub(cond_t
*);
167 __weak_alias(__libc_cond_init
,__libc_cond_init_stub
)
168 __weak_alias(__libc_cond_signal
,__libc_cond_catchall_stub
)
169 __weak_alias(__libc_cond_broadcast
,__libc_cond_catchall_stub
)
170 __weak_alias(__libc_cond_wait
,__libc_cond_catchall_stub
)
171 __weak_alias(__libc_cond_timedwait
,__libc_cond_timedwait_stub
)
172 __weak_alias(__libc_cond_destroy
,__libc_cond_catchall_stub
)
174 __strong_alias(__libc_cond_signal_stub
,__libc_cond_catchall_stub
)
175 __strong_alias(__libc_cond_broadcast_stub
,__libc_cond_catchall_stub
)
176 __strong_alias(__libc_cond_destroy_stub
,__libc_cond_catchall_stub
)
179 __libc_cond_init_stub(cond_t
*c
, const condattr_t
*a
)
181 /* LINTED deliberate lack of effect */
183 /* LINTED deliberate lack of effect */
186 CHECK_NOT_THREADED();
192 __libc_cond_wait_stub(cond_t
*c
, mutex_t
*m
)
194 /* LINTED deliberate lack of effect */
196 /* LINTED deliberate lack of effect */
199 CHECK_NOT_THREADED();
205 __libc_cond_timedwait_stub(cond_t
*c
, mutex_t
*m
, const struct timespec
*t
)
207 /* LINTED deliberate lack of effect */
209 /* LINTED deliberate lack of effect */
211 /* LINTED deliberate lack of effect */
214 CHECK_NOT_THREADED();
220 __libc_cond_catchall_stub(cond_t
*c
)
222 /* LINTED deliberate lack of effect */
225 CHECK_NOT_THREADED();
231 /* read-write locks */
233 int __libc_rwlock_catchall_stub(rwlock_t
*);
235 __weak_alias(__libc_rwlock_init
,__libc_rwlock_init_stub
)
236 __weak_alias(__libc_rwlock_rdlock
,__libc_rwlock_catchall_stub
)
237 __weak_alias(__libc_rwlock_wrlock
,__libc_rwlock_catchall_stub
)
238 __weak_alias(__libc_rwlock_tryrdlock
,__libc_rwlock_catchall_stub
)
239 __weak_alias(__libc_rwlock_trywrlock
,__libc_rwlock_catchall_stub
)
240 __weak_alias(__libc_rwlock_unlock
,__libc_rwlock_catchall_stub
)
241 __weak_alias(__libc_rwlock_destroy
,__libc_rwlock_catchall_stub
)
243 __strong_alias(__libc_rwlock_rdlock_stub
,__libc_rwlock_catchall_stub
)
244 __strong_alias(__libc_rwlock_wrlock_stub
,__libc_rwlock_catchall_stub
)
245 __strong_alias(__libc_rwlock_tryrdlock_stub
,__libc_rwlock_catchall_stub
)
246 __strong_alias(__libc_rwlock_trywrlock_stub
,__libc_rwlock_catchall_stub
)
247 __strong_alias(__libc_rwlock_unlock_stub
,__libc_rwlock_catchall_stub
)
248 __strong_alias(__libc_rwlock_destroy_stub
,__libc_rwlock_catchall_stub
)
252 __libc_rwlock_init_stub(rwlock_t
*l
, const rwlockattr_t
*a
)
254 /* LINTED deliberate lack of effect */
256 /* LINTED deliberate lack of effect */
259 CHECK_NOT_THREADED();
265 __libc_rwlock_catchall_stub(rwlock_t
*l
)
267 /* LINTED deliberate lack of effect */
270 CHECK_NOT_THREADED();
277 * thread-specific data; we need to actually provide a simple TSD
278 * implementation, since some thread-safe libraries want to use it.
281 #define TSD_KEYS_MAX 64
285 void (*tsd_dtor
)(void *);
287 } __libc_tsd
[TSD_KEYS_MAX
];
288 static int __libc_tsd_nextkey
;
290 __weak_alias(__libc_thr_keycreate
,__libc_thr_keycreate_stub
)
291 __weak_alias(__libc_thr_setspecific
,__libc_thr_setspecific_stub
)
292 __weak_alias(__libc_thr_getspecific
,__libc_thr_getspecific_stub
)
293 __weak_alias(__libc_thr_keydelete
,__libc_thr_keydelete_stub
)
296 __libc_thr_keycreate_stub(thread_key_t
*k
, void (*d
)(void *))
300 for (i
= __libc_tsd_nextkey
; i
< TSD_KEYS_MAX
; i
++) {
301 if (__libc_tsd
[i
].tsd_inuse
== 0)
305 for (i
= 0; i
< __libc_tsd_nextkey
; i
++) {
306 if (__libc_tsd
[i
].tsd_inuse
== 0)
314 * XXX We don't actually do anything with the destructor. We
315 * XXX probably should.
317 __libc_tsd
[i
].tsd_inuse
= 1;
318 __libc_tsd_nextkey
= (i
+ i
) % TSD_KEYS_MAX
;
319 __libc_tsd
[i
].tsd_dtor
= d
;
326 __libc_thr_setspecific_stub(thread_key_t k
, const void *v
)
329 __libc_tsd
[k
].tsd_val
= __UNCONST(v
);
335 __libc_thr_getspecific_stub(thread_key_t k
)
338 return (__libc_tsd
[k
].tsd_val
);
342 __libc_thr_keydelete_stub(thread_key_t k
)
346 * XXX Do not recycle key; see big comment in libpthread.
349 __libc_tsd
[k
].tsd_dtor
= NULL
;
357 __weak_alias(__libc_thr_once
,__libc_thr_once_stub
)
358 __weak_alias(__libc_thr_sigsetmask
,__libc_thr_sigsetmask_stub
)
359 __weak_alias(__libc_thr_self
,__libc_thr_self_stub
)
360 __weak_alias(__libc_thr_yield
,__libc_thr_yield_stub
)
361 __weak_alias(__libc_thr_create
,__libc_thr_create_stub
)
362 __weak_alias(__libc_thr_exit
,__libc_thr_exit_stub
)
363 __weak_alias(__libc_thr_setcancelstate
,__libc_thr_setcancelstate_stub
)
364 __weak_alias(__libc_thr_equal
,__libc_thr_equal_stub
)
365 __weak_alias(__libc_thr_curcpu
,__libc_thr_curcpu_stub
)
369 __libc_thr_once_stub(once_t
*o
, void (*r
)(void))
372 /* XXX Knowledge of libpthread types. */
374 if (o
->pto_done
== 0) {
383 __libc_thr_sigsetmask_stub(int h
, const sigset_t
*s
, sigset_t
*o
)
386 CHECK_NOT_THREADED();
388 return sigprocmask(h
, s
, o
);
392 __libc_thr_self_stub(void)
399 __libc_thr_yield_stub(void)
407 __libc_thr_create_stub(thr_t
*tp
, const thrattr_t
*ta
,
408 void *(*f
)(void *), void *a
)
410 /* LINTED deliberate lack of effect */
412 /* LINTED deliberate lack of effect */
414 /* LINTED deliberate lack of effect */
416 /* LINTED deliberate lack of effect */
425 __libc_thr_exit_stub(void *v
)
427 /* LINTED deliberate lack of effect */
433 __libc_thr_setcancelstate_stub(int new, int *old
)
435 /* LINTED deliberate lack of effect */
438 /* LINTED deliberate lack of effect */
441 CHECK_NOT_THREADED();
447 __libc_thr_equal_stub(pthread_t t1
, pthread_t t2
)
450 /* assert that t1=t2=pthread_self() */
455 __libc_thr_curcpu_stub(void)
461 #endif /* _REENTRANT */