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