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