Home | History | Annotate | Line # | Download | only in thread-stub
thread-stub.c revision 1.7
      1 /*	$NetBSD: thread-stub.c,v 1.7 2003/01/20 01:58:54 thorpej Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2003 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jason R. Thorpe.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     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.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *        This product includes software developed by the NetBSD
     21  *        Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 /*
     40  * Stubs for thread operations, for use when threads are not used by
     41  * the application.  See "reentrant.h" for details.
     42  */
     43 
     44 #ifdef _REENTRANT
     45 
     46 #define	__LIBC_THREAD_STUBS
     47 
     48 #include "namespace.h"
     49 #include "reentrant.h"
     50 
     51 #include <errno.h>
     52 #include <signal.h>
     53 #include <unistd.h>
     54 
     55 extern int __isthreaded;
     56 
     57 #define	DIE()	(void)kill(getpid(), SIGABRT)
     58 
     59 #define	CHECK_NOT_THREADED_ALWAYS()	\
     60 do {					\
     61 	if (__isthreaded)		\
     62 		DIE();			\
     63 } while (/*CONSTCOND*/0)
     64 
     65 #if 1
     66 #define	CHECK_NOT_THREADED()	CHECK_NOT_THREADED_ALWAYS()
     67 #else
     68 #define	CHECK_NOT_THREADED()	/* nothing */
     69 #endif
     70 
     71 /* mutexes */
     72 
     73 int	__libc_mutex_init_stub(mutex_t *, const mutexattr_t *);
     74 int	__libc_mutex_catchall_stub(mutex_t *);
     75 
     76 __weak_alias(__libc_mutex_init,__libc_mutex_init_stub)
     77 __weak_alias(__libc_mutex_lock,__libc_mutex_catchall_stub)
     78 __weak_alias(__libc_mutex_trylock,__libc_mutex_catchall_stub)
     79 __weak_alias(__libc_mutex_unlock,__libc_mutex_catchall_stub)
     80 __weak_alias(__libc_mutex_destroy,__libc_mutex_catchall_stub)
     81 
     82 int	__libc_mutexattr_catchall_stub(mutexattr_t *);
     83 int	__libc_mutexattr_settype_stub(mutexattr_t *, int);
     84 
     85 __weak_alias(__libc_mutexattr_init,__libc_mutexattr_catchall_stub)
     86 __weak_alias(__libc_mutexattr_destroy,__libc_mutexattr_catchall_stub)
     87 __weak_alias(__libc_mutexattr_settype,__libc_mutexattr_settype_stub)
     88 
     89 int
     90 __libc_mutex_init_stub(mutex_t *m, const mutexattr_t *a)
     91 {
     92 	/* LINTED deliberate lack of effect */
     93 	(void)m;
     94 	/* LINTED deliberate lack of effect */
     95 	(void)a;
     96 
     97 	CHECK_NOT_THREADED();
     98 
     99 	return (0);
    100 }
    101 
    102 int
    103 __libc_mutex_catchall_stub(mutex_t *m)
    104 {
    105 	/* LINTED deliberate lack of effect */
    106 	(void)m;
    107 
    108 	CHECK_NOT_THREADED();
    109 
    110 	return (0);
    111 }
    112 
    113 int
    114 __libc_mutexattr_settype_stub(mutexattr_t *ma, int type)
    115 {
    116 	/* LINTED deliberate lack of effect */
    117 	(void)ma;
    118 	/* LINTED deliberate lack of effect */
    119 	(void)type;
    120 
    121 	return (0);
    122 }
    123 
    124 int
    125 __libc_mutexattr_catchall_stub(mutexattr_t *ma)
    126 {
    127 	/* LINTED deliberate lack of effect */
    128 	(void)ma;
    129 
    130 	CHECK_NOT_THREADED();
    131 
    132 	return (0);
    133 }
    134 
    135 /* condition variables */
    136 
    137 int	__libc_cond_init_stub(cond_t *, const condattr_t *);
    138 int	__libc_cond_wait_stub(cond_t *, mutex_t *);
    139 int	__libc_cond_timedwait_stub(cond_t *, mutex_t *,
    140 				   const struct timespec *);
    141 int	__libc_cond_catchall_stub(cond_t *);
    142 
    143 __weak_alias(__libc_cond_init,__libc_cond_init_stub)
    144 __weak_alias(__libc_cond_signal,__libc_cond_catchall_stub)
    145 __weak_alias(__libc_cond_broadcast,__libc_cond_catchall_stub)
    146 __weak_alias(__libc_cond_wait,__libc_cond_wait_stub)
    147 __weak_alias(__libc_cond_timedwait,__libc_cond_timedwait_stub)
    148 __weak_alias(__libc_cond_destroy,__libc_cond_catchall_stub)
    149 
    150 int
    151 __libc_cond_init_stub(cond_t *c, const condattr_t *a)
    152 {
    153 	/* LINTED deliberate lack of effect */
    154 	(void)c;
    155 	/* LINTED deliberate lack of effect */
    156 	(void)a;
    157 
    158 	CHECK_NOT_THREADED();
    159 
    160 	return (0);
    161 }
    162 
    163 int
    164 __libc_cond_wait_stub(cond_t *c, mutex_t *m)
    165 {
    166 	/* LINTED deliberate lack of effect */
    167 	(void)c;
    168 	/* LINTED deliberate lack of effect */
    169 	(void)m;
    170 
    171 	CHECK_NOT_THREADED();
    172 
    173 	return (0);
    174 }
    175 
    176 int
    177 __libc_cond_timedwait_stub(cond_t *c, mutex_t *m, const struct timespec *t)
    178 {
    179 	/* LINTED deliberate lack of effect */
    180 	(void)c;
    181 	/* LINTED deliberate lack of effect */
    182 	(void)m;
    183 	/* LINTED deliberate lack of effect */
    184 	(void)t;
    185 
    186 	CHECK_NOT_THREADED();
    187 
    188 	return (0);
    189 }
    190 
    191 int
    192 __libc_cond_catchall_stub(cond_t *c)
    193 {
    194 	/* LINTED deliberate lack of effect */
    195 	(void)c;
    196 
    197 	CHECK_NOT_THREADED();
    198 
    199 	return (0);
    200 }
    201 
    202 
    203 /* read-write locks */
    204 
    205 int	__libc_rwlock_init_stub(rwlock_t *, rwlockattr_t *);
    206 int	__libc_rwlock_catchall_stub(rwlock_t *);
    207 
    208 __weak_alias(__libc_rwlock_init,__libc_rwlock_init_stub)
    209 __weak_alias(__libc_rwlock_rdlock,__libc_rwlock_catchall_stub)
    210 __weak_alias(__libc_rwlock_wrlock,__libc_rwlock_catchall_stub)
    211 __weak_alias(__libc_rwlock_tryrdlock,__libc_rwlock_catchall_stub)
    212 __weak_alias(__libc_rwlock_trywrlock,__libc_rwlock_catchall_stub)
    213 __weak_alias(__libc_rwlock_unlock,__libc_rwlock_catchall_stub)
    214 __weak_alias(__libc_rwlock_destroy,__libc_rwlock_catchall_stub)
    215 
    216 int
    217 __libc_rwlock_init_stub(rwlock_t *l, rwlockattr_t *a)
    218 {
    219 	/* LINTED deliberate lack of effect */
    220 	(void)l;
    221 	/* LINTED deliberate lack of effect */
    222 	(void)a;
    223 
    224 	CHECK_NOT_THREADED();
    225 
    226 	return (0);
    227 }
    228 
    229 int
    230 __libc_rwlock_catchall_stub(rwlock_t *l)
    231 {
    232 	/* LINTED deliberate lack of effect */
    233 	(void)l;
    234 
    235 	CHECK_NOT_THREADED();
    236 
    237 	return (0);
    238 }
    239 
    240 
    241 /*
    242  * thread-specific data; we need to actually provide a simple TSD
    243  * implementation, since some thread-safe libraries want to use it.
    244  */
    245 
    246 #define	TSD_KEYS_MAX	64
    247 
    248 static struct {
    249 	void *tsd_val;
    250 	void (*tsd_dtor)(void *);
    251 	int tsd_inuse;
    252 } __libc_tsd[TSD_KEYS_MAX];
    253 static int __libc_tsd_nextkey;
    254 
    255 int	__libc_thr_keycreate_stub(thread_key_t *, void (*)(void *));
    256 int	__libc_thr_setspecific_stub(thread_key_t, const void *);
    257 void	*__libc_thr_getspecific_stub(thread_key_t);
    258 int	__libc_thr_keydelete_stub(thread_key_t);
    259 
    260 __weak_alias(__libc_thr_keycreate,__libc_thr_keycreate_stub)
    261 __weak_alias(__libc_thr_setspecific,__libc_thr_setspecific_stub)
    262 __weak_alias(__libc_thr_getspecific,__libc_thr_getspecific_stub)
    263 __weak_alias(__libc_thr_keydelete,__libc_thr_keydelete_stub)
    264 
    265 int
    266 __libc_thr_keycreate_stub(thread_key_t *k, void (*d)(void *))
    267 {
    268 	int i;
    269 
    270 	for (i = __libc_tsd_nextkey; i < TSD_KEYS_MAX; i++) {
    271 		if (__libc_tsd[i].tsd_inuse == 0)
    272 			goto out;
    273 	}
    274 
    275 	for (i = 0; i < __libc_tsd_nextkey; i++) {
    276 		if (__libc_tsd[i].tsd_inuse == 0)
    277 			goto out;
    278 	}
    279 
    280 	return (EAGAIN);
    281 
    282  out:
    283 	/*
    284 	 * XXX We don't actually do anything with the destructor.  We
    285 	 * XXX probably should.
    286 	 */
    287 	__libc_tsd[i].tsd_inuse = 1;
    288 	__libc_tsd_nextkey = (i + i) % TSD_KEYS_MAX;
    289 	__libc_tsd[i].tsd_dtor = d;
    290 	*k = i;
    291 
    292 	return (0);
    293 }
    294 
    295 int
    296 __libc_thr_setspecific_stub(thread_key_t k, const void *v)
    297 {
    298 
    299 	/* LINTED cast away const */
    300 	__libc_tsd[k].tsd_val = (void *) v;
    301 
    302 	return (0);
    303 }
    304 
    305 void *
    306 __libc_thr_getspecific_stub(thread_key_t k)
    307 {
    308 
    309 	return (__libc_tsd[k].tsd_val);
    310 }
    311 
    312 int
    313 __libc_thr_keydelete_stub(thread_key_t k)
    314 {
    315 
    316 	/*
    317 	 * XXX Do not recycle key; see big comment in libpthread.
    318 	 */
    319 
    320 	__libc_tsd[k].tsd_dtor = NULL;
    321 
    322 	return (0);
    323 }
    324 
    325 
    326 /* misc. */
    327 
    328 int	__libc_thr_once_stub(once_t *, void (*)(void));
    329 int	__libc_thr_sigsetmask_stub(int, const sigset_t *, sigset_t *);
    330 thr_t	__libc_thr_self_stub(void);
    331 void	__libc_thr_yield_stub(void);
    332 int	__libc_thr_create_stub(thr_t *, const thrattr_t *,
    333 	    void *(*)(void *), void *);
    334 void	__libc_thr_exit_stub(void *);
    335 int	*__libc_thr_errno_stub(void);
    336 
    337 __weak_alias(__libc_thr_once,__libc_thr_once_stub)
    338 __weak_alias(__libc_thr_sigsetmask,__libc_thr_sigsetmask_stub)
    339 __weak_alias(__libc_thr_self,__libc_thr_self_stub)
    340 __weak_alias(__libc_thr_yield,__libc_thr_yield_stub)
    341 __weak_alias(__libc_thr_create,__libc_thr_create_stub)
    342 __weak_alias(__libc_thr_exit,__libc_thr_exit_stub)
    343 __weak_alias(__libc_thr_errno,__libc_thr_errno_stub)
    344 
    345 
    346 int
    347 __libc_thr_once_stub(once_t *o, void (*r)(void))
    348 {
    349 
    350 	/* XXX Knowledge of libpthread types. */
    351 
    352 	if (o->pto_done == 0) {
    353 		(*r)();
    354 		o->pto_done = 1;
    355 	}
    356 
    357 	return (0);
    358 }
    359 
    360 int
    361 __libc_thr_sigsetmask_stub(int h, const sigset_t *s, sigset_t *o)
    362 {
    363 	/* LINTED deliberate lack of effect */
    364 	(void)h;
    365 	/* LINTED deliberate lack of effect */
    366 	(void)s;
    367 	/* LINTED deliberate lack of effect */
    368 	(void)o;
    369 
    370 	CHECK_NOT_THREADED();
    371 
    372 	/* XXX just use sigmask(2)?  abort? */
    373 
    374 	return (0);
    375 }
    376 
    377 thr_t
    378 __libc_thr_self_stub(void)
    379 {
    380 
    381 	return ((thr_t) -1);
    382 }
    383 
    384 void
    385 __libc_thr_yield_stub(void)
    386 {
    387 
    388 	/* Nothing to do. */
    389 }
    390 
    391 int
    392 __libc_thr_create_stub(thr_t *tp, const thrattr_t *ta,
    393     void *(*f)(void *), void *a)
    394 {
    395 	/* LINTED deliberate lack of effect */
    396 	(void)tp;
    397 	/* LINTED deliberate lack of effect */
    398 	(void)ta;
    399 	/* LINTED deliberate lack of effect */
    400 	(void)f;
    401 	/* LINTED deliberate lack of effect */
    402 	(void)a;
    403 
    404 	DIE();
    405 
    406 	return (EOPNOTSUPP);
    407 }
    408 
    409 void
    410 __libc_thr_exit_stub(void *v)
    411 {
    412 	/* LINTED deliberate lack of effect */
    413 	(void)v;
    414 
    415 	exit(0);
    416 }
    417 
    418 int *
    419 __libc_thr_errno_stub(void)
    420 {
    421 
    422 	DIE();
    423 
    424 	return (NULL);
    425 }
    426 
    427 #endif /* _REENTRANT */
    428