4 # include <win32thread.h>
8 #ifdef OLD_PTHREADS_API
9 # define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
10 # define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
11 # define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
12 # define YIELD pthread_yield()
15 if (pthread_detach(&(t)->self)) { \
16 MUTEX_UNLOCK(&(t)->mutex); \
17 croak("panic: DETACH"); \
21 # define pthread_mutexattr_default NULL
22 # define pthread_condattr_default NULL
23 #endif /* OLD_PTHREADS_API */
26 #ifdef PTHREADS_CREATED_JOINABLE
27 # define ATTR_JOINABLE PTHREAD_CREATE_JOINABLE
29 # ifdef PTHREAD_CREATE_UNDETACHED
30 # define ATTR_JOINABLE PTHREAD_CREATE_UNDETACHED
32 # define ATTR_JOINABLE PTHREAD_CREATE_JOINABLE
37 # ifdef HAS_PTHREAD_YIELD
38 # define YIELD pthread_yield()
40 # define YIELD sched_yield()
45 #define MUTEX_INIT(m) \
47 if (pthread_mutex_init((m), pthread_mutexattr_default)) \
48 croak("panic: MUTEX_INIT"); \
50 #define MUTEX_LOCK(m) \
52 if (pthread_mutex_lock((m))) \
53 croak("panic: MUTEX_LOCK"); \
55 #define MUTEX_UNLOCK(m) \
57 if (pthread_mutex_unlock((m))) \
58 croak("panic: MUTEX_UNLOCK"); \
60 #define MUTEX_DESTROY(m) \
62 if (pthread_mutex_destroy((m))) \
63 croak("panic: MUTEX_DESTROY"); \
65 #endif /* MUTEX_INIT */
68 #define COND_INIT(c) \
70 if (pthread_cond_init((c), pthread_condattr_default)) \
71 croak("panic: COND_INIT"); \
73 #define COND_SIGNAL(c) \
75 if (pthread_cond_signal((c))) \
76 croak("panic: COND_SIGNAL"); \
78 #define COND_BROADCAST(c) \
80 if (pthread_cond_broadcast((c))) \
81 croak("panic: COND_BROADCAST"); \
83 #define COND_WAIT(c, m) \
85 if (pthread_cond_wait((c), (m))) \
86 croak("panic: COND_WAIT"); \
88 #define COND_DESTROY(c) \
90 if (pthread_cond_destroy((c))) \
91 croak("panic: COND_DESTROY"); \
93 #endif /* COND_INIT */
95 /* DETACH(t) must only be called while holding t->mutex */
99 if (pthread_detach((t)->self)) { \
100 MUTEX_UNLOCK(&(t)->mutex); \
101 croak("panic: DETACH"); \
107 #define JOIN(t, avp) \
109 if (pthread_join((t)->self, (void**)(avp))) \
110 croak("panic: pthread_join"); \
117 if (pthread_setspecific(thr_key, (void *) (t))) \
118 croak("panic: pthread_setspecific"); \
123 # ifdef OLD_PTHREADS_API
124 struct perl_thread *getTHR _((void));
125 # define THR getTHR()
127 # define THR ((struct perl_thread *) pthread_getspecific(thr_key))
128 # endif /* OLD_PTHREADS_API */
132 * dTHR is performance-critical. Here, we only do the pthread_get_specific
133 * if there may be more than one thread in existence, otherwise we get thr
134 * from thrsv which is cached in the per-interpreter structure.
135 * Systems with very fast pthread_get_specific (which should be all systems
136 * but unfortunately isn't) may wish to simplify to "...*thr = THR".
140 struct perl_thread *thr = threadnum? THR : (struct perl_thread*)SvPVX(thrsv)
144 # ifdef NEED_PTHREAD_INIT
145 # define INIT_THREADS pthread_init()
147 # define INIT_THREADS NOOP
151 /* Accessor for per-thread SVs */
152 #define THREADSV(i) (thr->threadsvp[i])
155 * LOCK_SV_MUTEX and UNLOCK_SV_MUTEX are performance-critical. Here, we
156 * try only locking them if there may be more than one thread in existence.
157 * Systems with very fast mutexes (and/or slow conditionals) may wish to
158 * remove the "if (threadnum) ..." test.
160 #define LOCK_SV_MUTEX \
163 MUTEX_LOCK(&sv_mutex); \
166 #define UNLOCK_SV_MUTEX \
169 MUTEX_UNLOCK(&sv_mutex); \
172 #ifndef THREAD_RET_TYPE
173 # define THREAD_RET_TYPE void *
174 # define THREAD_RET_CAST(p) ((void *)(p))
175 #endif /* THREAD_RET */
178 /* Values and macros for thr->flags */
179 #define THRf_STATE_MASK 7
180 #define THRf_R_JOINABLE 0
181 #define THRf_R_JOINED 1
182 #define THRf_R_DETACHED 2
183 #define THRf_ZOMBIE 3
186 #define THRf_DID_DIE 8
188 /* ThrSTATE(t) and ThrSETSTATE(t) must only be called while holding t->mutex */
189 #define ThrSTATE(t) ((t)->flags & THRf_STATE_MASK)
190 #define ThrSETSTATE(t, s) STMT_START { \
191 (t)->flags &= ~THRf_STATE_MASK; \
193 DEBUG_L(PerlIO_printf(PerlIO_stderr(), \
194 "thread %p set to state %d\n", (t), (s))); \
197 typedef struct condpair {
198 perl_mutex mutex; /* Protects all other fields */
199 perl_cond owner_cond; /* For when owner changes at all */
200 perl_cond cond; /* For cond_signal and cond_broadcast */
201 Thread owner; /* Currently owning thread */
204 #define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex)
205 #define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond)
206 #define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond)
207 #define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
210 /* USE_THREADS is not defined */
211 #define MUTEX_LOCK(m)
212 #define MUTEX_UNLOCK(m)
213 #define MUTEX_INIT(m)
214 #define MUTEX_DESTROY(m)
216 #define COND_SIGNAL(c)
217 #define COND_BROADCAST(c)
218 #define COND_WAIT(c, m)
219 #define COND_DESTROY(c)
220 #define LOCK_SV_MUTEX
221 #define UNLOCK_SV_MUTEX
224 /* Rats: if dTHR is just blank then the subsequent ";" throws an error */
228 #define dTHR extern int errno
230 #endif /* USE_THREADS */