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