1 /* Basic platform-independent macro definitions for mutexes and
3 Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Wolfram Gloger <wmglo@dent.med.uni-muenchen.de>, 1996.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with the GNU C Library; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
23 One out of _LIBC, USE_PTHREADS, USE_THR or USE_SPROC should be
24 defined, otherwise the token NO_THREADS and dummy implementations
25 of the macros will be defined. */
30 #undef thread_atfork_static
32 #if defined(_LIBC) /* The GNU C library, a special case of Posix threads */
34 #include <bits/libc-lock.h>
36 #ifdef PTHREAD_MUTEX_INITIALIZER
38 typedef pthread_t thread_id
;
41 typedef pthread_mutex_t mutex_t
;
43 #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
45 /* Even if not linking with libpthread, ensure usability of mutex as
46 an `in use' flag, see also the NO_THREADS case below. Assume
47 pthread_mutex_t is at least one int wide. */
49 #define mutex_init(m) \
50 (__pthread_mutex_init != NULL \
51 ? __pthread_mutex_init (m, NULL) : (*(int *)(m) = 0))
52 #define mutex_lock(m) \
53 (__pthread_mutex_lock != NULL \
54 ? __pthread_mutex_lock (m) : ((*(int *)(m) = 1), 0))
55 #define mutex_trylock(m) \
56 (__pthread_mutex_trylock != NULL \
57 ? __pthread_mutex_trylock (m) : (*(int *)(m) ? 1 : ((*(int *)(m) = 1), 0)))
58 #define mutex_unlock(m) \
59 (__pthread_mutex_unlock != NULL \
60 ? __pthread_mutex_unlock (m) : (*(int*)(m) = 0))
62 #define thread_atfork(prepare, parent, child) \
63 (__pthread_atfork != NULL ? __pthread_atfork(prepare, parent, child) : 0)
65 #elif defined(MUTEX_INITIALIZER)
66 /* Assume hurd, with cthreads */
68 /* Cthreads `mutex_t' is a pointer to a mutex, and malloc wants just the
71 #define mutex_t struct mutex
74 #define mutex_init(m) (__mutex_init(m), 0)
77 #define mutex_lock(m) (__mutex_lock(m), 0)
80 #define mutex_unlock(m) (__mutex_unlock(m), 0)
82 #define mutex_trylock(m) (!__mutex_trylock(m))
84 #define thread_atfork(prepare, parent, child) do {} while(0)
85 #define thread_atfork_static(prepare, parent, child) \
86 text_set_element(_hurd_fork_prepare_hook, prepare); \
87 text_set_element(_hurd_fork_parent_hook, parent); \
88 text_set_element(_hurd_fork_child_hook, child);
90 /* No we're *not* using pthreads. */
91 #define __pthread_initialize ((void (*)(void))0)
97 #endif /* MUTEX_INITIALIZER && PTHREAD_MUTEX_INITIALIZER */
101 /* thread specific data for glibc */
103 #include <bits/libc-tsd.h>
105 typedef int tsd_key_t
[1]; /* no key data structure, libc magic does it */
106 __libc_tsd_define (, MALLOC
) /* declaration/common definition */
107 #define tsd_key_create(key, destr) ((void) (key))
108 #define tsd_setspecific(key, data) __libc_tsd_set (MALLOC, (data))
109 #define tsd_getspecific(key, vptr) ((vptr) = __libc_tsd_get (MALLOC))
113 #elif defined(USE_PTHREADS) /* Posix threads */
117 typedef pthread_t thread_id
;
120 typedef pthread_mutex_t mutex_t
;
122 #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
123 #define mutex_init(m) pthread_mutex_init(m, NULL)
124 #define mutex_lock(m) pthread_mutex_lock(m)
125 #define mutex_trylock(m) pthread_mutex_trylock(m)
126 #define mutex_unlock(m) pthread_mutex_unlock(m)
128 /* thread specific data */
129 #if defined(__sgi) || defined(USE_TSD_DATA_HACK)
131 /* Hack for thread-specific data, e.g. on Irix 6.x. We can't use
132 pthread_setspecific because that function calls malloc() itself.
133 The hack only works when pthread_t can be converted to an integral
136 typedef void *tsd_key_t
[256];
137 #define tsd_key_create(key, destr) do { \
139 for(i=0; i<256; i++) (*key)[i] = 0; \
141 #define tsd_setspecific(key, data) \
142 (key[(unsigned)pthread_self() % 256] = (data))
143 #define tsd_getspecific(key, vptr) \
144 (vptr = key[(unsigned)pthread_self() % 256])
148 typedef pthread_key_t tsd_key_t
;
150 #define tsd_key_create(key, destr) pthread_key_create(key, destr)
151 #define tsd_setspecific(key, data) pthread_setspecific(key, data)
152 #define tsd_getspecific(key, vptr) (vptr = pthread_getspecific(key))
157 #define thread_atfork(prepare, parent, child) \
158 pthread_atfork(prepare, parent, child)
160 #elif USE_THR /* Solaris threads */
164 typedef thread_t thread_id
;
166 #define MUTEX_INITIALIZER { 0 }
167 #define mutex_init(m) mutex_init(m, USYNC_THREAD, NULL)
170 * Hack for thread-specific data on Solaris. We can't use thr_setspecific
171 * because that function calls malloc() itself.
173 typedef void *tsd_key_t
[256];
174 #define tsd_key_create(key, destr) do { \
176 for(i=0; i<256; i++) (*key)[i] = 0; \
178 #define tsd_setspecific(key, data) (key[(unsigned)thr_self() % 256] = (data))
179 #define tsd_getspecific(key, vptr) (vptr = key[(unsigned)thr_self() % 256])
181 #define thread_atfork(prepare, parent, child) do {} while(0)
183 #elif USE_SPROC /* SGI sproc() threads */
185 #include <sys/wait.h>
186 #include <sys/types.h>
187 #include <sys/prctl.h>
188 #include <abi_mutex.h>
190 typedef int thread_id
;
192 typedef abilock_t mutex_t
;
194 #define MUTEX_INITIALIZER { 0 }
195 #define mutex_init(m) init_lock(m)
196 #define mutex_lock(m) (spin_lock(m), 0)
197 #define mutex_trylock(m) acquire_lock(m)
198 #define mutex_unlock(m) release_lock(m)
200 typedef int tsd_key_t
;
202 #define tsd_key_create(key, destr) ((*key) = tsd_key_next++)
203 #define tsd_setspecific(key, data) (((void **)(&PRDA->usr_prda))[key] = data)
204 #define tsd_getspecific(key, vptr) (vptr = ((void **)(&PRDA->usr_prda))[key])
206 #define thread_atfork(prepare, parent, child) do {} while(0)
208 #else /* no _LIBC or USE_... are defined */
212 #endif /* defined(_LIBC) */
214 #ifdef NO_THREADS /* No threads, provide dummy macros */
216 typedef int thread_id
;
218 /* The mutex functions used to do absolutely nothing, i.e. lock,
219 trylock and unlock would always just return 0. However, even
220 without any concurrently active threads, a mutex can be used
221 legitimately as an `in use' flag. To make the code that is
222 protected by a mutex async-signal safe, these macros would have to
223 be based on atomic test-and-set operations, for example. */
226 #define MUTEX_INITIALIZER 0
227 #define mutex_init(m) (*(m) = 0)
228 #define mutex_lock(m) ((*(m) = 1), 0)
229 #define mutex_trylock(m) (*(m) ? 1 : ((*(m) = 1), 0))
230 #define mutex_unlock(m) (*(m) = 0)
232 typedef void *tsd_key_t
;
233 #define tsd_key_create(key, destr) do {} while(0)
234 #define tsd_setspecific(key, data) ((key) = (data))
235 #define tsd_getspecific(key, vptr) (vptr = (key))
237 #define thread_atfork(prepare, parent, child) do {} while(0)
239 #endif /* defined(NO_THREADS) */
241 #endif /* !defined(_THREAD_M_H) */