(__libc_lock_define_initialized): Don't use initializer since it is
[kopensolaris-gnu/glibc.git] / linuxthreads / sysdeps / pthread / bits / libc-lock.h
1 /* libc-internal interface for mutex locks.  LinuxThreads version.
2    Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #ifndef _BITS_LIBC_LOCK_H
21 #define _BITS_LIBC_LOCK_H 1
22
23 #include <pthread.h>
24
25 /* Mutex type.  */
26 #ifdef _LIBC
27 typedef pthread_mutex_t __libc_lock_t;
28 #else
29 typedef struct __libc_lock_opaque__ __libc_lock_t;
30 #endif
31
32 /* Type for key to thread-specific data.  */
33 typedef pthread_key_t __libc_key_t;
34
35 /* Define a lock variable NAME with storage class CLASS.  The lock must be
36    initialized with __libc_lock_init before it can be used (or define it
37    with __libc_lock_define_initialized, below).  Use `extern' for CLASS to
38    declare a lock defined in another module.  In public structure
39    definitions you must use a pointer to the lock structure (i.e., NAME
40    begins with a `*'), because its storage size will not be known outside
41    of libc.  */
42 #define __libc_lock_define(CLASS,NAME) \
43   CLASS __libc_lock_t NAME;
44
45 /* Define an initialized lock variable NAME with storage class CLASS.
46
47    For the C library we take a deeper look at the initializer.  For this
48    implementation all fields are initialized to zero.  Therefore we
49    don't initialize the variable which allows putting it into the BSS
50    section.  */
51 #define __libc_lock_define_initialized(CLASS,NAME) \
52   CLASS __libc_lock_t NAME;
53
54 /* Define an initialized recursive lock variable NAME with storage
55    class CLASS.  */
56 #define __libc_lock_define_initialized_recursive(CLASS,NAME) \
57   CLASS __libc_lock_t NAME = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
58
59 /* Initialize the named lock variable, leaving it in a consistent, unlocked
60    state.  */
61 #define __libc_lock_init(NAME) \
62   (__pthread_mutex_init != NULL ? __pthread_mutex_init (&(NAME), NULL) : 0);
63
64 /* Same as last but this time we initialize a recursive mutex.  */
65 #define __libc_lock_init_recursive(NAME) \
66   do {                                                                        \
67     if (__pthread_mutex_init != NULL)                                         \
68       {                                                                       \
69         pthread_mutexattr_t __attr;                                           \
70         __pthread_mutexattr_init (&__attr);                                   \
71         __pthread_mutexattr_settype (&__attr, PTHREAD_MUTEX_RECURSIVE_NP); \
72         __pthread_mutex_init (&(NAME), &__attr);                              \
73         __pthread_mutexattr_destroy (&__attr);                                \
74       }                                                                       \
75   } while (0);
76
77 /* Finalize the named lock variable, which must be locked.  It cannot be
78    used again until __libc_lock_init is called again on it.  This must be
79    called on a lock variable before the containing storage is reused.  */
80 #define __libc_lock_fini(NAME) \
81   (__pthread_mutex_destroy != NULL ? __pthread_mutex_destroy (&(NAME)) : 0);
82
83 /* Finalize recursive named lock.  */
84 #define __libc_lock_fini_recursive(NAME) __libc_lock_fini (NAME)
85
86 /* Lock the named lock variable.  */
87 #define __libc_lock_lock(NAME) \
88   (__pthread_mutex_lock != NULL ? __pthread_mutex_lock (&(NAME)) : 0);
89
90 /* Lock the recursive named lock variable.  */
91 #define __libc_lock_lock_recursive(NAME) __libc_lock_lock (NAME)
92
93 /* Try to lock the named lock variable.  */
94 #define __libc_lock_trylock(NAME) \
95   (__pthread_mutex_trylock != NULL ? __pthread_mutex_trylock (&(NAME)) : 0)
96
97 /* Try to lock the recursive named lock variable.  */
98 #define __libc_lock_trylock_recursive(NAME) __libc_lock_trylock (NAME)
99
100 /* Unlock the named lock variable.  */
101 #define __libc_lock_unlock(NAME) \
102   (__pthread_mutex_unlock != NULL ? __pthread_mutex_unlock (&(NAME)) : 0);
103
104 /* Unlock the recursive named lock variable.  */
105 #define __libc_lock_unlock_recursive(NAME) __libc_lock_unlock (NAME)
106
107
108 /* Define once control variable.  */
109 #if PTHREAD_ONCE_INIT == 0
110 /* Special case for static variables where we can avoid the initialization
111    if it is zero.  */
112 # define __libc_once_define(CLASS, NAME) \
113   CLASS pthread_once_t NAME
114 #else
115 # define __libc_once_define(CLASS, NAME) \
116   CLASS pthread_once_t NAME = PTHREAD_ONCE_INIT
117 #endif
118
119 /* Call handler iff the first call.  */
120 #define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
121   do {                                                                        \
122     if (__pthread_once != NULL)                                               \
123       __pthread_once (&(ONCE_CONTROL), (INIT_FUNCTION));                      \
124     else if ((ONCE_CONTROL) == 0) {                                           \
125       INIT_FUNCTION ();                                                       \
126       (ONCE_CONTROL) = 1;                                                     \
127     }                                                                         \
128   } while (0)
129
130
131 /* Start critical region with cleanup.  */
132 #define __libc_cleanup_region_start(FCT, ARG) \
133   { struct _pthread_cleanup_buffer _buffer;                                   \
134     int _avail = _pthread_cleanup_push_defer != NULL;                         \
135     if (_avail) {                                                             \
136       _pthread_cleanup_push_defer (&_buffer, (FCT), (ARG));                   \
137     }
138
139 /* End critical region with cleanup.  */
140 #define __libc_cleanup_region_end(DOIT) \
141     if (_avail) {                                                             \
142       _pthread_cleanup_pop_restore (&_buffer, (DOIT));                        \
143     }                                                                         \
144   }
145
146 /* Sometimes we have to exit the block in the middle.  */
147 #define __libc_cleanup_end(DOIT) \
148     if (_avail) {                                                             \
149       _pthread_cleanup_pop_restore (&_buffer, (DOIT));                        \
150     }
151
152 /* Create thread-specific key.  */
153 #define __libc_key_create(KEY, DESTRUCTOR) \
154   (__pthread_key_create != NULL ? __pthread_key_create (KEY, DESTRUCTOR) : 1)
155
156 /* Get thread-specific data.  */
157 #define __libc_getspecific(KEY) \
158   (__pthread_getspecific != NULL ? __pthread_getspecific (KEY) : NULL)
159
160 /* Set thread-specific data.  */
161 #define __libc_setspecific(KEY, VALUE) \
162   (__pthread_setspecific != NULL ? __pthread_setspecific (KEY, VALUE) : 0)
163
164
165 /* Register handlers to execute before and after `fork'.  */
166 #define __libc_atfork(PREPARE, PARENT, CHILD) \
167   (__pthread_atfork != NULL ? __pthread_atfork (PREPARE, PARENT, CHILD) : 0)
168
169
170 /* Make the pthread functions weak so that we can elide them from
171    single-threaded processes.  */
172 #ifndef __NO_WEAK_PTHREAD_ALIASES
173 # ifdef weak_extern
174 weak_extern (__pthread_mutex_init)
175 weak_extern (__pthread_mutex_destroy)
176 weak_extern (__pthread_mutex_lock)
177 weak_extern (__pthread_mutex_trylock)
178 weak_extern (__pthread_mutex_unlock)
179 weak_extern (__pthread_mutexattr_init)
180 weak_extern (__pthread_mutexattr_destroy)
181 weak_extern (__pthread_mutexattr_settype)
182 weak_extern (__pthread_key_create)
183 weak_extern (__pthread_setspecific)
184 weak_extern (__pthread_getspecific)
185 weak_extern (__pthread_once)
186 weak_extern (__pthread_initialize)
187 weak_extern (__pthread_atfork)
188 weak_extern (_pthread_cleanup_push_defer)
189 weak_extern (_pthread_cleanup_pop_restore)
190 # else
191 #  pragma weak __pthread_mutex_init
192 #  pragma weak __pthread_mutex_destroy
193 #  pragma weak __pthread_mutex_lock
194 #  pragma weak __pthread_mutex_trylock
195 #  pragma weak __pthread_mutex_unlock
196 #  pragma weak __pthread_mutexattr_init
197 #  pragma weak __pthread_mutexattr_destroy
198 #  pragma weak __pthread_mutexattr_settype
199 #  pragma weak __pthread_key_create
200 #  pragma weak __pthread_setspecific
201 #  pragma weak __pthread_getspecific
202 #  pragma weak __pthread_once
203 #  pragma weak __pthread_initialize
204 #  pragma weak __pthread_atfork
205 #  pragma weak _pthread_cleanup_push_defer
206 #  pragma weak _pthread_cleanup_pop_restore
207 # endif
208 #endif
209
210 /* We need portable names for some functions.  E.g., when they are
211    used as argument to __libc_cleanup_region_start.  */
212 #define __libc_mutex_unlock __pthread_mutex_unlock
213
214 #endif  /* bits/libc-lock.h */