check in all confperl changes as of change#1964 into cfgperl
[p5sagit/p5-mst-13.2.git] / thread.h
1 #ifdef USE_THREADS
2
3 #ifdef WIN32
4 #  include <win32thread.h>
5 #else
6 #  if defined(OLD_PTHREADS_API) && !defined(DJGPP)
7      /* POSIXish threads */
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))
11 #    define DETACH(t)                           \
12     STMT_START {                                \
13         if (pthread_detach(&(t)->self)) {       \
14             MUTEX_UNLOCK(&(t)->mutex);          \
15             croak("panic: DETACH");             \
16         }                                       \
17     } STMT_END
18 #  else
19 #    define pthread_mutexattr_default NULL
20 #    define pthread_condattr_default NULL
21 #  endif /* OLD_PTHREADS_API */
22 #endif
23
24 #ifndef YIELD
25 #  define YIELD SCHED_YIELD
26 #endif
27
28 #ifdef PTHREAD_CREATE_JOINABLE
29 #  define ATTR_JOINABLE PTHREAD_CREATE_JOINABLE
30 #else
31 #  ifdef PTHREAD_CREATE_UNDETACHED
32 #    define ATTR_JOINABLE PTHREAD_CREATE_UNDETACHED
33 #  else
34 #    ifdef __UNDETACHED
35 #      define ATTR_JOINABLE __UNDETACHED
36 #    endif
37 #  endif
38 #endif
39
40 #ifndef MUTEX_INIT
41 #define MUTEX_INIT(m)                                           \
42     STMT_START {                                                \
43         if (pthread_mutex_init((m), pthread_mutexattr_default)) \
44             croak("panic: MUTEX_INIT");                         \
45     } STMT_END
46 #define MUTEX_LOCK(m)                           \
47     STMT_START {                                \
48         if (pthread_mutex_lock((m)))            \
49             croak("panic: MUTEX_LOCK");         \
50     } STMT_END
51 #define MUTEX_UNLOCK(m)                         \
52     STMT_START {                                \
53         if (pthread_mutex_unlock((m)))          \
54             croak("panic: MUTEX_UNLOCK");       \
55     } STMT_END
56 #define MUTEX_DESTROY(m)                        \
57     STMT_START {                                \
58         if (pthread_mutex_destroy((m)))         \
59             croak("panic: MUTEX_DESTROY");      \
60     } STMT_END
61 #endif /* MUTEX_INIT */
62
63 #ifndef COND_INIT
64 #define COND_INIT(c)                                            \
65     STMT_START {                                                \
66         if (pthread_cond_init((c), pthread_condattr_default))   \
67             croak("panic: COND_INIT");                          \
68     } STMT_END
69 #define COND_SIGNAL(c)                          \
70     STMT_START {                                \
71         if (pthread_cond_signal((c)))           \
72             croak("panic: COND_SIGNAL");        \
73     } STMT_END
74 #define COND_BROADCAST(c)                       \
75     STMT_START {                                \
76         if (pthread_cond_broadcast((c)))        \
77             croak("panic: COND_BROADCAST");     \
78     } STMT_END
79 #define COND_WAIT(c, m)                         \
80     STMT_START {                                \
81         if (pthread_cond_wait((c), (m)))        \
82             croak("panic: COND_WAIT");          \
83     } STMT_END
84 #define COND_DESTROY(c)                         \
85     STMT_START {                                \
86         if (pthread_cond_destroy((c)))          \
87             croak("panic: COND_DESTROY");       \
88     } STMT_END
89 #endif /* COND_INIT */
90
91 /* DETACH(t) must only be called while holding t->mutex */
92 #ifndef DETACH
93 #define DETACH(t)                               \
94     STMT_START {                                \
95         if (pthread_detach((t)->self)) {        \
96             MUTEX_UNLOCK(&(t)->mutex);          \
97             croak("panic: DETACH");             \
98         }                                       \
99     } STMT_END
100 #endif /* DETACH */
101
102 #ifndef JOIN
103 #define JOIN(t, avp)                                    \
104     STMT_START {                                        \
105         if (pthread_join((t)->self, (void**)(avp)))     \
106             croak("panic: pthread_join");               \
107     } STMT_END
108 #endif /* JOIN */
109
110 #ifndef SET_THR
111 #define SET_THR(t)                                      \
112     STMT_START {                                        \
113         if (pthread_setspecific(PL_thr_key, (void *) (t)))      \
114             croak("panic: pthread_setspecific");        \
115     } STMT_END
116 #endif /* SET_THR */
117
118 #ifndef THR
119 #  ifdef OLD_PTHREADS_API
120 struct perl_thread *getTHR _((void));
121 #    define THR getTHR()
122 #  else
123 #    define THR ((struct perl_thread *) pthread_getspecific(PL_thr_key))
124 #  endif /* OLD_PTHREADS_API */
125 #endif /* THR */
126
127 /*
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".
133  */
134 #ifndef dTHR
135 #  define dTHR \
136     struct perl_thread *thr = PL_threadnum? THR : (struct perl_thread*)SvPVX(PL_thrsv)
137 #endif /* dTHR */
138
139 #ifndef INIT_THREADS
140 #  ifdef NEED_PTHREAD_INIT
141 #    define INIT_THREADS pthread_init()
142 #  else
143 #    define INIT_THREADS NOOP
144 #  endif
145 #endif
146
147 /* Accessor for per-thread SVs */
148 #define THREADSV(i) (thr->threadsvp[i])
149
150 /*
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.
155  */
156 #define LOCK_SV_MUTEX                           \
157     STMT_START {                                \
158         if (PL_threadnum)                       \
159             MUTEX_LOCK(&PL_sv_mutex);           \
160     } STMT_END
161
162 #define UNLOCK_SV_MUTEX                         \
163     STMT_START {                                \
164         if (PL_threadnum)                       \
165             MUTEX_UNLOCK(&PL_sv_mutex);         \
166     } STMT_END
167
168 /* Likewise for strtab_mutex */
169 #define LOCK_STRTAB_MUTEX                       \
170     STMT_START {                                \
171         if (PL_threadnum)                       \
172             MUTEX_LOCK(&PL_strtab_mutex);       \
173     } STMT_END
174
175 #define UNLOCK_STRTAB_MUTEX                     \
176     STMT_START {                                \
177         if (PL_threadnum)                       \
178             MUTEX_UNLOCK(&PL_strtab_mutex);     \
179     } STMT_END
180
181 #ifndef THREAD_RET_TYPE
182 #  define THREAD_RET_TYPE       void *
183 #  define THREAD_RET_CAST(p)    ((void *)(p))
184 #endif /* THREAD_RET */
185
186
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
193 #define THRf_DEAD       4
194
195 #define THRf_DID_DIE    8
196
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;         \
201         (t)->flags |= (s);                      \
202         DEBUG_S(PerlIO_printf(PerlIO_stderr(),  \
203                               "thread %p set to state %d\n", (t), (s))); \
204     } STMT_END
205
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 */
211 } condpair_t;
212
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
217
218 #else
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)
224 #define COND_INIT(c)
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
233
234 #define THR
235 /* Rats: if dTHR is just blank then the subsequent ";" throws an error */
236 #ifdef WIN32
237 #define dTHR extern int Perl___notused
238 #else
239 #define dTHR extern int errno
240 #endif
241 #endif /* USE_THREADS */