174462Salfred/*-
274462Salfred * Copyright (c) 1997,98 The NetBSD Foundation, Inc.
374462Salfred * All rights reserved.
474462Salfred *
574462Salfred * This code is derived from software contributed to The NetBSD Foundation
674462Salfred * by J.T. Conklin.
774462Salfred *
874462Salfred * Redistribution and use in source and binary forms, with or without
974462Salfred * modification, are permitted provided that the following conditions
1074462Salfred * are met:
1174462Salfred * 1. Redistributions of source code must retain the above copyright
1274462Salfred *    notice, this list of conditions and the following disclaimer.
1374462Salfred * 2. Redistributions in binary form must reproduce the above copyright
1474462Salfred *    notice, this list of conditions and the following disclaimer in the
1574462Salfred *    documentation and/or other materials provided with the distribution.
1674462Salfred *
1774462Salfred * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1874462Salfred * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1974462Salfred * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2074462Salfred * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2174462Salfred * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2274462Salfred * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2374462Salfred * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2474462Salfred * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2574462Salfred * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2674462Salfred * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2774462Salfred * POSSIBILITY OF SUCH DAMAGE.
2874462Salfred *
2974462Salfred * $FreeBSD$
3074462Salfred */
3174462Salfred
3274462Salfred/*
3374462Salfred * Requirements:
3474462Salfred *
3574462Salfred * 1. The thread safe mechanism should be lightweight so the library can
3674462Salfred *    be used by non-threaded applications without unreasonable overhead.
3774462Salfred *
3874462Salfred * 2. There should be no dependency on a thread engine for non-threaded
3974462Salfred *    applications.
4074462Salfred *
4174462Salfred * 3. There should be no dependency on any particular thread engine.
4274462Salfred *
4374462Salfred * 4. The library should be able to be compiled without support for thread
4474462Salfred *    safety.
4574462Salfred *
4674462Salfred *
4774462Salfred * Rationale:
4874462Salfred *
4974462Salfred * One approach for thread safety is to provide discrete versions of the
5074462Salfred * library: one thread safe, the other not.  The disadvantage of this is
5174462Salfred * that libc is rather large, and two copies of a library which are 99%+
5274462Salfred * identical is not an efficent use of resources.
5374462Salfred *
5474462Salfred * Another approach is to provide a single thread safe library.  However,
5574462Salfred * it should not add significant run time or code size overhead to non-
5674462Salfred * threaded applications.
5774462Salfred *
5874462Salfred * Since the NetBSD C library is used in other projects, it should be
5974462Salfred * easy to replace the mutual exclusion primitives with ones provided by
6074462Salfred * another system.  Similarly, it should also be easy to remove all
6174462Salfred * support for thread safety completely if the target environment does
6274462Salfred * not support threads.
6374462Salfred *
6474462Salfred *
6574462Salfred * Implementation Details:
6674462Salfred *
6774462Salfred * The mutex primitives used by the library (mutex_t, mutex_lock, etc.)
6874462Salfred * are macros which expand to the cooresponding primitives provided by
6974462Salfred * the thread engine or to nothing.  The latter is used so that code is
7074462Salfred * not unreasonably cluttered with #ifdefs when all thread safe support
7174462Salfred * is removed.
7274462Salfred *
7374462Salfred * The mutex macros can be directly mapped to the mutex primitives from
7474462Salfred * pthreads, however it should be reasonably easy to wrap another mutex
7574462Salfred * implementation so it presents a similar interface.
7674462Salfred *
7774462Salfred * Stub implementations of the mutex functions are provided with *weak*
7874462Salfred * linkage.  These functions simply return success.  When linked with a
7974462Salfred * thread library (i.e. -lpthread), the functions will override the
8074462Salfred * stubs.
8174462Salfred */
8274462Salfred
8374462Salfred#include <pthread.h>
8474462Salfred#include <pthread_np.h>
8574462Salfred#include "libc_private.h"
8674462Salfred
8774462Salfred#define mutex_t			pthread_mutex_t
8874462Salfred#define cond_t			pthread_cond_t
8974462Salfred#define rwlock_t		pthread_rwlock_t
90126243Sgreen#define once_t			pthread_once_t
9174462Salfred
9274462Salfred#define thread_key_t		pthread_key_t
9374462Salfred#define MUTEX_INITIALIZER	PTHREAD_MUTEX_INITIALIZER
9474462Salfred#define RWLOCK_INITIALIZER	PTHREAD_RWLOCK_INITIALIZER
95126243Sgreen#define ONCE_INITIALIZER	PTHREAD_ONCE_INIT
9674462Salfred
9774462Salfred#define mutex_init(m, a)	_pthread_mutex_init(m, a)
9874462Salfred#define mutex_lock(m)		if (__isthreaded) \
9974462Salfred				_pthread_mutex_lock(m)
10074462Salfred#define mutex_unlock(m)		if (__isthreaded) \
10174462Salfred				_pthread_mutex_unlock(m)
10274462Salfred#define mutex_trylock(m)	(__isthreaded ? 0 : _pthread_mutex_trylock(m))
10374462Salfred
10474462Salfred#define cond_init(c, a, p)	_pthread_cond_init(c, a)
10574462Salfred#define cond_signal(m)		if (__isthreaded) \
10674462Salfred				_pthread_cond_signal(m)
107106288Sdfr#define cond_broadcast(m)	if (__isthreaded) \
108106288Sdfr				_pthread_cond_broadcast(m)
10974462Salfred#define cond_wait(c, m)		if (__isthreaded) \
11074462Salfred				_pthread_cond_wait(c, m)
11174462Salfred
11274462Salfred#define rwlock_init(l, a)	_pthread_rwlock_init(l, a)
11374462Salfred#define rwlock_rdlock(l)	if (__isthreaded) \
11474462Salfred				_pthread_rwlock_rdlock(l)
11574462Salfred#define rwlock_wrlock(l)	if (__isthreaded) \
11674462Salfred				_pthread_rwlock_wrlock(l)
11774462Salfred#define rwlock_unlock(l)	if (__isthreaded) \
11874462Salfred				_pthread_rwlock_unlock(l)
11974462Salfred
12074462Salfred#define thr_keycreate(k, d)	_pthread_key_create(k, d)
12174462Salfred#define thr_setspecific(k, p)	_pthread_setspecific(k, p)
12274462Salfred#define thr_getspecific(k)	_pthread_getspecific(k)
12374462Salfred#define thr_sigsetmask(f, n, o)	_pthread_sigmask(f, n, o)
12474462Salfred
125126243Sgreen#define thr_once(o, i)		_pthread_once(o, i)
12674462Salfred#define thr_self()		_pthread_self()
12774462Salfred#define thr_exit(x)		_pthread_exit(x)
12874462Salfred#define thr_main()		_pthread_main_np()
129