1 /* Implement a trivial subset of POSIX 1003.1-2008 pthread.h.
2 
3    Copyright (C) 2009-2016 Free Software Foundation, Inc.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3, or (at your option)
8    any later version.
9 
10    This program 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
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, see <http://www.gnu.org/licenses/>.  */
17 
18 /* Written by Paul Eggert and Glen Lenker.  */
19 
20 #ifndef _@GUARD_PREFIX@_PTHREAD_H_
21 
22 #if __GNUC__ >= 3
23 @PRAGMA_SYSTEM_HEADER@
24 #endif
25 @PRAGMA_COLUMNS@
26 
27 /* The include_next requires a split double-inclusion guard.  */
28 #if @HAVE_PTHREAD_H@
29 # @INCLUDE_NEXT@ @NEXT_PTHREAD_H@
30 #endif
31 
32 #ifndef _@GUARD_PREFIX@_PTHREAD_H_
33 #define _@GUARD_PREFIX@_PTHREAD_H_
34 
35 #define __need_system_stdlib_h
36 #include <stdlib.h>
37 #undef __need_system_stdlib_h
38 
39 
40 /* The pthreads-win32 <pthread.h> defines a couple of broken macros.  */
41 #undef asctime_r
42 #undef ctime_r
43 #undef gmtime_r
44 #undef localtime_r
45 #undef rand_r
46 #undef strtok_r
47 
48 #include <errno.h>
49 #include <sched.h>
50 #include <sys/types.h>
51 #include <time.h>
52 
53 #ifndef _GL_INLINE_HEADER_BEGIN
54  #error "Please include config.h first."
55 #endif
56 _GL_INLINE_HEADER_BEGIN
57 #ifndef _GL_PTHREAD_INLINE
58 # define _GL_PTHREAD_INLINE _GL_INLINE
59 #endif
60 
61 #if ! @HAVE_PTHREAD_T@
62 # if !GNULIB_defined_pthread_types
63  typedef int pthread_t;
64  typedef int pthread_attr_t;
65  typedef int pthread_barrier_t;
66  typedef int pthread_barrierattr_t;
67  typedef int pthread_cond_t;
68  typedef int pthread_condattr_t;
69  typedef int pthread_key_t;
70  typedef int pthread_mutex_t;
71  typedef int pthread_mutexattr_t;
72  typedef int pthread_once_t;
73  typedef int pthread_rwlock_t;
74  typedef int pthread_rwlockattr_t;
75 #  define GNULIB_defined_pthread_types 1
76 # endif
77 #endif
78 
79 #ifndef PTHREAD_COND_INITIALIZER
80 #define PTHREAD_COND_INITIALIZER { 0 }
81 #define PTHREAD_MUTEX_INITIALIZER { 0 }
82 #define PTHREAD_ONCE_INIT { 0 }
83 #define PTHREAD_RWLOCK_INITIALIZER { 0 }
84 
85 #define PTHREAD_BARRIER_SERIAL_THREAD (-1)
86 
87 #define PTHREAD_CANCEL_DEFERRED 0
88 #define PTHREAD_CANCEL_ASYNCHRONOUS 1
89 
90 #define PTHREAD_CANCEL_ENABLE 0
91 #define PTHREAD_CANCEL_DISABLE 1
92 
93 #define PTHREAD_CANCELED ((void *) -1)
94 
95 #define PTHREAD_CREATE_JOINABLE 0
96 #define PTHREAD_CREATE_DETACHED 1
97 
98 #define PTHREAD_INHERIT_SCHED 0
99 #define PTHREAD_EXPLICIT_SCHED 1
100 
101 #define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
102 #define PTHREAD_MUTEX_NORMAL 0
103 #define PTHREAD_MUTEX_ERRORCHECK 1
104 #define PTHREAD_MUTEX_RECURSIVE 2
105 
106 #define PTHREAD_MUTEX_STALLED 0
107 #define PTHREAD_MUTEX_ROBUST 1
108 
109 #define PTHREAD_PRIO_NONE 0
110 #define PTHREAD_PRIO_INHERIT 1
111 #define PTHREAD_PRIO_PROTECT 2
112 
113 #define PTHREAD_PROCESS_PRIVATE 0
114 #define PTHREAD_PROCESS_SHARED 1
115 
116 #define PTHREAD_SCOPE_SYSTEM 0
117 #define PTHREAD_SCOPE_PROCESS 1
118 #endif
119 
120 #if ! @HAVE_PTHREAD_T@
121 
122 # if !GNULIB_defined_pthread_functions
123 
124 /* Provide substitutes for the thread functions that should work
125    adequately on a single-threaded implementation, where
126    pthread_create always fails.  The goal is to let programs compile
127    on non-pthread hosts with minimal runtime overhead.
128 
129    Omit interfaces that have not been analyzed and for which we do not
130    know what to do, so that they elicit a compile-time error for
131    now.  */
132 
133 _GL_PTHREAD_INLINE int
pthread_cond_destroy(pthread_cond_t * cond)134 pthread_cond_destroy (pthread_cond_t *cond)
135 {
136   /* COND is never seriously used.  */
137   return 0;
138 }
139 
140 _GL_PTHREAD_INLINE int
pthread_cond_init(pthread_cond_t * restrict cond,pthread_condattr_t const * restrict attr)141 pthread_cond_init (pthread_cond_t *restrict cond,
142                    pthread_condattr_t const *restrict attr)
143 {
144   /* COND is never seriously used.  */
145   return 0;
146 }
147 
148 _GL_PTHREAD_INLINE int
pthread_cond_signal(pthread_cond_t * cond)149 pthread_cond_signal (pthread_cond_t *cond)
150 {
151   /* No threads can currently be blocked on COND.  */
152   return 0;
153 }
154 
155 _GL_PTHREAD_INLINE int
pthread_cond_wait(pthread_cond_t * restrict cond,pthread_mutex_t * restrict mutex)156 pthread_cond_wait (pthread_cond_t *restrict cond,
157                    pthread_mutex_t *restrict mutex)
158 {
159   /* Properly-written applications never come here.  */
160   abort ();
161   return 0;
162 }
163 
164 _GL_PTHREAD_INLINE int
pthread_create(pthread_t * restrict thread,pthread_attr_t const * restrict attr,void * (* start_routine)(void *),void * restrict arg)165 pthread_create (pthread_t *restrict thread,
166                 pthread_attr_t const *restrict attr,
167                 void * (*start_routine) (void*), void *restrict arg)
168 {
169   /* Do not create a thread.  */
170   return EAGAIN;
171 }
172 
173 _GL_PTHREAD_INLINE void
pthread_exit(void * value)174 pthread_exit (void *value)
175 {
176   /* There is just one thread, so the process exits.  */
177   exit (0);
178 }
179 
180 _GL_PTHREAD_INLINE int
pthread_join(pthread_t thread,void ** pvalue)181 pthread_join (pthread_t thread, void **pvalue)
182 {
183   /* Properly-written applications never come here.  */
184   abort ();
185   return 0;
186 }
187 
188 _GL_PTHREAD_INLINE int
pthread_mutexattr_destroy(pthread_mutexattr_t * attr)189 pthread_mutexattr_destroy (pthread_mutexattr_t *attr)
190 {
191   return 0;
192 }
193 
194 _GL_PTHREAD_INLINE int
pthread_mutexattr_init(pthread_mutexattr_t * attr)195 pthread_mutexattr_init (pthread_mutexattr_t *attr)
196 {
197   return 0;
198 }
199 
200 _GL_PTHREAD_INLINE int
pthread_mutexattr_settype(pthread_mutexattr_t * attr,int attr_type)201 pthread_mutexattr_settype (pthread_mutexattr_t *attr, int attr_type)
202 {
203   return 0;
204 }
205 
206 _GL_PTHREAD_INLINE int
pthread_mutex_destroy(pthread_mutex_t * mutex)207 pthread_mutex_destroy (pthread_mutex_t *mutex)
208 {
209   /* MUTEX is never seriously used.  */
210   return 0;
211 }
212 
213 _GL_PTHREAD_INLINE int
pthread_mutex_init(pthread_mutex_t * restrict mutex,pthread_mutexattr_t const * restrict attr)214 pthread_mutex_init (pthread_mutex_t *restrict mutex,
215                     pthread_mutexattr_t const *restrict attr)
216 {
217   /* MUTEX is never seriously used.  */
218   return 0;
219 }
220 
221 _GL_PTHREAD_INLINE int
pthread_mutex_lock(pthread_mutex_t * mutex)222 pthread_mutex_lock (pthread_mutex_t *mutex)
223 {
224   /* There is only one thread, so it always gets the lock.  This
225      implementation does not support PTHREAD_MUTEX_ERRORCHECK.  */
226   return 0;
227 }
228 
229 _GL_PTHREAD_INLINE int
pthread_mutex_trylock(pthread_mutex_t * mutex)230 pthread_mutex_trylock (pthread_mutex_t *mutex)
231 {
232   return pthread_mutex_lock (mutex);
233 }
234 
235 _GL_PTHREAD_INLINE int
pthread_mutex_unlock(pthread_mutex_t * mutex)236 pthread_mutex_unlock (pthread_mutex_t *mutex)
237 {
238   /* There is only one thread, so it always unlocks successfully.
239      This implementation does not support robust mutexes or
240      PTHREAD_MUTEX_ERRORCHECK.  */
241   return 0;
242 }
243 
244 #  define GNULIB_defined_pthread_functions 1
245 # endif
246 
247 #endif
248 
249 #if ! @HAVE_PTHREAD_SPINLOCK_T@
250 
251 # if !GNULIB_defined_pthread_spinlock_t
252 
253 /* Approximate spinlocks with mutexes.  */
254 
255 typedef pthread_mutex_t pthread_spinlock_t;
256 
257 _GL_PTHREAD_INLINE int
pthread_spin_init(pthread_spinlock_t * lock,int pshared)258 pthread_spin_init (pthread_spinlock_t *lock, int pshared)
259 {
260   return pthread_mutex_init (lock, NULL);
261 }
262 
263 _GL_PTHREAD_INLINE int
pthread_spin_destroy(pthread_spinlock_t * lock)264 pthread_spin_destroy (pthread_spinlock_t *lock)
265 {
266   return pthread_mutex_destroy (lock);
267 }
268 
269 _GL_PTHREAD_INLINE int
pthread_spin_lock(pthread_spinlock_t * lock)270 pthread_spin_lock (pthread_spinlock_t *lock)
271 {
272   return pthread_mutex_lock (lock);
273 }
274 
275 _GL_PTHREAD_INLINE int
pthread_spin_trylock(pthread_spinlock_t * lock)276 pthread_spin_trylock (pthread_spinlock_t *lock)
277 {
278   return pthread_mutex_trylock (lock);
279 }
280 
281 _GL_PTHREAD_INLINE int
pthread_spin_unlock(pthread_spinlock_t * lock)282 pthread_spin_unlock (pthread_spinlock_t *lock)
283 {
284   return pthread_mutex_unlock (lock);
285 }
286 
287 #  define GNULIB_defined_pthread_spinlock_t 1
288 # endif
289 
290 #endif
291 
292 _GL_INLINE_HEADER_END
293 
294 #endif /* _@GUARD_PREFIX@_PTHREAD_H_ */
295 #endif /* _@GUARD_PREFIX@_PTHREAD_H_ */
296