4 # include <win32thread.h>
6 # ifdef OLD_PTHREADS_API /* Here be dragons. */
9 if (pthread_detach(&(t)->self)) { \
10 MUTEX_UNLOCK(&(t)->mutex); \
11 croak("panic: DETACH"); \
15 struct perl_thread *getTHR _((void));
16 # define PTHREAD_GETSPECIFIC_INT
18 # define pthread_addr_t any_t
19 # define NEED_PTHREAD_INIT
20 # define PTHREAD_CREATE_JOINABLE (&err)
23 # define pthread_addr_t void *
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)
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)
36 # if defined(DJGPP) || defined(VMS)
37 # define PTHREAD_CREATE(t,a,s,d) pthread_create(t,a,s,d)
41 # define pthread_mutexattr_default NULL
42 # define pthread_condattr_default NULL
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)
51 #ifndef PTHREAD_ATTR_SETDETACHSTATE
52 # define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_attr_setdetachstate(a,s)
57 # define YIELD SCHED_YIELD
59 # ifdef HAS_SCHED_YIELD
60 # define YIELD sched_yield()
62 # ifdef HAS_PTHREAD_YIELD
63 /* pthread_yield(NULL) platforms are expected
64 * to have #defined YIELD for themselves. */
65 # define YIELD pthread_yield()
71 #ifdef PTHREADS_CREATED_JOINABLE
72 # define ATTR_JOINABLE PTHREAD_CREATE_JOINABLE
74 # ifdef PTHREAD_CREATE_UNDETACHED
75 # define ATTR_JOINABLE PTHREAD_CREATE_UNDETACHED
78 # define ATTR_JOINABLE __UNDETACHED
84 #define MUTEX_INIT(m) \
86 if (pthread_mutex_init((m), pthread_mutexattr_default)) \
87 croak("panic: MUTEX_INIT"); \
89 #define MUTEX_LOCK(m) \
91 if (pthread_mutex_lock((m))) \
92 croak("panic: MUTEX_LOCK"); \
94 #define MUTEX_UNLOCK(m) \
96 if (pthread_mutex_unlock((m))) \
97 croak("panic: MUTEX_UNLOCK"); \
99 #define MUTEX_DESTROY(m) \
101 if (pthread_mutex_destroy((m))) \
102 croak("panic: MUTEX_DESTROY"); \
104 #endif /* MUTEX_INIT */
107 #define COND_INIT(c) \
109 if (pthread_cond_init((c), pthread_condattr_default)) \
110 croak("panic: COND_INIT"); \
112 #define COND_SIGNAL(c) \
114 if (pthread_cond_signal((c))) \
115 croak("panic: COND_SIGNAL"); \
117 #define COND_BROADCAST(c) \
119 if (pthread_cond_broadcast((c))) \
120 croak("panic: COND_BROADCAST"); \
122 #define COND_WAIT(c, m) \
124 if (pthread_cond_wait((c), (m))) \
125 croak("panic: COND_WAIT"); \
127 #define COND_DESTROY(c) \
129 if (pthread_cond_destroy((c))) \
130 croak("panic: COND_DESTROY"); \
132 #endif /* COND_INIT */
134 /* DETACH(t) must only be called while holding t->mutex */
138 if (pthread_detach((t)->self)) { \
139 MUTEX_UNLOCK(&(t)->mutex); \
140 croak("panic: DETACH"); \
146 #define JOIN(t, avp) \
148 if (pthread_join((t)->self, (void**)(avp))) \
149 croak("panic: pthread_join"); \
156 if (pthread_setspecific(PL_thr_key, (void *) (t))) \
157 croak("panic: pthread_setspecific"); \
162 #define THR ((struct perl_thread *) pthread_getspecific(PL_thr_key))
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".
174 struct perl_thread *thr = PL_threadnum? THR : (struct perl_thread*)SvPVX(PL_thrsv)
178 # ifdef NEED_PTHREAD_INIT
179 # define INIT_THREADS pthread_init()
181 # define INIT_THREADS NOOP
185 /* Accessor for per-thread SVs */
186 #define THREADSV(i) (thr->threadsvp[i])
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.
194 #define LOCK_SV_MUTEX \
197 MUTEX_LOCK(&PL_sv_mutex); \
200 #define UNLOCK_SV_MUTEX \
203 MUTEX_UNLOCK(&PL_sv_mutex); \
206 /* Likewise for strtab_mutex */
207 #define LOCK_STRTAB_MUTEX \
210 MUTEX_LOCK(&PL_strtab_mutex); \
213 #define UNLOCK_STRTAB_MUTEX \
216 MUTEX_UNLOCK(&PL_strtab_mutex); \
219 #ifndef THREAD_RET_TYPE
220 # define THREAD_RET_TYPE void *
221 # define THREAD_RET_CAST(p) ((void *)(p))
222 #endif /* THREAD_RET */
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
233 #define THRf_DID_DIE 8
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; \
240 DEBUG_S(PerlIO_printf(PerlIO_stderr(), \
241 "thread %p set to state %d\n", (t), (s))); \
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 */
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
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)
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
273 /* Rats: if dTHR is just blank then the subsequent ";" throws an error */
275 #define dTHR extern int Perl___notused
277 #define dTHR extern int errno
279 #endif /* USE_THREADS */