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