1 /* $NetBSD: thread-stub.c,v 1.20 2008/04/28 20:23:01 martin 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.20 2008/04/28 20:23:01 martin 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 #include "namespace.h"
47 #include "reentrant.h"
54 extern int __isthreaded
;
56 #define DIE() (void)raise(SIGABRT)
58 #define CHECK_NOT_THREADED_ALWAYS() \
62 } while (/*CONSTCOND*/0)
65 #define CHECK_NOT_THREADED() CHECK_NOT_THREADED_ALWAYS()
67 #define CHECK_NOT_THREADED() /* nothing */
72 void __libc_thr_init(void);
73 void __libc_thr_init_stub(void);
75 __weak_alias(__libc_thr_init
,__libc_thr_init_stub
)
78 __libc_thr_init_stub(void)
81 /* nothing, may be overridden by libpthread */
86 int __libc_mutex_init_stub(mutex_t
*, const mutexattr_t
*);
87 int __libc_mutex_catchall_stub(mutex_t
*);
89 __weak_alias(__libc_mutex_init
,__libc_mutex_init_stub
)
90 __weak_alias(__libc_mutex_lock
,__libc_mutex_catchall_stub
)
91 __weak_alias(__libc_mutex_trylock
,__libc_mutex_catchall_stub
)
92 __weak_alias(__libc_mutex_unlock
,__libc_mutex_catchall_stub
)
93 __weak_alias(__libc_mutex_destroy
,__libc_mutex_catchall_stub
)
95 int __libc_mutexattr_catchall_stub(mutexattr_t
*);
96 int __libc_mutexattr_settype_stub(mutexattr_t
*, int);
98 __weak_alias(__libc_mutexattr_init
,__libc_mutexattr_catchall_stub
)
99 __weak_alias(__libc_mutexattr_destroy
,__libc_mutexattr_catchall_stub
)
100 __weak_alias(__libc_mutexattr_settype
,__libc_mutexattr_settype_stub
)
103 __libc_mutex_init_stub(mutex_t
*m
, const mutexattr_t
*a
)
105 /* LINTED deliberate lack of effect */
107 /* LINTED deliberate lack of effect */
110 CHECK_NOT_THREADED();
116 __libc_mutex_catchall_stub(mutex_t
*m
)
118 /* LINTED deliberate lack of effect */
121 CHECK_NOT_THREADED();
127 __libc_mutexattr_settype_stub(mutexattr_t
*ma
, int type
)
129 /* LINTED deliberate lack of effect */
131 /* LINTED deliberate lack of effect */
138 __libc_mutexattr_catchall_stub(mutexattr_t
*ma
)
140 /* LINTED deliberate lack of effect */
143 CHECK_NOT_THREADED();
148 /* condition variables */
150 int __libc_cond_init_stub(cond_t
*, const condattr_t
*);
151 int __libc_cond_wait_stub(cond_t
*, mutex_t
*);
152 int __libc_cond_timedwait_stub(cond_t
*, mutex_t
*,
153 const struct timespec
*);
154 int __libc_cond_catchall_stub(cond_t
*);
156 __weak_alias(__libc_cond_init
,__libc_cond_init_stub
)
157 __weak_alias(__libc_cond_signal
,__libc_cond_catchall_stub
)
158 __weak_alias(__libc_cond_broadcast
,__libc_cond_catchall_stub
)
159 __weak_alias(__libc_cond_wait
,__libc_cond_wait_stub
)
160 __weak_alias(__libc_cond_timedwait
,__libc_cond_timedwait_stub
)
161 __weak_alias(__libc_cond_destroy
,__libc_cond_catchall_stub
)
164 __libc_cond_init_stub(cond_t
*c
, const condattr_t
*a
)
166 /* LINTED deliberate lack of effect */
168 /* LINTED deliberate lack of effect */
171 CHECK_NOT_THREADED();
177 __libc_cond_wait_stub(cond_t
*c
, mutex_t
*m
)
179 /* LINTED deliberate lack of effect */
181 /* LINTED deliberate lack of effect */
184 CHECK_NOT_THREADED();
190 __libc_cond_timedwait_stub(cond_t
*c
, mutex_t
*m
, const struct timespec
*t
)
192 /* LINTED deliberate lack of effect */
194 /* LINTED deliberate lack of effect */
196 /* LINTED deliberate lack of effect */
199 CHECK_NOT_THREADED();
205 __libc_cond_catchall_stub(cond_t
*c
)
207 /* LINTED deliberate lack of effect */
210 CHECK_NOT_THREADED();
216 /* read-write locks */
218 int __libc_rwlock_init_stub(rwlock_t
*, rwlockattr_t
*);
219 int __libc_rwlock_catchall_stub(rwlock_t
*);
221 __weak_alias(__libc_rwlock_init
,__libc_rwlock_init_stub
)
222 __weak_alias(__libc_rwlock_rdlock
,__libc_rwlock_catchall_stub
)
223 __weak_alias(__libc_rwlock_wrlock
,__libc_rwlock_catchall_stub
)
224 __weak_alias(__libc_rwlock_tryrdlock
,__libc_rwlock_catchall_stub
)
225 __weak_alias(__libc_rwlock_trywrlock
,__libc_rwlock_catchall_stub
)
226 __weak_alias(__libc_rwlock_unlock
,__libc_rwlock_catchall_stub
)
227 __weak_alias(__libc_rwlock_destroy
,__libc_rwlock_catchall_stub
)
230 __libc_rwlock_init_stub(rwlock_t
*l
, rwlockattr_t
*a
)
232 /* LINTED deliberate lack of effect */
234 /* LINTED deliberate lack of effect */
237 CHECK_NOT_THREADED();
243 __libc_rwlock_catchall_stub(rwlock_t
*l
)
245 /* LINTED deliberate lack of effect */
248 CHECK_NOT_THREADED();
255 * thread-specific data; we need to actually provide a simple TSD
256 * implementation, since some thread-safe libraries want to use it.
259 #define TSD_KEYS_MAX 64
263 void (*tsd_dtor
)(void *);
265 } __libc_tsd
[TSD_KEYS_MAX
];
266 static int __libc_tsd_nextkey
;
268 int __libc_thr_keycreate_stub(thread_key_t
*, void (*)(void *));
269 int __libc_thr_setspecific_stub(thread_key_t
, const void *);
270 void *__libc_thr_getspecific_stub(thread_key_t
);
271 int __libc_thr_keydelete_stub(thread_key_t
);
273 __weak_alias(__libc_thr_keycreate
,__libc_thr_keycreate_stub
)
274 __weak_alias(__libc_thr_setspecific
,__libc_thr_setspecific_stub
)
275 __weak_alias(__libc_thr_getspecific
,__libc_thr_getspecific_stub
)
276 __weak_alias(__libc_thr_keydelete
,__libc_thr_keydelete_stub
)
279 __libc_thr_keycreate_stub(thread_key_t
*k
, void (*d
)(void *))
283 for (i
= __libc_tsd_nextkey
; i
< TSD_KEYS_MAX
; i
++) {
284 if (__libc_tsd
[i
].tsd_inuse
== 0)
288 for (i
= 0; i
< __libc_tsd_nextkey
; i
++) {
289 if (__libc_tsd
[i
].tsd_inuse
== 0)
297 * XXX We don't actually do anything with the destructor. We
298 * XXX probably should.
300 __libc_tsd
[i
].tsd_inuse
= 1;
301 __libc_tsd_nextkey
= (i
+ i
) % TSD_KEYS_MAX
;
302 __libc_tsd
[i
].tsd_dtor
= d
;
309 __libc_thr_setspecific_stub(thread_key_t k
, const void *v
)
312 __libc_tsd
[k
].tsd_val
= __UNCONST(v
);
318 __libc_thr_getspecific_stub(thread_key_t k
)
321 return (__libc_tsd
[k
].tsd_val
);
325 __libc_thr_keydelete_stub(thread_key_t k
)
329 * XXX Do not recycle key; see big comment in libpthread.
332 __libc_tsd
[k
].tsd_dtor
= NULL
;
340 int __libc_thr_once_stub(once_t
*, void (*)(void));
341 int __libc_thr_sigsetmask_stub(int, const sigset_t
*, sigset_t
*);
342 thr_t
__libc_thr_self_stub(void);
343 int __libc_thr_yield_stub(void);
344 int __libc_thr_create_stub(thr_t
*, const thrattr_t
*,
345 void *(*)(void *), void *);
346 void __libc_thr_exit_stub(void *);
347 int *__libc_thr_errno_stub(void);
348 int __libc_thr_setcancelstate_stub(int, int *);
349 int __libc_thr_equal_stub(pthread_t
, pthread_t
);
350 unsigned int __libc_thr_curcpu_stub(void);
352 __weak_alias(__libc_thr_once
,__libc_thr_once_stub
)
353 __weak_alias(__libc_thr_sigsetmask
,__libc_thr_sigsetmask_stub
)
354 __weak_alias(__libc_thr_self
,__libc_thr_self_stub
)
355 __weak_alias(__libc_thr_yield
,__libc_thr_yield_stub
)
356 __weak_alias(__libc_thr_create
,__libc_thr_create_stub
)
357 __weak_alias(__libc_thr_exit
,__libc_thr_exit_stub
)
358 __weak_alias(__libc_thr_errno
,__libc_thr_errno_stub
)
359 __weak_alias(__libc_thr_setcancelstate
,__libc_thr_setcancelstate_stub
)
360 __weak_alias(__libc_thr_equal
,__libc_thr_equal_stub
)
361 __weak_alias(__libc_thr_curcpu
,__libc_thr_curcpu_stub
)
365 __libc_thr_once_stub(once_t
*o
, void (*r
)(void))
368 /* XXX Knowledge of libpthread types. */
370 if (o
->pto_done
== 0) {
379 __libc_thr_sigsetmask_stub(int h
, const sigset_t
*s
, sigset_t
*o
)
382 CHECK_NOT_THREADED();
384 return sigprocmask(h
, s
, o
);
388 __libc_thr_self_stub(void)
395 __libc_thr_yield_stub(void)
403 __libc_thr_create_stub(thr_t
*tp
, const thrattr_t
*ta
,
404 void *(*f
)(void *), void *a
)
406 /* LINTED deliberate lack of effect */
408 /* LINTED deliberate lack of effect */
410 /* LINTED deliberate lack of effect */
412 /* LINTED deliberate lack of effect */
421 __libc_thr_exit_stub(void *v
)
423 /* LINTED deliberate lack of effect */
429 __libc_thr_setcancelstate_stub(int new, int *old
)
431 /* LINTED deliberate lack of effect */
434 /* LINTED deliberate lack of effect */
437 CHECK_NOT_THREADED();
443 __libc_thr_equal_stub(pthread_t t1
, pthread_t t2
)
446 /* assert that t1=t2=pthread_self() */
451 __libc_thr_errno_stub(void)
460 __libc_thr_curcpu_stub(void)
466 #endif /* _REENTRANT */