4 # include <win32thread.h>
6 # if defined(OLD_PTHREADS_API) && !defined(DJGPP)
8 # define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
9 # define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
10 # define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
13 if (pthread_detach(&(t)->self)) { \
14 MUTEX_UNLOCK(&(t)->mutex); \
15 croak("panic: DETACH"); \
19 # define pthread_mutexattr_default NULL
20 # define pthread_condattr_default NULL
21 # endif /* OLD_PTHREADS_API */
25 # define YIELD SCHED_YIELD
28 #ifdef PTHREAD_CREATE_JOINABLE
29 # define ATTR_JOINABLE PTHREAD_CREATE_JOINABLE
31 # ifdef PTHREAD_CREATE_UNDETACHED
32 # define ATTR_JOINABLE PTHREAD_CREATE_UNDETACHED
35 # define ATTR_JOINABLE __UNDETACHED
41 #define MUTEX_INIT(m) \
43 if (pthread_mutex_init((m), pthread_mutexattr_default)) \
44 croak("panic: MUTEX_INIT"); \
46 #define MUTEX_LOCK(m) \
48 if (pthread_mutex_lock((m))) \
49 croak("panic: MUTEX_LOCK"); \
51 #define MUTEX_UNLOCK(m) \
53 if (pthread_mutex_unlock((m))) \
54 croak("panic: MUTEX_UNLOCK"); \
56 #define MUTEX_DESTROY(m) \
58 if (pthread_mutex_destroy((m))) \
59 croak("panic: MUTEX_DESTROY"); \
61 #endif /* MUTEX_INIT */
64 #define COND_INIT(c) \
66 if (pthread_cond_init((c), pthread_condattr_default)) \
67 croak("panic: COND_INIT"); \
69 #define COND_SIGNAL(c) \
71 if (pthread_cond_signal((c))) \
72 croak("panic: COND_SIGNAL"); \
74 #define COND_BROADCAST(c) \
76 if (pthread_cond_broadcast((c))) \
77 croak("panic: COND_BROADCAST"); \
79 #define COND_WAIT(c, m) \
81 if (pthread_cond_wait((c), (m))) \
82 croak("panic: COND_WAIT"); \
84 #define COND_DESTROY(c) \
86 if (pthread_cond_destroy((c))) \
87 croak("panic: COND_DESTROY"); \
89 #endif /* COND_INIT */
91 /* DETACH(t) must only be called while holding t->mutex */
95 if (pthread_detach((t)->self)) { \
96 MUTEX_UNLOCK(&(t)->mutex); \
97 croak("panic: DETACH"); \
103 #define JOIN(t, avp) \
105 if (pthread_join((t)->self, (void**)(avp))) \
106 croak("panic: pthread_join"); \
113 if (pthread_setspecific(PL_thr_key, (void *) (t))) \
114 croak("panic: pthread_setspecific"); \
119 # ifdef OLD_PTHREADS_API
120 struct perl_thread *getTHR _((void));
121 # define THR getTHR()
123 # define THR ((struct perl_thread *) pthread_getspecific(PL_thr_key))
124 # endif /* OLD_PTHREADS_API */
128 * dTHR is performance-critical. Here, we only do the pthread_get_specific
129 * if there may be more than one thread in existence, otherwise we get thr
130 * from thrsv which is cached in the per-interpreter structure.
131 * Systems with very fast pthread_get_specific (which should be all systems
132 * but unfortunately isn't) may wish to simplify to "...*thr = THR".
136 struct perl_thread *thr = PL_threadnum? THR : (struct perl_thread*)SvPVX(PL_thrsv)
140 # ifdef NEED_PTHREAD_INIT
141 # define INIT_THREADS pthread_init()
143 # define INIT_THREADS NOOP
147 /* Accessor for per-thread SVs */
148 #define THREADSV(i) (thr->threadsvp[i])
151 * LOCK_SV_MUTEX and UNLOCK_SV_MUTEX are performance-critical. Here, we
152 * try only locking them if there may be more than one thread in existence.
153 * Systems with very fast mutexes (and/or slow conditionals) may wish to
154 * remove the "if (threadnum) ..." test.
156 #define LOCK_SV_MUTEX \
159 MUTEX_LOCK(&PL_sv_mutex); \
162 #define UNLOCK_SV_MUTEX \
165 MUTEX_UNLOCK(&PL_sv_mutex); \
168 /* Likewise for strtab_mutex */
169 #define LOCK_STRTAB_MUTEX \
172 MUTEX_LOCK(&PL_strtab_mutex); \
175 #define UNLOCK_STRTAB_MUTEX \
178 MUTEX_UNLOCK(&PL_strtab_mutex); \
181 #ifndef THREAD_RET_TYPE
182 # define THREAD_RET_TYPE void *
183 # define THREAD_RET_CAST(p) ((void *)(p))
184 #endif /* THREAD_RET */
187 /* Values and macros for thr->flags */
188 #define THRf_STATE_MASK 7
189 #define THRf_R_JOINABLE 0
190 #define THRf_R_JOINED 1
191 #define THRf_R_DETACHED 2
192 #define THRf_ZOMBIE 3
195 #define THRf_DID_DIE 8
197 /* ThrSTATE(t) and ThrSETSTATE(t) must only be called while holding t->mutex */
198 #define ThrSTATE(t) ((t)->flags & THRf_STATE_MASK)
199 #define ThrSETSTATE(t, s) STMT_START { \
200 (t)->flags &= ~THRf_STATE_MASK; \
202 DEBUG_S(PerlIO_printf(PerlIO_stderr(), \
203 "thread %p set to state %d\n", (t), (s))); \
206 typedef struct condpair {
207 perl_mutex mutex; /* Protects all other fields */
208 perl_cond owner_cond; /* For when owner changes at all */
209 perl_cond cond; /* For cond_signal and cond_broadcast */
210 Thread owner; /* Currently owning thread */
213 #define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex)
214 #define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond)
215 #define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond)
216 #define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
219 /* USE_THREADS is not defined */
220 #define MUTEX_LOCK(m)
221 #define MUTEX_UNLOCK(m)
222 #define MUTEX_INIT(m)
223 #define MUTEX_DESTROY(m)
225 #define COND_SIGNAL(c)
226 #define COND_BROADCAST(c)
227 #define COND_WAIT(c, m)
228 #define COND_DESTROY(c)
229 #define LOCK_SV_MUTEX
230 #define UNLOCK_SV_MUTEX
231 #define LOCK_STRTAB_MUTEX
232 #define UNLOCK_STRTAB_MUTEX
235 /* Rats: if dTHR is just blank then the subsequent ";" throws an error */
237 #define dTHR extern int Perl___notused
239 #define dTHR extern int errno
241 #endif /* USE_THREADS */