DJGPP feedback for #2028.
[p5sagit/p5-mst-13.2.git] / thread.h
1 #ifdef USE_THREADS
2
3 #ifdef WIN32
4 #  include <win32thread.h>
5 #else
6 #  ifdef OLD_PTHREADS_API /* Here be dragons. */
7 #    define DETACH(t)                           \
8     STMT_START {                                \
9         if (pthread_detach(&(t)->self)) {       \
10             MUTEX_UNLOCK(&(t)->mutex);          \
11             croak("panic: DETACH");             \
12         }                                       \
13     } STMT_END
14 #    define THR getTHR()
15 struct perl_thread *getTHR _((void));
16 #    define PTHREAD_GETSPECIFIC_INT
17 #    ifdef DJGPP
18 #      define pthread_addr_t any_t
19 #      define NEED_PTHREAD_INIT
20 #      define PTHREAD_CREATE_JOINABLE (1)
21 #    endif
22 #    ifdef __OPEN_VM
23 #      define pthread_addr_t void *
24 #    endif
25 #    ifdef VMS
26 #      define pthread_attr_init(a) pthread_attr_create(a)
27 #      define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_setdetach_np(a,s)
28 #      define PTHREAD_CREATE(t,a,s,d) pthread_create(t,a,s,d)
29 #      define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
30 #      define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
31 #      define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
32 #    endif
33 #    if defined(DJGPP) || defined(__OPEN_VM)
34 #      define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_attr_setdetachstate(a,&(s))
35 #      define YIELD pthread_yield(NULL)
36 #    endif
37 #  endif
38 #  ifndef VMS
39 #    define pthread_mutexattr_default NULL
40 #    define pthread_condattr_default  NULL
41 #  endif
42 #endif
43
44 #ifndef PTHREAD_CREATE
45 /* You are not supposed to pass NULL as the 2nd arg of PTHREAD_CREATE(). */
46 #  define PTHREAD_CREATE(t,a,s,d) pthread_create(t,&(a),s,d)
47 #endif
48
49 #ifndef PTHREAD_ATTR_SETDETACHSTATE
50 #  define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_attr_setdetachstate(a,s)
51 #endif
52
53 #ifndef YIELD
54 #  ifdef SCHED_YIELD
55 #    define YIELD SCHED_YIELD
56 #  else
57 #    ifdef HAS_SCHED_YIELD
58 #      define YIELD sched_yield()
59 #    else
60 #      ifdef HAS_PTHREAD_YIELD
61     /* pthread_yield(NULL) platforms are expected
62      * to have #defined YIELD for themselves. */
63 #        define YIELD pthread_yield()
64 #      endif
65 #    endif
66 #  endif
67 #endif
68
69 #ifdef PTHREADS_CREATED_JOINABLE
70 #  define ATTR_JOINABLE PTHREAD_CREATE_JOINABLE
71 #else
72 #  ifdef PTHREAD_CREATE_UNDETACHED
73 #    define ATTR_JOINABLE PTHREAD_CREATE_UNDETACHED
74 #  else
75 #    ifdef __UNDETACHED
76 #      define ATTR_JOINABLE __UNDETACHED
77 #    endif
78 #  endif
79 #endif
80
81 #ifndef MUTEX_INIT
82 #define MUTEX_INIT(m)                                           \
83     STMT_START {                                                \
84         if (pthread_mutex_init((m), pthread_mutexattr_default)) \
85             croak("panic: MUTEX_INIT");                         \
86     } STMT_END
87 #define MUTEX_LOCK(m)                           \
88     STMT_START {                                \
89         if (pthread_mutex_lock((m)))            \
90             croak("panic: MUTEX_LOCK");         \
91     } STMT_END
92 #define MUTEX_UNLOCK(m)                         \
93     STMT_START {                                \
94         if (pthread_mutex_unlock((m)))          \
95             croak("panic: MUTEX_UNLOCK");       \
96     } STMT_END
97 #define MUTEX_DESTROY(m)                        \
98     STMT_START {                                \
99         if (pthread_mutex_destroy((m)))         \
100             croak("panic: MUTEX_DESTROY");      \
101     } STMT_END
102 #endif /* MUTEX_INIT */
103
104 #ifndef COND_INIT
105 #define COND_INIT(c)                                            \
106     STMT_START {                                                \
107         if (pthread_cond_init((c), pthread_condattr_default))   \
108             croak("panic: COND_INIT");                          \
109     } STMT_END
110 #define COND_SIGNAL(c)                          \
111     STMT_START {                                \
112         if (pthread_cond_signal((c)))           \
113             croak("panic: COND_SIGNAL");        \
114     } STMT_END
115 #define COND_BROADCAST(c)                       \
116     STMT_START {                                \
117         if (pthread_cond_broadcast((c)))        \
118             croak("panic: COND_BROADCAST");     \
119     } STMT_END
120 #define COND_WAIT(c, m)                         \
121     STMT_START {                                \
122         if (pthread_cond_wait((c), (m)))        \
123             croak("panic: COND_WAIT");          \
124     } STMT_END
125 #define COND_DESTROY(c)                         \
126     STMT_START {                                \
127         if (pthread_cond_destroy((c)))          \
128             croak("panic: COND_DESTROY");       \
129     } STMT_END
130 #endif /* COND_INIT */
131
132 /* DETACH(t) must only be called while holding t->mutex */
133 #ifndef DETACH
134 #define DETACH(t)                               \
135     STMT_START {                                \
136         if (pthread_detach((t)->self)) {        \
137             MUTEX_UNLOCK(&(t)->mutex);          \
138             croak("panic: DETACH");             \
139         }                                       \
140     } STMT_END
141 #endif /* DETACH */
142
143 #ifndef JOIN
144 #define JOIN(t, avp)                                    \
145     STMT_START {                                        \
146         if (pthread_join((t)->self, (void**)(avp)))     \
147             croak("panic: pthread_join");               \
148     } STMT_END
149 #endif /* JOIN */
150
151 #ifndef SET_THR
152 #define SET_THR(t)                                      \
153     STMT_START {                                        \
154         if (pthread_setspecific(PL_thr_key, (void *) (t)))      \
155             croak("panic: pthread_setspecific");        \
156     } STMT_END
157 #endif /* SET_THR */
158
159 #ifndef THR
160 #define THR ((struct perl_thread *) pthread_getspecific(PL_thr_key))
161 #endif
162
163 /*
164  * dTHR is performance-critical. Here, we only do the pthread_get_specific
165  * if there may be more than one thread in existence, otherwise we get thr
166  * from thrsv which is cached in the per-interpreter structure.
167  * Systems with very fast pthread_get_specific (which should be all systems
168  * but unfortunately isn't) may wish to simplify to "...*thr = THR".
169  */
170 #ifndef dTHR
171 #  define dTHR \
172     struct perl_thread *thr = PL_threadnum? THR : (struct perl_thread*)SvPVX(PL_thrsv)
173 #endif /* dTHR */
174
175 #ifndef INIT_THREADS
176 #  ifdef NEED_PTHREAD_INIT
177 #    define INIT_THREADS pthread_init()
178 #  else
179 #    define INIT_THREADS NOOP
180 #  endif
181 #endif
182
183 /* Accessor for per-thread SVs */
184 #define THREADSV(i) (thr->threadsvp[i])
185
186 /*
187  * LOCK_SV_MUTEX and UNLOCK_SV_MUTEX are performance-critical. Here, we
188  * try only locking them if there may be more than one thread in existence.
189  * Systems with very fast mutexes (and/or slow conditionals) may wish to
190  * remove the "if (threadnum) ..." test.
191  */
192 #define LOCK_SV_MUTEX                           \
193     STMT_START {                                \
194         if (PL_threadnum)                       \
195             MUTEX_LOCK(&PL_sv_mutex);           \
196     } STMT_END
197
198 #define UNLOCK_SV_MUTEX                         \
199     STMT_START {                                \
200         if (PL_threadnum)                       \
201             MUTEX_UNLOCK(&PL_sv_mutex);         \
202     } STMT_END
203
204 /* Likewise for strtab_mutex */
205 #define LOCK_STRTAB_MUTEX                       \
206     STMT_START {                                \
207         if (PL_threadnum)                       \
208             MUTEX_LOCK(&PL_strtab_mutex);       \
209     } STMT_END
210
211 #define UNLOCK_STRTAB_MUTEX                     \
212     STMT_START {                                \
213         if (PL_threadnum)                       \
214             MUTEX_UNLOCK(&PL_strtab_mutex);     \
215     } STMT_END
216
217 #ifndef THREAD_RET_TYPE
218 #  define THREAD_RET_TYPE       void *
219 #  define THREAD_RET_CAST(p)    ((void *)(p))
220 #endif /* THREAD_RET */
221
222
223 /* Values and macros for thr->flags */
224 #define THRf_STATE_MASK 7
225 #define THRf_R_JOINABLE 0
226 #define THRf_R_JOINED   1
227 #define THRf_R_DETACHED 2
228 #define THRf_ZOMBIE     3
229 #define THRf_DEAD       4
230
231 #define THRf_DID_DIE    8
232
233 /* ThrSTATE(t) and ThrSETSTATE(t) must only be called while holding t->mutex */
234 #define ThrSTATE(t) ((t)->flags & THRf_STATE_MASK)
235 #define ThrSETSTATE(t, s) STMT_START {          \
236         (t)->flags &= ~THRf_STATE_MASK;         \
237         (t)->flags |= (s);                      \
238         DEBUG_S(PerlIO_printf(PerlIO_stderr(),  \
239                               "thread %p set to state %d\n", (t), (s))); \
240     } STMT_END
241
242 typedef struct condpair {
243     perl_mutex  mutex;          /* Protects all other fields */
244     perl_cond   owner_cond;     /* For when owner changes at all */
245     perl_cond   cond;           /* For cond_signal and cond_broadcast */
246     Thread      owner;          /* Currently owning thread */
247 } condpair_t;
248
249 #define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex)
250 #define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond)
251 #define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond)
252 #define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
253
254 #else
255 /* USE_THREADS is not defined */
256 #define MUTEX_LOCK(m)
257 #define MUTEX_UNLOCK(m)
258 #define MUTEX_INIT(m)
259 #define MUTEX_DESTROY(m)
260 #define COND_INIT(c)
261 #define COND_SIGNAL(c)
262 #define COND_BROADCAST(c)
263 #define COND_WAIT(c, m)
264 #define COND_DESTROY(c)
265 #define LOCK_SV_MUTEX
266 #define UNLOCK_SV_MUTEX
267 #define LOCK_STRTAB_MUTEX
268 #define UNLOCK_STRTAB_MUTEX
269
270 #define THR
271 /* Rats: if dTHR is just blank then the subsequent ";" throws an error */
272 #ifdef WIN32
273 #define dTHR extern int Perl___notused
274 #else
275 #define dTHR extern int errno
276 #endif
277 #endif /* USE_THREADS */