66176a8dfc8c0c4a3261738c2be8b59f80ce710b
[p5sagit/p5-mst-13.2.git] / thread.h
1 #ifdef USE_THREADS
2
3 #ifdef WIN32
4 #  include <win32thread.h>
5 #else
6
7 /* POSIXish threads */
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()
13 #  define DETACH(t)                             \
14     STMT_START {                                \
15         if (pthread_detach(&(t)->self)) {       \
16             MUTEX_UNLOCK(&(t)->mutex);          \
17             croak("panic: DETACH");             \
18         }                                       \
19     } STMT_END
20 #else
21 #  define pthread_mutexattr_default NULL
22 #  define pthread_condattr_default NULL
23 #endif /* OLD_PTHREADS_API */
24 #endif
25
26 #ifdef PTHREADS_CREATED_JOINABLE
27 #  define ATTR_JOINABLE PTHREAD_CREATE_JOINABLE
28 #else
29 #  ifdef PTHREAD_CREATE_UNDETACHED
30 #    define ATTR_JOINABLE PTHREAD_CREATE_UNDETACHED
31 #  else
32 #    define ATTR_JOINABLE PTHREAD_CREATE_JOINABLE
33 #  endif
34 #endif
35
36 #ifndef YIELD
37 #  ifdef HAS_PTHREAD_YIELD
38 #    define YIELD pthread_yield()
39 #  else
40 #    define YIELD sched_yield()
41 #  endif
42 #endif
43
44 #ifndef MUTEX_INIT
45 #define MUTEX_INIT(m)                                           \
46     STMT_START {                                                \
47         if (pthread_mutex_init((m), pthread_mutexattr_default)) \
48             croak("panic: MUTEX_INIT");                         \
49     } STMT_END
50 #define MUTEX_LOCK(m)                           \
51     STMT_START {                                \
52         if (pthread_mutex_lock((m)))            \
53             croak("panic: MUTEX_LOCK");         \
54     } STMT_END
55 #define MUTEX_UNLOCK(m)                         \
56     STMT_START {                                \
57         if (pthread_mutex_unlock((m)))          \
58             croak("panic: MUTEX_UNLOCK");       \
59     } STMT_END
60 #define MUTEX_DESTROY(m)                        \
61     STMT_START {                                \
62         if (pthread_mutex_destroy((m)))         \
63             croak("panic: MUTEX_DESTROY");      \
64     } STMT_END
65 #endif /* MUTEX_INIT */
66
67 #ifndef COND_INIT
68 #define COND_INIT(c)                                            \
69     STMT_START {                                                \
70         if (pthread_cond_init((c), pthread_condattr_default))   \
71             croak("panic: COND_INIT");                          \
72     } STMT_END
73 #define COND_SIGNAL(c)                          \
74     STMT_START {                                \
75         if (pthread_cond_signal((c)))           \
76             croak("panic: COND_SIGNAL");        \
77     } STMT_END
78 #define COND_BROADCAST(c)                       \
79     STMT_START {                                \
80         if (pthread_cond_broadcast((c)))        \
81             croak("panic: COND_BROADCAST");     \
82     } STMT_END
83 #define COND_WAIT(c, m)                         \
84     STMT_START {                                \
85         if (pthread_cond_wait((c), (m)))        \
86             croak("panic: COND_WAIT");          \
87     } STMT_END
88 #define COND_DESTROY(c)                         \
89     STMT_START {                                \
90         if (pthread_cond_destroy((c)))          \
91             croak("panic: COND_DESTROY");       \
92     } STMT_END
93 #endif /* COND_INIT */
94
95 /* DETACH(t) must only be called while holding t->mutex */
96 #ifndef DETACH
97 #define DETACH(t)                               \
98     STMT_START {                                \
99         if (pthread_detach((t)->self)) {        \
100             MUTEX_UNLOCK(&(t)->mutex);          \
101             croak("panic: DETACH");             \
102         }                                       \
103     } STMT_END
104 #endif /* DETACH */
105
106 #ifndef JOIN
107 #define JOIN(t, avp)                                    \
108     STMT_START {                                        \
109         if (pthread_join((t)->self, (void**)(avp)))     \
110             croak("panic: pthread_join");               \
111     } STMT_END
112 #endif /* JOIN */
113
114 #ifndef SET_THR
115 #define SET_THR(t)                                      \
116     STMT_START {                                        \
117         if (pthread_setspecific(thr_key, (void *) (t))) \
118             croak("panic: pthread_setspecific");        \
119     } STMT_END
120 #endif /* SET_THR */
121
122 #ifndef THR
123 #  ifdef OLD_PTHREADS_API
124 struct perl_thread *getTHR _((void));
125 #    define THR getTHR()
126 #  else
127 #    define THR ((struct perl_thread *) pthread_getspecific(thr_key))
128 #  endif /* OLD_PTHREADS_API */
129 #endif /* THR */
130
131 /*
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".
137  */
138 #ifndef dTHR
139 #  define dTHR \
140     struct perl_thread *thr = threadnum? THR : (struct perl_thread*)SvPVX(thrsv)
141 #endif /* dTHR */
142
143 #ifndef INIT_THREADS
144 #  ifdef NEED_PTHREAD_INIT
145 #    define INIT_THREADS pthread_init()
146 #  else
147 #    define INIT_THREADS NOOP
148 #  endif
149 #endif
150
151 /* Accessor for per-thread SVs */
152 #define THREADSV(i) (thr->threadsvp[i])
153
154 /*
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.
159  */
160 #define LOCK_SV_MUTEX                   \
161     STMT_START {                        \
162         if (threadnum)                  \
163             MUTEX_LOCK(&sv_mutex);      \
164     } STMT_END
165
166 #define UNLOCK_SV_MUTEX                 \
167     STMT_START {                        \
168         if (threadnum)                  \
169             MUTEX_UNLOCK(&sv_mutex);    \
170     } STMT_END
171
172 #ifndef THREAD_RET_TYPE
173 #  define THREAD_RET_TYPE       void *
174 #  define THREAD_RET_CAST(p)    ((void *)(p))
175 #endif /* THREAD_RET */
176
177
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
184 #define THRf_DEAD       4
185
186 #define THRf_DID_DIE    8
187
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;         \
192         (t)->flags |= (s);                      \
193         DEBUG_L(PerlIO_printf(PerlIO_stderr(),  \
194                               "thread %p set to state %d\n", (t), (s))); \
195     } STMT_END
196
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 */
202 } condpair_t;
203
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
208
209 #else
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)
215 #define COND_INIT(c)
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
222
223 #define THR
224 /* Rats: if dTHR is just blank then the subsequent ";" throws an error */
225 #ifdef WIN32
226 #define dTHR
227 #else
228 #define dTHR extern int errno
229 #endif
230 #endif /* USE_THREADS */