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